From d59d3a7918080b6ab802e4a002d6057577351663 Mon Sep 17 00:00:00 2001 From: Nikita Zolotykh <58661343+bocembocem@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:50:57 +0300 Subject: [PATCH] feat: add input props for checkbox input (#191) --- docs/input-props-map.md | 11 ++++ docs/spec.md | 4 ++ .../components/Inputs/Checkbox/Checkbox.tsx | 11 +++- src/stories/ArrayBase.stories.tsx | 1 + src/stories/ArrayTable.stories.tsx | 1 + src/stories/BooleanSwitch.stories.tsx | 2 +- src/stories/ObjectBase.stories.tsx | 1 + src/stories/ObjectCardOneOf.stories.tsx | 7 ++- src/stories/ObjectInline.stories.tsx | 1 + src/stories/ObjectMultiOneOf.stories.tsx | 1 + src/stories/ObjectMultiOneOfFlat.stories.tsx | 1 + src/stories/ObjectOneOf.stories.tsx | 7 ++- src/stories/ObjectOneOfFlat.stories.tsx | 7 ++- src/stories/ObjectSecret.stories.tsx | 1 + src/stories/ObjectTextLink.stories.tsx | 1 + src/stories/ObjectValue.stories.tsx | 1 + src/stories/StringFileInput.stories.tsx | 1 + src/stories/StringMonaco.stories.tsx | 1 + src/stories/StringNumberWithScale.stories.tsx | 1 + src/stories/StringTextContent.stories.tsx | 1 + .../components/InputPreview/constants.ts | 50 +++++++++++++++++++ src/stories/components/InputPreview/utils.ts | 26 ++++++++++ 22 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 docs/input-props-map.md diff --git a/docs/input-props-map.md b/docs/input-props-map.md new file mode 100644 index 00000000..8d9df816 --- /dev/null +++ b/docs/input-props-map.md @@ -0,0 +1,11 @@ +## Supported input props map + +| Config type | Config name | Storybook | Type | Original component | +| :---------- | :---------- | :----------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- | :----------------------------------------------------------------------------- | +| `array` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/array-select--select) | [MultiSelectProps](../src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx#L10) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select | +| `boolean` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/boolean-base--base) | [CheckboxProps](../src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Checkbox | +| `number` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/number-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text | +| `string` | `base` | [Base](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-base--base) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text | +| `string` | `password` | [Password](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-password--password) | [TextProps](../src/lib/kit/components/Inputs/Text/Text.tsx#L9) | https://github.com/gravity-ui/uikit/tree/main/src/components/Text | +| `string` | `select` | [Select](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-select--select) | [SelectProps](../src/lib/kit/components/Inputs/Select/Select.tsx#L12) | https://github.com/gravity-ui/uikit/tree/main/src/components/Select | +| `string` | `textarea` | [TextArea](https://preview.gravity-ui.com/dynamic-forms/?path=/story/string-textarea--text-area) | [TextAreaProps](../src/lib/kit/components/Inputs/TextArea/TextArea.tsx#L7) | https://github.com/gravity-ui/uikit/tree/main/src/components/controls/TextArea | diff --git a/docs/spec.md b/docs/spec.md index e44813e6..837f5a3c 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -33,6 +33,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; | 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 @@ -50,6 +51,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; | viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering | | viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value | | viewSpec.hidden | `boolean` | | Hide field and view | +| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | ### NumberSpec @@ -72,6 +74,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; | viewSpec.placeholder | `string` | | A short hint displayed in the field before the user enters the value | | viewSpec.copy | `boolean` | | For `true`, will add a copy value button | | viewSpec.hidden | `boolean` | | Hide field and view | +| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | ### ObjectSpec @@ -127,6 +130,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; | viewSpec.textContentParams | `object` | | [Parameters](#textcontentparams) that must be passed to text content | | viewSpec.selectParams | `object` | | [Parameters](#selectparams) additional options for the selector | | viewSpec.generateRandomValueButton | `boolean` | | Shows a button that allows you to generate a random value depending on the passed [function generateRandomValue](./lib.md#dynamicfield) | +| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | #### SizeParams diff --git a/src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx b/src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx index 493ac261..ecf75da7 100644 --- a/src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx +++ b/src/lib/kit/components/Inputs/Checkbox/Checkbox.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Checkbox as CheckboxBase} from '@gravity-ui/uikit'; +import {Checkbox as CheckboxBase, CheckboxProps as CheckboxBaseProps} from '@gravity-ui/uikit'; import {BooleanInput} from '../../../../core'; import {block} from '../../../utils'; @@ -9,7 +9,13 @@ import './Checkbox.scss'; const b = block('checkbox'); -export const Checkbox: BooleanInput = ({name, input, spec}) => { +export interface CheckboxProps + extends Omit< + CheckboxBaseProps, + 'checked' | 'onChange' | 'onBlur' | 'onFocus' | 'disabled' | 'qa' + > {} + +export const Checkbox: BooleanInput = ({name, input, spec, inputProps}) => { const {value, onBlur, onChange, onFocus} = input; const handleChange = React.useCallback( @@ -20,6 +26,7 @@ export const Checkbox: BooleanInput = ({name, input, spec}) => { return (
{ diff --git a/src/stories/ArrayTable.stories.tsx b/src/stories/ArrayTable.stories.tsx index 4aed7943..26739f54 100644 --- a/src/stories/ArrayTable.stories.tsx +++ b/src/stories/ArrayTable.stories.tsx @@ -62,6 +62,7 @@ const excludeOptions = [ 'viewSpec.itemPrefix', 'viewSpec.addButtonPosition', 'viewSpec.selectParams', + 'viewSpec.inputProps', ]; const value = [ diff --git a/src/stories/BooleanSwitch.stories.tsx b/src/stories/BooleanSwitch.stories.tsx index b66e7eaf..448b519e 100644 --- a/src/stories/BooleanSwitch.stories.tsx +++ b/src/stories/BooleanSwitch.stories.tsx @@ -16,7 +16,7 @@ const baseSpec: BooleanSpec = { viewSpec: {type: 'switch', layout: 'row', layoutTitle: 'Flag'}, }; -const excludeOptions = ['viewSpec.type']; +const excludeOptions = ['viewSpec.type', 'viewSpec.inputProps']; const template = (spec: BooleanSpec = baseSpec) => { const Template: StoryFn = (__, {viewMode}) => ( diff --git a/src/stories/ObjectBase.stories.tsx b/src/stories/ObjectBase.stories.tsx index e8db0bc9..2d85c844 100644 --- a/src/stories/ObjectBase.stories.tsx +++ b/src/stories/ObjectBase.stories.tsx @@ -42,6 +42,7 @@ const excludeOptions = [ 'viewSpec.type', 'viewSpec.oneOfParams', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const template = (spec: ObjectSpec = baseSpec) => { diff --git a/src/stories/ObjectCardOneOf.stories.tsx b/src/stories/ObjectCardOneOf.stories.tsx index 248b3659..8a427ea3 100644 --- a/src/stories/ObjectCardOneOf.stories.tsx +++ b/src/stories/ObjectCardOneOf.stories.tsx @@ -59,7 +59,12 @@ const baseSpec: ObjectSpec = { }, }; -const excludeOptions = ['viewSpec.type', 'viewSpec.placeholder', 'viewSpec.delimiter']; +const excludeOptions = [ + 'viewSpec.type', + 'viewSpec.placeholder', + 'viewSpec.delimiter', + 'viewSpec.inputProps', +]; const template = (spec: ObjectSpec = baseSpec) => { const Template: StoryFn = (__, {viewMode}) => ( diff --git a/src/stories/ObjectInline.stories.tsx b/src/stories/ObjectInline.stories.tsx index 667a79e3..b06d9037 100644 --- a/src/stories/ObjectInline.stories.tsx +++ b/src/stories/ObjectInline.stories.tsx @@ -59,6 +59,7 @@ const excludeOptions = [ 'viewSpec.type', 'viewSpec.oneOfParams', 'viewSpec.placeholder', + 'viewSpec.inputProps', ]; const template = (spec: ObjectSpec = baseSpec) => { diff --git a/src/stories/ObjectMultiOneOf.stories.tsx b/src/stories/ObjectMultiOneOf.stories.tsx index 60cd889d..ca6d7086 100644 --- a/src/stories/ObjectMultiOneOf.stories.tsx +++ b/src/stories/ObjectMultiOneOf.stories.tsx @@ -62,6 +62,7 @@ const excludeOptions = [ 'viewSpec.table', 'viewSpec.oneOfParams', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const value = { diff --git a/src/stories/ObjectMultiOneOfFlat.stories.tsx b/src/stories/ObjectMultiOneOfFlat.stories.tsx index 3c18390b..d45ccc68 100644 --- a/src/stories/ObjectMultiOneOfFlat.stories.tsx +++ b/src/stories/ObjectMultiOneOfFlat.stories.tsx @@ -62,6 +62,7 @@ const excludeOptions = [ 'viewSpec.table', 'viewSpec.oneOfParams', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const value = { diff --git a/src/stories/ObjectOneOf.stories.tsx b/src/stories/ObjectOneOf.stories.tsx index 48647065..b6de963c 100644 --- a/src/stories/ObjectOneOf.stories.tsx +++ b/src/stories/ObjectOneOf.stories.tsx @@ -60,7 +60,12 @@ const baseSpec: ObjectSpec = { }, }; -const excludeOptions = ['viewSpec.type', 'viewSpec.placeholder', 'viewSpec.delimiter']; +const excludeOptions = [ + 'viewSpec.type', + 'viewSpec.placeholder', + 'viewSpec.delimiter', + 'viewSpec.inputProps', +]; const template = (spec: ObjectSpec = baseSpec) => { const Template: StoryFn = (__, {viewMode}) => ( diff --git a/src/stories/ObjectOneOfFlat.stories.tsx b/src/stories/ObjectOneOfFlat.stories.tsx index 1907950d..f50c9baf 100644 --- a/src/stories/ObjectOneOfFlat.stories.tsx +++ b/src/stories/ObjectOneOfFlat.stories.tsx @@ -60,7 +60,12 @@ const baseSpec: ObjectSpec = { }, }; -const excludeOptions = ['viewSpec.type', 'viewSpec.placeholder', 'viewSpec.delimiter']; +const excludeOptions = [ + 'viewSpec.type', + 'viewSpec.placeholder', + 'viewSpec.delimiter', + 'viewSpec.inputProps', +]; const template = (spec: ObjectSpec = baseSpec) => { const Template: StoryFn = (__, {viewMode}) => ( diff --git a/src/stories/ObjectSecret.stories.tsx b/src/stories/ObjectSecret.stories.tsx index 2337b619..d0a53304 100644 --- a/src/stories/ObjectSecret.stories.tsx +++ b/src/stories/ObjectSecret.stories.tsx @@ -36,6 +36,7 @@ const excludeOptions = [ 'viewSpec.oneOfParams', 'viewSpec.placeholder', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const template = (spec: ObjectSpec = baseSpec) => { diff --git a/src/stories/ObjectTextLink.stories.tsx b/src/stories/ObjectTextLink.stories.tsx index 8f78f090..0ac2fc39 100644 --- a/src/stories/ObjectTextLink.stories.tsx +++ b/src/stories/ObjectTextLink.stories.tsx @@ -41,6 +41,7 @@ const excludeOptions = [ 'viewSpec.oneOfParams', 'viewSpec.placeholder', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const template = (spec: ObjectSpec = baseSpec) => { diff --git a/src/stories/ObjectValue.stories.tsx b/src/stories/ObjectValue.stories.tsx index ec071064..43ab8c0e 100644 --- a/src/stories/ObjectValue.stories.tsx +++ b/src/stories/ObjectValue.stories.tsx @@ -38,6 +38,7 @@ const excludeOptions = [ 'viewSpec.oneOfParams', 'viewSpec.placeholder', 'viewSpec.delimiter', + 'viewSpec.inputProps', ]; const template = (spec: ObjectSpec = baseSpec) => { diff --git a/src/stories/StringFileInput.stories.tsx b/src/stories/StringFileInput.stories.tsx index 0fe8da85..bf25e5ae 100644 --- a/src/stories/StringFileInput.stories.tsx +++ b/src/stories/StringFileInput.stories.tsx @@ -34,6 +34,7 @@ const excludeOptions = [ 'viewSpec.layoutOpen', 'viewSpec.selectParams', 'viewSpec.generateRandomValueButton', + 'viewSpec.inputProps', ]; const template = (spec: StringSpec = baseSpec) => { diff --git a/src/stories/StringMonaco.stories.tsx b/src/stories/StringMonaco.stories.tsx index 69376e0b..3181fdad 100644 --- a/src/stories/StringMonaco.stories.tsx +++ b/src/stories/StringMonaco.stories.tsx @@ -36,6 +36,7 @@ const excludeOptions = [ 'viewSpec.copy', 'viewSpec.selectParams', 'viewSpec.generateRandomValueButton', + 'viewSpec.inputProps', ]; const template = (spec: StringSpec = baseSpec) => { diff --git a/src/stories/StringNumberWithScale.stories.tsx b/src/stories/StringNumberWithScale.stories.tsx index 5de4a136..a5b942d5 100644 --- a/src/stories/StringNumberWithScale.stories.tsx +++ b/src/stories/StringNumberWithScale.stories.tsx @@ -46,6 +46,7 @@ const excludeOptions = [ 'viewSpec.fileInput', 'viewSpec.selectParams', 'viewSpec.generateRandomValueButton', + 'viewSpec.inputProps', ]; const template = (spec: StringSpec = baseSpec) => { diff --git a/src/stories/StringTextContent.stories.tsx b/src/stories/StringTextContent.stories.tsx index fc500008..ae1eee79 100644 --- a/src/stories/StringTextContent.stories.tsx +++ b/src/stories/StringTextContent.stories.tsx @@ -44,6 +44,7 @@ const excludeOptions = [ 'viewSpec.copy', 'viewSpec.selectParams', 'viewSpec.generateRandomValueButton', + 'viewSpec.inputProps', ]; const value = 'value'; diff --git a/src/stories/components/InputPreview/constants.ts b/src/stories/components/InputPreview/constants.ts index 7f86190f..964bc547 100644 --- a/src/stories/components/InputPreview/constants.ts +++ b/src/stories/components/InputPreview/constants.ts @@ -480,6 +480,48 @@ const copy: BooleanSpec = { viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Copy'}, }; +const inputProps: ArraySpec = { + type: SpecTypes.Array, + items: { + type: SpecTypes.Object, + required: true, + properties: { + prop: { + type: SpecTypes.Object, + required: true, + properties: { + key: { + type: SpecTypes.String, + viewSpec: {type: 'base', layout: 'transparent', placeholder: 'property'}, + }, + value: { + type: SpecTypes.String, + viewSpec: {type: 'base', layout: 'transparent', placeholder: 'value'}, + }, + }, + viewSpec: { + type: 'inline', + layout: 'transparent', + delimiter: {key: ':'}, + }, + }, + parse: { + type: SpecTypes.Boolean, + viewSpec: { + type: 'base', + inputProps: {content: 'parse like JSON value'} as unknown as undefined, + }, + }, + }, + viewSpec: {type: 'base', layout: 'transparent'}, + }, + viewSpec: { + type: 'base', + layout: 'row', + layoutTitle: 'Input props', + }, +}; + export const getArrayOptions = (): ObjectSpec => ({ type: SpecTypes.Object, required: true, @@ -506,6 +548,7 @@ export const getArrayOptions = (): ObjectSpec => ({ addButtonPosition, hidden, selectParams, + inputProps, }, [ 'disabled', @@ -521,6 +564,7 @@ export const getArrayOptions = (): ObjectSpec => ({ 'addButtonPosition', 'hidden', 'selectParams', + 'inputProps', ], ), }, @@ -555,6 +599,7 @@ export const getBooleanOptions = (): ObjectSpec => ({ layoutDescription, layoutOpen, hidden, + inputProps, }, [ 'disabled', @@ -564,6 +609,7 @@ export const getBooleanOptions = (): ObjectSpec => ({ 'layoutDescription', 'layoutOpen', 'hidden', + 'inputProps', ], ), }, @@ -594,6 +640,7 @@ export const getNumberOptions = (): ObjectSpec => ({ placeholder, copy, hidden, + inputProps, }, [ 'disabled', @@ -605,6 +652,7 @@ export const getNumberOptions = (): ObjectSpec => ({ 'placeholder', 'copy', 'hidden', + 'inputProps', ], ), }, @@ -691,6 +739,7 @@ export const getStringOptions = (): ObjectSpec => ({ hidden, selectParams, generateRandomValueButton, + inputProps, }, [ 'disabled', @@ -708,6 +757,7 @@ export const getStringOptions = (): ObjectSpec => ({ 'hidden', 'selectParams', 'generateRandomValueButton', + 'inputProps', ], ), }, diff --git a/src/stories/components/InputPreview/utils.ts b/src/stories/components/InputPreview/utils.ts index 13f7ac8e..4c61849c 100644 --- a/src/stories/components/InputPreview/utils.ts +++ b/src/stories/components/InputPreview/utils.ts @@ -179,6 +179,32 @@ export const transformIncorrect = (spec: Spec) => { {}, ); } + if (_spec.viewSpec.inputProps) { + const incorrectInputProps = _spec.viewSpec.inputProps as unknown as { + prop?: {key?: string; value?: string}; + parse: string; + }[]; + + // @ts-ignore + _spec.viewSpec.inputProps = incorrectInputProps.reduce( + (acc: Record, {prop, parse}) => { + if (prop?.key && prop?.value) { + if (parse) { + try { + const _value = JSON.parse(prop.value); + + acc[prop.key] = _value; + } catch {} + } else { + acc[prop.key] = prop.value; + } + } + + return acc; + }, + {}, + ); + } return _spec; };