From 6e337bace662d2045a383a8581a1e947512001cd Mon Sep 17 00:00:00 2001 From: twin Date: Tue, 16 Jul 2024 16:30:15 +0500 Subject: [PATCH] feat: improve hints Add showLayoutDescription props Add tests and update docs --- docs/lib.md | 15 ++-- docs/spec.md | 52 ++++++------- playwright/core/DynamicView.tsx | 19 ++++- src/lib/core/components/View/DynamicView.tsx | 20 ++++- src/lib/core/components/View/index.ts | 1 + src/lib/core/components/View/types/context.ts | 1 + src/lib/core/types/specs.ts | 1 + .../TableArrayInput/TableArrayInput.tsx | 14 +++- .../__tests__/TableArrayInput.visual.test.tsx | 8 ++ .../TableArrayInput/__tests__/helpers.tsx | 74 +++++++++++++++++++ .../ViewAccordeon/ViewAccordeon.tsx | 8 +- .../ViewLayouts/ViewRow/ViewRow.scss | 4 + .../ViewLayouts/ViewRow/ViewRow.tsx | 12 ++- .../ViewRow/__tests__/ViewRow.visual.test.tsx | 20 +++++ .../ViewLayouts/ViewRow/__tests__/helpers.ts | 52 +++++++++++++ .../Views/TableArrayView/TableArrayView.tsx | 23 +++++- src/stories/ArrayTable.stories.tsx | 2 +- src/stories/Editor.stories.tsx | 9 ++- src/stories/ObjectBase.stories.tsx | 6 +- .../components/DynamicView/DynamicView.tsx | 4 +- src/stories/components/Editor/Editor.tsx | 21 +++++- .../components/InputPreview/constants.ts | 5 ++ 22 files changed, 317 insertions(+), 54 deletions(-) create mode 100644 src/lib/kit/components/ViewLayouts/ViewRow/__tests__/ViewRow.visual.test.tsx create mode 100644 src/lib/kit/components/ViewLayouts/ViewRow/__tests__/helpers.ts diff --git a/docs/lib.md b/docs/lib.md index 76797dc1..7d2bcd36 100644 --- a/docs/lib.md +++ b/docs/lib.md @@ -39,13 +39,14 @@ This component locates all required rendering elements and renders the entity. This component serves as the primary entry point for creating an overview of form values. -| Property | Type | Required | Description | -| :------- | :------------------------------------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------------------- | -| value | `AnyObject` | yes | Form value | -| spec | `Spec` | yes | An [spec](./spec.md#specs) describing the entity | -| config | `DynamicViewConfig` | yes | A [config](./config.md) containing [Views](./config.md#views) and [ViewLayouts](./config.md#viewlayouts) for each entity | -| Link | `React.ComponentType<{value: FormValue; link: Spec['viewSpec']['link'];}>` | | [Component](./spec.md#link) for converting values to links | -| Monaco | `React.ComponentType` | | [MonacoEditor](https://github.com/react-monaco-editor/react-monaco-editor) component for Monaco [Input](./config.md#inputs) | +| Property | Type | Required | Description | +| :-------------------- | :------------------------------------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------------------- | +| value | `AnyObject` | yes | Form value | +| spec | `Spec` | yes | An [spec](./spec.md#specs) describing the entity | +| config | `DynamicViewConfig` | yes | A [config](./config.md) containing [Views](./config.md#views) and [ViewLayouts](./config.md#viewlayouts) for each entity | +| Link | `React.ComponentType<{value: FormValue; link: Spec['viewSpec']['link'];}>` | | [Component](./spec.md#link) for converting values to links | +| Monaco | `React.ComponentType` | | [MonacoEditor](https://github.com/react-monaco-editor/react-monaco-editor) component for Monaco [Input](./config.md#inputs) | +| showLayoutDescription | boolean | | enable to show viewSpec.layoutDescription hint | ### ViewController diff --git a/docs/spec.md b/docs/spec.md index 58676797..08fc17f6 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -8,32 +8,32 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; ### ArraySpec -| Property | Type | Required | Description | -| :------------------------- | :------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| defaultValue | `FieldArrayValue` | | Default value | -| type | `"array"` | yes | Entity type | -| required | `boolean` | | Can the value be `undefined` or `null` | -| maxLength | `bigint` | | Maximum number of array elements | -| minLength | `bigint` | | Minimum number of array elements | -| items | `Spec` | | Entity `spec` for an array element | -| enum | `string[]` | | An array of valid values, for example for a select | -| description | `Record` | | Beautiful names for values from `enum` | -| validator | `string` | | The key for determining the [validator](./config.md#validators) for the entity, if the value is empty, the base [validator](./config.md#validators) from the entity config will be used | -| viewSpec.disabled | `boolean` | | Is the field available for editing | -| viewSpec.type | `string` | yes | Key to define [Input](./config.md#inputs) for an entity | -| viewSpec.layout | `string` | | Key to define [Layout](./config.md#layouts) for an entity | -| viewSpec.layoutTitle | `string` | | Title for [Layout](./config.md#layouts) | -| viewSpec.layoutDescription | `string` | | Additional description/hint for [Layout](./config.md#layouts) | -| viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering | -| viewSpec.itemLabel | `string` | | Text for the button that adds an array element | -| viewSpec.itemPrefix | `string` | | Additional text for an element in the array | -| viewSpec.table | `{label: string; property: string;}[]` | | An array whose elements are used to establish column names and their order, if `type === "table"` | -| viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value | -| viewSpec.placeholder | `string` | | A short hint displayed in the field before the user enters the value | -| viewSpec.addButtonPosition | `"down"/"right"` | | The location of the button adding a new element to the array. Default value "down". | -| viewSpec.hidden | `boolean` | | Hide field and view | -| viewSpec.selectParams | `object` | | [Parameters](#selectparams) additional options for the selector | -| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | +| Property | Type | Required | Description | +| :------------------------- | :----------------------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| defaultValue | `FieldArrayValue` | | Default value | +| type | `"array"` | yes | Entity type | +| required | `boolean` | | Can the value be `undefined` or `null` | +| maxLength | `bigint` | | Maximum number of array elements | +| minLength | `bigint` | | Minimum number of array elements | +| items | `Spec` | | Entity `spec` for an array element | +| enum | `string[]` | | An array of valid values, for example for a select | +| description | `Record` | | Beautiful names for values from `enum` | +| validator | `string` | | The key for determining the [validator](./config.md#validators) for the entity, if the value is empty, the base [validator](./config.md#validators) from the entity config will be used | +| viewSpec.disabled | `boolean` | | Is the field available for editing | +| viewSpec.type | `string` | yes | Key to define [Input](./config.md#inputs) for an entity | +| viewSpec.layout | `string` | | Key to define [Layout](./config.md#layouts) for an entity | +| viewSpec.layoutTitle | `string` | | Title for [Layout](./config.md#layouts) | +| viewSpec.layoutDescription | `string` | | Additional description/hint for [Layout](./config.md#layouts) | +| viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering | +| viewSpec.itemLabel | `string` | | Text for the button that adds an array element | +| viewSpec.itemPrefix | `string` | | Additional text for an element in the array | +| viewSpec.table | `{label: string; property: string; description?: string;}[]` | | An array whose elements are used to establish column names and their order, if `type === "table"`. `description` adds a hint to a field in the table's header | +| viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value | +| viewSpec.placeholder | `string` | | A short hint displayed in the field before the user enters the value | +| viewSpec.addButtonPosition | `"down"/"right"` | | The location of the button adding a new element to the array. Default value "down". | +| viewSpec.hidden | `boolean` | | Hide field and view | +| viewSpec.selectParams | `object` | | [Parameters](#selectparams) additional options for the selector | +| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | ### BooleanSpec diff --git a/playwright/core/DynamicView.tsx b/playwright/core/DynamicView.tsx index 494ffe0a..260329a6 100644 --- a/playwright/core/DynamicView.tsx +++ b/playwright/core/DynamicView.tsx @@ -5,6 +5,21 @@ import {Spec} from '../../src/lib/core/types/specs'; import {FormValue} from '../../src/lib/core/types/value'; import {dynamicViewConfig} from '../../src/lib/kit/constants/config'; -export const DynamicView = ({spec, value}: {spec: Spec; value: FormValue}) => { - return ; +export const DynamicView = ({ + spec, + value, + showLayoutDescription, +}: { + spec: Spec; + value: FormValue; + showLayoutDescription?: boolean; +}) => { + return ( + + ); }; diff --git a/src/lib/core/components/View/DynamicView.tsx b/src/lib/core/components/View/DynamicView.tsx index 5da8f6d3..e636685a 100644 --- a/src/lib/core/components/View/DynamicView.tsx +++ b/src/lib/core/components/View/DynamicView.tsx @@ -20,14 +20,28 @@ export interface DynamicViewProps { link: Spec['viewSpec']['link']; }>; Monaco?: React.ComponentType; + showLayoutDescription?: boolean; } -export const DynamicView = ({value, spec, config, Link, Monaco}: DynamicViewProps) => { +export const DynamicView = ({ + value, + spec, + config, + Link, + Monaco, + showLayoutDescription, +}: DynamicViewProps) => { const DynamicFormsCtx = useCreateContext(); const context = React.useMemo( - () => ({config, value, Link, Monaco: isValidElementType(Monaco) ? Monaco : undefined}), - [config, value, Link, Monaco], + () => ({ + config, + value, + showLayoutDescription, + Link, + Monaco: isValidElementType(Monaco) ? Monaco : undefined, + }), + [config, value, Link, Monaco, showLayoutDescription], ); if (isCorrectSpec(spec) && isCorrectViewConfig(config)) { diff --git a/src/lib/core/components/View/index.ts b/src/lib/core/components/View/index.ts index a7f9f6bc..96e59804 100644 --- a/src/lib/core/components/View/index.ts +++ b/src/lib/core/components/View/index.ts @@ -2,3 +2,4 @@ export * from './DynamicView'; export * from './ViewController'; export * from './helpers'; export * from './types'; +export {useDynamicFormsCtx} from './hooks'; diff --git a/src/lib/core/components/View/types/context.ts b/src/lib/core/components/View/types/context.ts index e4474f00..89e8e3d8 100644 --- a/src/lib/core/components/View/types/context.ts +++ b/src/lib/core/components/View/types/context.ts @@ -9,6 +9,7 @@ import {DynamicViewConfig} from './'; export interface DynamicViewContext { config: DynamicViewConfig; value: FormValue; + showLayoutDescription?: boolean; Link?: React.ComponentType<{ value: FormValue; link: Spec['viewSpec']['link']; diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index dc9a6b52..b19f291b 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -31,6 +31,7 @@ export interface ArraySpec< table?: { label: string; property: string; + description?: string; }[]; link?: LinkType; placeholder?: string; diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index 393e4b23..7e8afa3e 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -1,7 +1,8 @@ import React from 'react'; import {Plus, TrashBin} from '@gravity-ui/icons'; -import {Button, Icon, Table} from '@gravity-ui/uikit'; +import {Button, Flex, Icon, Table} from '@gravity-ui/uikit'; +import {HelpPopover} from '@gravity-ui/components'; import noop from 'lodash/noop'; import set from 'lodash/set'; @@ -100,9 +101,16 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => ), }; - const columns = table.map(({property, label}) => ({ + const columns = table.map(({property, label, description}) => ({ id: property, - name: label, + name: !description + ? label + : () => ( + + {label} + + + ), template: ( { key, diff --git a/src/lib/kit/components/Inputs/TableArrayInput/__tests__/TableArrayInput.visual.test.tsx b/src/lib/kit/components/Inputs/TableArrayInput/__tests__/TableArrayInput.visual.test.tsx index d34d205d..fb5e41d8 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/__tests__/TableArrayInput.visual.test.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/__tests__/TableArrayInput.visual.test.tsx @@ -40,6 +40,14 @@ test.describe('Table Array Input', () => { await expectScreenshot(); }); + + test('table property description', async ({mount, expectScreenshot}) => { + const component = await mount(); + + await component.getByText('Candidate').click(); + + await expectScreenshot(); + }); }); test.describe('Table Array Input view', () => { diff --git a/src/lib/kit/components/Inputs/TableArrayInput/__tests__/helpers.tsx b/src/lib/kit/components/Inputs/TableArrayInput/__tests__/helpers.tsx index 7cbaba25..d24a3fde 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/__tests__/helpers.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/__tests__/helpers.tsx @@ -406,6 +406,80 @@ export const TABLE_ARRAY_INPUT: Record = { ], }, }, + propertyDescription: { + type: SpecTypes.Array, + items: { + type: SpecTypes.Object, + properties: { + name: { + type: SpecTypes.String, + viewSpec: { + type: 'base', + layout: 'table_item', + }, + }, + age: { + type: SpecTypes.Number, + viewSpec: { + type: 'base', + layout: 'table_item', + }, + }, + size: { + type: SpecTypes.Array, + enum: ['s', 'm', 'l'], + description: { + s: 'Small', + m: 'Medium', + l: 'Large', + }, + viewSpec: { + type: 'select', + layout: 'table_item', + }, + }, + license: { + type: SpecTypes.Boolean, + viewSpec: { + type: 'base', + layout: 'table_item', + }, + }, + }, + viewSpec: { + type: '', + }, + }, + viewSpec: { + type: 'table', + layout: 'accordeon', + layoutTitle: 'Table', + layoutOpen: true, + itemLabel: 'Candidate', + table: [ + { + label: 'Name', + property: 'name', + description: 'Description for name', + }, + { + label: 'Age', + property: 'age', + description: 'Description for age', + }, + { + label: 'Size', + property: 'size', + description: 'Description for size', + }, + { + label: 'Driver license', + property: 'license', + description: 'Description for license', + }, + ], + }, + }, }; export const VALUE: Record = { diff --git a/src/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.tsx b/src/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.tsx index f089701c..7e866445 100644 --- a/src/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.tsx +++ b/src/lib/kit/components/ViewLayouts/ViewAccordeon/ViewAccordeon.tsx @@ -2,7 +2,7 @@ import React from 'react'; import isBoolean from 'lodash/isBoolean'; -import {ArrayViewLayoutProps, ObjectViewLayoutProps} from '../../../../core'; +import {ArrayViewLayoutProps, ObjectViewLayoutProps, useDynamicFormsCtx} from '../../../../core'; import {isNotEmptyValue} from '../../../utils'; import {SimpleVerticalAccordeon} from '../../SimpleVerticalAccordeon'; @@ -12,6 +12,7 @@ export const ViewAccordeon = { + const {showLayoutDescription} = useDynamicFormsCtx(); const [open, setOpen] = React.useState( isBoolean(spec.viewSpec.layoutOpen) ? spec.viewSpec.layoutOpen : true, ); @@ -24,6 +25,11 @@ export const ViewAccordeon = ({ spec, children, }: ViewLayoutProps) => { + const {showLayoutDescription} = useDynamicFormsCtx(); + if (!isNotEmptyValue(value, spec)) { return null; } @@ -25,6 +28,13 @@ export const ViewRow = ({ {spec.viewSpec.layoutTitle} + {showLayoutDescription && spec.viewSpec.layoutDescription ? ( + + ) : null}
{children}
diff --git a/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/ViewRow.visual.test.tsx b/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/ViewRow.visual.test.tsx new file mode 100644 index 00000000..ce4f38fa --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/ViewRow.visual.test.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +import {VALUE, VIEW_ROW} from './helpers'; + +import {test} from '~playwright/core'; +import {DynamicView} from '~playwright/core/DynamicView'; + +test.describe('ViewRow View', () => { + test('object spec', async ({mount, expectScreenshot}) => { + await mount(); + + await expectScreenshot(); + }); + + test('object spec with layoutDescription', async ({mount, expectScreenshot}) => { + await mount(); + + await expectScreenshot(); + }); +}); diff --git a/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/helpers.ts b/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/helpers.ts new file mode 100644 index 00000000..0153ea36 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewRow/__tests__/helpers.ts @@ -0,0 +1,52 @@ +import {FormValue, ObjectSpec, SpecTypes} from '../../../../../core'; + +export const VIEW_ROW: ObjectSpec = { + defaultValue: { + name: 'value', + age: 10, + license: false, + }, + type: SpecTypes.Object, + properties: { + name: { + type: SpecTypes.String, + viewSpec: { + type: 'base', + layout: 'row', + layoutDescription: 'Description for Name', + layoutTitle: 'Name', + }, + }, + age: { + type: SpecTypes.Number, + viewSpec: { + type: 'base', + layout: 'row', + layoutDescription: 'Description for Age', + layoutTitle: 'Age', + }, + }, + license: { + type: SpecTypes.Boolean, + viewSpec: { + type: 'base', + layout: 'row', + layoutDescription: 'Description for License', + layoutTitle: 'License', + }, + }, + }, + viewSpec: { + type: 'base', + layout: 'accordeon', + layoutTitle: 'Candidate', + layoutDescription: 'Description for base', + layoutOpen: true, + }, +}; + +export const VALUE: FormValue = { + name: 'name', + age: 21, + license: true, +}; diff --git a/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx b/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx index f602388b..0ee084d7 100644 --- a/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx +++ b/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Table} from '@gravity-ui/uikit'; +import {Flex, Table} from '@gravity-ui/uikit'; import { ArrayView, @@ -10,14 +10,18 @@ import { isArraySpec, isBooleanSpec, isObjectSpec, + useDynamicFormsCtx, } from '../../../../core'; import {block} from '../../../utils'; import './TableArrayView.scss'; +import {HelpPopover} from '@gravity-ui/components'; const b = block('table-array-view'); export const TableArrayView: ArrayView = ({value = [], spec, name}) => { + const {showLayoutDescription} = useDynamicFormsCtx(); + const columns = React.useMemo(() => { const { items, @@ -39,9 +43,20 @@ export const TableArrayView: ArrayView = ({value = [], spec, name}) => { ), }; - const columns = table.map(({property, label}) => ({ + const columns = table.map(({property, label, description}) => ({ id: property, - name: label, + name: + description && showLayoutDescription + ? () => ( + + {label} + + + ) + : label, template: (_: FormValue, idx: number) => { const entitySpec = items?.properties?.[property]; @@ -65,7 +80,7 @@ export const TableArrayView: ArrayView = ({value = [], spec, name}) => { })); return [idxColumn, ...columns]; - }, [name, spec]); + }, [name, spec, showLayoutDescription]); if (!columns) { return null; diff --git a/src/stories/ArrayTable.stories.tsx b/src/stories/ArrayTable.stories.tsx index 26739f54..1ffa74c1 100644 --- a/src/stories/ArrayTable.stories.tsx +++ b/src/stories/ArrayTable.stories.tsx @@ -46,7 +46,7 @@ const spec: ArraySpec = { layoutOpen: true, itemLabel: 'Candidate', table: [ - {label: 'Name', property: 'name'}, + {label: 'Name', property: 'name', description: 'Your first name'}, {label: 'Age', property: 'age'}, {label: 'Size', property: 'size'}, {label: 'Driver license', property: 'license'}, diff --git a/src/stories/Editor.stories.tsx b/src/stories/Editor.stories.tsx index 992e1569..09c91af8 100644 --- a/src/stories/Editor.stories.tsx +++ b/src/stories/Editor.stories.tsx @@ -33,7 +33,13 @@ const spec: ObjectSpec = { properties: { id: { type: SpecTypes.Number, - viewSpec: {type: 'base', layout: 'row', layoutTitle: 'id', copy: true}, + viewSpec: { + type: 'base', + layout: 'row', + layoutTitle: 'id', + layoutDescription: 'uniq id', + copy: true, + }, }, name: { type: SpecTypes.String, @@ -121,6 +127,7 @@ const spec: ObjectSpec = { type: 'base', layout: 'accordeon', layoutTitle: 'Labels', + layoutDescription: 'List of tags', layoutOpen: true, itemLabel: 'Add element', }, diff --git a/src/stories/ObjectBase.stories.tsx b/src/stories/ObjectBase.stories.tsx index 2d85c844..ae82d076 100644 --- a/src/stories/ObjectBase.stories.tsx +++ b/src/stories/ObjectBase.stories.tsx @@ -16,7 +16,11 @@ const baseSpec: ObjectSpec = { properties: { name: { type: SpecTypes.String, - viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Name'}, + viewSpec: { + type: 'base', + layout: 'row', + layoutTitle: 'Name', + }, }, age: { type: SpecTypes.Number, diff --git a/src/stories/components/DynamicView/DynamicView.tsx b/src/stories/components/DynamicView/DynamicView.tsx index 38d83844..27fa6e83 100644 --- a/src/stories/components/DynamicView/DynamicView.tsx +++ b/src/stories/components/DynamicView/DynamicView.tsx @@ -15,14 +15,16 @@ import {DynLink} from './DynLink'; export interface DynamicViewProps { value: FormValue; spec: Spec; + showLayoutDescription?: boolean; } -export const DynamicView: React.FC = ({value, spec}) => ( +export const DynamicView: React.FC = ({value, spec, showLayoutDescription}) => ( ); diff --git a/src/stories/components/Editor/Editor.tsx b/src/stories/components/Editor/Editor.tsx index d8800321..38fd3cdf 100644 --- a/src/stories/components/Editor/Editor.tsx +++ b/src/stories/components/Editor/Editor.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {RadioButton, Switch, Text, useTheme} from '@gravity-ui/uikit'; +import {Flex, RadioButton, Switch, Text, useTheme} from '@gravity-ui/uikit'; import noop from 'lodash/noop'; import {Form} from 'react-final-form'; import MonacoEditor from 'react-monaco-editor'; @@ -30,6 +30,7 @@ export interface EditorProps { export const Editor: React.FC = ({spec: externalSpec, value, viewMode}) => { const [spec, setSpec] = React.useState(externalSpec); const [ready, setReady] = React.useState(true); + const [showLayoutDescription, setShowLayoutDescription] = React.useState(false); const [toggler, setToggler] = React.useState<'form' | 'view' | 'json'>('form'); const [parseJson, setParseJson] = React.useState(false); const theme = useTheme(); @@ -105,13 +106,14 @@ export const Editor: React.FC = ({spec: externalSpec, value, viewMo ); const getViewProps = React.useCallback( - (values: FormValue, spec: Spec) => ({ + (values: FormValue, spec: Spec, showLayoutDescription: boolean) => ({ value: {'__any-name': values}, spec: { type: SpecTypes.Object, properties: {'__any-name': spec}, viewSpec: {type: 'base'}, }, + showLayoutDescription, }), [], ); @@ -158,7 +160,20 @@ export const Editor: React.FC = ({spec: externalSpec, value, viewMo ) : null}
- + + Enable showLayoutDescription props + setShowLayoutDescription((v) => !v)} + className={b('switch')} + /> + +
{toggler === 'json' ? (
diff --git a/src/stories/components/InputPreview/constants.ts b/src/stories/components/InputPreview/constants.ts index 62bebe5a..1c309224 100644 --- a/src/stories/components/InputPreview/constants.ts +++ b/src/stories/components/InputPreview/constants.ts @@ -267,6 +267,10 @@ const table: ArraySpec = { type: SpecTypes.String, viewSpec: {type: 'base', layout: 'table_item'}, }, + description: { + type: SpecTypes.String, + viewSpec: {type: 'base', layout: 'table_item'}, + }, }, viewSpec: {type: ''}, }, @@ -277,6 +281,7 @@ const table: ArraySpec = { table: [ {label: 'Property', property: 'property'}, {label: 'Label', property: 'label'}, + {label: 'Description', property: 'description'}, ], }, };