@lmb-it/kitsconcerto-native 0.1.271 → 0.1.272
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/form-renderer/components/FormRenderer/index.cjs +2 -1
- package/form-renderer/components/FormRenderer/index.cjs.map +1 -1
- package/form-renderer/components/FormRenderer/index.js +2 -1
- package/form-renderer/components/FormRenderer/index.js.map +1 -1
- package/form-renderer/components/fields/Group/index.cjs +3 -1
- package/form-renderer/components/fields/Group/index.cjs.map +1 -1
- package/form-renderer/components/fields/Group/index.js +3 -1
- package/form-renderer/components/fields/Group/index.js.map +1 -1
- package/form-renderer/components/fields/Object/index.cjs +5 -3
- package/form-renderer/components/fields/Object/index.cjs.map +1 -1
- package/form-renderer/components/fields/Object/index.js +5 -3
- package/form-renderer/components/fields/Object/index.js.map +1 -1
- package/form-renderer/hooks/useFieldLogic.cjs +0 -1
- package/form-renderer/hooks/useFieldLogic.cjs.map +1 -1
- package/form-renderer/hooks/useFieldLogic.js +0 -1
- package/form-renderer/hooks/useFieldLogic.js.map +1 -1
- package/index.d.ts +23 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../src/form-renderer/components/FormRenderer/index.native.tsx"],"sourcesContent":["// components/FormRenderer.tsx\n\nimport React, {useCallback, useEffect, useMemo, useState} from 'react';\nimport type {Control, FieldValues, UseFormGetValues} from 'react-hook-form';\nimport type {GroupFieldConfigs, IFormElement} from '@lmb-it/kitsconcerto-types';\nimport {FieldWrapper} from '../layout/FieldWrapper';\nimport {KeyboardNavContext, useKeyboardNavProvider} from '../../../hooks/useKeyboardNavigation';\n\n// Import all your \"dumb\" field components\nimport {\n Checkboxes,\n ColorPicker,\n CombinedElement,\n ContainerElement,\n DateField,\n FileUploader,\n Group,\n InputNumber,\n InputText,\n ListBox,\n Location,\n NormalSelect,\n ObjectElement,\n Password,\n Phone,\n RadiusPicker,\n Radios,\n Select,\n Switch,\n TagsSelect,\n Textarea,\n TreeSelect\n} from '../fields';\nimport {Grid, GridItem} from \"../../../_compat\";\nimport type {IStyleClasses} from \"@lmb-it/kitsconcerto-types\";\n\n// ... import all other field components\n\n/**\n * ⛔ THE NUMBER THIS RENDERER HAS ALWAYS USED. It is named rather than written\n * twice so the default and the documentation cannot drift apart; a caller that\n * passes no `rowGap` gets exactly what it got before this prop existed.\n */\nconst DEFAULT_ROW_GAP = 6;\n\ninterface FormRendererProps<T extends FieldValues> extends GroupFieldConfigs<T> {\n elements: IFormElement<T>[];\n control: Control<T>;\n getValues: UseFormGetValues<T>;\n parentPath?: string; // ✨ Pass down the parent path for nesting\n grid?: IStyleClasses;\n /**\n * Vertical space between rows, in points. Omitted, the 6 this renderer has\n * always used — see `IFormComponent.rowGap` for why it is a named prop and\n * not the existing `grid` bag.\n */\n rowGap?: number;\n focusedField?: string;\n setFocusedField: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const FormRenderer = <T extends FieldValues>({\n elements,\n control,\n getValues,\n groupField,\n grid = {},\n rowGap = DEFAULT_ROW_GAP,\n parentPath = '',\n focusedField, setFocusedField\n }: FormRendererProps<T>) => {\n\n const [gridItemProps, setGridItemProps] = useState<Record<string, string>>({})\n\n // --- Keyboard navigation ---\n const TEXT_TYPES = ['Text', 'Email', 'Number', 'Password', 'Phone', 'Textarea'];\n const textFieldIds = useMemo(() => {\n return elements\n .filter((el) => TEXT_TYPES.includes(el.type))\n .map((el) => `${parentPath}${el.id as string}`);\n }, [elements, parentPath]);\n\n const keyboardNavCtx = useKeyboardNavProvider();\n\n useEffect(() => {\n keyboardNavCtx.setElementsOrder(textFieldIds);\n }, [textFieldIds]);\n\n const getElement = useCallback((elementType: string) => {\n\n switch (elementType) {\n\n case 'Email':\n case 'Text':\n return InputText;\n case 'Number':\n return InputNumber;\n case 'Password':\n return Password;\n case 'Location':\n return Location;\n case 'Phone':\n return Phone\n case 'Date':\n return DateField\n case 'ColorPicker':\n return ColorPicker\n case 'RadiusPicker':\n return RadiusPicker\n case 'Radios':\n return Radios\n case 'Textarea':\n return Textarea\n case 'Image':\n case 'File':\n return FileUploader\n case 'Switch':\n return Switch\n case 'Checkbox':\n return Checkboxes\n case 'Select':\n return NormalSelect\n case 'TreeSelect':\n return TreeSelect\n case 'Tags':\n return TagsSelect\n case 'ListBox':\n return ListBox\n case 'Multiselect':\n return Select\n case 'Group':\n return Group\n case 'Object':\n return ObjectElement\n case 'Container':\n return ContainerElement\n case 'Combined':\n return CombinedElement\n // default:\n // return <Flex/>;\n }\n }, []);\n\n\n return (\n <KeyboardNavContext.Provider value={keyboardNavCtx}>\n <Grid\n columns={12}\n rowGap={rowGap}\n columnGap={8}\n >\n {elements.map((element) => {\n\n const FieldComponent = getElement(element.type);\n\n const elementId = `${parentPath}${element.id as string}`;\n const resolvedElement = elementId !== element.id ? { ...element, id: elementId } : element;\n\n\n if (!FieldComponent) {\n console.warn(`No component found for element type: \"${resolvedElement.type}\"`);\n return null;\n }\n\n const colSpan = parseInt(gridItemProps[elementId] ?? '12', 10);\n\n return (\n <GridItem\n key={elementId}\n id={elementId}\n colSpan={colSpan}\n /* The cell's own style — the stacking level an\n element config cannot otherwise reach. Sizing keys\n are forbidden by the type. */\n style={(resolvedElement as any).cellStyle}\n >\n <FieldWrapper\n key={elementId}\n element={resolvedElement}\n control={control}\n grid={grid}\n groupField={groupField}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n onGridChange={(value) => {\n if (value != gridItemProps[elementId]) {\n setGridItemProps(prevState => ({\n ...prevState,\n [elementId]: value\n }));\n }\n }}\n\n\n >\n {(props) => <FieldComponent\n groupField={groupField}\n element={resolvedElement}\n control={control}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n fieldLogic={props}\n\n />}\n </FieldWrapper>\n </GridItem>\n );\n })}\n </Grid>\n </KeyboardNavContext.Provider>\n );\n};\n"],"names":["useState","useMemo","useKeyboardNavProvider","useEffect","useCallback","InputText","InputNumber","Password","Location","Phone","DateField","ColorPicker","RadiusPicker","Radios","Textarea","FileUploader","Switch","Checkboxes","NormalSelect","TreeSelect","TagsSelect","ListBox","Select","Group","ObjectElement","ContainerElement","CombinedElement","jsx","KeyboardNavContext","Grid","GridItem","FieldWrapper"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../src/form-renderer/components/FormRenderer/index.native.tsx"],"sourcesContent":["// components/FormRenderer.tsx\n\nimport React, {useCallback, useEffect, useMemo, useState} from 'react';\nimport type {Control, FieldValues, UseFormGetValues} from 'react-hook-form';\nimport type {GroupFieldConfigs, IFormElement} from '@lmb-it/kitsconcerto-types';\nimport {FieldWrapper} from '../layout/FieldWrapper';\nimport {KeyboardNavContext, useKeyboardNavProvider} from '../../../hooks/useKeyboardNavigation';\n\n// Import all your \"dumb\" field components\nimport {\n Checkboxes,\n ColorPicker,\n CombinedElement,\n ContainerElement,\n DateField,\n FileUploader,\n Group,\n InputNumber,\n InputText,\n ListBox,\n Location,\n NormalSelect,\n ObjectElement,\n Password,\n Phone,\n RadiusPicker,\n Radios,\n Select,\n Switch,\n TagsSelect,\n Textarea,\n TreeSelect\n} from '../fields';\nimport {Grid, GridItem} from \"../../../_compat\";\nimport type {IStyleClasses} from \"@lmb-it/kitsconcerto-types\";\n\n// ... import all other field components\n\n/**\n * ⛔ THE NUMBER THIS RENDERER HAS ALWAYS USED. It is named rather than written\n * twice so the default and the documentation cannot drift apart; a caller that\n * passes no `rowGap` gets exactly what it got before this prop existed.\n */\nconst DEFAULT_ROW_GAP = 6;\n\ninterface FormRendererProps<T extends FieldValues> extends GroupFieldConfigs<T> {\n elements: IFormElement<T>[];\n control: Control<T>;\n getValues: UseFormGetValues<T>;\n parentPath?: string; // ✨ Pass down the parent path for nesting\n grid?: IStyleClasses;\n /**\n * Vertical space between rows, in points. Omitted, the 6 this renderer has\n * always used — see `IFormComponent.rowGap` for why it is a named prop and\n * not the existing `grid` bag.\n */\n rowGap?: number;\n focusedField?: string;\n setFocusedField: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const FormRenderer = <T extends FieldValues>({\n elements,\n control,\n getValues,\n groupField,\n grid = {},\n rowGap = DEFAULT_ROW_GAP,\n parentPath = '',\n focusedField, setFocusedField\n }: FormRendererProps<T>) => {\n\n const [gridItemProps, setGridItemProps] = useState<Record<string, string>>({})\n\n // --- Keyboard navigation ---\n const TEXT_TYPES = ['Text', 'Email', 'Number', 'Password', 'Phone', 'Textarea'];\n const textFieldIds = useMemo(() => {\n return elements\n .filter((el) => TEXT_TYPES.includes(el.type))\n .map((el) => `${parentPath}${el.id as string}`);\n }, [elements, parentPath]);\n\n const keyboardNavCtx = useKeyboardNavProvider();\n\n useEffect(() => {\n keyboardNavCtx.setElementsOrder(textFieldIds);\n }, [textFieldIds]);\n\n const getElement = useCallback((elementType: string) => {\n\n switch (elementType) {\n\n case 'Email':\n case 'Text':\n return InputText;\n case 'Number':\n return InputNumber;\n case 'Password':\n return Password;\n case 'Location':\n return Location;\n case 'Phone':\n return Phone\n case 'Date':\n return DateField\n case 'ColorPicker':\n return ColorPicker\n case 'RadiusPicker':\n return RadiusPicker\n case 'Radios':\n return Radios\n case 'Textarea':\n return Textarea\n case 'Image':\n case 'File':\n return FileUploader\n case 'Switch':\n return Switch\n case 'Checkbox':\n return Checkboxes\n case 'Select':\n return NormalSelect\n case 'TreeSelect':\n return TreeSelect\n case 'Tags':\n return TagsSelect\n case 'ListBox':\n return ListBox\n case 'Multiselect':\n return Select\n case 'Group':\n return Group\n case 'Object':\n return ObjectElement\n case 'Container':\n return ContainerElement\n case 'Combined':\n return CombinedElement\n // default:\n // return <Flex/>;\n }\n }, []);\n\n\n return (\n <KeyboardNavContext.Provider value={keyboardNavCtx}>\n <Grid\n columns={12}\n rowGap={rowGap}\n columnGap={8}\n >\n {elements.map((element) => {\n\n const FieldComponent = getElement(element.type);\n\n const elementId = `${parentPath}${element.id as string}`;\n const resolvedElement = elementId !== element.id ? { ...element, id: elementId } : element;\n\n\n if (!FieldComponent) {\n console.warn(`No component found for element type: \"${resolvedElement.type}\"`);\n return null;\n }\n\n const colSpan = parseInt(gridItemProps[elementId] ?? '12', 10);\n\n return (\n <GridItem\n key={elementId}\n id={elementId}\n colSpan={colSpan}\n /* The cell's own style — the stacking level an\n element config cannot otherwise reach. Sizing keys\n are forbidden by the type. */\n style={(resolvedElement as any).cellStyle}\n >\n <FieldWrapper\n key={elementId}\n element={resolvedElement}\n control={control}\n grid={grid}\n groupField={groupField}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n onGridChange={(value) => {\n if (value != gridItemProps[elementId]) {\n setGridItemProps(prevState => ({\n ...prevState,\n [elementId]: value\n }));\n }\n }}\n\n\n >\n {(props) => <FieldComponent\n groupField={groupField}\n element={resolvedElement}\n control={control}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n fieldLogic={props}\n /* ⛔ SO THE NESTING CAN CARRY IT DOWN. `Object`\n and `Group` each render their children through\n a NESTED FormRenderer; a renderer handed\n nothing falls back to its own default, which\n stopped the form's `rowGap` at the top level.\n Every other field type ignores this prop. */\n rowGap={rowGap}\n\n />}\n </FieldWrapper>\n </GridItem>\n );\n })}\n </Grid>\n </KeyboardNavContext.Provider>\n );\n};\n"],"names":["useState","useMemo","useKeyboardNavProvider","useEffect","useCallback","InputText","InputNumber","Password","Location","Phone","DateField","ColorPicker","RadiusPicker","Radios","Textarea","FileUploader","Switch","Checkboxes","NormalSelect","TreeSelect","TagsSelect","ListBox","Select","Group","ObjectElement","ContainerElement","CombinedElement","jsx","KeyboardNavContext","Grid","GridItem","FieldWrapper"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../src/form-renderer/components/FormRenderer/index.native.tsx"],"sourcesContent":["// components/FormRenderer.tsx\n\nimport React, {useCallback, useEffect, useMemo, useState} from 'react';\nimport type {Control, FieldValues, UseFormGetValues} from 'react-hook-form';\nimport type {GroupFieldConfigs, IFormElement} from '@lmb-it/kitsconcerto-types';\nimport {FieldWrapper} from '../layout/FieldWrapper';\nimport {KeyboardNavContext, useKeyboardNavProvider} from '../../../hooks/useKeyboardNavigation';\n\n// Import all your \"dumb\" field components\nimport {\n Checkboxes,\n ColorPicker,\n CombinedElement,\n ContainerElement,\n DateField,\n FileUploader,\n Group,\n InputNumber,\n InputText,\n ListBox,\n Location,\n NormalSelect,\n ObjectElement,\n Password,\n Phone,\n RadiusPicker,\n Radios,\n Select,\n Switch,\n TagsSelect,\n Textarea,\n TreeSelect\n} from '../fields';\nimport {Grid, GridItem} from \"../../../_compat\";\nimport type {IStyleClasses} from \"@lmb-it/kitsconcerto-types\";\n\n// ... import all other field components\n\n/**\n * ⛔ THE NUMBER THIS RENDERER HAS ALWAYS USED. It is named rather than written\n * twice so the default and the documentation cannot drift apart; a caller that\n * passes no `rowGap` gets exactly what it got before this prop existed.\n */\nconst DEFAULT_ROW_GAP = 6;\n\ninterface FormRendererProps<T extends FieldValues> extends GroupFieldConfigs<T> {\n elements: IFormElement<T>[];\n control: Control<T>;\n getValues: UseFormGetValues<T>;\n parentPath?: string; // ✨ Pass down the parent path for nesting\n grid?: IStyleClasses;\n /**\n * Vertical space between rows, in points. Omitted, the 6 this renderer has\n * always used — see `IFormComponent.rowGap` for why it is a named prop and\n * not the existing `grid` bag.\n */\n rowGap?: number;\n focusedField?: string;\n setFocusedField: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const FormRenderer = <T extends FieldValues>({\n elements,\n control,\n getValues,\n groupField,\n grid = {},\n rowGap = DEFAULT_ROW_GAP,\n parentPath = '',\n focusedField, setFocusedField\n }: FormRendererProps<T>) => {\n\n const [gridItemProps, setGridItemProps] = useState<Record<string, string>>({})\n\n // --- Keyboard navigation ---\n const TEXT_TYPES = ['Text', 'Email', 'Number', 'Password', 'Phone', 'Textarea'];\n const textFieldIds = useMemo(() => {\n return elements\n .filter((el) => TEXT_TYPES.includes(el.type))\n .map((el) => `${parentPath}${el.id as string}`);\n }, [elements, parentPath]);\n\n const keyboardNavCtx = useKeyboardNavProvider();\n\n useEffect(() => {\n keyboardNavCtx.setElementsOrder(textFieldIds);\n }, [textFieldIds]);\n\n const getElement = useCallback((elementType: string) => {\n\n switch (elementType) {\n\n case 'Email':\n case 'Text':\n return InputText;\n case 'Number':\n return InputNumber;\n case 'Password':\n return Password;\n case 'Location':\n return Location;\n case 'Phone':\n return Phone\n case 'Date':\n return DateField\n case 'ColorPicker':\n return ColorPicker\n case 'RadiusPicker':\n return RadiusPicker\n case 'Radios':\n return Radios\n case 'Textarea':\n return Textarea\n case 'Image':\n case 'File':\n return FileUploader\n case 'Switch':\n return Switch\n case 'Checkbox':\n return Checkboxes\n case 'Select':\n return NormalSelect\n case 'TreeSelect':\n return TreeSelect\n case 'Tags':\n return TagsSelect\n case 'ListBox':\n return ListBox\n case 'Multiselect':\n return Select\n case 'Group':\n return Group\n case 'Object':\n return ObjectElement\n case 'Container':\n return ContainerElement\n case 'Combined':\n return CombinedElement\n // default:\n // return <Flex/>;\n }\n }, []);\n\n\n return (\n <KeyboardNavContext.Provider value={keyboardNavCtx}>\n <Grid\n columns={12}\n rowGap={rowGap}\n columnGap={8}\n >\n {elements.map((element) => {\n\n const FieldComponent = getElement(element.type);\n\n const elementId = `${parentPath}${element.id as string}`;\n const resolvedElement = elementId !== element.id ? { ...element, id: elementId } : element;\n\n\n if (!FieldComponent) {\n console.warn(`No component found for element type: \"${resolvedElement.type}\"`);\n return null;\n }\n\n const colSpan = parseInt(gridItemProps[elementId] ?? '12', 10);\n\n return (\n <GridItem\n key={elementId}\n id={elementId}\n colSpan={colSpan}\n /* The cell's own style — the stacking level an\n element config cannot otherwise reach. Sizing keys\n are forbidden by the type. */\n style={(resolvedElement as any).cellStyle}\n >\n <FieldWrapper\n key={elementId}\n element={resolvedElement}\n control={control}\n grid={grid}\n groupField={groupField}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n onGridChange={(value) => {\n if (value != gridItemProps[elementId]) {\n setGridItemProps(prevState => ({\n ...prevState,\n [elementId]: value\n }));\n }\n }}\n\n\n >\n {(props) => <FieldComponent\n groupField={groupField}\n element={resolvedElement}\n control={control}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n fieldLogic={props}\n\n />}\n </FieldWrapper>\n </GridItem>\n );\n })}\n </Grid>\n </KeyboardNavContext.Provider>\n );\n};\n"],"names":["NormalSelect","TreeSelect","TagsSelect","ListBox","ContainerElement","Grid","GridItem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../src/form-renderer/components/FormRenderer/index.native.tsx"],"sourcesContent":["// components/FormRenderer.tsx\n\nimport React, {useCallback, useEffect, useMemo, useState} from 'react';\nimport type {Control, FieldValues, UseFormGetValues} from 'react-hook-form';\nimport type {GroupFieldConfigs, IFormElement} from '@lmb-it/kitsconcerto-types';\nimport {FieldWrapper} from '../layout/FieldWrapper';\nimport {KeyboardNavContext, useKeyboardNavProvider} from '../../../hooks/useKeyboardNavigation';\n\n// Import all your \"dumb\" field components\nimport {\n Checkboxes,\n ColorPicker,\n CombinedElement,\n ContainerElement,\n DateField,\n FileUploader,\n Group,\n InputNumber,\n InputText,\n ListBox,\n Location,\n NormalSelect,\n ObjectElement,\n Password,\n Phone,\n RadiusPicker,\n Radios,\n Select,\n Switch,\n TagsSelect,\n Textarea,\n TreeSelect\n} from '../fields';\nimport {Grid, GridItem} from \"../../../_compat\";\nimport type {IStyleClasses} from \"@lmb-it/kitsconcerto-types\";\n\n// ... import all other field components\n\n/**\n * ⛔ THE NUMBER THIS RENDERER HAS ALWAYS USED. It is named rather than written\n * twice so the default and the documentation cannot drift apart; a caller that\n * passes no `rowGap` gets exactly what it got before this prop existed.\n */\nconst DEFAULT_ROW_GAP = 6;\n\ninterface FormRendererProps<T extends FieldValues> extends GroupFieldConfigs<T> {\n elements: IFormElement<T>[];\n control: Control<T>;\n getValues: UseFormGetValues<T>;\n parentPath?: string; // ✨ Pass down the parent path for nesting\n grid?: IStyleClasses;\n /**\n * Vertical space between rows, in points. Omitted, the 6 this renderer has\n * always used — see `IFormComponent.rowGap` for why it is a named prop and\n * not the existing `grid` bag.\n */\n rowGap?: number;\n focusedField?: string;\n setFocusedField: React.Dispatch<React.SetStateAction<string>>;\n}\n\nexport const FormRenderer = <T extends FieldValues>({\n elements,\n control,\n getValues,\n groupField,\n grid = {},\n rowGap = DEFAULT_ROW_GAP,\n parentPath = '',\n focusedField, setFocusedField\n }: FormRendererProps<T>) => {\n\n const [gridItemProps, setGridItemProps] = useState<Record<string, string>>({})\n\n // --- Keyboard navigation ---\n const TEXT_TYPES = ['Text', 'Email', 'Number', 'Password', 'Phone', 'Textarea'];\n const textFieldIds = useMemo(() => {\n return elements\n .filter((el) => TEXT_TYPES.includes(el.type))\n .map((el) => `${parentPath}${el.id as string}`);\n }, [elements, parentPath]);\n\n const keyboardNavCtx = useKeyboardNavProvider();\n\n useEffect(() => {\n keyboardNavCtx.setElementsOrder(textFieldIds);\n }, [textFieldIds]);\n\n const getElement = useCallback((elementType: string) => {\n\n switch (elementType) {\n\n case 'Email':\n case 'Text':\n return InputText;\n case 'Number':\n return InputNumber;\n case 'Password':\n return Password;\n case 'Location':\n return Location;\n case 'Phone':\n return Phone\n case 'Date':\n return DateField\n case 'ColorPicker':\n return ColorPicker\n case 'RadiusPicker':\n return RadiusPicker\n case 'Radios':\n return Radios\n case 'Textarea':\n return Textarea\n case 'Image':\n case 'File':\n return FileUploader\n case 'Switch':\n return Switch\n case 'Checkbox':\n return Checkboxes\n case 'Select':\n return NormalSelect\n case 'TreeSelect':\n return TreeSelect\n case 'Tags':\n return TagsSelect\n case 'ListBox':\n return ListBox\n case 'Multiselect':\n return Select\n case 'Group':\n return Group\n case 'Object':\n return ObjectElement\n case 'Container':\n return ContainerElement\n case 'Combined':\n return CombinedElement\n // default:\n // return <Flex/>;\n }\n }, []);\n\n\n return (\n <KeyboardNavContext.Provider value={keyboardNavCtx}>\n <Grid\n columns={12}\n rowGap={rowGap}\n columnGap={8}\n >\n {elements.map((element) => {\n\n const FieldComponent = getElement(element.type);\n\n const elementId = `${parentPath}${element.id as string}`;\n const resolvedElement = elementId !== element.id ? { ...element, id: elementId } : element;\n\n\n if (!FieldComponent) {\n console.warn(`No component found for element type: \"${resolvedElement.type}\"`);\n return null;\n }\n\n const colSpan = parseInt(gridItemProps[elementId] ?? '12', 10);\n\n return (\n <GridItem\n key={elementId}\n id={elementId}\n colSpan={colSpan}\n /* The cell's own style — the stacking level an\n element config cannot otherwise reach. Sizing keys\n are forbidden by the type. */\n style={(resolvedElement as any).cellStyle}\n >\n <FieldWrapper\n key={elementId}\n element={resolvedElement}\n control={control}\n grid={grid}\n groupField={groupField}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n onGridChange={(value) => {\n if (value != gridItemProps[elementId]) {\n setGridItemProps(prevState => ({\n ...prevState,\n [elementId]: value\n }));\n }\n }}\n\n\n >\n {(props) => <FieldComponent\n groupField={groupField}\n element={resolvedElement}\n control={control}\n getValues={getValues}\n focusedField={focusedField}\n setFocusedField={setFocusedField}\n fieldLogic={props}\n /* ⛔ SO THE NESTING CAN CARRY IT DOWN. `Object`\n and `Group` each render their children through\n a NESTED FormRenderer; a renderer handed\n nothing falls back to its own default, which\n stopped the form's `rowGap` at the top level.\n Every other field type ignores this prop. */\n rowGap={rowGap}\n\n />}\n </FieldWrapper>\n </GridItem>\n );\n })}\n </Grid>\n </KeyboardNavContext.Provider>\n );\n};\n"],"names":["NormalSelect","TreeSelect","TagsSelect","ListBox","ContainerElement","Grid","GridItem"],"mappings":"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"}
|
|
@@ -22,7 +22,8 @@ const Group = ({
|
|
|
22
22
|
groupField,
|
|
23
23
|
focusedField,
|
|
24
24
|
setFocusedField,
|
|
25
|
-
fieldLogic
|
|
25
|
+
fieldLogic,
|
|
26
|
+
rowGap
|
|
26
27
|
}) => {
|
|
27
28
|
const { isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots } = fieldLogic;
|
|
28
29
|
const [_focusedField, _setFocusedField] = React.useState("");
|
|
@@ -140,6 +141,7 @@ const Group = ({
|
|
|
140
141
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
141
142
|
index_native$1.FormRenderer,
|
|
142
143
|
{
|
|
144
|
+
rowGap,
|
|
143
145
|
elements: reBuildElements(field, index$2),
|
|
144
146
|
control,
|
|
145
147
|
groupField: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../../src/form-renderer/components/fields/Group/index.native.tsx"],"sourcesContent":["// components/fields/Group.tsx\n\nimport React, {useCallback, useEffect, useImperativeHandle, useMemo, useState} from 'react';\nimport {type FieldArrayWithId, type FieldValues, useFieldArray} from 'react-hook-form';\nimport type {IFormElement, IGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Box, Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {useComponentDefaults, useResolvedElementStyles} from \"../../../../hooks\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a repeatable group of fields (a field array), preserving all the logic\n * for default values, min/max repeats, and custom action buttons.\n */\nexport const Group = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n }: UseFieldLogicElementProps<T>) => { // Ensure UseFieldLogicProps is updated to pass focus props\n // 1. Get the group's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n // Fallback focus state, used only when the parent form doesn't supply\n // focusedField/setFocusedField — web passes the props straight through.\n const [_focusedField, _setFocusedField] = useState<string>('');\n\n const groupElement = element as IGroup<T>;\n const {groupsSettings} = groupElement;\n\n // Resolve groupSlots (dynamic or static) and merge with theme Group defaults\n const resolvedGroupSlots = useMemo(() => {\n const gs = groupElement.groupSlots;\n if (!gs) return undefined;\n if (typeof gs === 'function') {\n return (gs as any)(fieldLogic.watchedValues, fieldLogic.formContext.getValues(), fieldLogic.formContext, groupField);\n }\n return gs;\n }, [groupElement.groupSlots, fieldLogic.watchedValues, fieldLogic.formContext, groupField]);\n\n const {elementStyles: groupStyles} = useComponentDefaults('Group', {\n slots: resolvedGroupSlots,\n } as any);\n const elStyles = useResolvedElementStyles(groupStyles);\n\n // Element-level `slots` (the outer KitsContainer's container/label/helperText/\n // error) arrive in the nested IElementSlotConfig shape; flatten to the flat\n // { [slot]: styleRecord } map KitsContainer expects. (groupSlots above drive\n // the inner repeatable list — root/body/row — and are already flattened.)\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n // 2. Initialize react-hook-form's field array management.\n const fieldArray = useFieldArray({\n control,\n name: element.id as any,\n });\n const {fields, append, remove} = fieldArray;\n\n // console.log('hitted', element, {fields}, element.id)\n // 3. Process group settings with defaults, exactly like the original component.\n const settings = useMemo(() => ({\n grid: groupsSettings?.grid,\n repeatable: {\n minRepeats: groupsSettings?.repeatable?.minRepeats || 0,\n maxRepeats: groupsSettings?.repeatable?.maxRepeats || Infinity,\n plusButton: groupsSettings?.repeatable?.plusButton,\n minusButton: groupsSettings?.repeatable?.minusButton,\n },\n removeButtonRow: groupsSettings?.removeButtonRow,\n }), [groupsSettings]);\n\n // 4. Replicate the logic to build a default item object for new rows.\n const createDefaultItem = (): FieldValues => {\n const item: FieldValues = {};\n elements?.forEach(el => {\n if (\"displayOnly\" in el && el.displayOnly) return;\n\n if (\"initialUri\" in el) {\n item[el.id as string] = (el as any).initialUri;\n } else if (\"initialValue\" in el && el.initialValue !== undefined) {\n item[el.id as string] = el.initialValue;\n }\n });\n return item;\n };\n\n const handleAppend = (count = 1) => {\n const max = settings.repeatable.maxRepeats;\n\n if (max && fields.length >= max) {\n return;\n }\n const itemsToAdd = Array(count).fill(0).map(() => createDefaultItem());\n append(itemsToAdd as any, {shouldFocus: true});\n };\n\n const handleRemove = (index: number) => {\n if (fields.length > (settings.repeatable.minRepeats || 0)) {\n remove(index);\n }\n };\n useEffect(() => {\n const generateGroupElements = () => {\n const min = settings.repeatable.minRepeats || 0;\n if (fields.length < min) {\n const itemsToAppend = min - fields.length;\n // console.log({itemsToAppend, current: fields.length})\n\n handleAppend(itemsToAppend);\n }\n };\n\n // This pattern correctly avoids the infinite loop by not depending on `append` or `fields`.\n // The timeout gives react-hook-form time to initialize before we check the length.\n const timer = setTimeout(generateGroupElements, 100);\n return () => clearTimeout(timer);\n\n }, [element.id, settings.repeatable.minRepeats]); // Stable dependencies\n\n // 6. Replicate the `useImperativeHandle` logic to expose the ref.\n useImperativeHandle(groupsSettings?.ref, () => fieldArray, [fieldArray]);\n\n\n const reBuildElements = useCallback((field: FieldArrayWithId, index: number) => {\n return elements?.map((childElement) => {\n const toArray = Object.entries(field);\n\n const findField = toArray.find(([name]) => name == childElement.id);\n\n return {\n ...childElement,\n initialValue: findField ? findField[1] : undefined,\n };\n }) as IFormElement<any>[];\n }, [element, elements]);\n\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={groupHelperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6} mb={4}\n style={elStyles.root || undefined}>\n\n <Box style={elStyles.body || undefined}>\n {fields.map((field, index) => (\n <Flex key={field.id} w=\"full\" position=\"relative\" flexDirection=\"column\"\n rowGap={6}\n columnGap={8}\n style={elStyles.row || undefined}>\n\n <FormRenderer\n elements={reBuildElements(field, index)}\n control={control}\n groupField={{\n index,\n name: element.id.toString(),\n // Use the path-arg form of getValues so a Group nested inside\n // an Object resolves correctly: the FormRenderer rewrites this\n // Group's id to a dotted path (e.g. \"addressGroup.addresses\"),\n // and getValues()[dottedKey] would be undefined (→ crash on\n // [index]). getValues(path) traverses the nesting instead.\n values: (getValues(element.id as any) as any)?.[index],\n append: handleAppend,\n remove: () => handleRemove(index),\n }}\n getValues={getValues}\n parentPath={`${element.id.toString()}.${index}.`}\n focusedField={(focusedField ?? _focusedField)!}\n setFocusedField={(setFocusedField ?? _setFocusedField)!}\n grid={groupsSettings?.grid}\n />\n\n {settings.removeButtonRow && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.removeButtonRow(fields.length, () => handleRemove(index), index)}\n </Box>\n )}\n\n\n {settings.repeatable.minusButton && fields.length > settings.repeatable.minRepeats && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.repeatable.minusButton(fields.length, () => handleRemove(index))}\n </Box>\n )}\n </Flex>\n ))}\n </Box>\n\n {settings.repeatable.plusButton && (\n <Flex justifyContent=\"flex-start\" w=\"full\" mt={8}\n style={elStyles.addButton || undefined}>\n {settings.repeatable.plusButton(fields.length, handleAppend)}\n </Flex>\n )}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default Group;\n"],"names":["useState","useMemo","useComponentDefaults","useResolvedElementStyles","flattenSlotStyles","useFieldArray","useEffect","useImperativeHandle","useCallback","jsx","KitsContainer","jsxs","Flex","Box","index","FormRenderer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../../src/form-renderer/components/fields/Group/index.native.tsx"],"sourcesContent":["// components/fields/Group.tsx\n\nimport React, {useCallback, useEffect, useImperativeHandle, useMemo, useState} from 'react';\nimport {type FieldArrayWithId, type FieldValues, useFieldArray} from 'react-hook-form';\nimport type {IFormElement, IGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Box, Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {useComponentDefaults, useResolvedElementStyles} from \"../../../../hooks\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a repeatable group of fields (a field array), preserving all the logic\n * for default values, min/max repeats, and custom action buttons.\n */\nexport const Group = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n rowGap,\n }: UseFieldLogicElementProps<T>) => { // Ensure UseFieldLogicProps is updated to pass focus props\n // 1. Get the group's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n // Fallback focus state, used only when the parent form doesn't supply\n // focusedField/setFocusedField — web passes the props straight through.\n const [_focusedField, _setFocusedField] = useState<string>('');\n\n const groupElement = element as IGroup<T>;\n const {groupsSettings} = groupElement;\n\n // Resolve groupSlots (dynamic or static) and merge with theme Group defaults\n const resolvedGroupSlots = useMemo(() => {\n const gs = groupElement.groupSlots;\n if (!gs) return undefined;\n if (typeof gs === 'function') {\n return (gs as any)(fieldLogic.watchedValues, fieldLogic.formContext.getValues(), fieldLogic.formContext, groupField);\n }\n return gs;\n }, [groupElement.groupSlots, fieldLogic.watchedValues, fieldLogic.formContext, groupField]);\n\n const {elementStyles: groupStyles} = useComponentDefaults('Group', {\n slots: resolvedGroupSlots,\n } as any);\n const elStyles = useResolvedElementStyles(groupStyles);\n\n // Element-level `slots` (the outer KitsContainer's container/label/helperText/\n // error) arrive in the nested IElementSlotConfig shape; flatten to the flat\n // { [slot]: styleRecord } map KitsContainer expects. (groupSlots above drive\n // the inner repeatable list — root/body/row — and are already flattened.)\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n // 2. Initialize react-hook-form's field array management.\n const fieldArray = useFieldArray({\n control,\n name: element.id as any,\n });\n const {fields, append, remove} = fieldArray;\n\n // console.log('hitted', element, {fields}, element.id)\n // 3. Process group settings with defaults, exactly like the original component.\n const settings = useMemo(() => ({\n grid: groupsSettings?.grid,\n repeatable: {\n minRepeats: groupsSettings?.repeatable?.minRepeats || 0,\n maxRepeats: groupsSettings?.repeatable?.maxRepeats || Infinity,\n plusButton: groupsSettings?.repeatable?.plusButton,\n minusButton: groupsSettings?.repeatable?.minusButton,\n },\n removeButtonRow: groupsSettings?.removeButtonRow,\n }), [groupsSettings]);\n\n // 4. Replicate the logic to build a default item object for new rows.\n const createDefaultItem = (): FieldValues => {\n const item: FieldValues = {};\n elements?.forEach(el => {\n if (\"displayOnly\" in el && el.displayOnly) return;\n\n if (\"initialUri\" in el) {\n item[el.id as string] = (el as any).initialUri;\n } else if (\"initialValue\" in el && el.initialValue !== undefined) {\n item[el.id as string] = el.initialValue;\n }\n });\n return item;\n };\n\n const handleAppend = (count = 1) => {\n const max = settings.repeatable.maxRepeats;\n\n if (max && fields.length >= max) {\n return;\n }\n const itemsToAdd = Array(count).fill(0).map(() => createDefaultItem());\n append(itemsToAdd as any, {shouldFocus: true});\n };\n\n const handleRemove = (index: number) => {\n if (fields.length > (settings.repeatable.minRepeats || 0)) {\n remove(index);\n }\n };\n useEffect(() => {\n const generateGroupElements = () => {\n const min = settings.repeatable.minRepeats || 0;\n if (fields.length < min) {\n const itemsToAppend = min - fields.length;\n // console.log({itemsToAppend, current: fields.length})\n\n handleAppend(itemsToAppend);\n }\n };\n\n // This pattern correctly avoids the infinite loop by not depending on `append` or `fields`.\n // The timeout gives react-hook-form time to initialize before we check the length.\n const timer = setTimeout(generateGroupElements, 100);\n return () => clearTimeout(timer);\n\n }, [element.id, settings.repeatable.minRepeats]); // Stable dependencies\n\n // 6. Replicate the `useImperativeHandle` logic to expose the ref.\n useImperativeHandle(groupsSettings?.ref, () => fieldArray, [fieldArray]);\n\n\n const reBuildElements = useCallback((field: FieldArrayWithId, index: number) => {\n return elements?.map((childElement) => {\n const toArray = Object.entries(field);\n\n const findField = toArray.find(([name]) => name == childElement.id);\n\n return {\n ...childElement,\n initialValue: findField ? findField[1] : undefined,\n };\n }) as IFormElement<any>[];\n }, [element, elements]);\n\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={groupHelperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6} mb={4}\n style={elStyles.root || undefined}>\n\n <Box style={elStyles.body || undefined}>\n {fields.map((field, index) => (\n <Flex key={field.id} w=\"full\" position=\"relative\" flexDirection=\"column\"\n rowGap={6}\n columnGap={8}\n style={elStyles.row || undefined}>\n\n <FormRenderer\n /* ⛔ THE SAME REASON AS `Object`: a repeated item's\n fields go through this nested renderer, so without\n this the form's `rowGap` never reaches the rows\n inside a repeatable card. The `rowGap={6}` on the\n Flex above is NOT this — it separates the item's\n fields from its remove button, and is deliberately\n left alone. */\n rowGap={rowGap}\n elements={reBuildElements(field, index)}\n control={control}\n groupField={{\n index,\n name: element.id.toString(),\n // Use the path-arg form of getValues so a Group nested inside\n // an Object resolves correctly: the FormRenderer rewrites this\n // Group's id to a dotted path (e.g. \"addressGroup.addresses\"),\n // and getValues()[dottedKey] would be undefined (→ crash on\n // [index]). getValues(path) traverses the nesting instead.\n values: (getValues(element.id as any) as any)?.[index],\n append: handleAppend,\n remove: () => handleRemove(index),\n }}\n getValues={getValues}\n parentPath={`${element.id.toString()}.${index}.`}\n focusedField={(focusedField ?? _focusedField)!}\n setFocusedField={(setFocusedField ?? _setFocusedField)!}\n grid={groupsSettings?.grid}\n />\n\n {settings.removeButtonRow && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.removeButtonRow(fields.length, () => handleRemove(index), index)}\n </Box>\n )}\n\n\n {settings.repeatable.minusButton && fields.length > settings.repeatable.minRepeats && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.repeatable.minusButton(fields.length, () => handleRemove(index))}\n </Box>\n )}\n </Flex>\n ))}\n </Box>\n\n {settings.repeatable.plusButton && (\n <Flex justifyContent=\"flex-start\" w=\"full\" mt={8}\n style={elStyles.addButton || undefined}>\n {settings.repeatable.plusButton(fields.length, handleAppend)}\n </Flex>\n )}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default Group;\n"],"names":["useState","useMemo","useComponentDefaults","useResolvedElementStyles","flattenSlotStyles","useFieldArray","useEffect","useImperativeHandle","useCallback","jsx","KitsContainer","jsxs","Flex","Box","index","FormRenderer"],"mappings":"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"}
|
|
@@ -18,7 +18,8 @@ const Group = ({
|
|
|
18
18
|
groupField,
|
|
19
19
|
focusedField,
|
|
20
20
|
setFocusedField,
|
|
21
|
-
fieldLogic
|
|
21
|
+
fieldLogic,
|
|
22
|
+
rowGap
|
|
22
23
|
}) => {
|
|
23
24
|
const { isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots } = fieldLogic;
|
|
24
25
|
const [_focusedField, _setFocusedField] = useState("");
|
|
@@ -136,6 +137,7 @@ const Group = ({
|
|
|
136
137
|
/* @__PURE__ */ jsx(
|
|
137
138
|
FormRenderer,
|
|
138
139
|
{
|
|
140
|
+
rowGap,
|
|
139
141
|
elements: reBuildElements(field, index),
|
|
140
142
|
control,
|
|
141
143
|
groupField: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../src/form-renderer/components/fields/Group/index.native.tsx"],"sourcesContent":["// components/fields/Group.tsx\n\nimport React, {useCallback, useEffect, useImperativeHandle, useMemo, useState} from 'react';\nimport {type FieldArrayWithId, type FieldValues, useFieldArray} from 'react-hook-form';\nimport type {IFormElement, IGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Box, Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {useComponentDefaults, useResolvedElementStyles} from \"../../../../hooks\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a repeatable group of fields (a field array), preserving all the logic\n * for default values, min/max repeats, and custom action buttons.\n */\nexport const Group = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n }: UseFieldLogicElementProps<T>) => { // Ensure UseFieldLogicProps is updated to pass focus props\n // 1. Get the group's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n // Fallback focus state, used only when the parent form doesn't supply\n // focusedField/setFocusedField — web passes the props straight through.\n const [_focusedField, _setFocusedField] = useState<string>('');\n\n const groupElement = element as IGroup<T>;\n const {groupsSettings} = groupElement;\n\n // Resolve groupSlots (dynamic or static) and merge with theme Group defaults\n const resolvedGroupSlots = useMemo(() => {\n const gs = groupElement.groupSlots;\n if (!gs) return undefined;\n if (typeof gs === 'function') {\n return (gs as any)(fieldLogic.watchedValues, fieldLogic.formContext.getValues(), fieldLogic.formContext, groupField);\n }\n return gs;\n }, [groupElement.groupSlots, fieldLogic.watchedValues, fieldLogic.formContext, groupField]);\n\n const {elementStyles: groupStyles} = useComponentDefaults('Group', {\n slots: resolvedGroupSlots,\n } as any);\n const elStyles = useResolvedElementStyles(groupStyles);\n\n // Element-level `slots` (the outer KitsContainer's container/label/helperText/\n // error) arrive in the nested IElementSlotConfig shape; flatten to the flat\n // { [slot]: styleRecord } map KitsContainer expects. (groupSlots above drive\n // the inner repeatable list — root/body/row — and are already flattened.)\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n // 2. Initialize react-hook-form's field array management.\n const fieldArray = useFieldArray({\n control,\n name: element.id as any,\n });\n const {fields, append, remove} = fieldArray;\n\n // console.log('hitted', element, {fields}, element.id)\n // 3. Process group settings with defaults, exactly like the original component.\n const settings = useMemo(() => ({\n grid: groupsSettings?.grid,\n repeatable: {\n minRepeats: groupsSettings?.repeatable?.minRepeats || 0,\n maxRepeats: groupsSettings?.repeatable?.maxRepeats || Infinity,\n plusButton: groupsSettings?.repeatable?.plusButton,\n minusButton: groupsSettings?.repeatable?.minusButton,\n },\n removeButtonRow: groupsSettings?.removeButtonRow,\n }), [groupsSettings]);\n\n // 4. Replicate the logic to build a default item object for new rows.\n const createDefaultItem = (): FieldValues => {\n const item: FieldValues = {};\n elements?.forEach(el => {\n if (\"displayOnly\" in el && el.displayOnly) return;\n\n if (\"initialUri\" in el) {\n item[el.id as string] = (el as any).initialUri;\n } else if (\"initialValue\" in el && el.initialValue !== undefined) {\n item[el.id as string] = el.initialValue;\n }\n });\n return item;\n };\n\n const handleAppend = (count = 1) => {\n const max = settings.repeatable.maxRepeats;\n\n if (max && fields.length >= max) {\n return;\n }\n const itemsToAdd = Array(count).fill(0).map(() => createDefaultItem());\n append(itemsToAdd as any, {shouldFocus: true});\n };\n\n const handleRemove = (index: number) => {\n if (fields.length > (settings.repeatable.minRepeats || 0)) {\n remove(index);\n }\n };\n useEffect(() => {\n const generateGroupElements = () => {\n const min = settings.repeatable.minRepeats || 0;\n if (fields.length < min) {\n const itemsToAppend = min - fields.length;\n // console.log({itemsToAppend, current: fields.length})\n\n handleAppend(itemsToAppend);\n }\n };\n\n // This pattern correctly avoids the infinite loop by not depending on `append` or `fields`.\n // The timeout gives react-hook-form time to initialize before we check the length.\n const timer = setTimeout(generateGroupElements, 100);\n return () => clearTimeout(timer);\n\n }, [element.id, settings.repeatable.minRepeats]); // Stable dependencies\n\n // 6. Replicate the `useImperativeHandle` logic to expose the ref.\n useImperativeHandle(groupsSettings?.ref, () => fieldArray, [fieldArray]);\n\n\n const reBuildElements = useCallback((field: FieldArrayWithId, index: number) => {\n return elements?.map((childElement) => {\n const toArray = Object.entries(field);\n\n const findField = toArray.find(([name]) => name == childElement.id);\n\n return {\n ...childElement,\n initialValue: findField ? findField[1] : undefined,\n };\n }) as IFormElement<any>[];\n }, [element, elements]);\n\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={groupHelperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6} mb={4}\n style={elStyles.root || undefined}>\n\n <Box style={elStyles.body || undefined}>\n {fields.map((field, index) => (\n <Flex key={field.id} w=\"full\" position=\"relative\" flexDirection=\"column\"\n rowGap={6}\n columnGap={8}\n style={elStyles.row || undefined}>\n\n <FormRenderer\n elements={reBuildElements(field, index)}\n control={control}\n groupField={{\n index,\n name: element.id.toString(),\n // Use the path-arg form of getValues so a Group nested inside\n // an Object resolves correctly: the FormRenderer rewrites this\n // Group's id to a dotted path (e.g. \"addressGroup.addresses\"),\n // and getValues()[dottedKey] would be undefined (→ crash on\n // [index]). getValues(path) traverses the nesting instead.\n values: (getValues(element.id as any) as any)?.[index],\n append: handleAppend,\n remove: () => handleRemove(index),\n }}\n getValues={getValues}\n parentPath={`${element.id.toString()}.${index}.`}\n focusedField={(focusedField ?? _focusedField)!}\n setFocusedField={(setFocusedField ?? _setFocusedField)!}\n grid={groupsSettings?.grid}\n />\n\n {settings.removeButtonRow && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.removeButtonRow(fields.length, () => handleRemove(index), index)}\n </Box>\n )}\n\n\n {settings.repeatable.minusButton && fields.length > settings.repeatable.minRepeats && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.repeatable.minusButton(fields.length, () => handleRemove(index))}\n </Box>\n )}\n </Flex>\n ))}\n </Box>\n\n {settings.repeatable.plusButton && (\n <Flex justifyContent=\"flex-start\" w=\"full\" mt={8}\n style={elStyles.addButton || undefined}>\n {settings.repeatable.plusButton(fields.length, handleAppend)}\n </Flex>\n )}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default Group;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../src/form-renderer/components/fields/Group/index.native.tsx"],"sourcesContent":["// components/fields/Group.tsx\n\nimport React, {useCallback, useEffect, useImperativeHandle, useMemo, useState} from 'react';\nimport {type FieldArrayWithId, type FieldValues, useFieldArray} from 'react-hook-form';\nimport type {IFormElement, IGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Box, Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {useComponentDefaults, useResolvedElementStyles} from \"../../../../hooks\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a repeatable group of fields (a field array), preserving all the logic\n * for default values, min/max repeats, and custom action buttons.\n */\nexport const Group = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n rowGap,\n }: UseFieldLogicElementProps<T>) => { // Ensure UseFieldLogicProps is updated to pass focus props\n // 1. Get the group's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText: groupHelperText, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n // Fallback focus state, used only when the parent form doesn't supply\n // focusedField/setFocusedField — web passes the props straight through.\n const [_focusedField, _setFocusedField] = useState<string>('');\n\n const groupElement = element as IGroup<T>;\n const {groupsSettings} = groupElement;\n\n // Resolve groupSlots (dynamic or static) and merge with theme Group defaults\n const resolvedGroupSlots = useMemo(() => {\n const gs = groupElement.groupSlots;\n if (!gs) return undefined;\n if (typeof gs === 'function') {\n return (gs as any)(fieldLogic.watchedValues, fieldLogic.formContext.getValues(), fieldLogic.formContext, groupField);\n }\n return gs;\n }, [groupElement.groupSlots, fieldLogic.watchedValues, fieldLogic.formContext, groupField]);\n\n const {elementStyles: groupStyles} = useComponentDefaults('Group', {\n slots: resolvedGroupSlots,\n } as any);\n const elStyles = useResolvedElementStyles(groupStyles);\n\n // Element-level `slots` (the outer KitsContainer's container/label/helperText/\n // error) arrive in the nested IElementSlotConfig shape; flatten to the flat\n // { [slot]: styleRecord } map KitsContainer expects. (groupSlots above drive\n // the inner repeatable list — root/body/row — and are already flattened.)\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n // 2. Initialize react-hook-form's field array management.\n const fieldArray = useFieldArray({\n control,\n name: element.id as any,\n });\n const {fields, append, remove} = fieldArray;\n\n // console.log('hitted', element, {fields}, element.id)\n // 3. Process group settings with defaults, exactly like the original component.\n const settings = useMemo(() => ({\n grid: groupsSettings?.grid,\n repeatable: {\n minRepeats: groupsSettings?.repeatable?.minRepeats || 0,\n maxRepeats: groupsSettings?.repeatable?.maxRepeats || Infinity,\n plusButton: groupsSettings?.repeatable?.plusButton,\n minusButton: groupsSettings?.repeatable?.minusButton,\n },\n removeButtonRow: groupsSettings?.removeButtonRow,\n }), [groupsSettings]);\n\n // 4. Replicate the logic to build a default item object for new rows.\n const createDefaultItem = (): FieldValues => {\n const item: FieldValues = {};\n elements?.forEach(el => {\n if (\"displayOnly\" in el && el.displayOnly) return;\n\n if (\"initialUri\" in el) {\n item[el.id as string] = (el as any).initialUri;\n } else if (\"initialValue\" in el && el.initialValue !== undefined) {\n item[el.id as string] = el.initialValue;\n }\n });\n return item;\n };\n\n const handleAppend = (count = 1) => {\n const max = settings.repeatable.maxRepeats;\n\n if (max && fields.length >= max) {\n return;\n }\n const itemsToAdd = Array(count).fill(0).map(() => createDefaultItem());\n append(itemsToAdd as any, {shouldFocus: true});\n };\n\n const handleRemove = (index: number) => {\n if (fields.length > (settings.repeatable.minRepeats || 0)) {\n remove(index);\n }\n };\n useEffect(() => {\n const generateGroupElements = () => {\n const min = settings.repeatable.minRepeats || 0;\n if (fields.length < min) {\n const itemsToAppend = min - fields.length;\n // console.log({itemsToAppend, current: fields.length})\n\n handleAppend(itemsToAppend);\n }\n };\n\n // This pattern correctly avoids the infinite loop by not depending on `append` or `fields`.\n // The timeout gives react-hook-form time to initialize before we check the length.\n const timer = setTimeout(generateGroupElements, 100);\n return () => clearTimeout(timer);\n\n }, [element.id, settings.repeatable.minRepeats]); // Stable dependencies\n\n // 6. Replicate the `useImperativeHandle` logic to expose the ref.\n useImperativeHandle(groupsSettings?.ref, () => fieldArray, [fieldArray]);\n\n\n const reBuildElements = useCallback((field: FieldArrayWithId, index: number) => {\n return elements?.map((childElement) => {\n const toArray = Object.entries(field);\n\n const findField = toArray.find(([name]) => name == childElement.id);\n\n return {\n ...childElement,\n initialValue: findField ? findField[1] : undefined,\n };\n }) as IFormElement<any>[];\n }, [element, elements]);\n\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={groupHelperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6} mb={4}\n style={elStyles.root || undefined}>\n\n <Box style={elStyles.body || undefined}>\n {fields.map((field, index) => (\n <Flex key={field.id} w=\"full\" position=\"relative\" flexDirection=\"column\"\n rowGap={6}\n columnGap={8}\n style={elStyles.row || undefined}>\n\n <FormRenderer\n /* ⛔ THE SAME REASON AS `Object`: a repeated item's\n fields go through this nested renderer, so without\n this the form's `rowGap` never reaches the rows\n inside a repeatable card. The `rowGap={6}` on the\n Flex above is NOT this — it separates the item's\n fields from its remove button, and is deliberately\n left alone. */\n rowGap={rowGap}\n elements={reBuildElements(field, index)}\n control={control}\n groupField={{\n index,\n name: element.id.toString(),\n // Use the path-arg form of getValues so a Group nested inside\n // an Object resolves correctly: the FormRenderer rewrites this\n // Group's id to a dotted path (e.g. \"addressGroup.addresses\"),\n // and getValues()[dottedKey] would be undefined (→ crash on\n // [index]). getValues(path) traverses the nesting instead.\n values: (getValues(element.id as any) as any)?.[index],\n append: handleAppend,\n remove: () => handleRemove(index),\n }}\n getValues={getValues}\n parentPath={`${element.id.toString()}.${index}.`}\n focusedField={(focusedField ?? _focusedField)!}\n setFocusedField={(setFocusedField ?? _setFocusedField)!}\n grid={groupsSettings?.grid}\n />\n\n {settings.removeButtonRow && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.removeButtonRow(fields.length, () => handleRemove(index), index)}\n </Box>\n )}\n\n\n {settings.repeatable.minusButton && fields.length > settings.repeatable.minRepeats && (\n <Box style={{zIndex: 1, ...(elStyles.removeButton || {})}}>\n {settings.repeatable.minusButton(fields.length, () => handleRemove(index))}\n </Box>\n )}\n </Flex>\n ))}\n </Box>\n\n {settings.repeatable.plusButton && (\n <Flex justifyContent=\"flex-start\" w=\"full\" mt={8}\n style={elStyles.addButton || undefined}>\n {settings.repeatable.plusButton(fields.length, handleAppend)}\n </Flex>\n )}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default Group;\n"],"names":[],"mappings":"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"}
|
|
@@ -17,7 +17,8 @@ const ObjectElement = ({
|
|
|
17
17
|
groupField,
|
|
18
18
|
focusedField,
|
|
19
19
|
setFocusedField,
|
|
20
|
-
fieldLogic
|
|
20
|
+
fieldLogic,
|
|
21
|
+
rowGap
|
|
21
22
|
}) => {
|
|
22
23
|
const { isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots } = fieldLogic;
|
|
23
24
|
const objectElement = element;
|
|
@@ -37,10 +38,11 @@ const ObjectElement = ({
|
|
|
37
38
|
parentPath: `${element.id.toString()}.`,
|
|
38
39
|
focusedField,
|
|
39
40
|
setFocusedField,
|
|
40
|
-
grid
|
|
41
|
+
grid,
|
|
42
|
+
rowGap
|
|
41
43
|
}
|
|
42
44
|
);
|
|
43
|
-
}, [elements, focusedField, groupField, grid]);
|
|
45
|
+
}, [elements, focusedField, groupField, grid, rowGap]);
|
|
44
46
|
if (!isShown) {
|
|
45
47
|
return null;
|
|
46
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../../../src/form-renderer/components/fields/Object/index.tsx"],"sourcesContent":["// components/fields/Object.tsx\n\nimport React, {useMemo} from 'react';\nimport {type FieldValues} from 'react-hook-form';\nimport type {IObjectGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a static, non-repeatable group of fields (a nested object).\n * It provides a layout wrapper and recursively renders its children with the correct nested path.\n */\nexport const ObjectElement = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n }: UseFieldLogicElementProps<T>) => {\n\n // 1. Get the object's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n const objectElement = element as IObjectGroup<T>;\n const {grid} = objectElement;\n\n // `slots` from the logic hook is the nested IElementSlotConfig shape\n // ({ [slot]: { style, props } }). KitsContainer expects the FLAT\n // { [slot]: styleRecord } map (the same shape useComponentDefaults yields\n // for inputs), so flatten before handing it over — otherwise container /\n // label / helperText / error slot styles never reach the wrapper.\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n const renderer = useMemo(() => {\n if (!elements) {\n return null;\n }\n return <FormRenderer\n elements={elements}\n control={control}\n getValues={getValues}\n groupField={groupField}\n parentPath={`${element.id.toString()}.`}\n focusedField={focusedField}\n setFocusedField={setFocusedField!}\n grid={grid}\n />\n }, [elements, focusedField, groupField, grid])\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={helperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n containerStyle={elementStyle?.container}\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6}>\n {renderer}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default ObjectElement\n"],"names":["useMemo","flattenSlotStyles","jsx","FormRenderer","KitsContainer","Flex"],"mappings":";;;;;;;;;;;;AAcO,MAAM,gBAAgB,CAAwB;AAAA,EACH,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA;AACJ,CAAA,KAAoC;AAG9E,EAAA,MAAM,EAAC,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,YAAA,EAAc,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,KAAA,EAAK,GAAI,UAAA;AAE9G,EAAA,MAAM,aAAA,GAAgB,OAAA;AACtB,EAAA,MAAM,EAAC,MAAI,GAAI,aAAA;AAOf,EAAA,MAAM,cAAA,GAAiBA,cAAQ,MAAMC,yBAAA,CAAkB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEtE,EAAA,MAAM,QAAA,GAAWD,cAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,QAAA,EAAU;AACX,MAAA,OAAO,IAAA;AAAA,IACX;AACA,IAAA,uBAAOE,cAAA;AAAA,MAACC,yBAAA;AAAA,MAAA;AAAA,QACJ,QAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA,EAAY,CAAA,EAAG,OAAA,CAAQ,EAAA,CAAG,UAAU,CAAA,CAAA,CAAA;AAAA,QACpC,YAAA;AAAA,QACA,eAAA;AAAA,QACA;AAAA;AAAA,KACJ;AAAA,EACJ,GAAG,CAAC,QAAA,EAAU,
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../../../src/form-renderer/components/fields/Object/index.tsx"],"sourcesContent":["// components/fields/Object.tsx\n\nimport React, {useMemo} from 'react';\nimport {type FieldValues} from 'react-hook-form';\nimport type {IObjectGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a static, non-repeatable group of fields (a nested object).\n * It provides a layout wrapper and recursively renders its children with the correct nested path.\n */\nexport const ObjectElement = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n rowGap,\n }: UseFieldLogicElementProps<T>) => {\n\n // 1. Get the object's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n const objectElement = element as IObjectGroup<T>;\n const {grid} = objectElement;\n\n // `slots` from the logic hook is the nested IElementSlotConfig shape\n // ({ [slot]: { style, props } }). KitsContainer expects the FLAT\n // { [slot]: styleRecord } map (the same shape useComponentDefaults yields\n // for inputs), so flatten before handing it over — otherwise container /\n // label / helperText / error slot styles never reach the wrapper.\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n const renderer = useMemo(() => {\n if (!elements) {\n return null;\n }\n return <FormRenderer\n elements={elements}\n control={control}\n getValues={getValues}\n groupField={groupField}\n parentPath={`${element.id.toString()}.`}\n focusedField={focusedField}\n setFocusedField={setFocusedField!}\n grid={grid}\n /* ⛔ WITHOUT THIS THE FORM-LEVEL `rowGap` STOPS HERE. An Object\n renders its children through a NESTED FormRenderer, and a renderer\n that is handed nothing falls back to its own default — so a form\n that asked for a different row gap got it on its top-level rows\n and nowhere else. Every card on a screen like Edit Profile is an\n Object or a Group, which is to say: nowhere that matters.\n Measured before this line existed: the gap from an input box to\n the next label was 8.67pt with the form asking for 6 and 8.67pt\n with it asking for 14. */\n rowGap={rowGap}\n />\n }, [elements, focusedField, groupField, grid, rowGap])\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={helperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n containerStyle={elementStyle?.container}\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6}>\n {renderer}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default ObjectElement\n"],"names":["useMemo","flattenSlotStyles","jsx","FormRenderer","KitsContainer","Flex"],"mappings":";;;;;;;;;;;;AAcO,MAAM,gBAAgB,CAAwB;AAAA,EACH,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA;AACJ,CAAA,KAAoC;AAG9E,EAAA,MAAM,EAAC,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,YAAA,EAAc,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,KAAA,EAAK,GAAI,UAAA;AAE9G,EAAA,MAAM,aAAA,GAAgB,OAAA;AACtB,EAAA,MAAM,EAAC,MAAI,GAAI,aAAA;AAOf,EAAA,MAAM,cAAA,GAAiBA,cAAQ,MAAMC,yBAAA,CAAkB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEtE,EAAA,MAAM,QAAA,GAAWD,cAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,QAAA,EAAU;AACX,MAAA,OAAO,IAAA;AAAA,IACX;AACA,IAAA,uBAAOE,cAAA;AAAA,MAACC,yBAAA;AAAA,MAAA;AAAA,QACJ,QAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA,EAAY,CAAA,EAAG,OAAA,CAAQ,EAAA,CAAG,UAAU,CAAA,CAAA,CAAA;AAAA,QACpC,YAAA;AAAA,QACA,eAAA;AAAA,QACA,IAAA;AAAA,QAUA;AAAA;AAAA,KACJ;AAAA,EACJ,GAAG,CAAC,QAAA,EAAU,cAAc,UAAA,EAAY,IAAA,EAAM,MAAM,CAAC,CAAA;AAErD,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA,OAAO,IAAA;AAAA,EACX;AAEA,EAAA,uBACID,cAAA;AAAA,IAACE,sBAAA;AAAA,IAAA;AAAA,MACG,EAAA,EAAI,OAAA,CAAQ,EAAA,CAAG,QAAA,EAAS;AAAA,MACxB,KAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,YAAY,KAAA,EAAO,OAAA;AAAA,MAC3B,SAAS,UAAA,EAAY,OAAA;AAAA,MACrB,SAAA;AAAA,MACA,QAAA,EAAU,UAAA;AAAA,MACV,IAAA,EAAI,IAAA;AAAA,MACJ,gBAAgB,YAAA,EAAc,SAAA;AAAA,MAC9B,aAAA,EAAe,cAAA;AAAA,MAEf,QAAA,kBAAAF,cAAA,CAACG,iBAAK,CAAA,EAAE,MAAA,EAAO,eAAc,QAAA,EAAS,GAAA,EAAK,GACtC,QAAA,EAAA,QAAA,EACL;AAAA;AAAA,GACJ;AAER;;;;;"}
|
|
@@ -13,7 +13,8 @@ const ObjectElement = ({
|
|
|
13
13
|
groupField,
|
|
14
14
|
focusedField,
|
|
15
15
|
setFocusedField,
|
|
16
|
-
fieldLogic
|
|
16
|
+
fieldLogic,
|
|
17
|
+
rowGap
|
|
17
18
|
}) => {
|
|
18
19
|
const { isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots } = fieldLogic;
|
|
19
20
|
const objectElement = element;
|
|
@@ -33,10 +34,11 @@ const ObjectElement = ({
|
|
|
33
34
|
parentPath: `${element.id.toString()}.`,
|
|
34
35
|
focusedField,
|
|
35
36
|
setFocusedField,
|
|
36
|
-
grid
|
|
37
|
+
grid,
|
|
38
|
+
rowGap
|
|
37
39
|
}
|
|
38
40
|
);
|
|
39
|
-
}, [elements, focusedField, groupField, grid]);
|
|
41
|
+
}, [elements, focusedField, groupField, grid, rowGap]);
|
|
40
42
|
if (!isShown) {
|
|
41
43
|
return null;
|
|
42
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../../../src/form-renderer/components/fields/Object/index.tsx"],"sourcesContent":["// components/fields/Object.tsx\n\nimport React, {useMemo} from 'react';\nimport {type FieldValues} from 'react-hook-form';\nimport type {IObjectGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a static, non-repeatable group of fields (a nested object).\n * It provides a layout wrapper and recursively renders its children with the correct nested path.\n */\nexport const ObjectElement = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n }: UseFieldLogicElementProps<T>) => {\n\n // 1. Get the object's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n const objectElement = element as IObjectGroup<T>;\n const {grid} = objectElement;\n\n // `slots` from the logic hook is the nested IElementSlotConfig shape\n // ({ [slot]: { style, props } }). KitsContainer expects the FLAT\n // { [slot]: styleRecord } map (the same shape useComponentDefaults yields\n // for inputs), so flatten before handing it over — otherwise container /\n // label / helperText / error slot styles never reach the wrapper.\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n const renderer = useMemo(() => {\n if (!elements) {\n return null;\n }\n return <FormRenderer\n elements={elements}\n control={control}\n getValues={getValues}\n groupField={groupField}\n parentPath={`${element.id.toString()}.`}\n focusedField={focusedField}\n setFocusedField={setFocusedField!}\n grid={grid}\n />\n }, [elements, focusedField, groupField, grid])\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={helperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n containerStyle={elementStyle?.container}\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6}>\n {renderer}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default ObjectElement\n"],"names":[],"mappings":";;;;;;;;AAcO,MAAM,gBAAgB,CAAwB;AAAA,EACH,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA;AACJ,CAAA,KAAoC;AAG9E,EAAA,MAAM,EAAC,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,YAAA,EAAc,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,KAAA,EAAK,GAAI,UAAA;AAE9G,EAAA,MAAM,aAAA,GAAgB,OAAA;AACtB,EAAA,MAAM,EAAC,MAAI,GAAI,aAAA;AAOf,EAAA,MAAM,cAAA,GAAiB,QAAQ,MAAM,iBAAA,CAAkB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEtE,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,QAAA,EAAU;AACX,MAAA,OAAO,IAAA;AAAA,IACX;AACA,IAAA,uBAAO,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACJ,QAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA,EAAY,CAAA,EAAG,OAAA,CAAQ,EAAA,CAAG,UAAU,CAAA,CAAA,CAAA;AAAA,QACpC,YAAA;AAAA,QACA,eAAA;AAAA,QACA;AAAA;AAAA,KACJ;AAAA,EACJ,GAAG,CAAC,QAAA,EAAU,
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../src/form-renderer/components/fields/Object/index.tsx"],"sourcesContent":["// components/fields/Object.tsx\n\nimport React, {useMemo} from 'react';\nimport {type FieldValues} from 'react-hook-form';\nimport type {IObjectGroup, UseFieldLogicElementProps} from \"@lmb-it/kitsconcerto-types\";\nimport {Flex} from \"../../../../_compat\";\nimport KitsContainer from \"../../../../form/helpers/FormContainer\";\nimport {FormRenderer} from \"../../FormRenderer\";\nimport {flattenSlotStyles} from \"../../../utils\";\n\n/**\n * Renders a static, non-repeatable group of fields (a nested object).\n * It provides a layout wrapper and recursively renders its children with the correct nested path.\n */\nexport const ObjectElement = <T extends FieldValues>({\n element,\n control,\n getValues,\n groupField,\n focusedField,\n setFocusedField,\n fieldLogic,\n rowGap,\n }: UseFieldLogicElementProps<T>) => {\n\n // 1. Get the object's own dynamic state (visibility, layout, label) from the logic hook.\n const {isShown, label, elements, helperText, style: elementStyle, fieldState, hideError, isRequired, slots} = fieldLogic;\n\n const objectElement = element as IObjectGroup<T>;\n const {grid} = objectElement;\n\n // `slots` from the logic hook is the nested IElementSlotConfig shape\n // ({ [slot]: { style, props } }). KitsContainer expects the FLAT\n // { [slot]: styleRecord } map (the same shape useComponentDefaults yields\n // for inputs), so flatten before handing it over — otherwise container /\n // label / helperText / error slot styles never reach the wrapper.\n const containerSlots = useMemo(() => flattenSlotStyles(slots), [slots]);\n\n const renderer = useMemo(() => {\n if (!elements) {\n return null;\n }\n return <FormRenderer\n elements={elements}\n control={control}\n getValues={getValues}\n groupField={groupField}\n parentPath={`${element.id.toString()}.`}\n focusedField={focusedField}\n setFocusedField={setFocusedField!}\n grid={grid}\n /* ⛔ WITHOUT THIS THE FORM-LEVEL `rowGap` STOPS HERE. An Object\n renders its children through a NESTED FormRenderer, and a renderer\n that is handed nothing falls back to its own default — so a form\n that asked for a different row gap got it on its top-level rows\n and nowhere else. Every card on a screen like Edit Profile is an\n Object or a Group, which is to say: nowhere that matters.\n Measured before this line existed: the gap from an input box to\n the next label was 8.67pt with the form asking for 6 and 8.67pt\n with it asking for 14. */\n rowGap={rowGap}\n />\n }, [elements, focusedField, groupField, grid, rowGap])\n\n if (!isShown) {\n return null;\n }\n\n return (\n <KitsContainer\n id={element.id.toString()}\n label={label}\n helperText={helperText}\n errors={fieldState?.error?.message}\n invalid={fieldState?.invalid}\n hideError={hideError}\n required={isRequired}\n bare\n containerStyle={elementStyle?.container}\n elementStyles={containerSlots}\n >\n <Flex w=\"full\" flexDirection=\"column\" gap={6}>\n {renderer}\n </Flex>\n </KitsContainer>\n );\n};\n\nexport default ObjectElement\n"],"names":[],"mappings":";;;;;;;;AAcO,MAAM,gBAAgB,CAAwB;AAAA,EACH,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA;AACJ,CAAA,KAAoC;AAG9E,EAAA,MAAM,EAAC,OAAA,EAAS,KAAA,EAAO,QAAA,EAAU,UAAA,EAAY,KAAA,EAAO,YAAA,EAAc,UAAA,EAAY,SAAA,EAAW,UAAA,EAAY,KAAA,EAAK,GAAI,UAAA;AAE9G,EAAA,MAAM,aAAA,GAAgB,OAAA;AACtB,EAAA,MAAM,EAAC,MAAI,GAAI,aAAA;AAOf,EAAA,MAAM,cAAA,GAAiB,QAAQ,MAAM,iBAAA,CAAkB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEtE,EAAA,MAAM,QAAA,GAAW,QAAQ,MAAM;AAC3B,IAAA,IAAI,CAAC,QAAA,EAAU;AACX,MAAA,OAAO,IAAA;AAAA,IACX;AACA,IAAA,uBAAO,GAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACJ,QAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA;AAAA,QACA,UAAA;AAAA,QACA,UAAA,EAAY,CAAA,EAAG,OAAA,CAAQ,EAAA,CAAG,UAAU,CAAA,CAAA,CAAA;AAAA,QACpC,YAAA;AAAA,QACA,eAAA;AAAA,QACA,IAAA;AAAA,QAUA;AAAA;AAAA,KACJ;AAAA,EACJ,GAAG,CAAC,QAAA,EAAU,cAAc,UAAA,EAAY,IAAA,EAAM,MAAM,CAAC,CAAA;AAErD,EAAA,IAAI,CAAC,OAAA,EAAS;AACV,IAAA,OAAO,IAAA;AAAA,EACX;AAEA,EAAA,uBACI,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACG,EAAA,EAAI,OAAA,CAAQ,EAAA,CAAG,QAAA,EAAS;AAAA,MACxB,KAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA,EAAQ,YAAY,KAAA,EAAO,OAAA;AAAA,MAC3B,SAAS,UAAA,EAAY,OAAA;AAAA,MACrB,SAAA;AAAA,MACA,QAAA,EAAU,UAAA;AAAA,MACV,IAAA,EAAI,IAAA;AAAA,MACJ,gBAAgB,YAAA,EAAc,SAAA;AAAA,MAC9B,aAAA,EAAe,cAAA;AAAA,MAEf,QAAA,kBAAA,GAAA,CAAC,QAAK,CAAA,EAAE,MAAA,EAAO,eAAc,QAAA,EAAS,GAAA,EAAK,GACtC,QAAA,EAAA,QAAA,EACL;AAAA;AAAA,GACJ;AAER;;;;"}
|
|
@@ -228,7 +228,6 @@ const useFieldLogic = ({
|
|
|
228
228
|
colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,
|
|
229
229
|
rowSpan: getDynamicProp(element.rowSpan),
|
|
230
230
|
columnGap: getDynamicProp(element.columnGap),
|
|
231
|
-
rowGap: getDynamicProp(element.rowGap),
|
|
232
231
|
colOffset: getDynamicProp(element.colOffset),
|
|
233
232
|
area: getDynamicProp(element.area)
|
|
234
233
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldLogic.cjs","sources":["../../../../src/form-renderer/hooks/useFieldLogic.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {type FieldValues, useController, useFormContext, type UseFormReturn} from 'react-hook-form';\nimport {Schema} from 'yup';\n\n// Assuming your types are consolidated in a central file.\nimport type {\n IElementStyle,\n IFormElement,\n ILabelElement,\n ITextFieldProps,\n LogicFunction,\n UseFieldLogicProps,\n UseFieldLogicReturn\n} from '@lmb-it/kitsconcerto-types';\nimport {dynamicList} from \"../utils\";\nimport _ from \"lodash\";\n\n// --- Hook Return Value ---\n\n/**\n * The core logic engine for an individual form field.\n * This hook replaces LogicContext and FormFieldContext. It watches dependencies,\n * calculates all dynamic properties (visibility, disabled state, required status, etc.),\n * and provides the necessary props from react-hook-form.\n *\n * @param {UseFieldLogicProps<T>} props - The element definition and form control.\n * @returns {UseFieldLogicReturn<T>} An object containing all necessary props and states for rendering the field.\n */\nexport const useFieldLogic = <T extends FieldValues>({\n element: {onDepsChange, ...element},\n control,\n getValues,\n isFocused,\n groupField,\n watchedValues\n }: UseFieldLogicProps<T>): UseFieldLogicReturn<T> => {\n\n\n const formContext = useFormContext<T>()\n\n const prevDepsRef = useRef<string>(\"\");\n\n const watchedSig = useMemo(() => JSON.stringify(watchedValues), [watchedValues]);\n\n const allFormValues = useMemo(() => getValues(), [getValues, watchedSig]);\n\n /*const watchedObject = useMemo(() => {\n return dependencies.reduce((acc, dep, index) => {\n acc[dep] = watchedValues[index];\n return acc;\n }, {} as any)\n }, [watchedValues, dependencies])*/\n\n const childElements = useMemo(() => {\n if (!('elements' in element)) {\n return [];\n }\n const elements = element.elements;\n if (typeof elements === 'function') {\n return (elements as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return elements;\n /*\n * ⛔ `element` BELONGS HERE BECAUSE THE BODY READS IT. Without it this\n * memo returns the children captured on the FIRST render and never\n * looks at `element` again — so a container (Object, Group) freezes\n * its whole subtree at mount.\n *\n * What that cost: AlphaMatch's profile screen mounts with\n * `list: []` and is handed 250 nationalities about a second later.\n * The parent rebuilds its element array, the new array reaches the\n * container, and this memo hands the children the OLD one. The\n * device log says `items=250` and the picker draws nothing —\n * because the picker was still holding the empty list.\n *\n * ⚠️ A top-level Select never showed this. It is not a container, so\n * it does not come through here at all; its props are resolved per\n * render. Only a field nested in an Object or a Group was affected,\n * which is why a harness that put the Select at the top level\n * reported the case clear.\n */\n }, [element, watchedValues])\n\n const resolvedProps = useMemo(() => {\n const getDynamicProp = (propName: keyof IFormElement<T> | string) => {\n const propValue: LogicFunction<T> = (element as any)[propName];\n if (typeof propValue === 'function') {\n return propValue(watchedValues, allFormValues, formContext, groupField);\n }\n return propValue;\n };\n\n return {\n helperText: getDynamicProp('helperText'),\n leftAddon: getDynamicProp('leftAddon'),\n rightAddon: getDynamicProp('rightAddon'),\n keyFilter: getDynamicProp('keyFilter') as ITextFieldProps<T>['keyFilter'],\n withMask: getDynamicProp('withMask'),\n // ... resolve other dynamic props here\n };\n }, [watchedValues, allFormValues, element, control, getValues]);\n\n const lastListRef = useRef<T[] | undefined>(undefined);\n const lastElementRef = useRef<any>(null);\n const lastWatchedRef = useRef<any>(null);\n\n const list = useMemo(() => {\n if (!(\"list\" in element)) return undefined;\n\n const elementChanged = !_.isEqual(lastElementRef.current, element);\n const watchedChanged = !_.isEqual(lastWatchedRef.current, watchedValues);\n\n // ✅ nothing meaningful changed → reuse\n if (!elementChanged && !watchedChanged) {\n return lastListRef.current;\n }\n\n // 🔁 rebuild\n const nextList = dynamicList<T>(\n element,\n watchedValues,\n allFormValues,\n groupField,\n formContext\n );\n\n lastElementRef.current = element;\n lastWatchedRef.current = watchedValues;\n lastListRef.current = nextList;\n\n return nextList;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n // 4. Centralize dynamic property calculations using memoization.\n const isShown = useMemo(() => {\n // console.log({watchedObject, allFormValues})\n const showLogic = element.show || element.logic?.show;\n if (typeof showLogic === 'function') {\n return (showLogic as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return true;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isDisabled = useMemo(() => {\n const disableLogic = element.isDisabled || element.logic?.disable;\n if (typeof disableLogic === 'function') {\n return (disableLogic as LogicFunction<T, boolean>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return !!disableLogic;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isRequired = useMemo(() => {\n if (!('schema' in element) || !element.schema) return false;\n\n const schema = element.schema as Schema<any>;\n\n const checkRequired = (schema: Schema<any>, parentValues: any): boolean => {\n try {\n const type = (schema as any)._type;\n\n const testValue = (() => {\n switch (type) {\n case 'array':\n return [];\n case 'object':\n return {};\n case 'boolean':\n return undefined;\n case 'number':\n return undefined;\n case 'date':\n return undefined;\n default:\n return ''; // string or unknown\n }\n })();\n // Try validating an empty string\n schema.validateSync(\n testValue, // simulating the field is empty\n {\n context: parentValues,\n // @ts-ignore\n parent: parentValues,\n abortEarly: false,\n }\n );\n\n return false; // Passed even when empty => not required\n } catch (err: any) {\n // if (element.id === 'count/ries') {\n // console.log(err.inner || err);\n // }\n\n if (err?.inner?.length) {\n return err.inner.some(\n (e: any) =>\n e.type === 'required' ||\n e.message?.toLowerCase().includes('required')\n );\n }\n\n return (\n err?.type === 'required' ||\n err?.message?.toLowerCase().includes('required')\n );\n }\n };\n\n // Get the parent object (either group or full form)\n const parent = groupField && groupField.index !== undefined\n ? getValues?.()?.[groupField.name]?.[groupField.index]\n : getValues?.();\n\n return checkRequired(schema, parent);\n }, [element, watchedValues, allFormValues]);\n\n const label = useMemo(() => {\n if (typeof element.label === 'function') {\n return (element.label as LogicFunction<T, ILabelElement>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return element.label;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const placeholder = useMemo(() => {\n if ('placeholder' in element && typeof element.placeholder === 'function') {\n return (element.placeholder as LogicFunction<T, string>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return ('placeholder' in element ? element.placeholder : undefined) as string | undefined;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const resolvedStyle = useMemo(() => {\n const s = 'style' in element ? element.style : undefined;\n\n if (s && typeof s === 'function') {\n return s(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return s;\n }, [watchedValues, allFormValues, control, getValues, element])\n\n // ─────────────────────────────────────────────────────────────\n // Dev-mode deprecation warning for the legacy `style` prop.\n // Fires ONCE per field-instance mount (guarded by hasWarnedRef +\n // empty deps) so it does not re-fire on keystrokes / re-renders /\n // theme changes / etc. The bridge below remains functional —\n // this is a soft deprecation only; runtime removal is deferred\n // to the next major version.\n // ─────────────────────────────────────────────────────────────\n const hasWarnedDeprecatedStyleRef = useRef(false);\n useEffect(() => {\n // `process` is undeclared on native (no @types/node) but the\n // bundler statically replaces it on both platforms in production\n // builds. Reading it via globalThis sidesteps the TS lookup\n // without changing the runtime behaviour.\n const nodeEnv = (globalThis as any)?.process?.env?.NODE_ENV;\n if (nodeEnv === 'production') return;\n if (hasWarnedDeprecatedStyleRef.current) return;\n if (!('style' in element) || (element as any).style === undefined) return;\n\n hasWarnedDeprecatedStyleRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[KitsConcerto] Field \"${(element as any).id}\": the \"style\" prop is deprecated. ` +\n `Use \"slots\" instead. Migration: ` +\n `style.input → slots.root.style, ` +\n `style.container → slots.container.style, ` +\n `style.label → slots.label.style, ` +\n `style.helperText → slots.helperText.style, ` +\n `style.errorMessage → slots.error.style. ` +\n `This prop will be removed in the next major version.`\n );\n // Empty deps: warn once on mount only — element identity may\n // change every render (form re-constructs configs), so we\n // cannot key on it without re-firing the warning.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Merge explicit `slots` with `style` sub-keys.\n * IElementStyle sub-keys are bridged into the slot system so they\n * flow through useComponentDefaults → elementStyles → KitsContainer.\n * Priority: style sub-keys (lowest) < explicit slots (highest).\n */\n const slots = useMemo(() => {\n // 1. Resolve explicit slots (DynamicValue)\n const rawSlots = 'slots' in element ? element.slots : undefined;\n let explicitSlots: Record<string, { props?: any; style?: any }> | undefined;\n if (rawSlots && typeof rawSlots === 'function') {\n explicitSlots = (rawSlots as any)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n } else {\n explicitSlots = rawSlots as any;\n }\n\n // 2. Bridge IElementStyle sub-keys into slot format\n if (!resolvedStyle && !explicitSlots) return undefined;\n if (!resolvedStyle) return explicitSlots;\n\n const STYLE_TO_SLOT: Record<string, string> = {\n input: 'root',\n container: 'container',\n label: 'label',\n helperText: 'helperText',\n errorMessage: 'error',\n };\n\n const result: Record<string, { props?: any; style?: any }> = {};\n\n // First layer: style sub-keys (lower priority)\n for (const [styleKey, slotKey] of Object.entries(STYLE_TO_SLOT)) {\n const val = (resolvedStyle as any)[styleKey];\n if (val) {\n result[slotKey] = { style: val };\n }\n }\n\n // Second layer: explicit slots override\n if (explicitSlots) {\n for (const [key, slot] of Object.entries(explicitSlots)) {\n if (!result[key]) {\n result[key] = slot;\n } else {\n result[key] = {\n ...slot,\n style: { ...result[key].style, ...(slot.style || {}) },\n };\n }\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }, [watchedValues, allFormValues, control, getValues, element, resolvedStyle])\n\n // 6. Calculate layout properties.\n const layout = useMemo(() => {\n const getDynamicProp = (prop: any) => typeof prop === 'function'\n ? prop(watchedValues, allFormValues, {control, getValues})\n : prop;\n\n return {\n colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,\n rowSpan: getDynamicProp(element.rowSpan),\n columnGap: getDynamicProp(element.columnGap),\n rowGap: getDynamicProp(element.rowGap),\n colOffset: getDynamicProp(element.colOffset),\n area: getDynamicProp(element.area),\n };\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n\n /*\n * ⛔ IT READ FIVE VALUES AND DEPENDED ON ONE. The dependency array here\n * was `[watchedValues]` while the body reads `onDepsChange`,\n * `allFormValues`, `formContext` and `groupField` as well — so every\n * one of those four was frozen at the render that first built this\n * callback, and a caller would have handed the consumer stale form\n * values under a fresh `watchedValues`.\n *\n * ⚠️ IT IS THE SAME DEFECT AS THE ONE FIXED IN 0.1.261 TWENTY LINES UP,\n * where the children memo read `element.elements` while depending on\n * `[watchedValues]` alone and froze every field nested in a container.\n * That one cost two days of hunting on the App's nationality picker.\n * This is the second instance in the same hook, found while reading the\n * first, and it is fixed here rather than left for someone to meet.\n *\n * ⛔ AND NOTHING CALLS IT TODAY — that is a fact about the blast radius,\n * not a reason to leave it wrong. `onWatchedValuesChange` is returned\n * from this hook and declared optional in `internal.types.ts`, and a\n * sweep of this repo and of the App, ClientPortal and Dashboard finds no\n * invocation anywhere. The real work is done by the effect below, which\n * already carries the full dependency list. So there is no user-visible\n * symptom to reproduce and no story to film; there is a loaded trap for\n * the first caller, and this disarms it.\n */\n const onWatchedValuesChange = useCallback(() => {\n if (onDepsChange) {\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField)\n }\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField])\n\n // 7. Get the field's state and methods from react-hook-form.\n // For Object elements, default to {} so react-hook-form treats the field\n // as a nested object — children register with dot-notation paths\n // (e.g. contactPhone.phoneNumber) and build the nested structure.\n const isObjectElement = element.type === 'Object';\n const {field, fieldState} = useController({\n name: element.id as any,\n control,\n shouldUnregister: !isShown,\n ...(isObjectElement ? {defaultValue: {} as any} : {}),\n });\n\n useEffect(() => {\n if (!onDepsChange) return;\n\n // Create a stable signature for watched values\n // (stringify is fine here because deps lists are small)\n const sig = JSON.stringify(watchedValues);\n\n if (sig === prevDepsRef.current) return; // ✅ no real change\n\n prevDepsRef.current = sig;\n\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField);\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField]);\n\n // 8. Return a single, clean object for the UI component.\n return {\n field: {\n ...field,\n onChange: (event) => {\n if ('onChangeValue' in element && element?.onChangeValue) {\n const value = event != null && typeof event === 'object' && 'target' in event\n ? event.target.value\n : event;\n element.onChangeValue(\n value,\n {...fieldState, isFocused: !!isFocused},\n formContext\n )\n }\n field.onChange(event)\n }\n },\n fieldState,\n watchedValues,\n onWatchedValuesChange,\n elements: childElements,\n isShown,\n isDisabled,\n isRequired,\n hideError: element.hideError,\n label,\n placeholder,\n formContext,\n layout,\n list,\n style: resolvedStyle as IElementStyle,\n slots,\n ...resolvedProps,\n localProps: 'localProps' in element ? element?.localProps : undefined,\n attached: element.attached,\n animation: element.animation,\n };\n }\n;\n"],"names":["useFormContext","useRef","useMemo","dynamicList","schema","useEffect","useCallback","useController"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFieldLogic.cjs","sources":["../../../../src/form-renderer/hooks/useFieldLogic.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {type FieldValues, useController, useFormContext, type UseFormReturn} from 'react-hook-form';\nimport {Schema} from 'yup';\n\n// Assuming your types are consolidated in a central file.\nimport type {\n IElementStyle,\n IFormElement,\n ILabelElement,\n ITextFieldProps,\n LogicFunction,\n UseFieldLogicProps,\n UseFieldLogicReturn\n} from '@lmb-it/kitsconcerto-types';\nimport {dynamicList} from \"../utils\";\nimport _ from \"lodash\";\n\n// --- Hook Return Value ---\n\n/**\n * The core logic engine for an individual form field.\n * This hook replaces LogicContext and FormFieldContext. It watches dependencies,\n * calculates all dynamic properties (visibility, disabled state, required status, etc.),\n * and provides the necessary props from react-hook-form.\n *\n * @param {UseFieldLogicProps<T>} props - The element definition and form control.\n * @returns {UseFieldLogicReturn<T>} An object containing all necessary props and states for rendering the field.\n */\nexport const useFieldLogic = <T extends FieldValues>({\n element: {onDepsChange, ...element},\n control,\n getValues,\n isFocused,\n groupField,\n watchedValues\n }: UseFieldLogicProps<T>): UseFieldLogicReturn<T> => {\n\n\n const formContext = useFormContext<T>()\n\n const prevDepsRef = useRef<string>(\"\");\n\n const watchedSig = useMemo(() => JSON.stringify(watchedValues), [watchedValues]);\n\n const allFormValues = useMemo(() => getValues(), [getValues, watchedSig]);\n\n /*const watchedObject = useMemo(() => {\n return dependencies.reduce((acc, dep, index) => {\n acc[dep] = watchedValues[index];\n return acc;\n }, {} as any)\n }, [watchedValues, dependencies])*/\n\n const childElements = useMemo(() => {\n if (!('elements' in element)) {\n return [];\n }\n const elements = element.elements;\n if (typeof elements === 'function') {\n return (elements as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return elements;\n /*\n * ⛔ `element` BELONGS HERE BECAUSE THE BODY READS IT. Without it this\n * memo returns the children captured on the FIRST render and never\n * looks at `element` again — so a container (Object, Group) freezes\n * its whole subtree at mount.\n *\n * What that cost: AlphaMatch's profile screen mounts with\n * `list: []` and is handed 250 nationalities about a second later.\n * The parent rebuilds its element array, the new array reaches the\n * container, and this memo hands the children the OLD one. The\n * device log says `items=250` and the picker draws nothing —\n * because the picker was still holding the empty list.\n *\n * ⚠️ A top-level Select never showed this. It is not a container, so\n * it does not come through here at all; its props are resolved per\n * render. Only a field nested in an Object or a Group was affected,\n * which is why a harness that put the Select at the top level\n * reported the case clear.\n */\n }, [element, watchedValues])\n\n const resolvedProps = useMemo(() => {\n const getDynamicProp = (propName: keyof IFormElement<T> | string) => {\n const propValue: LogicFunction<T> = (element as any)[propName];\n if (typeof propValue === 'function') {\n return propValue(watchedValues, allFormValues, formContext, groupField);\n }\n return propValue;\n };\n\n return {\n helperText: getDynamicProp('helperText'),\n leftAddon: getDynamicProp('leftAddon'),\n rightAddon: getDynamicProp('rightAddon'),\n keyFilter: getDynamicProp('keyFilter') as ITextFieldProps<T>['keyFilter'],\n withMask: getDynamicProp('withMask'),\n // ... resolve other dynamic props here\n };\n }, [watchedValues, allFormValues, element, control, getValues]);\n\n const lastListRef = useRef<T[] | undefined>(undefined);\n const lastElementRef = useRef<any>(null);\n const lastWatchedRef = useRef<any>(null);\n\n const list = useMemo(() => {\n if (!(\"list\" in element)) return undefined;\n\n const elementChanged = !_.isEqual(lastElementRef.current, element);\n const watchedChanged = !_.isEqual(lastWatchedRef.current, watchedValues);\n\n // ✅ nothing meaningful changed → reuse\n if (!elementChanged && !watchedChanged) {\n return lastListRef.current;\n }\n\n // 🔁 rebuild\n const nextList = dynamicList<T>(\n element,\n watchedValues,\n allFormValues,\n groupField,\n formContext\n );\n\n lastElementRef.current = element;\n lastWatchedRef.current = watchedValues;\n lastListRef.current = nextList;\n\n return nextList;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n // 4. Centralize dynamic property calculations using memoization.\n const isShown = useMemo(() => {\n // console.log({watchedObject, allFormValues})\n const showLogic = element.show || element.logic?.show;\n if (typeof showLogic === 'function') {\n return (showLogic as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return true;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isDisabled = useMemo(() => {\n const disableLogic = element.isDisabled || element.logic?.disable;\n if (typeof disableLogic === 'function') {\n return (disableLogic as LogicFunction<T, boolean>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return !!disableLogic;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isRequired = useMemo(() => {\n if (!('schema' in element) || !element.schema) return false;\n\n const schema = element.schema as Schema<any>;\n\n const checkRequired = (schema: Schema<any>, parentValues: any): boolean => {\n try {\n const type = (schema as any)._type;\n\n const testValue = (() => {\n switch (type) {\n case 'array':\n return [];\n case 'object':\n return {};\n case 'boolean':\n return undefined;\n case 'number':\n return undefined;\n case 'date':\n return undefined;\n default:\n return ''; // string or unknown\n }\n })();\n // Try validating an empty string\n schema.validateSync(\n testValue, // simulating the field is empty\n {\n context: parentValues,\n // @ts-ignore\n parent: parentValues,\n abortEarly: false,\n }\n );\n\n return false; // Passed even when empty => not required\n } catch (err: any) {\n // if (element.id === 'count/ries') {\n // console.log(err.inner || err);\n // }\n\n if (err?.inner?.length) {\n return err.inner.some(\n (e: any) =>\n e.type === 'required' ||\n e.message?.toLowerCase().includes('required')\n );\n }\n\n return (\n err?.type === 'required' ||\n err?.message?.toLowerCase().includes('required')\n );\n }\n };\n\n // Get the parent object (either group or full form)\n const parent = groupField && groupField.index !== undefined\n ? getValues?.()?.[groupField.name]?.[groupField.index]\n : getValues?.();\n\n return checkRequired(schema, parent);\n }, [element, watchedValues, allFormValues]);\n\n const label = useMemo(() => {\n if (typeof element.label === 'function') {\n return (element.label as LogicFunction<T, ILabelElement>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return element.label;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const placeholder = useMemo(() => {\n if ('placeholder' in element && typeof element.placeholder === 'function') {\n return (element.placeholder as LogicFunction<T, string>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return ('placeholder' in element ? element.placeholder : undefined) as string | undefined;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const resolvedStyle = useMemo(() => {\n const s = 'style' in element ? element.style : undefined;\n\n if (s && typeof s === 'function') {\n return s(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return s;\n }, [watchedValues, allFormValues, control, getValues, element])\n\n // ─────────────────────────────────────────────────────────────\n // Dev-mode deprecation warning for the legacy `style` prop.\n // Fires ONCE per field-instance mount (guarded by hasWarnedRef +\n // empty deps) so it does not re-fire on keystrokes / re-renders /\n // theme changes / etc. The bridge below remains functional —\n // this is a soft deprecation only; runtime removal is deferred\n // to the next major version.\n // ─────────────────────────────────────────────────────────────\n const hasWarnedDeprecatedStyleRef = useRef(false);\n useEffect(() => {\n // `process` is undeclared on native (no @types/node) but the\n // bundler statically replaces it on both platforms in production\n // builds. Reading it via globalThis sidesteps the TS lookup\n // without changing the runtime behaviour.\n const nodeEnv = (globalThis as any)?.process?.env?.NODE_ENV;\n if (nodeEnv === 'production') return;\n if (hasWarnedDeprecatedStyleRef.current) return;\n if (!('style' in element) || (element as any).style === undefined) return;\n\n hasWarnedDeprecatedStyleRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[KitsConcerto] Field \"${(element as any).id}\": the \"style\" prop is deprecated. ` +\n `Use \"slots\" instead. Migration: ` +\n `style.input → slots.root.style, ` +\n `style.container → slots.container.style, ` +\n `style.label → slots.label.style, ` +\n `style.helperText → slots.helperText.style, ` +\n `style.errorMessage → slots.error.style. ` +\n `This prop will be removed in the next major version.`\n );\n // Empty deps: warn once on mount only — element identity may\n // change every render (form re-constructs configs), so we\n // cannot key on it without re-firing the warning.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Merge explicit `slots` with `style` sub-keys.\n * IElementStyle sub-keys are bridged into the slot system so they\n * flow through useComponentDefaults → elementStyles → KitsContainer.\n * Priority: style sub-keys (lowest) < explicit slots (highest).\n */\n const slots = useMemo(() => {\n // 1. Resolve explicit slots (DynamicValue)\n const rawSlots = 'slots' in element ? element.slots : undefined;\n let explicitSlots: Record<string, { props?: any; style?: any }> | undefined;\n if (rawSlots && typeof rawSlots === 'function') {\n explicitSlots = (rawSlots as any)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n } else {\n explicitSlots = rawSlots as any;\n }\n\n // 2. Bridge IElementStyle sub-keys into slot format\n if (!resolvedStyle && !explicitSlots) return undefined;\n if (!resolvedStyle) return explicitSlots;\n\n const STYLE_TO_SLOT: Record<string, string> = {\n input: 'root',\n container: 'container',\n label: 'label',\n helperText: 'helperText',\n errorMessage: 'error',\n };\n\n const result: Record<string, { props?: any; style?: any }> = {};\n\n // First layer: style sub-keys (lower priority)\n for (const [styleKey, slotKey] of Object.entries(STYLE_TO_SLOT)) {\n const val = (resolvedStyle as any)[styleKey];\n if (val) {\n result[slotKey] = { style: val };\n }\n }\n\n // Second layer: explicit slots override\n if (explicitSlots) {\n for (const [key, slot] of Object.entries(explicitSlots)) {\n if (!result[key]) {\n result[key] = slot;\n } else {\n result[key] = {\n ...slot,\n style: { ...result[key].style, ...(slot.style || {}) },\n };\n }\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }, [watchedValues, allFormValues, control, getValues, element, resolvedStyle])\n\n // 6. Calculate layout properties.\n const layout = useMemo(() => {\n const getDynamicProp = (prop: any) => typeof prop === 'function'\n ? prop(watchedValues, allFormValues, {control, getValues})\n : prop;\n\n return {\n colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,\n rowSpan: getDynamicProp(element.rowSpan),\n columnGap: getDynamicProp(element.columnGap),\n colOffset: getDynamicProp(element.colOffset),\n area: getDynamicProp(element.area),\n };\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n\n /*\n * ⛔ IT READ FIVE VALUES AND DEPENDED ON ONE. The dependency array here\n * was `[watchedValues]` while the body reads `onDepsChange`,\n * `allFormValues`, `formContext` and `groupField` as well — so every\n * one of those four was frozen at the render that first built this\n * callback, and a caller would have handed the consumer stale form\n * values under a fresh `watchedValues`.\n *\n * ⚠️ IT IS THE SAME DEFECT AS THE ONE FIXED IN 0.1.261 TWENTY LINES UP,\n * where the children memo read `element.elements` while depending on\n * `[watchedValues]` alone and froze every field nested in a container.\n * That one cost two days of hunting on the App's nationality picker.\n * This is the second instance in the same hook, found while reading the\n * first, and it is fixed here rather than left for someone to meet.\n *\n * ⛔ AND NOTHING CALLS IT TODAY — that is a fact about the blast radius,\n * not a reason to leave it wrong. `onWatchedValuesChange` is returned\n * from this hook and declared optional in `internal.types.ts`, and a\n * sweep of this repo and of the App, ClientPortal and Dashboard finds no\n * invocation anywhere. The real work is done by the effect below, which\n * already carries the full dependency list. So there is no user-visible\n * symptom to reproduce and no story to film; there is a loaded trap for\n * the first caller, and this disarms it.\n */\n const onWatchedValuesChange = useCallback(() => {\n if (onDepsChange) {\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField)\n }\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField])\n\n // 7. Get the field's state and methods from react-hook-form.\n // For Object elements, default to {} so react-hook-form treats the field\n // as a nested object — children register with dot-notation paths\n // (e.g. contactPhone.phoneNumber) and build the nested structure.\n const isObjectElement = element.type === 'Object';\n const {field, fieldState} = useController({\n name: element.id as any,\n control,\n shouldUnregister: !isShown,\n ...(isObjectElement ? {defaultValue: {} as any} : {}),\n });\n\n useEffect(() => {\n if (!onDepsChange) return;\n\n // Create a stable signature for watched values\n // (stringify is fine here because deps lists are small)\n const sig = JSON.stringify(watchedValues);\n\n if (sig === prevDepsRef.current) return; // ✅ no real change\n\n prevDepsRef.current = sig;\n\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField);\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField]);\n\n // 8. Return a single, clean object for the UI component.\n return {\n field: {\n ...field,\n onChange: (event) => {\n if ('onChangeValue' in element && element?.onChangeValue) {\n const value = event != null && typeof event === 'object' && 'target' in event\n ? event.target.value\n : event;\n element.onChangeValue(\n value,\n {...fieldState, isFocused: !!isFocused},\n formContext\n )\n }\n field.onChange(event)\n }\n },\n fieldState,\n watchedValues,\n onWatchedValuesChange,\n elements: childElements,\n isShown,\n isDisabled,\n isRequired,\n hideError: element.hideError,\n label,\n placeholder,\n formContext,\n layout,\n list,\n style: resolvedStyle as IElementStyle,\n slots,\n ...resolvedProps,\n localProps: 'localProps' in element ? element?.localProps : undefined,\n attached: element.attached,\n animation: element.animation,\n };\n }\n;\n"],"names":["useFormContext","useRef","useMemo","dynamicList","schema","useEffect","useCallback","useController"],"mappings":"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"}
|
|
@@ -226,7 +226,6 @@ const useFieldLogic = ({
|
|
|
226
226
|
colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,
|
|
227
227
|
rowSpan: getDynamicProp(element.rowSpan),
|
|
228
228
|
columnGap: getDynamicProp(element.columnGap),
|
|
229
|
-
rowGap: getDynamicProp(element.rowGap),
|
|
230
229
|
colOffset: getDynamicProp(element.colOffset),
|
|
231
230
|
area: getDynamicProp(element.area)
|
|
232
231
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFieldLogic.js","sources":["../../../../src/form-renderer/hooks/useFieldLogic.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {type FieldValues, useController, useFormContext, type UseFormReturn} from 'react-hook-form';\nimport {Schema} from 'yup';\n\n// Assuming your types are consolidated in a central file.\nimport type {\n IElementStyle,\n IFormElement,\n ILabelElement,\n ITextFieldProps,\n LogicFunction,\n UseFieldLogicProps,\n UseFieldLogicReturn\n} from '@lmb-it/kitsconcerto-types';\nimport {dynamicList} from \"../utils\";\nimport _ from \"lodash\";\n\n// --- Hook Return Value ---\n\n/**\n * The core logic engine for an individual form field.\n * This hook replaces LogicContext and FormFieldContext. It watches dependencies,\n * calculates all dynamic properties (visibility, disabled state, required status, etc.),\n * and provides the necessary props from react-hook-form.\n *\n * @param {UseFieldLogicProps<T>} props - The element definition and form control.\n * @returns {UseFieldLogicReturn<T>} An object containing all necessary props and states for rendering the field.\n */\nexport const useFieldLogic = <T extends FieldValues>({\n element: {onDepsChange, ...element},\n control,\n getValues,\n isFocused,\n groupField,\n watchedValues\n }: UseFieldLogicProps<T>): UseFieldLogicReturn<T> => {\n\n\n const formContext = useFormContext<T>()\n\n const prevDepsRef = useRef<string>(\"\");\n\n const watchedSig = useMemo(() => JSON.stringify(watchedValues), [watchedValues]);\n\n const allFormValues = useMemo(() => getValues(), [getValues, watchedSig]);\n\n /*const watchedObject = useMemo(() => {\n return dependencies.reduce((acc, dep, index) => {\n acc[dep] = watchedValues[index];\n return acc;\n }, {} as any)\n }, [watchedValues, dependencies])*/\n\n const childElements = useMemo(() => {\n if (!('elements' in element)) {\n return [];\n }\n const elements = element.elements;\n if (typeof elements === 'function') {\n return (elements as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return elements;\n /*\n * ⛔ `element` BELONGS HERE BECAUSE THE BODY READS IT. Without it this\n * memo returns the children captured on the FIRST render and never\n * looks at `element` again — so a container (Object, Group) freezes\n * its whole subtree at mount.\n *\n * What that cost: AlphaMatch's profile screen mounts with\n * `list: []` and is handed 250 nationalities about a second later.\n * The parent rebuilds its element array, the new array reaches the\n * container, and this memo hands the children the OLD one. The\n * device log says `items=250` and the picker draws nothing —\n * because the picker was still holding the empty list.\n *\n * ⚠️ A top-level Select never showed this. It is not a container, so\n * it does not come through here at all; its props are resolved per\n * render. Only a field nested in an Object or a Group was affected,\n * which is why a harness that put the Select at the top level\n * reported the case clear.\n */\n }, [element, watchedValues])\n\n const resolvedProps = useMemo(() => {\n const getDynamicProp = (propName: keyof IFormElement<T> | string) => {\n const propValue: LogicFunction<T> = (element as any)[propName];\n if (typeof propValue === 'function') {\n return propValue(watchedValues, allFormValues, formContext, groupField);\n }\n return propValue;\n };\n\n return {\n helperText: getDynamicProp('helperText'),\n leftAddon: getDynamicProp('leftAddon'),\n rightAddon: getDynamicProp('rightAddon'),\n keyFilter: getDynamicProp('keyFilter') as ITextFieldProps<T>['keyFilter'],\n withMask: getDynamicProp('withMask'),\n // ... resolve other dynamic props here\n };\n }, [watchedValues, allFormValues, element, control, getValues]);\n\n const lastListRef = useRef<T[] | undefined>(undefined);\n const lastElementRef = useRef<any>(null);\n const lastWatchedRef = useRef<any>(null);\n\n const list = useMemo(() => {\n if (!(\"list\" in element)) return undefined;\n\n const elementChanged = !_.isEqual(lastElementRef.current, element);\n const watchedChanged = !_.isEqual(lastWatchedRef.current, watchedValues);\n\n // ✅ nothing meaningful changed → reuse\n if (!elementChanged && !watchedChanged) {\n return lastListRef.current;\n }\n\n // 🔁 rebuild\n const nextList = dynamicList<T>(\n element,\n watchedValues,\n allFormValues,\n groupField,\n formContext\n );\n\n lastElementRef.current = element;\n lastWatchedRef.current = watchedValues;\n lastListRef.current = nextList;\n\n return nextList;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n // 4. Centralize dynamic property calculations using memoization.\n const isShown = useMemo(() => {\n // console.log({watchedObject, allFormValues})\n const showLogic = element.show || element.logic?.show;\n if (typeof showLogic === 'function') {\n return (showLogic as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return true;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isDisabled = useMemo(() => {\n const disableLogic = element.isDisabled || element.logic?.disable;\n if (typeof disableLogic === 'function') {\n return (disableLogic as LogicFunction<T, boolean>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return !!disableLogic;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isRequired = useMemo(() => {\n if (!('schema' in element) || !element.schema) return false;\n\n const schema = element.schema as Schema<any>;\n\n const checkRequired = (schema: Schema<any>, parentValues: any): boolean => {\n try {\n const type = (schema as any)._type;\n\n const testValue = (() => {\n switch (type) {\n case 'array':\n return [];\n case 'object':\n return {};\n case 'boolean':\n return undefined;\n case 'number':\n return undefined;\n case 'date':\n return undefined;\n default:\n return ''; // string or unknown\n }\n })();\n // Try validating an empty string\n schema.validateSync(\n testValue, // simulating the field is empty\n {\n context: parentValues,\n // @ts-ignore\n parent: parentValues,\n abortEarly: false,\n }\n );\n\n return false; // Passed even when empty => not required\n } catch (err: any) {\n // if (element.id === 'count/ries') {\n // console.log(err.inner || err);\n // }\n\n if (err?.inner?.length) {\n return err.inner.some(\n (e: any) =>\n e.type === 'required' ||\n e.message?.toLowerCase().includes('required')\n );\n }\n\n return (\n err?.type === 'required' ||\n err?.message?.toLowerCase().includes('required')\n );\n }\n };\n\n // Get the parent object (either group or full form)\n const parent = groupField && groupField.index !== undefined\n ? getValues?.()?.[groupField.name]?.[groupField.index]\n : getValues?.();\n\n return checkRequired(schema, parent);\n }, [element, watchedValues, allFormValues]);\n\n const label = useMemo(() => {\n if (typeof element.label === 'function') {\n return (element.label as LogicFunction<T, ILabelElement>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return element.label;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const placeholder = useMemo(() => {\n if ('placeholder' in element && typeof element.placeholder === 'function') {\n return (element.placeholder as LogicFunction<T, string>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return ('placeholder' in element ? element.placeholder : undefined) as string | undefined;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const resolvedStyle = useMemo(() => {\n const s = 'style' in element ? element.style : undefined;\n\n if (s && typeof s === 'function') {\n return s(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return s;\n }, [watchedValues, allFormValues, control, getValues, element])\n\n // ─────────────────────────────────────────────────────────────\n // Dev-mode deprecation warning for the legacy `style` prop.\n // Fires ONCE per field-instance mount (guarded by hasWarnedRef +\n // empty deps) so it does not re-fire on keystrokes / re-renders /\n // theme changes / etc. The bridge below remains functional —\n // this is a soft deprecation only; runtime removal is deferred\n // to the next major version.\n // ─────────────────────────────────────────────────────────────\n const hasWarnedDeprecatedStyleRef = useRef(false);\n useEffect(() => {\n // `process` is undeclared on native (no @types/node) but the\n // bundler statically replaces it on both platforms in production\n // builds. Reading it via globalThis sidesteps the TS lookup\n // without changing the runtime behaviour.\n const nodeEnv = (globalThis as any)?.process?.env?.NODE_ENV;\n if (nodeEnv === 'production') return;\n if (hasWarnedDeprecatedStyleRef.current) return;\n if (!('style' in element) || (element as any).style === undefined) return;\n\n hasWarnedDeprecatedStyleRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[KitsConcerto] Field \"${(element as any).id}\": the \"style\" prop is deprecated. ` +\n `Use \"slots\" instead. Migration: ` +\n `style.input → slots.root.style, ` +\n `style.container → slots.container.style, ` +\n `style.label → slots.label.style, ` +\n `style.helperText → slots.helperText.style, ` +\n `style.errorMessage → slots.error.style. ` +\n `This prop will be removed in the next major version.`\n );\n // Empty deps: warn once on mount only — element identity may\n // change every render (form re-constructs configs), so we\n // cannot key on it without re-firing the warning.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Merge explicit `slots` with `style` sub-keys.\n * IElementStyle sub-keys are bridged into the slot system so they\n * flow through useComponentDefaults → elementStyles → KitsContainer.\n * Priority: style sub-keys (lowest) < explicit slots (highest).\n */\n const slots = useMemo(() => {\n // 1. Resolve explicit slots (DynamicValue)\n const rawSlots = 'slots' in element ? element.slots : undefined;\n let explicitSlots: Record<string, { props?: any; style?: any }> | undefined;\n if (rawSlots && typeof rawSlots === 'function') {\n explicitSlots = (rawSlots as any)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n } else {\n explicitSlots = rawSlots as any;\n }\n\n // 2. Bridge IElementStyle sub-keys into slot format\n if (!resolvedStyle && !explicitSlots) return undefined;\n if (!resolvedStyle) return explicitSlots;\n\n const STYLE_TO_SLOT: Record<string, string> = {\n input: 'root',\n container: 'container',\n label: 'label',\n helperText: 'helperText',\n errorMessage: 'error',\n };\n\n const result: Record<string, { props?: any; style?: any }> = {};\n\n // First layer: style sub-keys (lower priority)\n for (const [styleKey, slotKey] of Object.entries(STYLE_TO_SLOT)) {\n const val = (resolvedStyle as any)[styleKey];\n if (val) {\n result[slotKey] = { style: val };\n }\n }\n\n // Second layer: explicit slots override\n if (explicitSlots) {\n for (const [key, slot] of Object.entries(explicitSlots)) {\n if (!result[key]) {\n result[key] = slot;\n } else {\n result[key] = {\n ...slot,\n style: { ...result[key].style, ...(slot.style || {}) },\n };\n }\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }, [watchedValues, allFormValues, control, getValues, element, resolvedStyle])\n\n // 6. Calculate layout properties.\n const layout = useMemo(() => {\n const getDynamicProp = (prop: any) => typeof prop === 'function'\n ? prop(watchedValues, allFormValues, {control, getValues})\n : prop;\n\n return {\n colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,\n rowSpan: getDynamicProp(element.rowSpan),\n columnGap: getDynamicProp(element.columnGap),\n rowGap: getDynamicProp(element.rowGap),\n colOffset: getDynamicProp(element.colOffset),\n area: getDynamicProp(element.area),\n };\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n\n /*\n * ⛔ IT READ FIVE VALUES AND DEPENDED ON ONE. The dependency array here\n * was `[watchedValues]` while the body reads `onDepsChange`,\n * `allFormValues`, `formContext` and `groupField` as well — so every\n * one of those four was frozen at the render that first built this\n * callback, and a caller would have handed the consumer stale form\n * values under a fresh `watchedValues`.\n *\n * ⚠️ IT IS THE SAME DEFECT AS THE ONE FIXED IN 0.1.261 TWENTY LINES UP,\n * where the children memo read `element.elements` while depending on\n * `[watchedValues]` alone and froze every field nested in a container.\n * That one cost two days of hunting on the App's nationality picker.\n * This is the second instance in the same hook, found while reading the\n * first, and it is fixed here rather than left for someone to meet.\n *\n * ⛔ AND NOTHING CALLS IT TODAY — that is a fact about the blast radius,\n * not a reason to leave it wrong. `onWatchedValuesChange` is returned\n * from this hook and declared optional in `internal.types.ts`, and a\n * sweep of this repo and of the App, ClientPortal and Dashboard finds no\n * invocation anywhere. The real work is done by the effect below, which\n * already carries the full dependency list. So there is no user-visible\n * symptom to reproduce and no story to film; there is a loaded trap for\n * the first caller, and this disarms it.\n */\n const onWatchedValuesChange = useCallback(() => {\n if (onDepsChange) {\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField)\n }\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField])\n\n // 7. Get the field's state and methods from react-hook-form.\n // For Object elements, default to {} so react-hook-form treats the field\n // as a nested object — children register with dot-notation paths\n // (e.g. contactPhone.phoneNumber) and build the nested structure.\n const isObjectElement = element.type === 'Object';\n const {field, fieldState} = useController({\n name: element.id as any,\n control,\n shouldUnregister: !isShown,\n ...(isObjectElement ? {defaultValue: {} as any} : {}),\n });\n\n useEffect(() => {\n if (!onDepsChange) return;\n\n // Create a stable signature for watched values\n // (stringify is fine here because deps lists are small)\n const sig = JSON.stringify(watchedValues);\n\n if (sig === prevDepsRef.current) return; // ✅ no real change\n\n prevDepsRef.current = sig;\n\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField);\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField]);\n\n // 8. Return a single, clean object for the UI component.\n return {\n field: {\n ...field,\n onChange: (event) => {\n if ('onChangeValue' in element && element?.onChangeValue) {\n const value = event != null && typeof event === 'object' && 'target' in event\n ? event.target.value\n : event;\n element.onChangeValue(\n value,\n {...fieldState, isFocused: !!isFocused},\n formContext\n )\n }\n field.onChange(event)\n }\n },\n fieldState,\n watchedValues,\n onWatchedValuesChange,\n elements: childElements,\n isShown,\n isDisabled,\n isRequired,\n hideError: element.hideError,\n label,\n placeholder,\n formContext,\n layout,\n list,\n style: resolvedStyle as IElementStyle,\n slots,\n ...resolvedProps,\n localProps: 'localProps' in element ? element?.localProps : undefined,\n attached: element.attached,\n animation: element.animation,\n };\n }\n;\n"],"names":["schema"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useFieldLogic.js","sources":["../../../../src/form-renderer/hooks/useFieldLogic.ts"],"sourcesContent":["import {useCallback, useEffect, useMemo, useRef} from 'react';\nimport {type FieldValues, useController, useFormContext, type UseFormReturn} from 'react-hook-form';\nimport {Schema} from 'yup';\n\n// Assuming your types are consolidated in a central file.\nimport type {\n IElementStyle,\n IFormElement,\n ILabelElement,\n ITextFieldProps,\n LogicFunction,\n UseFieldLogicProps,\n UseFieldLogicReturn\n} from '@lmb-it/kitsconcerto-types';\nimport {dynamicList} from \"../utils\";\nimport _ from \"lodash\";\n\n// --- Hook Return Value ---\n\n/**\n * The core logic engine for an individual form field.\n * This hook replaces LogicContext and FormFieldContext. It watches dependencies,\n * calculates all dynamic properties (visibility, disabled state, required status, etc.),\n * and provides the necessary props from react-hook-form.\n *\n * @param {UseFieldLogicProps<T>} props - The element definition and form control.\n * @returns {UseFieldLogicReturn<T>} An object containing all necessary props and states for rendering the field.\n */\nexport const useFieldLogic = <T extends FieldValues>({\n element: {onDepsChange, ...element},\n control,\n getValues,\n isFocused,\n groupField,\n watchedValues\n }: UseFieldLogicProps<T>): UseFieldLogicReturn<T> => {\n\n\n const formContext = useFormContext<T>()\n\n const prevDepsRef = useRef<string>(\"\");\n\n const watchedSig = useMemo(() => JSON.stringify(watchedValues), [watchedValues]);\n\n const allFormValues = useMemo(() => getValues(), [getValues, watchedSig]);\n\n /*const watchedObject = useMemo(() => {\n return dependencies.reduce((acc, dep, index) => {\n acc[dep] = watchedValues[index];\n return acc;\n }, {} as any)\n }, [watchedValues, dependencies])*/\n\n const childElements = useMemo(() => {\n if (!('elements' in element)) {\n return [];\n }\n const elements = element.elements;\n if (typeof elements === 'function') {\n return (elements as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return elements;\n /*\n * ⛔ `element` BELONGS HERE BECAUSE THE BODY READS IT. Without it this\n * memo returns the children captured on the FIRST render and never\n * looks at `element` again — so a container (Object, Group) freezes\n * its whole subtree at mount.\n *\n * What that cost: AlphaMatch's profile screen mounts with\n * `list: []` and is handed 250 nationalities about a second later.\n * The parent rebuilds its element array, the new array reaches the\n * container, and this memo hands the children the OLD one. The\n * device log says `items=250` and the picker draws nothing —\n * because the picker was still holding the empty list.\n *\n * ⚠️ A top-level Select never showed this. It is not a container, so\n * it does not come through here at all; its props are resolved per\n * render. Only a field nested in an Object or a Group was affected,\n * which is why a harness that put the Select at the top level\n * reported the case clear.\n */\n }, [element, watchedValues])\n\n const resolvedProps = useMemo(() => {\n const getDynamicProp = (propName: keyof IFormElement<T> | string) => {\n const propValue: LogicFunction<T> = (element as any)[propName];\n if (typeof propValue === 'function') {\n return propValue(watchedValues, allFormValues, formContext, groupField);\n }\n return propValue;\n };\n\n return {\n helperText: getDynamicProp('helperText'),\n leftAddon: getDynamicProp('leftAddon'),\n rightAddon: getDynamicProp('rightAddon'),\n keyFilter: getDynamicProp('keyFilter') as ITextFieldProps<T>['keyFilter'],\n withMask: getDynamicProp('withMask'),\n // ... resolve other dynamic props here\n };\n }, [watchedValues, allFormValues, element, control, getValues]);\n\n const lastListRef = useRef<T[] | undefined>(undefined);\n const lastElementRef = useRef<any>(null);\n const lastWatchedRef = useRef<any>(null);\n\n const list = useMemo(() => {\n if (!(\"list\" in element)) return undefined;\n\n const elementChanged = !_.isEqual(lastElementRef.current, element);\n const watchedChanged = !_.isEqual(lastWatchedRef.current, watchedValues);\n\n // ✅ nothing meaningful changed → reuse\n if (!elementChanged && !watchedChanged) {\n return lastListRef.current;\n }\n\n // 🔁 rebuild\n const nextList = dynamicList<T>(\n element,\n watchedValues,\n allFormValues,\n groupField,\n formContext\n );\n\n lastElementRef.current = element;\n lastWatchedRef.current = watchedValues;\n lastListRef.current = nextList;\n\n return nextList;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n // 4. Centralize dynamic property calculations using memoization.\n const isShown = useMemo(() => {\n // console.log({watchedObject, allFormValues})\n const showLogic = element.show || element.logic?.show;\n if (typeof showLogic === 'function') {\n return (showLogic as LogicFunction<T>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return true;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isDisabled = useMemo(() => {\n const disableLogic = element.isDisabled || element.logic?.disable;\n if (typeof disableLogic === 'function') {\n return (disableLogic as LogicFunction<T, boolean>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return !!disableLogic;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const isRequired = useMemo(() => {\n if (!('schema' in element) || !element.schema) return false;\n\n const schema = element.schema as Schema<any>;\n\n const checkRequired = (schema: Schema<any>, parentValues: any): boolean => {\n try {\n const type = (schema as any)._type;\n\n const testValue = (() => {\n switch (type) {\n case 'array':\n return [];\n case 'object':\n return {};\n case 'boolean':\n return undefined;\n case 'number':\n return undefined;\n case 'date':\n return undefined;\n default:\n return ''; // string or unknown\n }\n })();\n // Try validating an empty string\n schema.validateSync(\n testValue, // simulating the field is empty\n {\n context: parentValues,\n // @ts-ignore\n parent: parentValues,\n abortEarly: false,\n }\n );\n\n return false; // Passed even when empty => not required\n } catch (err: any) {\n // if (element.id === 'count/ries') {\n // console.log(err.inner || err);\n // }\n\n if (err?.inner?.length) {\n return err.inner.some(\n (e: any) =>\n e.type === 'required' ||\n e.message?.toLowerCase().includes('required')\n );\n }\n\n return (\n err?.type === 'required' ||\n err?.message?.toLowerCase().includes('required')\n );\n }\n };\n\n // Get the parent object (either group or full form)\n const parent = groupField && groupField.index !== undefined\n ? getValues?.()?.[groupField.name]?.[groupField.index]\n : getValues?.();\n\n return checkRequired(schema, parent);\n }, [element, watchedValues, allFormValues]);\n\n const label = useMemo(() => {\n if (typeof element.label === 'function') {\n return (element.label as LogicFunction<T, ILabelElement>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return element.label;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const placeholder = useMemo(() => {\n if ('placeholder' in element && typeof element.placeholder === 'function') {\n return (element.placeholder as LogicFunction<T, string>)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return ('placeholder' in element ? element.placeholder : undefined) as string | undefined;\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n const resolvedStyle = useMemo(() => {\n const s = 'style' in element ? element.style : undefined;\n\n if (s && typeof s === 'function') {\n return s(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n }\n return s;\n }, [watchedValues, allFormValues, control, getValues, element])\n\n // ─────────────────────────────────────────────────────────────\n // Dev-mode deprecation warning for the legacy `style` prop.\n // Fires ONCE per field-instance mount (guarded by hasWarnedRef +\n // empty deps) so it does not re-fire on keystrokes / re-renders /\n // theme changes / etc. The bridge below remains functional —\n // this is a soft deprecation only; runtime removal is deferred\n // to the next major version.\n // ─────────────────────────────────────────────────────────────\n const hasWarnedDeprecatedStyleRef = useRef(false);\n useEffect(() => {\n // `process` is undeclared on native (no @types/node) but the\n // bundler statically replaces it on both platforms in production\n // builds. Reading it via globalThis sidesteps the TS lookup\n // without changing the runtime behaviour.\n const nodeEnv = (globalThis as any)?.process?.env?.NODE_ENV;\n if (nodeEnv === 'production') return;\n if (hasWarnedDeprecatedStyleRef.current) return;\n if (!('style' in element) || (element as any).style === undefined) return;\n\n hasWarnedDeprecatedStyleRef.current = true;\n // eslint-disable-next-line no-console\n console.warn(\n `[KitsConcerto] Field \"${(element as any).id}\": the \"style\" prop is deprecated. ` +\n `Use \"slots\" instead. Migration: ` +\n `style.input → slots.root.style, ` +\n `style.container → slots.container.style, ` +\n `style.label → slots.label.style, ` +\n `style.helperText → slots.helperText.style, ` +\n `style.errorMessage → slots.error.style. ` +\n `This prop will be removed in the next major version.`\n );\n // Empty deps: warn once on mount only — element identity may\n // change every render (form re-constructs configs), so we\n // cannot key on it without re-firing the warning.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n /**\n * Merge explicit `slots` with `style` sub-keys.\n * IElementStyle sub-keys are bridged into the slot system so they\n * flow through useComponentDefaults → elementStyles → KitsContainer.\n * Priority: style sub-keys (lowest) < explicit slots (highest).\n */\n const slots = useMemo(() => {\n // 1. Resolve explicit slots (DynamicValue)\n const rawSlots = 'slots' in element ? element.slots : undefined;\n let explicitSlots: Record<string, { props?: any; style?: any }> | undefined;\n if (rawSlots && typeof rawSlots === 'function') {\n explicitSlots = (rawSlots as any)(watchedValues, allFormValues, {\n control,\n getValues,\n setValue: formContext.setValue\n } as any, groupField);\n } else {\n explicitSlots = rawSlots as any;\n }\n\n // 2. Bridge IElementStyle sub-keys into slot format\n if (!resolvedStyle && !explicitSlots) return undefined;\n if (!resolvedStyle) return explicitSlots;\n\n const STYLE_TO_SLOT: Record<string, string> = {\n input: 'root',\n container: 'container',\n label: 'label',\n helperText: 'helperText',\n errorMessage: 'error',\n };\n\n const result: Record<string, { props?: any; style?: any }> = {};\n\n // First layer: style sub-keys (lower priority)\n for (const [styleKey, slotKey] of Object.entries(STYLE_TO_SLOT)) {\n const val = (resolvedStyle as any)[styleKey];\n if (val) {\n result[slotKey] = { style: val };\n }\n }\n\n // Second layer: explicit slots override\n if (explicitSlots) {\n for (const [key, slot] of Object.entries(explicitSlots)) {\n if (!result[key]) {\n result[key] = slot;\n } else {\n result[key] = {\n ...slot,\n style: { ...result[key].style, ...(slot.style || {}) },\n };\n }\n }\n }\n\n return Object.keys(result).length > 0 ? result : undefined;\n }, [watchedValues, allFormValues, control, getValues, element, resolvedStyle])\n\n // 6. Calculate layout properties.\n const layout = useMemo(() => {\n const getDynamicProp = (prop: any) => typeof prop === 'function'\n ? prop(watchedValues, allFormValues, {control, getValues})\n : prop;\n\n return {\n colSpan: getDynamicProp(element.logic?.colSpan ?? element.colSpan) ?? 12,\n rowSpan: getDynamicProp(element.rowSpan),\n columnGap: getDynamicProp(element.columnGap),\n colOffset: getDynamicProp(element.colOffset),\n area: getDynamicProp(element.area),\n };\n }, [watchedValues, allFormValues, control, getValues, element]);\n\n\n /*\n * ⛔ IT READ FIVE VALUES AND DEPENDED ON ONE. The dependency array here\n * was `[watchedValues]` while the body reads `onDepsChange`,\n * `allFormValues`, `formContext` and `groupField` as well — so every\n * one of those four was frozen at the render that first built this\n * callback, and a caller would have handed the consumer stale form\n * values under a fresh `watchedValues`.\n *\n * ⚠️ IT IS THE SAME DEFECT AS THE ONE FIXED IN 0.1.261 TWENTY LINES UP,\n * where the children memo read `element.elements` while depending on\n * `[watchedValues]` alone and froze every field nested in a container.\n * That one cost two days of hunting on the App's nationality picker.\n * This is the second instance in the same hook, found while reading the\n * first, and it is fixed here rather than left for someone to meet.\n *\n * ⛔ AND NOTHING CALLS IT TODAY — that is a fact about the blast radius,\n * not a reason to leave it wrong. `onWatchedValuesChange` is returned\n * from this hook and declared optional in `internal.types.ts`, and a\n * sweep of this repo and of the App, ClientPortal and Dashboard finds no\n * invocation anywhere. The real work is done by the effect below, which\n * already carries the full dependency list. So there is no user-visible\n * symptom to reproduce and no story to film; there is a loaded trap for\n * the first caller, and this disarms it.\n */\n const onWatchedValuesChange = useCallback(() => {\n if (onDepsChange) {\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField)\n }\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField])\n\n // 7. Get the field's state and methods from react-hook-form.\n // For Object elements, default to {} so react-hook-form treats the field\n // as a nested object — children register with dot-notation paths\n // (e.g. contactPhone.phoneNumber) and build the nested structure.\n const isObjectElement = element.type === 'Object';\n const {field, fieldState} = useController({\n name: element.id as any,\n control,\n shouldUnregister: !isShown,\n ...(isObjectElement ? {defaultValue: {} as any} : {}),\n });\n\n useEffect(() => {\n if (!onDepsChange) return;\n\n // Create a stable signature for watched values\n // (stringify is fine here because deps lists are small)\n const sig = JSON.stringify(watchedValues);\n\n if (sig === prevDepsRef.current) return; // ✅ no real change\n\n prevDepsRef.current = sig;\n\n onDepsChange(watchedValues, allFormValues, formContext as UseFormReturn<T>, groupField);\n }, [onDepsChange, watchedValues, allFormValues, formContext, groupField]);\n\n // 8. Return a single, clean object for the UI component.\n return {\n field: {\n ...field,\n onChange: (event) => {\n if ('onChangeValue' in element && element?.onChangeValue) {\n const value = event != null && typeof event === 'object' && 'target' in event\n ? event.target.value\n : event;\n element.onChangeValue(\n value,\n {...fieldState, isFocused: !!isFocused},\n formContext\n )\n }\n field.onChange(event)\n }\n },\n fieldState,\n watchedValues,\n onWatchedValuesChange,\n elements: childElements,\n isShown,\n isDisabled,\n isRequired,\n hideError: element.hideError,\n label,\n placeholder,\n formContext,\n layout,\n list,\n style: resolvedStyle as IElementStyle,\n slots,\n ...resolvedProps,\n localProps: 'localProps' in element ? element?.localProps : undefined,\n attached: element.attached,\n animation: element.animation,\n };\n }\n;\n"],"names":["schema"],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -1711,8 +1711,19 @@ export interface IElementBase<T extends FieldValues> {
|
|
|
1711
1711
|
colSpan?: DynamicValue<T, KitsResponsiveValue<string | number>>;
|
|
1712
1712
|
rowSpan?: DynamicValue<T, KitsResponsiveValue<string | number>>;
|
|
1713
1713
|
colOffset?: DynamicValue<T, KitsResponsiveValue<string | number>>;
|
|
1714
|
+
/**
|
|
1715
|
+
* ⚠️ `rowGap` USED TO SIT HERE AND IT WAS NEVER READ. `useFieldLogic`
|
|
1716
|
+
* computed it into `layout` and neither FieldWrapper consumed it — native
|
|
1717
|
+
* reads `colSpan`, web reads `colSpan`, `rowSpan`, `colOffset` and `area`.
|
|
1718
|
+
* An element could declare it, the value was resolved on every render, and
|
|
1719
|
+
* nothing moved. Removed 2 October 2026 after sweeping every consumer repo:
|
|
1720
|
+
* zero callers (the App's one hit is a comment, the Portal's two are the
|
|
1721
|
+
* Form's `grid` prop, the Dashboard's are slot `style` objects and direct
|
|
1722
|
+
* `<Grid>` use). The row gap is set on the FORM — see `IFormComponent.rowGap`.
|
|
1723
|
+
* ⛔ `columnGap` BELOW IS THE SAME DEAD LEVER and is kept pending a ruling,
|
|
1724
|
+
* recorded here rather than removed quietly.
|
|
1725
|
+
*/
|
|
1714
1726
|
columnGap?: DynamicValue<T, KitsResponsiveValue<string | number>>;
|
|
1715
|
-
rowGap?: DynamicValue<T, KitsResponsiveValue<string | number>>;
|
|
1716
1727
|
area?: DynamicValue<T, KitsResponsiveValue<string>>;
|
|
1717
1728
|
leftAddon?: DynamicValue<T, ReactElement | IconType | string>;
|
|
1718
1729
|
rightAddon?: DynamicValue<T, ReactElement | IconType | string>;
|
|
@@ -2117,6 +2128,17 @@ export type IFormComponent<T extends FieldValues> = UseFormManagerEvents<T> & (I
|
|
|
2117
2128
|
rowGap?: number;
|
|
2118
2129
|
};
|
|
2119
2130
|
export interface UseFieldLogicElementProps<T extends FieldValues> extends GroupFieldConfigs<T> {
|
|
2131
|
+
/**
|
|
2132
|
+
* The form's row gap, passed down so a field type that renders a NESTED
|
|
2133
|
+
* `FormRenderer` can carry it further.
|
|
2134
|
+
*
|
|
2135
|
+
* ⛔ ONLY `Object` AND `Group` READ IT, AND THAT IS THE POINT. They are the
|
|
2136
|
+
* two types whose children go through another renderer, and a renderer
|
|
2137
|
+
* handed nothing falls back to its own default — which is why a form that
|
|
2138
|
+
* set `rowGap` got it on its top-level rows and on nothing inside a card.
|
|
2139
|
+
* Every other field type receives it and ignores it.
|
|
2140
|
+
*/
|
|
2141
|
+
rowGap?: number;
|
|
2120
2142
|
element: IFormElement<T>;
|
|
2121
2143
|
control: Control<T>;
|
|
2122
2144
|
getValues: UseFormGetValues<T>;
|