Skip to content

Commit

Permalink
fix: simplify some code, remove toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
DrewHoo committed Mar 20, 2024
1 parent 76ee7fb commit 1b36d73
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 125 deletions.
95 changes: 95 additions & 0 deletions src/common/ControlLabel.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { JSONSchema } from "json-schema-to-ts"
import { screen } from "@testing-library/react"
import { test, describe, expect } from "vitest"
import { render } from "../common/test-render"
import { UISchema } from "../ui-schema"

const schema = {
type: "object",
properties: {
labelMe: { title: "Label Me", oneOf: [{ type: "string" }] },
},
} satisfies JSONSchema

describe("ControlLabel", () => {
test("ControlLabel renders a title jsonschema property as the label", async () => {
render({ schema })
await screen.findByText("Label Me")
})
test("ControlLabel gives precedence to a string literal label property over the jsonschema title", async () => {
render({
schema,
uischema: {
type: "VerticalLayout",
elements: [
{
type: "Control",
scope: "#/properties/labelMe",
label: "No, Label ME",
},
],
} satisfies UISchema,
})
await screen.findByText("No, Label ME")
})
test("ControlLabel renders text from a label property that is a LabelDescription", async () => {
render({
schema,
uischema: {
type: "VerticalLayout",
elements: [
{
type: "Control",
scope: "#/properties/labelMe",
label: { text: "Srsly, label me instead" },
},
],
} satisfies UISchema,
})
await screen.findByText("Srsly, label me instead")
})
test("ControlLabel renders an AntD Text component from a LabelDescription", async () => {
render({
schema,
uischema: {
type: "VerticalLayout",
elements: [
{
type: "Control",
scope: "#/properties/labelMe",
label: {
text: "Srsly, label me instead",
type: "Text",
textProps: { disabled: true },
},
},
],
} satisfies UISchema,
})
await screen.findByText("Srsly, label me instead")

expect(screen.getByText("Srsly, label me instead")).toHaveClass(
"ant-typography-disabled",
)
})
test("ControlLabel renders an AntD Title component from a LabelDescription", async () => {
render({
schema,
uischema: {
type: "VerticalLayout",
elements: [
{
type: "Control",
scope: "#/properties/labelMe",
label: {
text: "Srsly, label me instead",
type: "Title",
titleProps: { copyable: true },
},
},
],
} satisfies UISchema,
})
await screen.findByLabelText("copy")
})
})
39 changes: 10 additions & 29 deletions src/common/ControlLabelRenderer.tsx → src/common/ControlLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import { JsonSchema } from "@jsonforms/core"
import { ControlUISchema, LabelDescription } from "../ui-schema"
import { JsonSchema, Helpers } from "@jsonforms/core"
import { ControlUISchema } from "../ui-schema"
import { Typography } from "antd"
import { assertNever } from "./assert-never"

export function ControlLabelRenderer({
// This consumes a LabelDescription (+ other formats) in a Control UI Schema
export function ControlLabel({
uischema,
schema,
}: {
uischema: ControlUISchema
schema: JsonSchema
}) {
const controlUISchema: ControlUISchema = uischema
const text = getUiSchemaLabel(controlUISchema)
const labelDescription = Helpers.createLabelDescriptionFrom(uischema, schema)
const text = labelDescription.show ? labelDescription.text : null

if (!text && !schema.title) {
return null
}

if (!text && schema.title) {
return <Typography.Title>{schema.title}</Typography.Title>
}

if (typeof controlUISchema.label === "object" && controlUISchema.label.type) {
if (
typeof controlUISchema.label === "object" &&
"type" in controlUISchema.label
) {
const labelType = controlUISchema.label.type
switch (labelType) {
case "Text":
Expand Down Expand Up @@ -49,19 +46,3 @@ export function ControlLabelRenderer({
}
return <Typography.Title>{text}</Typography.Title>
}

function getUiSchemaLabel(uischema: ControlUISchema): string | undefined {
const label = uischema.label
if (!label) {
return undefined
}
if (
(label as LabelDescription).text &&
(label as LabelDescription).show !== false
) {
return (label as LabelDescription).text
}
if (typeof label === "string") {
return label
}
}
86 changes: 34 additions & 52 deletions src/controls/combinators/CombinatorSchemaSwitcher.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import {
Radio,
RadioChangeEvent,
Select,
Space,
Switch,
Typography,
} from "antd"
import { Radio, RadioChangeEvent, Select } from "antd"
import { OneOfControlOptions } from "../../ui-schema"
import merge from "lodash.merge"
import { useEffect, useState } from "react"
Expand All @@ -16,7 +9,6 @@ import {
createDefaultValue,
} from "@jsonforms/core"
import { usePreviousValue } from "../../common/usePreviousValue"
import { shouldUseRadioGroupSwitcher } from "./utils"

type CombinatorSchemaSwitcherProps = {
renderInfos: CombinatorSubSchemaRenderInfo[]
Expand All @@ -30,12 +22,10 @@ type CombinatorSchemaSwitcherProps = {
| "rootSchema"
| "uischema"
| "config"
| "indexOfFittingSchema"
>

export function CombinatorSchemaSwitcher({
renderInfos,
indexOfFittingSchema,
config,
uischema,
setSelectedIndex,
Expand Down Expand Up @@ -93,50 +83,42 @@ export function CombinatorSchemaSwitcher({
value: index,
}))

if (shouldUseRadioGroupSwitcher(oneOfOptionType)) {
return (
<Radio.Group
{...(oneOfOptionType === "button" && {
optionType: "button",
buttonStyle: "solid",
})}
options={options}
onChange={(e: RadioChangeEvent) => {
const combinatorIndex = e.target.value as number
setSelectedIndex(combinatorIndex)
}}
value={selectedIndex}
/>
)
}
if (oneOfOptionType === "dropdown") {
return (
<Select
options={options}
onChange={(combinatorIndex: number) =>
setSelectedIndex(combinatorIndex)
}
defaultValue={selectedIndex}
/>
)
}
if (oneOfOptionType === "toggle") {
return (
<Space>
<Switch
onChange={(value: boolean) => {
const combinatorIndex = value === false ? 0 : 1
switch (oneOfOptionType) {
case "button":
return (
<Radio.Group
optionType="button"
buttonStyle="solid"
options={options}
onChange={(e: RadioChangeEvent) => {
const combinatorIndex = e.target.value as number
setSelectedIndex(combinatorIndex)
}}
value={selectedIndex}
/>
)
case "dropdown":
return (
<Select
options={options}
onChange={(combinatorIndex: number) =>
setSelectedIndex(combinatorIndex)
}
defaultValue={selectedIndex}
/>
)
case "radio":
default:
return (
<Radio.Group
options={options}
onChange={(e: RadioChangeEvent) => {
const combinatorIndex = e.target.value as number
setSelectedIndex(combinatorIndex)
}}
defaultChecked={indexOfFittingSchema === 1}
value={selectedIndex}
/>
{appliedUiSchemaOptions.toggleLabel && (
<Typography.Text>
{appliedUiSchemaOptions.toggleLabel}
</Typography.Text>
)}
</Space>
)
)
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/controls/combinators/OneOfControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { JsonFormsDispatch, withJsonFormsOneOfProps } from "@jsonforms/react"
import { Space } from "antd"
import { useState } from "react"
import { ControlUISchema } from "../../ui-schema"
import { ControlLabelRenderer } from "../../common/ControlLabelRenderer"
import { ControlLabel } from "../../common/ControlLabel"
import { CombinatorSchemaSwitcher } from "./CombinatorSchemaSwitcher"

export function OneOfControl({
Expand Down Expand Up @@ -39,14 +39,13 @@ export function OneOfControl({
<Space direction="vertical" style={{ width: "100%" }} size="middle">
{uischema.type === "Control" && ( // I don't think it's possible for this to be false
// but until we improve the UISchema types a bit, it's hard to be sure
<ControlLabelRenderer
<ControlLabel
uischema={uischema as ControlUISchema}
schema={schema}
/>
)}
<CombinatorSchemaSwitcher
config={config as unknown}
indexOfFittingSchema={indexOfFittingSchema}
renderInfos={oneOfRenderInfos}
selectedIndex={selectedIndex}
setSelectedIndex={setSelectedIndex}
Expand Down
12 changes: 0 additions & 12 deletions src/controls/combinators/utils.ts

This file was deleted.

31 changes: 30 additions & 1 deletion src/stories/controls/OneOfControl.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export const Dropdown: Story = {
},
}

export const OneOfLabelStyling: Story = {
export const OneOfTitleLabelStyling: Story = {
parameters: { controls: { expanded: true } },
tags: ["autodocs"],
args: {
Expand Down Expand Up @@ -166,3 +166,32 @@ export const OneOfLabelStyling: Story = {
},
},
}

export const OneOfTextLabelStyling: Story = {
parameters: { controls: { expanded: true } },
tags: ["autodocs"],
args: {
jsonSchema: schema,
uiSchema: {
type: "VerticalLayout",
elements: [
{
type: "Control",
label: {
type: "Text",
text: "Titles are configurable with AntD Title Props",
textProps: { disabled: true, type: "secondary" },
},
scope: "#/properties/deliveryOption",
options: { optionType: "dropdown" } satisfies OneOfControlOptions,
},
],
},
},
argTypes: {
jsonSchema: {
control: "object",
description: "this is a minimal oneOf combinator schema",
},
},
}
Loading

0 comments on commit 1b36d73

Please sign in to comment.