Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: redesign InfoCards component and update schema #414

Merged
merged 14 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/studio/src/components/PageEditor/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const DEFAULT_BLOCKS: Record<
type: "infocards",
title: "This is an optional title of the Infocards component",
subtitle: "This is an optional subtitle for the Infocards component",
variant: "cardsWithImages",
cards: [
{
title: "This is the first card",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useEffect, useState } from "react"
import { Box, FormControl } from "@chakra-ui/react"
import {
createCombinatorRenderInfos,
createDefaultValue,
isAnyOfControl,
rankWith,
} from "@jsonforms/core"
Expand All @@ -27,7 +28,9 @@ export function JsonFormsAnyOfControl({
label,
handleChange,
indexOfFittingSchema,
data,
}: CombinatorRendererProps) {
const [variant, setVariant] = useState("")
const anyOfRenderInfos = createCombinatorRenderInfos(
schema.anyOf ?? [],
rootSchema,
Expand All @@ -46,11 +49,21 @@ export function JsonFormsAnyOfControl({
}
})

const [variant, setVariant] = useState("")

const onChange = (value: string) => {
setVariant(value)
handleChange(path, value)

const newSchema =
anyOfRenderInfos[options.findIndex((option) => option.value === value)]
?.schema
if (!newSchema) {
handleChange(path, {})
} else {
const newData = createDefaultValue(newSchema, rootSchema)
handleChange(path, {
...data,
...newData,
})
}
}

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export function JsonFormsBooleanControl({
errors,
path,
description,
}: ControlProps) {
schema,
}: ControlProps): JSX.Element {
if (schema.const !== undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's schema.const?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

schema.const is a JSON Schema construct where the particular property takes in a specific literal (can be string/number/boolean). In this case, if the const is defined (say it's true) then it is not meaningful to show the toggle, since the false` case is invalid.

return <></>
}

return (
<Box py={2}>
<FormControl>
Expand All @@ -34,7 +39,7 @@ export function JsonFormsBooleanControl({
<Switch
id={id}
isDisabled={!enabled}
checked={data || false}
checked={!!data}
onChange={(e) => handleChange(path, e.target.checked)}
/>
<FormErrorMessage>{errors}</FormErrorMessage>
Expand Down
2 changes: 2 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
"chromatic": "npx chromatic --project-token=$CHROMATIC_PROJECT_TOKEN",
"clean": "git clean -xdf .turbo node_modules dist",
"format": "prettier --check . --ignore-path ../../.gitignore",
"format:fix": "prettier --write . --ignore-path ../../.gitignore",
"lint": "eslint",
"lint:fix": "eslint --fix",
"typecheck": "tsc --noEmit --emitDeclarationOnly false"
},
"author": {
Expand Down
108 changes: 75 additions & 33 deletions packages/components/src/interfaces/complex/InfoCards.ts
Original file line number Diff line number Diff line change
@@ -1,61 +1,103 @@
import type { Static } from "@sinclair/typebox"
import { Type } from "@sinclair/typebox"

export const SingleCardSchema = Type.Object({
const SingleCardNoImageSchema = Type.Object({
title: Type.String({
title: "Title",
default: "This is the title of the card",
}),
description: Type.Optional(
Type.String({
title: "Description",
default: "This is an optional description for the card",
}),
),
buttonLabel: Type.Optional(
url: Type.Optional(
Type.String({
title: "Link text",
description:
"A descriptive text. Avoid generic text such as “Click here” or “Learn more”",
title: "Link destination",
description: "When this is clicked, open:",
}),
),
url: Type.String({
title: "Link destination",
description: "When this is clicked, open:",
}),
imageUrl: Type.String({
title: "Upload image",
format: "image",
}),
imageAlt: Type.String({
title: "Alternate text",
description:
"Add a descriptive alternative text for this image. This helps visually impaired users to understand your image.",
})

const SingleCardWithImageSchema = Type.Composite([
SingleCardNoImageSchema,
Type.Object({
imageUrl: Type.String({
title: "Upload image",
format: "image",
}),
imageAlt: Type.String({
title: "Alternate text",
description:
"Add a descriptive alternative text for this image. This helps visually impaired users to understand your image.",
}),
}),
])

const InfoCardsBaseSchema = Type.Object({
type: Type.Literal("infocards", { default: "infocards" }),
title: Type.Optional(
Type.String({
title: "Title",
default: "This is an optional title of the Cards component",
}),
),
subtitle: Type.Optional(
Type.String({
title: "Description",
default: "This is an optional description for the Cards component",
}),
),
})

export const InfoCardsSchema = Type.Object(
const InfoCardsWithImageSchema = Type.Object(
{
type: Type.Literal("infocards", { default: "infocards" }),
title: Type.Optional(
Type.String({
title: "Title",
}),
),
subtitle: Type.Optional(
Type.String({
title: "Description",
}),
),
cards: Type.Array(SingleCardSchema, {
variant: Type.Literal("cardsWithImages", { default: "cardsWithImages" }),
cards: Type.Array(SingleCardWithImageSchema, {
title: "Cards",
minItems: 1,
default: [],
}),
},
{
title: "Infocards component",
title: "Cards with images",
},
)

export type SingleCardProps = Static<typeof SingleCardSchema>
const InfoCardsNoImageSchema = Type.Object(
{
variant: Type.Literal("cardsWithoutImages", {
default: "cardsWithoutImages",
}),
cards: Type.Array(SingleCardNoImageSchema, {
title: "Cards",
default: [],
}),
},
{
title: "Cards without images",
},
)

export const InfoCardsSchema = Type.Intersect(
[
InfoCardsBaseSchema,
Type.Union([InfoCardsWithImageSchema, InfoCardsNoImageSchema]),
],
{
title: "Cards component",
},
)

export type SingleCardNoImageProps = Static<typeof SingleCardNoImageSchema> & {
LinkComponent?: any // Next.js link

Check warning on line 93 in packages/components/src/interfaces/complex/InfoCards.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
}
export type SingleCardWithImageProps = Static<
typeof SingleCardWithImageSchema
> & {
LinkComponent?: any // Next.js link

Check warning on line 98 in packages/components/src/interfaces/complex/InfoCards.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
}
export type InfoCardsProps = Static<typeof InfoCardsSchema> & {
LinkComponent?: any // Next.js link

Check warning on line 101 in packages/components/src/interfaces/complex/InfoCards.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
sectionIdx?: number // TODO: Remove this property, only used in classic theme
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export { default as Footer } from "./Footer"
export { default as Header } from "./Header"
export { default as Image } from "./Image"
export { default as Infobar } from "./Infobar"
export { default as InfoCards } from "./InfoCards"
export { default as InfoPic } from "./Infopic"
export { default as Masthead } from "./Masthead"
export { default as Navbar } from "./Navbar"
Expand Down
Loading
Loading