From dbff18679e83e7db3e087baf4b0ee94dbb3f1492 Mon Sep 17 00:00:00 2001 From: Andrei Bitiutskii Date: Wed, 31 Jan 2024 18:43:54 +0700 Subject: [PATCH 1/4] feat(spec): add generic for InputProps and LaypoutProps into Spec --- .../core/components/Form/Controller/utils.tsx | 17 ++++++-- src/lib/core/components/Form/types/array.ts | 29 +++++++++++--- src/lib/core/components/Form/types/input.ts | 1 + src/lib/core/components/Form/types/layout.ts | 1 + src/lib/core/components/Form/types/number.ts | 31 +++++++++++--- src/lib/core/components/Form/types/string.ts | 32 ++++++++++++--- src/lib/core/types/specs.ts | 40 ++++++++++++++++--- .../Inputs/MultiSelect/MultiSelect.tsx | 5 ++- .../kit/components/Inputs/Select/Select.tsx | 5 ++- src/lib/kit/components/Inputs/Text/Text.tsx | 8 +++- .../components/Inputs/TextArea/TextArea.tsx | 5 ++- 11 files changed, 140 insertions(+), 34 deletions(-) diff --git a/src/lib/core/components/Form/Controller/utils.tsx b/src/lib/core/components/Form/Controller/utils.tsx index 87bd23d2..1ceaa245 100644 --- a/src/lib/core/components/Form/Controller/utils.tsx +++ b/src/lib/core/components/Form/Controller/utils.tsx @@ -135,18 +135,29 @@ export const getRender = ( const render = (props: FieldRenderProps) => { if (inputEntity && isCorrectSpec(spec) && _.isString(name)) { if (!spec.viewSpec.hidden) { + const {layoutProps, inputProps} = spec.viewSpec; if (inputEntity.independent) { const InputComponent = inputEntity.Component; - return ; + return ( + + ); } const InputComponent = inputEntity.Component; - const input = ; + const input = ( + + ); if (Layout) { return ( - + {input} ); diff --git a/src/lib/core/components/Form/types/array.ts b/src/lib/core/components/Form/types/array.ts index 5829db25..1f90719d 100644 --- a/src/lib/core/components/Form/types/array.ts +++ b/src/lib/core/components/Form/types/array.ts @@ -16,13 +16,30 @@ import { ValidatorsMap, } from './'; -export type ArrayInputProps = InputProps; -export type ArrayIndependentInputProps = IndependentInputProps; -export type ArrayLayoutProps = LayoutProps; +export type ArrayInputProps = {}> = InputProps< + FieldArrayValue, + ArraySpec +>; +export type ArrayIndependentInputProps = {}> = + IndependentInputProps>; + +export type ArrayLayoutProps = {}> = LayoutProps< + FieldArrayValue, + ArraySpec +>; -export type ArrayInput = InputType; -export type ArrayIndependentInput = IndependentInputType; -export type ArrayLayout = LayoutType; +export type ArrayInput = {}> = InputType< + FieldArrayValue, + ArraySpec +>; +export type ArrayIndependentInput = {}> = IndependentInputType< + FieldArrayValue, + ArraySpec +>; +export type ArrayLayout = {}> = LayoutType< + FieldArrayValue, + ArraySpec +>; export type ArrayInputEntity = InputEntity; export type ArrayIndependentInputEntity = IndependentInputEntity; diff --git a/src/lib/core/components/Form/types/input.ts b/src/lib/core/components/Form/types/input.ts index 746edc0e..c73927ed 100644 --- a/src/lib/core/components/Form/types/input.ts +++ b/src/lib/core/components/Form/types/input.ts @@ -7,6 +7,7 @@ import {FieldRenderProps, FieldValue, LayoutType} from './'; export type InputProps = { spec: SpecType; name: string; + inputProps?: SpecType['viewSpec']['inputProps']; } & FieldRenderProps; export type IndependentInputProps = { diff --git a/src/lib/core/components/Form/types/layout.ts b/src/lib/core/components/Form/types/layout.ts index a359c61d..6e5ca018 100644 --- a/src/lib/core/components/Form/types/layout.ts +++ b/src/lib/core/components/Form/types/layout.ts @@ -6,6 +6,7 @@ import {FieldValue, InputProps} from './'; export type LayoutProps = { children: React.ReactElement; + layoutProps?: SpecType['viewSpec']['layoutProps']; } & InputProps; export type LayoutType = ( diff --git a/src/lib/core/components/Form/types/number.ts b/src/lib/core/components/Form/types/number.ts index 48f196af..449116ce 100644 --- a/src/lib/core/components/Form/types/number.ts +++ b/src/lib/core/components/Form/types/number.ts @@ -15,13 +15,32 @@ import { ValidatorsMap, } from './'; -export type NumberInputProps = InputProps; -export type NumberIndependentInputProps = IndependentInputProps; -export type NumberLayoutProps = LayoutProps; +export type NumberInputProps = {}> = InputProps< + number, + NumberSpec +>; -export type NumberInput = InputType; -export type NumberIndependentInput = IndependentInputType; -export type NumberLayout = LayoutType; +export type NumberIndependentInputProps = {}> = + IndependentInputProps>; + +export type NumberLayoutProps = {}> = LayoutProps< + number, + NumberSpec +>; + +export type NumberInput = {}> = InputType< + number, + NumberSpec +>; + +export type NumberIndependentInput = {}> = IndependentInputType< + number, + NumberSpec +>; +export type NumberLayout = {}> = LayoutType< + number, + NumberSpec +>; export type NumberInputEntity = InputEntity; export type NumberIndependentInputEntity = IndependentInputEntity; diff --git a/src/lib/core/components/Form/types/string.ts b/src/lib/core/components/Form/types/string.ts index f0a96caf..ac930658 100644 --- a/src/lib/core/components/Form/types/string.ts +++ b/src/lib/core/components/Form/types/string.ts @@ -15,13 +15,33 @@ import { ValidatorsMap, } from './'; -export type StringInputProps = InputProps; -export type StringIndependentInputProps = IndependentInputProps; -export type StringLayoutProps = LayoutProps; +export type StringInputProps = {}> = InputProps< + string, + StringSpec +>; -export type StringInput = InputType; -export type StringIndependentInput = IndependentInputType; -export type StringLayout = LayoutType; +export type StringIndependentInputProps = {}> = + IndependentInputProps>; + +export type StringLayoutProps = {}> = LayoutProps< + string, + StringSpec +>; + +export type StringInput = {}> = InputType< + string, + StringSpec +>; + +export type StringIndependentInput = {}> = IndependentInputType< + string, + StringSpec +>; + +export type StringLayout = {}> = LayoutType< + string, + StringSpec +>; export type StringInputEntity = InputEntity; export type StringIndependentInputEntity = IndependentInputEntity; diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index 830336fb..c81a5a7a 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -5,7 +5,11 @@ import {ReadAsMethod, SpecTypes} from '../constants'; import {ArrayValue, ObjectValue} from './'; -export interface ArraySpec { +export interface ArraySpec< + LinkType = any, + InputProps extends Record = {}, + LayoutProps extends Record = {}, +> { defaultValue?: ArrayValue; type: SpecTypes.Array; required?: boolean; @@ -36,10 +40,16 @@ export interface ArraySpec { filterPlaceholder?: string; meta?: Record; }; + inputProps?: InputProps; + layoutProps?: LayoutProps; }; } -export interface BooleanSpec { +export interface BooleanSpec< + LinkType = any, + InputProps extends Record = {}, + LayoutProps extends Record = {}, +> { defaultValue?: boolean; type: SpecTypes.Boolean; required?: boolean; @@ -53,10 +63,16 @@ export interface BooleanSpec { layoutOpen?: boolean; link?: LinkType; hidden?: boolean; + inputProps?: InputProps; + layoutProps?: LayoutProps; }; } -export interface NumberSpec { +export interface NumberSpec< + LinkType = any, + InputProps extends Record = {}, + LayoutProps extends Record = {}, +> { defaultValue?: number; type: SpecTypes.Number; required?: boolean; @@ -75,10 +91,16 @@ export interface NumberSpec { placeholder?: string; copy?: boolean; hidden?: boolean; + inputProps?: InputProps; + layoutProps?: LayoutProps; }; } -export interface ObjectSpec { +export interface ObjectSpec< + LinkType = any, + InputProps extends Record = {}, + LayoutProps extends Record = {}, +> { defaultValue?: ObjectValue; type: SpecTypes.Object; required?: boolean; @@ -99,10 +121,16 @@ export interface ObjectSpec { }; placeholder?: string; hidden?: boolean; + layoutProps?: LayoutProps; + inputProps?: InputProps; }; } -export interface StringSpec { +export interface StringSpec< + LinkType = any, + InputProps extends Record = {}, + LayoutProps extends Record = {}, +> { defaultValue?: string; type: SpecTypes.String; required?: boolean; @@ -149,6 +177,8 @@ export interface StringSpec { filterPlaceholder?: string; meta?: Record; }; + inputProps?: InputProps; + layoutProps?: LayoutProps; generateRandomValueButton?: boolean; }; } diff --git a/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx b/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx index f262aad9..8550b7e9 100644 --- a/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx +++ b/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Select, Text} from '@gravity-ui/uikit'; +import {Select, SelectProps as SelectBaseProps, Text} from '@gravity-ui/uikit'; import {ArrayInput, FieldArrayValue, transformArrIn, transformArrOut} from '../../../../core'; import {block} from '../../../utils'; @@ -9,7 +9,7 @@ import './MultiSelect.scss'; const b = block('multi-select'); -export const MultiSelect: ArrayInput = ({name, input, spec}) => { +export const MultiSelect: ArrayInput = ({name, input, spec, inputProps}) => { const {value, onBlur, onChange, onFocus} = input; const filterable = React.useMemo(() => (spec.enum?.length || 0) > 9, [spec.enum?.length]); @@ -81,6 +81,7 @@ export const MultiSelect: ArrayInput = ({name, input, spec}) => { getOptionHeight={getOptionHeight} multiple qa={name} + {...inputProps} /> ); }; diff --git a/src/lib/kit/components/Inputs/Select/Select.tsx b/src/lib/kit/components/Inputs/Select/Select.tsx index 955f882e..d28fe234 100644 --- a/src/lib/kit/components/Inputs/Select/Select.tsx +++ b/src/lib/kit/components/Inputs/Select/Select.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Select as SelectBase, Text} from '@gravity-ui/uikit'; +import {Select as SelectBase, SelectProps as SelectBaseProps, Text} from '@gravity-ui/uikit'; import {StringInput} from '../../../../core'; import {block} from '../../../utils'; @@ -9,7 +9,7 @@ import './Select.scss'; const b = block('select'); -export const Select: StringInput = ({name, input, spec}) => { +export const Select: StringInput = ({name, input, spec, inputProps}) => { const {value, onBlur, onChange, onFocus} = input; const filterable = React.useMemo(() => (spec.enum?.length || 0) > 9, [spec.enum?.length]); @@ -75,6 +75,7 @@ export const Select: StringInput = ({name, input, spec}) => { getOptionHeight={getOptionHeight} renderOption={renderOption} qa={name} + {...inputProps} /> ); }; diff --git a/src/lib/kit/components/Inputs/Text/Text.tsx b/src/lib/kit/components/Inputs/Text/Text.tsx index a3bcde03..0867c889 100644 --- a/src/lib/kit/components/Inputs/Text/Text.tsx +++ b/src/lib/kit/components/Inputs/Text/Text.tsx @@ -1,15 +1,18 @@ import React from 'react'; import {PasswordInput} from '@gravity-ui/components'; -import {TextInput} from '@gravity-ui/uikit'; +import {TextInput, TextInputProps as TextInputBaseProps} from '@gravity-ui/uikit'; import _ from 'lodash'; import {FieldRenderProps, NumberInputProps, StringInputProps} from '../../../../core'; -export const Text = ({ +export const Text = < + T extends NumberInputProps | StringInputProps, +>({ name, input: {value, onBlur, onChange, onFocus}, spec, + inputProps, }: T) => { const props = { value: _.isNil(value) ? '' : `${value}`, @@ -20,6 +23,7 @@ export const Text = ({ disabled: spec.viewSpec.disabled, placeholder: spec.viewSpec.placeholder, qa: name, + ...inputProps, }; if (spec.viewSpec.type === 'password') { diff --git a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx index 594a28af..9a15d12e 100644 --- a/src/lib/kit/components/Inputs/TextArea/TextArea.tsx +++ b/src/lib/kit/components/Inputs/TextArea/TextArea.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import {TextArea as TextAreaBase} from '@gravity-ui/uikit'; +import {TextArea as TextAreaBase, TextAreaProps as TextAreaBaseProps} from '@gravity-ui/uikit'; import {StringInput} from '../../../../core'; -export const TextArea: StringInput = ({name, input, spec}) => { +export const TextArea: StringInput = ({name, input, spec, inputProps}) => { const {value, onBlur, onChange, onFocus} = input; return ( @@ -19,6 +19,7 @@ export const TextArea: StringInput = ({name, input, spec}) => { disabled={spec.viewSpec.disabled} placeholder={spec.viewSpec.placeholder} qa={name} + {...inputProps} /> ); }; From 9d17b7e4e22d85bcc68c3ccdfabc95e8d5f34eb8 Mon Sep 17 00:00:00 2001 From: Andrei Bitiutskii Date: Thu, 1 Feb 2024 14:52:17 +0300 Subject: [PATCH 2/4] fix(types): rename generic type; fix(input): strict inputProps type --- .../core/components/Form/Controller/utils.tsx | 1 + src/lib/core/components/Form/types/array.ts | 33 +++++---- src/lib/core/components/Form/types/boolean.ts | 40 +++++++++-- src/lib/core/components/Form/types/input.ts | 1 + src/lib/core/components/Form/types/number.ts | 31 ++++---- src/lib/core/components/Form/types/object.ts | 39 +++++++++-- src/lib/core/components/Form/types/string.ts | 30 ++++---- src/lib/core/types/specs.ts | 40 +++++------ .../Inputs/MultiSelect/MultiSelect.tsx | 69 ++++++++++++------ .../kit/components/Inputs/Select/Select.tsx | 70 +++++++++++++------ src/lib/kit/components/Inputs/Text/Text.tsx | 14 ++-- .../components/Inputs/TextArea/TextArea.tsx | 16 +++-- 12 files changed, 257 insertions(+), 127 deletions(-) diff --git a/src/lib/core/components/Form/Controller/utils.tsx b/src/lib/core/components/Form/Controller/utils.tsx index 1ceaa245..68280acf 100644 --- a/src/lib/core/components/Form/Controller/utils.tsx +++ b/src/lib/core/components/Form/Controller/utils.tsx @@ -145,6 +145,7 @@ export const getRender = ( name={name} Layout={Layout} inputProps={inputProps} + layoutProps={layoutProps} {...props} /> ); diff --git a/src/lib/core/components/Form/types/array.ts b/src/lib/core/components/Form/types/array.ts index 1f90719d..a5d2645e 100644 --- a/src/lib/core/components/Form/types/array.ts +++ b/src/lib/core/components/Form/types/array.ts @@ -16,29 +16,38 @@ import { ValidatorsMap, } from './'; -export type ArrayInputProps = {}> = InputProps< +export type ArrayInputProps = {}> = InputProps< FieldArrayValue, - ArraySpec + ArraySpec +>; +export type ArrayIndependentInputProps< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputProps< + FieldArrayValue, + ArraySpec >; -export type ArrayIndependentInputProps = {}> = - IndependentInputProps>; -export type ArrayLayoutProps = {}> = LayoutProps< +export type ArrayLayoutProps = {}> = LayoutProps< FieldArrayValue, - ArraySpec + ArraySpec >; -export type ArrayInput = {}> = InputType< +export type ArrayInput = {}> = InputType< FieldArrayValue, - ArraySpec + ArraySpec >; -export type ArrayIndependentInput = {}> = IndependentInputType< +export type ArrayIndependentInput< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputType< FieldArrayValue, - ArraySpec + ArraySpec >; -export type ArrayLayout = {}> = LayoutType< + +export type ArrayLayout = {}> = LayoutType< FieldArrayValue, - ArraySpec + ArraySpec >; export type ArrayInputEntity = InputEntity; diff --git a/src/lib/core/components/Form/types/boolean.ts b/src/lib/core/components/Form/types/boolean.ts index 457d7d98..7a5e292e 100644 --- a/src/lib/core/components/Form/types/boolean.ts +++ b/src/lib/core/components/Form/types/boolean.ts @@ -15,13 +15,41 @@ import { ValidatorsMap, } from './'; -export type BooleanInputProps = InputProps; -export type BooleanIndependentInputProps = IndependentInputProps; -export type BooleanLayoutProps = LayoutProps; +export type BooleanInputProps = {}> = InputProps< + boolean, + BooleanSpec +>; -export type BooleanInput = InputType; -export type BooleanIndependentInput = IndependentInputType; -export type BooleanLayout = LayoutType; +export type BooleanIndependentInputProps< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputProps< + boolean, + BooleanSpec +>; + +export type BooleanLayoutProps = {}> = LayoutProps< + boolean, + BooleanSpec +>; + +export type BooleanInput = {}> = InputType< + boolean, + BooleanSpec +>; + +export type BooleanIndependentInput< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputType< + boolean, + BooleanSpec +>; + +export type BooleanLayout = {}> = LayoutType< + boolean, + BooleanSpec +>; export type BooleanInputEntity = InputEntity; export type BooleanIndependentInputEntity = IndependentInputEntity; diff --git a/src/lib/core/components/Form/types/input.ts b/src/lib/core/components/Form/types/input.ts index c73927ed..613fee8e 100644 --- a/src/lib/core/components/Form/types/input.ts +++ b/src/lib/core/components/Form/types/input.ts @@ -12,6 +12,7 @@ export type InputProps = { export type IndependentInputProps = { Layout: LayoutType | undefined; + layoutProps?: SpecType['viewSpec']['layoutProps']; } & InputProps; export type InputType = ( diff --git a/src/lib/core/components/Form/types/number.ts b/src/lib/core/components/Form/types/number.ts index 449116ce..b488c967 100644 --- a/src/lib/core/components/Form/types/number.ts +++ b/src/lib/core/components/Form/types/number.ts @@ -15,31 +15,34 @@ import { ValidatorsMap, } from './'; -export type NumberInputProps = {}> = InputProps< +export type NumberInputProps = {}> = InputProps< number, - NumberSpec + NumberSpec >; -export type NumberIndependentInputProps = {}> = - IndependentInputProps>; +export type NumberIndependentInputProps< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputProps>; -export type NumberLayoutProps = {}> = LayoutProps< +export type NumberLayoutProps = {}> = LayoutProps< number, - NumberSpec + NumberSpec >; -export type NumberInput = {}> = InputType< +export type NumberInput = {}> = InputType< number, - NumberSpec + NumberSpec >; -export type NumberIndependentInput = {}> = IndependentInputType< - number, - NumberSpec ->; -export type NumberLayout = {}> = LayoutType< +export type NumberIndependentInput< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputType>; + +export type NumberLayout = {}> = LayoutType< number, - NumberSpec + NumberSpec >; export type NumberInputEntity = InputEntity; diff --git a/src/lib/core/components/Form/types/object.ts b/src/lib/core/components/Form/types/object.ts index 57e915c2..1946cbc4 100644 --- a/src/lib/core/components/Form/types/object.ts +++ b/src/lib/core/components/Form/types/object.ts @@ -16,13 +16,40 @@ import { ValidatorsMap, } from './'; -export type ObjectInputProps = InputProps; -export type ObjectIndependentInputProps = IndependentInputProps; -export type ObjectLayoutProps = LayoutProps; +export type ObjectInputProps = {}> = InputProps< + FieldObjectValue, + ObjectSpec +>; +export type ObjectIndependentInputProps< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputProps< + FieldObjectValue, + ObjectSpec +>; -export type ObjectInput = InputType; -export type ObjectIndependentInput = IndependentInputType; -export type ObjectLayout = LayoutType; +export type ObjectLayoutProps = {}> = LayoutProps< + FieldObjectValue, + ObjectSpec +>; + +export type ObjectInput = {}> = InputType< + FieldObjectValue, + ObjectSpec +>; + +export type ObjectIndependentInput< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputType< + FieldObjectValue, + ObjectSpec +>; + +export type ObjectLayout = {}> = LayoutType< + FieldObjectValue, + ObjectSpec +>; export type ObjectInputEntity = InputEntity; export type ObjectIndependentInputEntity = IndependentInputEntity; diff --git a/src/lib/core/components/Form/types/string.ts b/src/lib/core/components/Form/types/string.ts index ac930658..932418aa 100644 --- a/src/lib/core/components/Form/types/string.ts +++ b/src/lib/core/components/Form/types/string.ts @@ -15,32 +15,34 @@ import { ValidatorsMap, } from './'; -export type StringInputProps = {}> = InputProps< +export type StringInputProps = {}> = InputProps< string, - StringSpec + StringSpec >; -export type StringIndependentInputProps = {}> = - IndependentInputProps>; +export type StringIndependentInputProps< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputProps>; -export type StringLayoutProps = {}> = LayoutProps< +export type StringLayoutProps = {}> = LayoutProps< string, - StringSpec + StringSpec >; -export type StringInput = {}> = InputType< +export type StringInput = {}> = InputType< string, - StringSpec + StringSpec >; -export type StringIndependentInput = {}> = IndependentInputType< - string, - StringSpec ->; +export type StringIndependentInput< + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, +> = IndependentInputType>; -export type StringLayout = {}> = LayoutType< +export type StringLayout = {}> = LayoutType< string, - StringSpec + StringSpec >; export type StringInputEntity = InputEntity; diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index c81a5a7a..74a7111e 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -7,8 +7,8 @@ import {ArrayValue, ObjectValue} from './'; export interface ArraySpec< LinkType = any, - InputProps extends Record = {}, - LayoutProps extends Record = {}, + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, > { defaultValue?: ArrayValue; type: SpecTypes.Array; @@ -40,15 +40,15 @@ export interface ArraySpec< filterPlaceholder?: string; meta?: Record; }; - inputProps?: InputProps; - layoutProps?: LayoutProps; + inputProps?: InputComponentProps; + layoutProps?: LayoutComponentProps; }; } export interface BooleanSpec< LinkType = any, - InputProps extends Record = {}, - LayoutProps extends Record = {}, + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, > { defaultValue?: boolean; type: SpecTypes.Boolean; @@ -63,15 +63,15 @@ export interface BooleanSpec< layoutOpen?: boolean; link?: LinkType; hidden?: boolean; - inputProps?: InputProps; - layoutProps?: LayoutProps; + inputProps?: InputComponentProps; + layoutProps?: LayoutComponentProps; }; } export interface NumberSpec< LinkType = any, - InputProps extends Record = {}, - LayoutProps extends Record = {}, + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, > { defaultValue?: number; type: SpecTypes.Number; @@ -91,15 +91,15 @@ export interface NumberSpec< placeholder?: string; copy?: boolean; hidden?: boolean; - inputProps?: InputProps; - layoutProps?: LayoutProps; + inputProps?: InputComponentProps; + layoutProps?: LayoutComponentProps; }; } export interface ObjectSpec< LinkType = any, - InputProps extends Record = {}, - LayoutProps extends Record = {}, + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, > { defaultValue?: ObjectValue; type: SpecTypes.Object; @@ -121,15 +121,15 @@ export interface ObjectSpec< }; placeholder?: string; hidden?: boolean; - layoutProps?: LayoutProps; - inputProps?: InputProps; + inputProps?: InputComponentProps; + layoutProps?: LayoutComponentProps; }; } export interface StringSpec< LinkType = any, - InputProps extends Record = {}, - LayoutProps extends Record = {}, + InputComponentProps extends Record = {}, + LayoutComponentProps extends Record = {}, > { defaultValue?: string; type: SpecTypes.String; @@ -177,8 +177,8 @@ export interface StringSpec< filterPlaceholder?: string; meta?: Record; }; - inputProps?: InputProps; - layoutProps?: LayoutProps; + inputProps?: InputComponentProps; + layoutProps?: LayoutComponentProps; generateRandomValueButton?: boolean; }; } diff --git a/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx b/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx index 8550b7e9..d427135c 100644 --- a/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx +++ b/src/lib/kit/components/Inputs/MultiSelect/MultiSelect.tsx @@ -7,32 +7,57 @@ import {block} from '../../../utils'; import './MultiSelect.scss'; +export interface MultiSelectProps + extends Omit< + SelectBaseProps, + | 'onUpdate' + | 'value' + | 'onOpenChange' + | 'disabled' + | 'placeholder' + | 'filterPlaceholder' + | 'multiple' + | 'qa' + > { + withCustomOptions?: boolean; +} + const b = block('multi-select'); -export const MultiSelect: ArrayInput = ({name, input, spec, inputProps}) => { +export const MultiSelect: ArrayInput = ({name, input, spec, inputProps}) => { const {value, onBlur, onChange, onFocus} = input; const filterable = React.useMemo(() => (spec.enum?.length || 0) > 9, [spec.enum?.length]); + const {withCustomOptions, options: externalOptions} = inputProps || {}; + const options = React.useMemo( () => - spec.enum?.map((id) => ({ - id, - value: id, - text: spec.description?.[id] || id, - content: spec.viewSpec.selectParams?.meta?.[id] ? ( -
- {spec.description?.[id] || id} - - {spec.viewSpec.selectParams.meta[id]} - -
- ) : ( - spec.description?.[id] || id - ), - key: id, - })), - [spec.enum, spec.description, spec.viewSpec.selectParams?.meta], + withCustomOptions + ? externalOptions + : spec.enum?.map((id) => ({ + id, + value: id, + text: spec.description?.[id] || id, + content: spec.viewSpec.selectParams?.meta?.[id] ? ( +
+ {spec.description?.[id] || id} + + {spec.viewSpec.selectParams.meta[id]} + +
+ ) : ( + spec.description?.[id] || id + ), + key: id, + })), + [ + spec.enum, + spec.description, + spec.viewSpec.selectParams?.meta, + externalOptions, + withCustomOptions, + ], ); const renderOption = React.useCallback((option: {value: string; content?: React.ReactNode}) => { @@ -69,19 +94,19 @@ export const MultiSelect: ArrayInput = ({name, input, spec, inp