@k3-universe/react-kit 0.0.8 → 0.0.10
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/dist/index.js +18655 -16777
- package/dist/kit/builder/data-table/components/DataTable.d.ts +2 -2
- package/dist/kit/builder/data-table/components/DataTable.d.ts.map +1 -1
- package/dist/kit/builder/form/components/FormBuilder.d.ts +42 -14
- package/dist/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
- package/dist/kit/builder/form/components/FormBuilderField.d.ts.map +1 -1
- package/dist/kit/builder/form/components/fields/AutocompleteField.d.ts.map +1 -1
- package/dist/kit/builder/form/components/fields/DatePickerField.d.ts +3 -0
- package/dist/kit/builder/form/components/fields/DatePickerField.d.ts.map +1 -0
- package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts +3 -0
- package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts.map +1 -0
- package/dist/kit/builder/form/components/fields/MonthPickerField.d.ts +3 -0
- package/dist/kit/builder/form/components/fields/MonthPickerField.d.ts.map +1 -0
- package/dist/kit/builder/form/components/fields/MonthRangePickerField.d.ts +3 -0
- package/dist/kit/builder/form/components/fields/MonthRangePickerField.d.ts.map +1 -0
- package/dist/kit/builder/form/components/fields/index.d.ts +4 -0
- package/dist/kit/builder/form/components/fields/index.d.ts.map +1 -1
- package/dist/kit/builder/section/SectionBuilder.d.ts.map +1 -1
- package/dist/kit/builder/section/types.d.ts +12 -1
- package/dist/kit/builder/section/types.d.ts.map +1 -1
- package/dist/kit/builder/stack-dialog/context.d.ts +3 -0
- package/dist/kit/builder/stack-dialog/context.d.ts.map +1 -0
- package/dist/kit/builder/stack-dialog/hooks.d.ts +6 -0
- package/dist/kit/builder/stack-dialog/hooks.d.ts.map +1 -0
- package/dist/kit/builder/stack-dialog/index.d.ts +5 -0
- package/dist/kit/builder/stack-dialog/index.d.ts.map +1 -0
- package/dist/kit/builder/stack-dialog/provider.d.ts +3 -0
- package/dist/kit/builder/stack-dialog/provider.d.ts.map +1 -0
- package/dist/kit/builder/stack-dialog/renderer.d.ts +6 -0
- package/dist/kit/builder/stack-dialog/renderer.d.ts.map +1 -0
- package/dist/kit/builder/stack-dialog/types.d.ts +20 -0
- package/dist/kit/builder/stack-dialog/types.d.ts.map +1 -0
- package/dist/kit/components/autocomplete/Autocomplete.d.ts +35 -3
- package/dist/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
- package/dist/kit/components/autocomplete/index.d.ts +1 -0
- package/dist/kit/components/autocomplete/index.d.ts.map +1 -1
- package/dist/kit/components/datepicker/DatePicker.d.ts +27 -0
- package/dist/kit/components/datepicker/DatePicker.d.ts.map +1 -0
- package/dist/kit/components/datepicker/DateRangePicker.d.ts +41 -0
- package/dist/kit/components/datepicker/DateRangePicker.d.ts.map +1 -0
- package/dist/kit/components/monthpicker/MonthInput.d.ts +26 -0
- package/dist/kit/components/monthpicker/MonthInput.d.ts.map +1 -0
- package/dist/kit/components/monthpicker/MonthPicker.d.ts +32 -0
- package/dist/kit/components/monthpicker/MonthPicker.d.ts.map +1 -0
- package/dist/kit/components/monthpicker/MonthRangeInput.d.ts +31 -0
- package/dist/kit/components/monthpicker/MonthRangeInput.d.ts.map +1 -0
- package/dist/kit/components/monthpicker/MonthRangePicker.d.ts +48 -0
- package/dist/kit/components/monthpicker/MonthRangePicker.d.ts.map +1 -0
- package/dist/kit/themes/clean-slate.css +165 -1
- package/dist/kit/themes/default.css +165 -1
- package/dist/kit/themes/minimal-modern.css +165 -1
- package/dist/kit/themes/spotify.css +165 -1
- package/package.json +1 -1
- package/src/kit/builder/data-table/components/DataTable.tsx +9 -9
- package/src/kit/builder/form/components/FormBuilder.tsx +363 -145
- package/src/kit/builder/form/components/FormBuilderField.tsx +52 -3
- package/src/kit/builder/form/components/fields/AutocompleteField.tsx +29 -1
- package/src/kit/builder/form/components/fields/DatePickerField.tsx +24 -0
- package/src/kit/builder/form/components/fields/DateRangePickerField.tsx +41 -0
- package/src/kit/builder/form/components/fields/MonthPickerField.tsx +26 -0
- package/src/kit/builder/form/components/fields/MonthRangePickerField.tsx +35 -0
- package/src/kit/builder/form/components/fields/index.ts +4 -0
- package/src/kit/builder/section/SectionBuilder.tsx +24 -2
- package/src/kit/builder/section/types.ts +15 -1
- package/src/kit/builder/stack-dialog/context.ts +9 -0
- package/src/kit/builder/stack-dialog/hooks.ts +11 -0
- package/src/kit/builder/stack-dialog/index.ts +13 -0
- package/src/kit/builder/stack-dialog/provider.tsx +55 -0
- package/src/kit/builder/stack-dialog/renderer.tsx +33 -0
- package/src/kit/builder/stack-dialog/types.ts +22 -0
- package/src/kit/components/autocomplete/Autocomplete.tsx +783 -233
- package/src/kit/components/autocomplete/index.ts +1 -0
- package/src/kit/components/datepicker/DatePicker.tsx +149 -0
- package/src/kit/components/datepicker/DateRangePicker.tsx +454 -0
- package/src/kit/components/monthpicker/MonthInput.tsx +122 -0
- package/src/kit/components/monthpicker/MonthPicker.tsx +223 -0
- package/src/kit/components/monthpicker/MonthRangeInput.tsx +132 -0
- package/src/kit/components/monthpicker/MonthRangePicker.tsx +407 -0
- package/src/stories/kit/builder/Form.Autocomplete.stories.tsx +210 -0
- package/src/stories/kit/builder/Form.Complex.stories.tsx +101 -0
- package/src/stories/kit/builder/Form.Dynamic.stories.tsx +149 -0
- package/src/stories/kit/builder/Form.Pickers.stories.tsx +71 -0
- package/src/stories/kit/builder/Section.stories.tsx +58 -2
- package/src/stories/kit/components/Autocomplete.stories.tsx +27 -0
- package/src/stories/kit/components/DatePicker.stories.tsx +128 -0
- package/src/stories/kit/components/DateRangePicker.stories.tsx +154 -0
- package/src/stories/kit/components/MonthPicker.stories.tsx +80 -0
- package/src/stories/kit/components/MonthRangePicker.stories.tsx +98 -0
- package/storybook-static/assets/{Accordion.stories-q6yg6wg1.js → Accordion.stories-KU4JBR8U.js} +1 -1
- package/storybook-static/assets/{AdminLayout-B9bV4J_6.js → AdminLayout-CPvVCwfY.js} +10 -10
- package/storybook-static/assets/AdminLayout.Basic.stories-DkP2UVXe.js +4 -0
- package/storybook-static/assets/AdminLayout.Collapsible.stories-BuuVjtpW.js +4 -0
- package/storybook-static/assets/AdminLayout.Complex.stories-D-k4H0hJ.js +29 -0
- package/storybook-static/assets/AdminLayout.CustomSidebarHeaderComponent.stories-B_0IEDd4.js +9 -0
- package/storybook-static/assets/AdminLayout.CustomSidebarTitleAndIcon.stories-CvAeXUyA.js +4 -0
- package/storybook-static/assets/AdminLayout.HeaderSlots.stories-RBFHoSZK.js +7 -0
- package/storybook-static/assets/{Alert.stories-DXwNfJ3w.js → Alert.stories-DKxKtIc0.js} +1 -1
- package/storybook-static/assets/{AlertDialog.stories-I324NsnP.js → AlertDialog.stories-BqTpZ_nG.js} +1 -1
- package/storybook-static/assets/{AspectRatio.stories-CghHiX3Z.js → AspectRatio.stories-DPO9QQ5F.js} +1 -1
- package/storybook-static/assets/Autocomplete-Cpg4CaJe.js +56 -0
- package/storybook-static/assets/Autocomplete.stories-CWj4G5fh.js +56 -0
- package/storybook-static/assets/{Avatar.stories-CEF5FVSR.js → Avatar.stories-DPhov_2g.js} +1 -1
- package/storybook-static/assets/Badge.stories-DFKrRdXq.js +12 -0
- package/storybook-static/assets/{Breadcrumb.stories-DORe9T4b.js → Breadcrumb.stories-CTE6CZUC.js} +1 -1
- package/storybook-static/assets/{Button.stories-3nQ6wsBX.js → Button.stories-cbt2InL-.js} +1 -1
- package/storybook-static/assets/{Calendar.stories-Dn__djE1.js → Calendar.stories-DRhTw_43.js} +1 -1
- package/storybook-static/assets/{Card.stories-BJcbdwCI.js → Card.stories-Isf6n_K3.js} +1 -1
- package/storybook-static/assets/{Carousel.stories-CfqbE7Va.js → Carousel.stories-Cmg0I3fR.js} +1 -1
- package/storybook-static/assets/{Chart.stories-cGgef3tv.js → Chart.stories-aQ-fNijT.js} +1 -1
- package/storybook-static/assets/{Checkbox.stories-BcaxWzCS.js → Checkbox.stories-B7YMXPDc.js} +1 -1
- package/storybook-static/assets/{Collapsible.stories-CQ95s7Cs.js → Collapsible.stories-BUzl17ZZ.js} +1 -1
- package/storybook-static/assets/{Combination-CeVus13L.js → Combination-BdQWAuko.js} +1 -1
- package/storybook-static/assets/{Command.stories-DYflJh8u.js → Command.stories-DzBlWQs0.js} +1 -1
- package/storybook-static/assets/{ContextMenu.stories-CU7ehYrE.js → ContextMenu.stories-CJlBQyXc.js} +1 -1
- package/storybook-static/assets/DataTable.Basic.stories-BWYKFDmK.js +6 -0
- package/storybook-static/assets/DataTable.Filters.stories-uZdtJk8t.js +21 -0
- package/storybook-static/assets/DataTable.Pagination.stories-C5N1khkp.js +24 -0
- package/storybook-static/assets/DataTable.SelectionAndActions.stories-FhCqZKvO.js +26 -0
- package/storybook-static/assets/DataTable.Sorting.stories-D-k7EtRj.js +6 -0
- package/storybook-static/assets/{Dialog.stories-DobNZ0Hp.js → Dialog.stories-C62AF-Gx.js} +1 -1
- package/storybook-static/assets/{Dialog.stories-Bu6ZJXNH.js → Dialog.stories-lrjRwOus.js} +1 -1
- package/storybook-static/assets/{Drawer.stories-BN0idp4u.js → Drawer.stories-CGjkdJeV.js} +1 -1
- package/storybook-static/assets/{DropdownMenu.stories-sfsVDTvm.js → DropdownMenu.stories-DkGClRAA.js} +1 -1
- package/storybook-static/assets/Form.ArrayLayouts.stories-C5d_062d.js +130 -0
- package/storybook-static/assets/Form.Autocomplete.stories-CPZPkk4o.js +142 -0
- package/storybook-static/assets/Form.Basic.stories-Bhcu3-3n.js +58 -0
- package/storybook-static/assets/Form.Complex.stories-QnXh5a7Q.js +361 -0
- package/storybook-static/assets/Form.Dynamic.stories-DFW6wIuT.js +502 -0
- package/storybook-static/assets/Form.Simple.stories-BhJcyhbE.js +53 -0
- package/storybook-static/assets/{Form.stories-27doU7JS.js → Form.stories-PFNsMYxO.js} +1 -1
- package/storybook-static/assets/FormBuilder-BQBBxo_k.js +5 -0
- package/storybook-static/assets/{HoverCard.stories-0lted9Zx.js → HoverCard.stories-CAlQEVn8.js} +1 -1
- package/storybook-static/assets/{Input.stories-CwsIObFs.js → Input.stories-CEhODt0V.js} +1 -1
- package/storybook-static/assets/{InputOtp.stories-DVc086h4.js → InputOtp.stories-DSvNP4dS.js} +1 -1
- package/storybook-static/assets/{Label.stories-bJa0rk1A.js → Label.stories-B3pa8ZLY.js} +1 -1
- package/storybook-static/assets/{Login.stories-C6X6Kj5B.js → Login.stories-C7KQkmR_.js} +5 -5
- package/storybook-static/assets/{Menubar.stories-CuediVp7.js → Menubar.stories-CHXhSHxc.js} +1 -1
- package/storybook-static/assets/MonthPicker.stories-BnrOc4fm.js +99 -0
- package/storybook-static/assets/MonthRangePicker.stories-55Gk1t-7.js +134 -0
- package/storybook-static/assets/{NavigationMenu.stories-CKGZYhKk.js → NavigationMenu.stories-CXoS080P.js} +1 -1
- package/storybook-static/assets/{Page.stories-Cf76wtRx.js → Page.stories-GdSJgZ6-.js} +1 -1
- package/storybook-static/assets/{Pagination.stories-D7IdL1_4.js → Pagination.stories-BEBwqH4N.js} +1 -1
- package/storybook-static/assets/{Popover.stories-1VP_zNY8.js → Popover.stories-BICy98Cw.js} +1 -1
- package/storybook-static/assets/{Progress.stories-C35R5YvA.js → Progress.stories-DECHNOME.js} +1 -1
- package/storybook-static/assets/{RadioGroup.stories-CjuD3CwD.js → RadioGroup.stories-DA7-uKfV.js} +1 -1
- package/storybook-static/assets/{Resizable.stories-Cs8dvdc5.js → Resizable.stories-B99kWkH7.js} +1 -1
- package/storybook-static/assets/{ScrollArea.stories-D6_z-5jm.js → ScrollArea.stories-BqvUAXqU.js} +1 -1
- package/storybook-static/assets/Section.stories-lFMlFBQn.js +277 -0
- package/storybook-static/assets/SectionBuilder-BQW705x0.js +1 -0
- package/storybook-static/assets/{Select.stories-w_kbza5k.js → Select.stories-BsKyZ6Io.js} +1 -1
- package/storybook-static/assets/{Separator.stories-B5QnaJXb.js → Separator.stories-BTDOaOM2.js} +1 -1
- package/storybook-static/assets/{Sheet.stories-CORnEGvV.js → Sheet.stories-Cam1gR6G.js} +1 -1
- package/storybook-static/assets/{Sidebar.stories-DVuWTi4j.js → Sidebar.stories-DnOa6G7y.js} +1 -1
- package/storybook-static/assets/{Slider.stories-YoS2vvT2.js → Slider.stories-Bslq7hjq.js} +1 -1
- package/storybook-static/assets/Sonner.stories-D34pBBtI.js +18 -0
- package/storybook-static/assets/Switch.stories-Puyb1-Bx.js +3 -0
- package/storybook-static/assets/{Table.stories-BuGU4MUM.js → Table.stories-ClZxAhut.js} +1 -1
- package/storybook-static/assets/Tabs.stories-CURNTETB.js +10 -0
- package/storybook-static/assets/{Textarea.stories-CHXVobz6.js → Textarea.stories-Cf1ZBrWw.js} +1 -1
- package/storybook-static/assets/{Toggle.stories-C4uB4Hkq.js → Toggle.stories-CdMHY_bi.js} +1 -1
- package/storybook-static/assets/{ToggleGroup.stories-Cr229wf_.js → ToggleGroup.stories-BM68m1dX.js} +1 -1
- package/storybook-static/assets/{Tooltip.stories-DmMYGR3T.js → Tooltip.stories-DiQv64dM.js} +1 -1
- package/storybook-static/assets/{accordion-BCfsz_gl.js → accordion-DVgwQcnw.js} +1 -1
- package/storybook-static/assets/{alert-dialog-BYt6Z7Kt.js → alert-dialog-DCUEwpqm.js} +1 -1
- package/storybook-static/assets/{avatar-CRn1qQsC.js → avatar-BzwOE-mi.js} +1 -1
- package/storybook-static/assets/{axe-JCJl60WC.js → axe-HmUsR1st.js} +1 -1
- package/storybook-static/assets/badge-BnQWua6u.js +1 -0
- package/storybook-static/assets/{button-BObfgcV1.js → button-0oMkiryo.js} +1 -1
- package/storybook-static/assets/{chart-column-CplFCmg8.js → chart-column-DZGb4ZZS.js} +1 -1
- package/storybook-static/assets/{check-DyecuwP4.js → check-B9hBGj6o.js} +1 -1
- package/storybook-static/assets/{checkbox-D5BmNJeL.js → checkbox-CyIeaWHX.js} +1 -1
- package/storybook-static/assets/{chevron-down-Bp7zbUB0.js → chevron-down-D_37S6il.js} +1 -1
- package/storybook-static/assets/{chevron-left-D1L4J3UW.js → chevron-left-BBoN0vbI.js} +1 -1
- package/storybook-static/assets/{chevron-right-oMYqDJ_f.js → chevron-right-B5vIMLxK.js} +1 -1
- package/storybook-static/assets/{circle-CyarsADt.js → circle-C5Lzx6Nx.js} +1 -1
- package/storybook-static/assets/clean-slate-D1HmMFJM.css +1 -0
- package/storybook-static/assets/{command-DCnXmNmT.js → command-Csa9p8_a.js} +1 -1
- package/storybook-static/assets/{createLucideIcon-CLBo0iA0.js → createLucideIcon-BrHXro7t.js} +1 -1
- package/storybook-static/assets/default-CN_Fo1GY.css +1 -0
- package/storybook-static/assets/{dialog-DL0QBIbC.js → dialog-CsnqITTn.js} +1 -1
- package/storybook-static/assets/{dropdown-menu-BwL9gQwG.js → dropdown-menu-BWxxwPHL.js} +1 -1
- package/storybook-static/assets/{ellipsis-DPg968Rc.js → ellipsis-BRS038RR.js} +1 -1
- package/storybook-static/assets/{grip-vertical-CM0GDwvq.js → grip-vertical-BxXG8KNA.js} +1 -1
- package/storybook-static/assets/{iframe-BWjPIle6.js → iframe-v7iAhKit.js} +219 -219
- package/storybook-static/assets/{index-DschQYGl.js → index-0-qMRXou.js} +1 -1
- package/storybook-static/assets/{index-CKwUGXmt.js → index-AvwFFKJc.js} +1 -1
- package/storybook-static/assets/{index-BfKpUbCE.js → index-BVDb4dFc.js} +1 -1
- package/storybook-static/assets/{index-Dr2xmx-F.js → index-B_qx7A5T.js} +1 -1
- package/storybook-static/assets/index-BfiCOk42.js +1 -0
- package/storybook-static/assets/{index-C9xvlw_B.js → index-Bv9yk470.js} +1 -1
- package/storybook-static/assets/{index-DMk2qc2_.js → index-Bw1A27Kp.js} +1 -1
- package/storybook-static/assets/{index-7XoYQV2z.js → index-ByqivBWx.js} +1 -1
- package/storybook-static/assets/{index-URSssr5a.js → index-C9Ta0ZTH.js} +1 -1
- package/storybook-static/assets/{index-Pk2lGsul.js → index-CDY5kTx5.js} +1 -1
- package/storybook-static/assets/{index-3zykFCgl.js → index-CGnyVRgB.js} +1 -1
- package/storybook-static/assets/{index-Cw7p-pms.js → index-CWjrGFAQ.js} +1 -1
- package/storybook-static/assets/{index-npvyVsxD.js → index-CwBdPBFz.js} +1 -1
- package/storybook-static/assets/index-D8RXF03I.js +1 -0
- package/storybook-static/assets/{index-DE2OlfDP.js → index-DLIxT4Z7.js} +1 -1
- package/storybook-static/assets/{index-BcAKBHrX.js → index-DbaA6-o1.js} +1 -1
- package/storybook-static/assets/index-Dph_5COR.js +1 -0
- package/storybook-static/assets/index-DrN5n71E.js +1 -0
- package/storybook-static/assets/{index-04C4iZwC.js → index-Tp9IdbR8.js} +1 -1
- package/storybook-static/assets/{index-Dsg7S8zu.js → index-WyF3-wTE.js} +1 -1
- package/storybook-static/assets/{index-A7UzX-Xw.js → index-XSmPROEP.js} +1 -1
- package/storybook-static/assets/{index-u70nzfOV.js → index-Z6wF44KX.js} +1 -1
- package/storybook-static/assets/{index-Dqw7miiX.js → index-_RPqOjlQ.js} +1 -1
- package/storybook-static/assets/{index-Cce91yJQ.js → index-jrimW4QO.js} +1 -1
- package/storybook-static/assets/{index-C6O7WofA.js → index-nqc17SX4.js} +1 -1
- package/storybook-static/assets/{label-CwntpYJ0.js → label-Do8ODIVk.js} +1 -1
- package/storybook-static/assets/lodash-DDwpuhPG.js +73 -0
- package/storybook-static/assets/minimal-modern-BlYVzfQU.css +1 -0
- package/storybook-static/assets/{popover-ClqrrvjL.js → popover-CcciSWAw.js} +1 -1
- package/storybook-static/assets/{radio-group-CvN0LQZp.js → radio-group-DiJ0Y_KQ.js} +1 -1
- package/storybook-static/assets/{react-18-Bj31y5Nr.js → react-18-Cr9fq_Ip.js} +1 -1
- package/storybook-static/assets/{react-icons.esm-DNr9VcvP.js → react-icons.esm-B_ULMmNU.js} +1 -1
- package/storybook-static/assets/{refresh-cw-OZakDsFY.js → refresh-cw-BmRDhIV_.js} +1 -1
- package/storybook-static/assets/{schemas-CaLvKjsI.js → schemas-CGNYCiJ6.js} +3 -3
- package/storybook-static/assets/{section-factories-DKfKL-5s.js → section-factories-DCCY9R35.js} +1 -1
- package/storybook-static/assets/{select-gtXRB92c.js → select-DDrkxaOg.js} +1 -1
- package/storybook-static/assets/{separator-CxCWfpZX.js → separator-o5SAUnaJ.js} +1 -1
- package/storybook-static/assets/{settings-2-DSSkfF6W.js → settings-2-xWGvvbG6.js} +1 -1
- package/storybook-static/assets/{sheet-r0VNiBiN.js → sheet-C7jhU3XE.js} +1 -1
- package/storybook-static/assets/{shopping-cart-CJBClF2m.js → shopping-cart-BFlrufvo.js} +1 -1
- package/storybook-static/assets/{sidebar-BsMnOE7Y.js → sidebar-C8hU1Mxy.js} +1 -1
- package/storybook-static/assets/spotify-CUDj7g8m.css +1 -0
- package/storybook-static/assets/switch-CKGRuk3u.js +1 -0
- package/storybook-static/assets/tabs-CopK2m3j.js +1 -0
- package/storybook-static/assets/{toggle-D08-8sQA.js → toggle-DmHbWetf.js} +1 -1
- package/storybook-static/assets/{tooltip-CZ1UAE_e.js → tooltip-_LqYEYFw.js} +1 -1
- package/storybook-static/assets/{trash-2-D55eseMQ.js → trash-2-xdbApPby.js} +1 -1
- package/storybook-static/assets/{x-n8sFtlI2.js → x-B1a4fyWM.js} +1 -1
- package/storybook-static/iframe.html +1 -1
- package/storybook-static/index.json +1 -1
- package/storybook-static/kit/builder/data-table/components/DataTable.d.ts +6 -3
- package/storybook-static/kit/builder/data-table/components/DataTable.d.ts.map +1 -1
- package/storybook-static/kit/builder/data-table/index.d.ts +6 -5
- package/storybook-static/kit/builder/data-table/index.d.ts.map +1 -1
- package/storybook-static/kit/builder/form/components/FormBuilder.d.ts +53 -13
- package/storybook-static/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
- package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts +5 -5
- package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts.map +1 -1
- package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/DateField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/DateField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/FileField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/FileField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/TextField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/TextField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts +3 -0
- package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/index.d.ts +14 -0
- package/storybook-static/kit/builder/form/components/fields/index.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/components/fields/types.d.ts +14 -0
- package/storybook-static/kit/builder/form/components/fields/types.d.ts.map +1 -0
- package/storybook-static/kit/builder/form/utils/field-factories.d.ts +1 -0
- package/storybook-static/kit/builder/form/utils/field-factories.d.ts.map +1 -1
- package/storybook-static/kit/builder/section/SectionBuilder.d.ts.map +1 -1
- package/storybook-static/kit/builder/section/types.d.ts +12 -1
- package/storybook-static/kit/builder/section/types.d.ts.map +1 -1
- package/storybook-static/kit/builder/stack-dialog/context.d.ts +3 -0
- package/storybook-static/kit/builder/stack-dialog/context.d.ts.map +1 -0
- package/storybook-static/kit/builder/stack-dialog/hooks.d.ts +6 -0
- package/storybook-static/kit/builder/stack-dialog/hooks.d.ts.map +1 -0
- package/storybook-static/kit/builder/stack-dialog/index.d.ts +5 -0
- package/storybook-static/kit/builder/stack-dialog/index.d.ts.map +1 -0
- package/storybook-static/kit/builder/stack-dialog/provider.d.ts +3 -0
- package/storybook-static/kit/builder/stack-dialog/provider.d.ts.map +1 -0
- package/storybook-static/kit/builder/stack-dialog/renderer.d.ts +6 -0
- package/storybook-static/kit/builder/stack-dialog/renderer.d.ts.map +1 -0
- package/storybook-static/kit/builder/stack-dialog/types.d.ts +20 -0
- package/storybook-static/kit/builder/stack-dialog/types.d.ts.map +1 -0
- package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts +35 -3
- package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
- package/storybook-static/kit/components/autocomplete/index.d.ts +1 -0
- package/storybook-static/kit/components/autocomplete/index.d.ts.map +1 -1
- package/storybook-static/kit/components/autocomplete/types.d.ts +1 -1
- package/storybook-static/kit/components/autocomplete/types.d.ts.map +1 -1
- package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts +32 -0
- package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts.map +1 -0
- package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts +48 -0
- package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts.map +1 -0
- package/storybook-static/kit/layouts/admin/components/AdminLayout.d.ts.map +1 -1
- package/storybook-static/kit/layouts/admin/hooks/menu.d.ts +1 -0
- package/storybook-static/kit/layouts/admin/hooks/menu.d.ts.map +1 -1
- package/storybook-static/kit/providers/ThemeProvider.d.ts.map +1 -1
- package/storybook-static/project.json +1 -1
- package/storybook-static/assets/AdminLayout.Basic.stories-C-ZxuH-O.js +0 -4
- package/storybook-static/assets/AdminLayout.Collapsible.stories-xcQzkxio.js +0 -4
- package/storybook-static/assets/AdminLayout.Complex.stories-DyjkVpvE.js +0 -29
- package/storybook-static/assets/AdminLayout.CustomSidebarHeaderComponent.stories-BqhzWCIA.js +0 -9
- package/storybook-static/assets/AdminLayout.CustomSidebarTitleAndIcon.stories-aWxyR67T.js +0 -4
- package/storybook-static/assets/AdminLayout.HeaderSlots.stories-dNzhUdDt.js +0 -7
- package/storybook-static/assets/Autocomplete-B4gV705L.js +0 -35
- package/storybook-static/assets/Autocomplete.stories-CyOvjTGN.js +0 -33
- package/storybook-static/assets/Badge.stories-_-G3GriP.js +0 -12
- package/storybook-static/assets/DataTable.Basic.stories-BQNWUKiw.js +0 -6
- package/storybook-static/assets/DataTable.Filters.stories-DPCoeYhK.js +0 -21
- package/storybook-static/assets/DataTable.Pagination.stories-8UNqTNgw.js +0 -24
- package/storybook-static/assets/DataTable.SelectionAndActions.stories-CDEjgQ6T.js +0 -26
- package/storybook-static/assets/DataTable.Sorting.stories-qG7-X_6r.js +0 -6
- package/storybook-static/assets/Form.Basic.stories-dE4nbgpr.js +0 -45
- package/storybook-static/assets/Form.Complex.stories-BEZufnjb.js +0 -230
- package/storybook-static/assets/Form.Dynamic.stories-cJTbd6cV.js +0 -247
- package/storybook-static/assets/Form.Simple.stories-DOPzZKhh.js +0 -50
- package/storybook-static/assets/FormBuilder-C0S7C69Q.js +0 -5
- package/storybook-static/assets/Section.stories-Ce5qYITI.js +0 -196
- package/storybook-static/assets/SectionBuilder-Df_lRZkj.js +0 -1
- package/storybook-static/assets/Sonner.stories-CXW5e_Qg.js +0 -18
- package/storybook-static/assets/Switch.stories-zr6i-aNi.js +0 -3
- package/storybook-static/assets/Tabs.stories-jxkJ-AUI.js +0 -10
- package/storybook-static/assets/clean-slate-V4nUw2Bm.css +0 -1
- package/storybook-static/assets/default-CuTBjDca.css +0 -1
- package/storybook-static/assets/index-BN5_W3Yi.js +0 -1
- package/storybook-static/assets/index-C5eJ31Z3.js +0 -1
- package/storybook-static/assets/index-DWC9SV-P.js +0 -1
- package/storybook-static/assets/lodash-BkmSIg_J.js +0 -73
- package/storybook-static/assets/minimal-modern-d2yFlFJM.css +0 -1
- package/storybook-static/assets/spotify-BuPUgQEa.css +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
3
|
import { useForm, useWatch, type Control, type FieldValues } from 'react-hook-form';
|
|
3
4
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
4
5
|
import { z } from 'zod';
|
|
@@ -6,8 +7,16 @@ import { cn } from '../../../../shadcn/lib/utils';
|
|
|
6
7
|
import { Button } from '../../../../shadcn/ui/button';
|
|
7
8
|
import { FormBuilderField } from './FormBuilderField';
|
|
8
9
|
import SectionBuilder from '../../section/SectionBuilder';
|
|
9
|
-
import type {
|
|
10
|
-
|
|
10
|
+
import type {
|
|
11
|
+
SectionLayout,
|
|
12
|
+
SectionGridOptions,
|
|
13
|
+
SectionFlexOptions,
|
|
14
|
+
SectionNode,
|
|
15
|
+
} from '../../section/types';
|
|
16
|
+
import type {
|
|
17
|
+
AutocompleteFetcher,
|
|
18
|
+
AutocompleteOption,
|
|
19
|
+
} from '../../../components/autocomplete/types';
|
|
11
20
|
|
|
12
21
|
export interface FormBuilderFieldConfig {
|
|
13
22
|
id?: string; // Optional ID for test fixtures
|
|
@@ -24,7 +33,11 @@ export interface FormBuilderFieldConfig {
|
|
|
24
33
|
| 'checkbox'
|
|
25
34
|
| 'switch'
|
|
26
35
|
| 'radio'
|
|
27
|
-
| 'date'
|
|
36
|
+
| 'date' // native input date
|
|
37
|
+
| 'date_picker' // UI DatePicker
|
|
38
|
+
| 'date_range' // UI DateRangePicker
|
|
39
|
+
| 'month' // UI MonthPicker (single month Date)
|
|
40
|
+
| 'month_range' // UI MonthRangePicker { start: Date, end: Date }
|
|
28
41
|
| 'file'
|
|
29
42
|
| 'object'
|
|
30
43
|
| 'array';
|
|
@@ -42,25 +55,35 @@ export interface FormBuilderFieldConfig {
|
|
|
42
55
|
option: AutocompleteOption,
|
|
43
56
|
selected: boolean
|
|
44
57
|
) => React.ReactNode;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
// New autocomplete features
|
|
59
|
+
multiple?: boolean;
|
|
60
|
+
allowCustomValue?: boolean;
|
|
61
|
+
chipVariant?: 'default' | 'secondary' | 'destructive' | 'outline';
|
|
62
|
+
chipClassName?: string;
|
|
63
|
+
clearable?: boolean;
|
|
64
|
+
initialSelectedOptions?: AutocompleteOption | AutocompleteOption[] | null;
|
|
65
|
+
loadSelected?: (values: Array<string | number>) => Promise<AutocompleteOption[]>;
|
|
66
|
+
validation?:
|
|
67
|
+
| z.ZodType<unknown>
|
|
68
|
+
| {
|
|
69
|
+
pattern?: { value: RegExp; message: string };
|
|
70
|
+
min?: { value: number; message: string };
|
|
71
|
+
max?: { value: number; message: string };
|
|
72
|
+
minLength?: { value: number; message: string };
|
|
73
|
+
maxLength?: { value: number; message: string };
|
|
74
|
+
};
|
|
75
|
+
defaultValue?: unknown;
|
|
53
76
|
fields?: FormBuilderFieldConfig[]; // For nested object/array fields
|
|
54
77
|
dependencies?: {
|
|
55
78
|
field: string;
|
|
56
|
-
condition: (value:
|
|
79
|
+
condition: (value: unknown) => boolean;
|
|
57
80
|
action: 'show' | 'hide' | 'enable' | 'disable' | 'setValue';
|
|
58
|
-
value?:
|
|
81
|
+
value?: unknown;
|
|
59
82
|
}[];
|
|
60
83
|
onChange?: (
|
|
61
|
-
value:
|
|
62
|
-
setValue: (field: string, value:
|
|
63
|
-
getValues: () =>
|
|
84
|
+
value: unknown,
|
|
85
|
+
setValue: (field: string, value: unknown) => void,
|
|
86
|
+
getValues: () => Record<string, unknown>
|
|
64
87
|
) => void;
|
|
65
88
|
className?: string;
|
|
66
89
|
gridCols?: number;
|
|
@@ -73,8 +96,8 @@ export interface FormBuilderFieldConfig {
|
|
|
73
96
|
field: FormBuilderFieldConfig;
|
|
74
97
|
control: Control<FieldValues>;
|
|
75
98
|
fieldPath: string;
|
|
76
|
-
value:
|
|
77
|
-
onChange: (value:
|
|
99
|
+
value: unknown;
|
|
100
|
+
onChange: (value: unknown) => void;
|
|
78
101
|
addItem: () => void;
|
|
79
102
|
removeItem: (index: number) => void;
|
|
80
103
|
disabled?: boolean;
|
|
@@ -88,20 +111,29 @@ export interface FormBuilderFieldConfig {
|
|
|
88
111
|
};
|
|
89
112
|
conditional?: {
|
|
90
113
|
field: string;
|
|
91
|
-
value:
|
|
114
|
+
value: unknown;
|
|
92
115
|
}; // For conditional field visibility
|
|
93
116
|
hidden?: boolean; // Declarative hide
|
|
94
117
|
// Label placement control across inputs
|
|
95
118
|
labelPlacement?: 'stacked' | 'inline' | 'hidden';
|
|
96
119
|
// Wrapper container className (applies to the field wrapper, not the input)
|
|
97
120
|
wrapperClassName?: string;
|
|
121
|
+
// Picker-specific optional props (passed through to components when applicable)
|
|
122
|
+
minDate?: Date;
|
|
123
|
+
maxDate?: Date;
|
|
124
|
+
disabledDates?: Array<Date | { from: Date; to: Date }>;
|
|
125
|
+
numberOfMonths?: number;
|
|
126
|
+
popoverSide?: 'top' | 'right' | 'bottom' | 'left';
|
|
127
|
+
showFooter?: boolean;
|
|
128
|
+
cancelLabel?: string;
|
|
129
|
+
applyLabel?: string;
|
|
98
130
|
}
|
|
99
131
|
|
|
100
132
|
export interface FormBuilderSectionConfig {
|
|
101
133
|
id?: string;
|
|
102
134
|
title?: string;
|
|
103
135
|
description?: string;
|
|
104
|
-
fields
|
|
136
|
+
fields?: FormBuilderFieldConfig[];
|
|
105
137
|
variant?: 'card' | 'separator' | 'plain';
|
|
106
138
|
className?: string;
|
|
107
139
|
collapsible?: boolean;
|
|
@@ -110,19 +142,30 @@ export interface FormBuilderSectionConfig {
|
|
|
110
142
|
grid?: SectionGridOptions;
|
|
111
143
|
flex?: SectionFlexOptions;
|
|
112
144
|
hidden?: boolean; // Declarative hide
|
|
145
|
+
// Tabs layout support: when layout === 'tabs', provide tabs instead of direct fields
|
|
146
|
+
tabs?: Array<{
|
|
147
|
+
id: string;
|
|
148
|
+
label: React.ReactNode;
|
|
149
|
+
sections: FormBuilderSectionConfig[];
|
|
150
|
+
className?: string;
|
|
151
|
+
contentClassName?: string;
|
|
152
|
+
}>;
|
|
153
|
+
defaultTabId?: string;
|
|
154
|
+
tabsListClassName?: string;
|
|
155
|
+
tabsContentClassName?: string;
|
|
113
156
|
}
|
|
114
157
|
|
|
115
158
|
export interface FormBuilderProps {
|
|
116
159
|
sections: FormBuilderSectionConfig[];
|
|
117
|
-
schema?: z.ZodType<
|
|
118
|
-
defaultValues?: Record<string,
|
|
119
|
-
onSubmit: (data:
|
|
160
|
+
schema?: z.ZodType<unknown>;
|
|
161
|
+
defaultValues?: Record<string, unknown> | null;
|
|
162
|
+
onSubmit: (data: unknown) => void | Promise<void>;
|
|
120
163
|
onCancel?: () => void;
|
|
121
164
|
onReset?: () => void;
|
|
122
165
|
onFieldChange?: (
|
|
123
166
|
name: string,
|
|
124
|
-
value:
|
|
125
|
-
allValues: Record<string,
|
|
167
|
+
value: unknown,
|
|
168
|
+
allValues: Record<string, unknown>
|
|
126
169
|
) => void;
|
|
127
170
|
submitLabel?: string;
|
|
128
171
|
cancelLabel?: string;
|
|
@@ -160,15 +203,21 @@ export function FormBuilder({
|
|
|
160
203
|
const generatedSchema = useMemo(() => {
|
|
161
204
|
if (schema) return schema;
|
|
162
205
|
|
|
163
|
-
const generateFieldSchema = (
|
|
206
|
+
const generateFieldSchema = (
|
|
207
|
+
field: FormBuilderFieldConfig
|
|
208
|
+
): z.ZodType<unknown> => {
|
|
164
209
|
if (field.validation && field.validation instanceof z.ZodType) {
|
|
165
210
|
return field.validation;
|
|
166
211
|
}
|
|
167
212
|
|
|
168
213
|
// Handle validation object format
|
|
169
|
-
if (
|
|
214
|
+
if (
|
|
215
|
+
field.validation &&
|
|
216
|
+
typeof field.validation === 'object' &&
|
|
217
|
+
!(field.validation instanceof z.ZodType)
|
|
218
|
+
) {
|
|
170
219
|
const validationObj = field.validation;
|
|
171
|
-
let baseSchema: z.ZodType<
|
|
220
|
+
let baseSchema: z.ZodType<unknown>;
|
|
172
221
|
|
|
173
222
|
// Determine base schema type
|
|
174
223
|
switch (field.type) {
|
|
@@ -178,41 +227,75 @@ export function FormBuilder({
|
|
|
178
227
|
case 'number':
|
|
179
228
|
baseSchema = z.number();
|
|
180
229
|
break;
|
|
181
|
-
case '
|
|
182
|
-
|
|
230
|
+
case 'date_picker':
|
|
231
|
+
case 'month':
|
|
232
|
+
case 'date':
|
|
233
|
+
baseSchema = z.date();
|
|
234
|
+
break;
|
|
235
|
+
case 'date_range':
|
|
236
|
+
baseSchema = z
|
|
237
|
+
.object({ from: z.date().optional().nullable(), to: z.date().optional().nullable() })
|
|
238
|
+
.nullable();
|
|
239
|
+
break;
|
|
240
|
+
case 'month_range':
|
|
241
|
+
baseSchema = z
|
|
242
|
+
.object({ start: z.date().optional().nullable(), end: z.date().optional().nullable() })
|
|
243
|
+
.nullable();
|
|
244
|
+
break;
|
|
245
|
+
case 'autocomplete': {
|
|
246
|
+
const single = z
|
|
247
|
+
.union([z.string(), z.number(), z.object({})])
|
|
248
|
+
.nullable();
|
|
249
|
+
const multi = z.array(
|
|
250
|
+
z.union([z.string(), z.number(), z.object({})])
|
|
251
|
+
);
|
|
252
|
+
baseSchema = field.multiple ? multi : single;
|
|
183
253
|
break;
|
|
254
|
+
}
|
|
184
255
|
case 'checkbox':
|
|
185
256
|
case 'switch':
|
|
186
257
|
baseSchema = z.boolean();
|
|
187
258
|
break;
|
|
188
|
-
case 'date':
|
|
189
|
-
baseSchema = z.date();
|
|
190
|
-
break;
|
|
191
259
|
default:
|
|
192
260
|
baseSchema = z.string();
|
|
193
261
|
}
|
|
194
262
|
|
|
195
263
|
// Apply validation constraints
|
|
196
264
|
if (validationObj.pattern && baseSchema instanceof z.ZodString) {
|
|
197
|
-
baseSchema = baseSchema.regex(
|
|
265
|
+
baseSchema = baseSchema.regex(
|
|
266
|
+
validationObj.pattern.value,
|
|
267
|
+
validationObj.pattern.message
|
|
268
|
+
);
|
|
198
269
|
}
|
|
199
270
|
if (validationObj.min && baseSchema instanceof z.ZodNumber) {
|
|
200
|
-
baseSchema = baseSchema.min(
|
|
271
|
+
baseSchema = baseSchema.min(
|
|
272
|
+
validationObj.min.value,
|
|
273
|
+
validationObj.min.message
|
|
274
|
+
);
|
|
201
275
|
}
|
|
202
276
|
if (validationObj.max && baseSchema instanceof z.ZodNumber) {
|
|
203
|
-
baseSchema = baseSchema.max(
|
|
277
|
+
baseSchema = baseSchema.max(
|
|
278
|
+
validationObj.max.value,
|
|
279
|
+
validationObj.max.message
|
|
280
|
+
);
|
|
204
281
|
}
|
|
205
282
|
if (validationObj.minLength && baseSchema instanceof z.ZodString) {
|
|
206
|
-
baseSchema = baseSchema.min(
|
|
283
|
+
baseSchema = baseSchema.min(
|
|
284
|
+
validationObj.minLength.value,
|
|
285
|
+
validationObj.minLength.message
|
|
286
|
+
);
|
|
207
287
|
}
|
|
208
288
|
if (validationObj.maxLength && baseSchema instanceof z.ZodString) {
|
|
209
|
-
baseSchema = baseSchema.max(
|
|
289
|
+
baseSchema = baseSchema.max(
|
|
290
|
+
validationObj.maxLength.value,
|
|
291
|
+
validationObj.maxLength.message
|
|
292
|
+
);
|
|
210
293
|
}
|
|
211
294
|
|
|
212
295
|
return field.required ? baseSchema : baseSchema.optional();
|
|
213
296
|
}
|
|
214
297
|
|
|
215
|
-
let fieldSchema: z.ZodType<
|
|
298
|
+
let fieldSchema: z.ZodType<unknown>;
|
|
216
299
|
|
|
217
300
|
switch (field.type) {
|
|
218
301
|
case 'email':
|
|
@@ -221,60 +304,81 @@ export function FormBuilder({
|
|
|
221
304
|
case 'number':
|
|
222
305
|
fieldSchema = z.number();
|
|
223
306
|
break;
|
|
224
|
-
case '
|
|
225
|
-
|
|
307
|
+
case 'date_picker':
|
|
308
|
+
case 'month':
|
|
309
|
+
case 'date':
|
|
310
|
+
fieldSchema = z.date();
|
|
311
|
+
break;
|
|
312
|
+
case 'date_range':
|
|
313
|
+
fieldSchema = z
|
|
314
|
+
.object({ from: z.date().optional().nullable(), to: z.date().optional().nullable() })
|
|
315
|
+
.nullable();
|
|
226
316
|
break;
|
|
317
|
+
case 'month_range':
|
|
318
|
+
fieldSchema = z
|
|
319
|
+
.object({ start: z.date().optional().nullable(), end: z.date().optional().nullable() })
|
|
320
|
+
.nullable();
|
|
321
|
+
break;
|
|
322
|
+
case 'autocomplete': {
|
|
323
|
+
const single = z
|
|
324
|
+
.union([z.string(), z.number(), z.object({})])
|
|
325
|
+
.nullable();
|
|
326
|
+
const multi = z.array(
|
|
327
|
+
z.union([z.string(), z.number(), z.object({})])
|
|
328
|
+
);
|
|
329
|
+
fieldSchema = field.multiple ? multi : single;
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
227
332
|
case 'checkbox':
|
|
228
333
|
case 'switch':
|
|
229
334
|
fieldSchema = z.boolean();
|
|
230
335
|
break;
|
|
231
|
-
case 'date':
|
|
232
|
-
fieldSchema = z.date();
|
|
233
|
-
break;
|
|
234
336
|
case 'select':
|
|
235
337
|
case 'radio':
|
|
236
338
|
if (field.options && field.options.length > 0) {
|
|
237
339
|
// Build a union of literals to allow specific values, including null if present
|
|
238
|
-
const literals = field.options.map(opt =>
|
|
340
|
+
const literals: Array<z.ZodLiteral<string | number | null>> = field.options.map((opt) =>
|
|
341
|
+
z.literal(opt.value as string | number | null)
|
|
342
|
+
);
|
|
239
343
|
if (literals.length === 1) {
|
|
240
344
|
fieldSchema = literals[0];
|
|
345
|
+
} else {
|
|
346
|
+
fieldSchema = z.union(
|
|
347
|
+
literals as [
|
|
348
|
+
z.ZodLiteral<string | number | null>,
|
|
349
|
+
...z.ZodLiteral<string | number | null>[]
|
|
350
|
+
]
|
|
351
|
+
);
|
|
241
352
|
}
|
|
242
|
-
|
|
243
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
244
|
-
fieldSchema = z.union(literals as any);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
353
|
+
} else {
|
|
248
354
|
fieldSchema = z.string();
|
|
249
355
|
}
|
|
250
356
|
break;
|
|
251
357
|
case 'object':
|
|
252
358
|
if (field.fields) {
|
|
253
|
-
const objectSchema: Record<string, z.ZodType<
|
|
254
|
-
field.fields
|
|
359
|
+
const objectSchema: Record<string, z.ZodType<unknown>> = {};
|
|
360
|
+
for (const subField of field.fields) {
|
|
255
361
|
objectSchema[subField.name] = generateFieldSchema(subField);
|
|
256
|
-
}
|
|
362
|
+
}
|
|
257
363
|
fieldSchema = z.object(objectSchema);
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
364
|
+
} else {
|
|
260
365
|
fieldSchema = z.object({});
|
|
261
366
|
}
|
|
262
367
|
break;
|
|
263
368
|
case 'array':
|
|
264
369
|
if (field.fields && field.fields.length > 0) {
|
|
265
|
-
const arrayItemSchema
|
|
266
|
-
|
|
370
|
+
const arrayItemSchema =
|
|
371
|
+
field.fields.length === 1
|
|
267
372
|
? generateFieldSchema(field.fields[0])
|
|
268
373
|
: z.object(
|
|
269
374
|
field.fields.reduce((acc, subField) => {
|
|
270
375
|
acc[subField.name] = generateFieldSchema(subField);
|
|
271
376
|
return acc;
|
|
272
|
-
}, {} as Record<string, z.ZodType<
|
|
377
|
+
}, {} as Record<string, z.ZodType<unknown>>)
|
|
273
378
|
);
|
|
274
379
|
fieldSchema = z.array(arrayItemSchema);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
fieldSchema = z.array(z.any());
|
|
380
|
+
} else {
|
|
381
|
+
fieldSchema = z.array(z.unknown());
|
|
278
382
|
}
|
|
279
383
|
break;
|
|
280
384
|
default:
|
|
@@ -284,39 +388,53 @@ export function FormBuilder({
|
|
|
284
388
|
return field.required ? fieldSchema : fieldSchema.optional();
|
|
285
389
|
};
|
|
286
390
|
|
|
287
|
-
const schemaObject: Record<string, z.ZodType<
|
|
391
|
+
const schemaObject: Record<string, z.ZodType<unknown>> = {};
|
|
288
392
|
|
|
289
|
-
|
|
290
|
-
section
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
393
|
+
const forEachField = (secs: FormBuilderSectionConfig[]) => {
|
|
394
|
+
for (const section of secs) {
|
|
395
|
+
// Traverse tabs if present
|
|
396
|
+
if (section.tabs && section.tabs.length > 0) {
|
|
397
|
+
for (const tab of section.tabs) {
|
|
398
|
+
forEachField(tab.sections);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
for (const field of (section.fields ?? [])) {
|
|
402
|
+
schemaObject[field.name] = generateFieldSchema(field);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
forEachField(sections);
|
|
294
408
|
|
|
295
409
|
return z.object(schemaObject);
|
|
296
410
|
}, [sections, schema]);
|
|
297
411
|
|
|
298
412
|
// Generate default values from field configs
|
|
299
413
|
const generatedDefaultValues = useMemo(() => {
|
|
300
|
-
const values: Record<string,
|
|
414
|
+
const values: Record<string, unknown> = { ...defaultValues };
|
|
301
415
|
|
|
302
416
|
const processFields = (fields: FormBuilderFieldConfig[]) => {
|
|
303
|
-
|
|
417
|
+
for (const field of fields) {
|
|
304
418
|
if (
|
|
305
|
-
values[field.name] === undefined
|
|
306
|
-
|
|
419
|
+
values[field.name] === undefined &&
|
|
420
|
+
field.defaultValue !== undefined
|
|
307
421
|
) {
|
|
308
422
|
values[field.name] = field.defaultValue;
|
|
309
423
|
}
|
|
310
424
|
|
|
311
425
|
if (field.type === 'object' && field.fields) {
|
|
312
426
|
if (!values[field.name]) values[field.name] = {};
|
|
313
|
-
const nestedValues: Record<string,
|
|
314
|
-
field.fields
|
|
427
|
+
const nestedValues: Record<string, unknown> = {};
|
|
428
|
+
for (const subField of field.fields) {
|
|
315
429
|
if (subField.defaultValue !== undefined) {
|
|
316
430
|
nestedValues[subField.name] = subField.defaultValue;
|
|
317
431
|
}
|
|
318
|
-
}
|
|
319
|
-
|
|
432
|
+
}
|
|
433
|
+
const existing =
|
|
434
|
+
values[field.name] && typeof values[field.name] === 'object'
|
|
435
|
+
? (values[field.name] as Record<string, unknown>)
|
|
436
|
+
: {};
|
|
437
|
+
values[field.name] = { ...nestedValues, ...existing };
|
|
320
438
|
}
|
|
321
439
|
|
|
322
440
|
if (field.type === 'array' && field.fields) {
|
|
@@ -324,17 +442,30 @@ export function FormBuilder({
|
|
|
324
442
|
values[field.name] = field.defaultValue || [];
|
|
325
443
|
}
|
|
326
444
|
}
|
|
327
|
-
}
|
|
445
|
+
}
|
|
328
446
|
};
|
|
329
447
|
|
|
330
|
-
|
|
448
|
+
const forEachSection = (secs: FormBuilderSectionConfig[]) => {
|
|
449
|
+
for (const section of secs) {
|
|
450
|
+
if (section.tabs && section.tabs.length > 0) {
|
|
451
|
+
for (const tab of section.tabs) {
|
|
452
|
+
forEachSection(tab.sections);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
processFields(section.fields ?? []);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
forEachSection(sections);
|
|
331
460
|
|
|
332
461
|
return values;
|
|
333
462
|
}, [sections, defaultValues]);
|
|
334
463
|
|
|
335
|
-
const form = useForm<
|
|
336
|
-
|
|
337
|
-
|
|
464
|
+
const form = useForm<FieldValues>({
|
|
465
|
+
// Dynamic schema shape: cast to any to satisfy resolver generics
|
|
466
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
467
|
+
resolver: zodResolver(generatedSchema as any) as unknown as import('react-hook-form').Resolver<FieldValues, any, FieldValues>,
|
|
468
|
+
defaultValues: generatedDefaultValues as FieldValues,
|
|
338
469
|
});
|
|
339
470
|
|
|
340
471
|
const { control, handleSubmit, reset, setValue, getValues } = form;
|
|
@@ -342,11 +473,21 @@ export function FormBuilder({
|
|
|
342
473
|
// Determine dependency fields to watch
|
|
343
474
|
const dependencyFields = useMemo(() => {
|
|
344
475
|
const set = new Set<string>();
|
|
345
|
-
|
|
346
|
-
section
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
476
|
+
const forEachField = (secs: FormBuilderSectionConfig[]) => {
|
|
477
|
+
for (const section of secs) {
|
|
478
|
+
if (section.tabs && section.tabs.length > 0) {
|
|
479
|
+
for (const tab of section.tabs) {
|
|
480
|
+
forEachField(tab.sections);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
for (const f of (section.fields ?? [])) {
|
|
484
|
+
for (const d of f.dependencies || []) {
|
|
485
|
+
set.add(d.field);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
forEachField(sections);
|
|
350
491
|
return Array.from(set);
|
|
351
492
|
}, [sections]);
|
|
352
493
|
|
|
@@ -356,16 +497,20 @@ export function FormBuilder({
|
|
|
356
497
|
// Always call useWatch to satisfy hooks rules. Passing an empty array is safe and returns an empty array.
|
|
357
498
|
const depValuesArr = useWatch({ control, name: dependencyFields });
|
|
358
499
|
const watchedValues = useMemo(() => {
|
|
359
|
-
if (!hasDependencies) return {} as Record<string,
|
|
360
|
-
const obj: Record<string,
|
|
361
|
-
dependencyFields.forEach((n, i) => {
|
|
500
|
+
if (!hasDependencies) return {} as Record<string, unknown>;
|
|
501
|
+
const obj: Record<string, unknown> = {};
|
|
502
|
+
dependencyFields.forEach((n, i) => {
|
|
503
|
+
obj[n] = (depValuesArr as unknown[])[i];
|
|
504
|
+
});
|
|
362
505
|
return obj;
|
|
363
506
|
// dependencyFields is stable from sections; depValuesArr changes only when values change
|
|
364
507
|
}, [hasDependencies, dependencyFields, depValuesArr]);
|
|
365
508
|
|
|
366
509
|
// Handle field dependencies
|
|
367
510
|
// Queue dependency-driven value updates to avoid calling setValue during render
|
|
368
|
-
const pendingValueUpdatesRef = useRef<Array<{ name: string; value:
|
|
511
|
+
const pendingValueUpdatesRef = useRef<Array<{ name: string; value: unknown }>>(
|
|
512
|
+
[]
|
|
513
|
+
);
|
|
369
514
|
|
|
370
515
|
const handleFieldDependencies = useCallback(
|
|
371
516
|
(field: FormBuilderFieldConfig) => {
|
|
@@ -373,7 +518,7 @@ export function FormBuilder({
|
|
|
373
518
|
|
|
374
519
|
const result: { disabled?: boolean; hidden?: boolean } = {};
|
|
375
520
|
|
|
376
|
-
field.dependencies
|
|
521
|
+
for (const dep of field.dependencies) {
|
|
377
522
|
const dependentValue = watchedValues[dep.field];
|
|
378
523
|
const conditionMet = dep.condition(dependentValue);
|
|
379
524
|
|
|
@@ -395,53 +540,61 @@ export function FormBuilder({
|
|
|
395
540
|
const currentValue = getValues(field.name);
|
|
396
541
|
if (currentValue !== dep.value) {
|
|
397
542
|
// Defer the update to an effect to prevent state changes during render
|
|
398
|
-
pendingValueUpdatesRef.current.push({
|
|
543
|
+
pendingValueUpdatesRef.current.push({
|
|
544
|
+
name: field.name,
|
|
545
|
+
value: dep.value,
|
|
546
|
+
});
|
|
399
547
|
}
|
|
400
548
|
}
|
|
401
549
|
break;
|
|
402
550
|
}
|
|
403
|
-
}
|
|
551
|
+
}
|
|
404
552
|
|
|
405
553
|
return result;
|
|
406
554
|
},
|
|
407
|
-
[hasDependencies, watchedValues, getValues]
|
|
555
|
+
[hasDependencies, watchedValues, getValues]
|
|
408
556
|
);
|
|
409
557
|
|
|
410
558
|
// Flush any pending setValue updates after watchedValues change
|
|
411
559
|
useEffect(() => {
|
|
412
560
|
if (pendingValueUpdatesRef.current.length === 0) return;
|
|
413
|
-
const updatesMap = new Map<string,
|
|
561
|
+
const updatesMap = new Map<string, unknown>();
|
|
414
562
|
// last write wins per field
|
|
415
|
-
|
|
563
|
+
for (const { name, value } of pendingValueUpdatesRef.current) {
|
|
564
|
+
updatesMap.set(name, value);
|
|
565
|
+
}
|
|
416
566
|
pendingValueUpdatesRef.current = [];
|
|
417
|
-
|
|
567
|
+
for (const [name, value] of updatesMap) {
|
|
418
568
|
const current = getValues(name);
|
|
419
569
|
if (current !== value) {
|
|
420
|
-
setValue(name, value, {
|
|
570
|
+
setValue(name, value, {
|
|
571
|
+
shouldDirty: false,
|
|
572
|
+
shouldTouch: false,
|
|
573
|
+
shouldValidate: false,
|
|
574
|
+
});
|
|
421
575
|
}
|
|
422
|
-
}
|
|
423
|
-
}, [
|
|
576
|
+
}
|
|
577
|
+
}, [setValue, getValues]);
|
|
424
578
|
|
|
425
579
|
// Handle field change with custom onChange
|
|
426
580
|
const handleFieldChange = useCallback(
|
|
427
|
-
(field: FormBuilderFieldConfig, value:
|
|
581
|
+
(field: FormBuilderFieldConfig, value: unknown) => {
|
|
428
582
|
if (field.onChange) {
|
|
429
583
|
field.onChange(value, setValue, getValues);
|
|
430
584
|
}
|
|
431
585
|
},
|
|
432
|
-
[setValue, getValues]
|
|
586
|
+
[setValue, getValues]
|
|
433
587
|
);
|
|
434
588
|
|
|
435
589
|
const handleFormSubmit = useCallback(
|
|
436
|
-
async (data:
|
|
590
|
+
async (data: unknown) => {
|
|
437
591
|
try {
|
|
438
592
|
await onSubmit(data);
|
|
439
|
-
}
|
|
440
|
-
catch (error) {
|
|
593
|
+
} catch (error) {
|
|
441
594
|
console.error('Form submission error:', error);
|
|
442
595
|
}
|
|
443
596
|
},
|
|
444
|
-
[onSubmit]
|
|
597
|
+
[onSubmit]
|
|
445
598
|
);
|
|
446
599
|
|
|
447
600
|
const handleReset = useCallback(() => {
|
|
@@ -451,52 +604,103 @@ export function FormBuilder({
|
|
|
451
604
|
|
|
452
605
|
// Build SectionBuilder nodes from form sections/fields
|
|
453
606
|
const sectionNodes: SectionNode[] = useMemo(() => {
|
|
454
|
-
|
|
455
|
-
|
|
607
|
+
const buildLeavesFromFields = (fields?: FormBuilderFieldConfig[]): SectionNode['children'] =>
|
|
608
|
+
(fields ?? [])
|
|
609
|
+
.map((field) => {
|
|
610
|
+
const fieldState = handleFieldDependencies(field);
|
|
611
|
+
if (field.hidden || fieldState.hidden) return null;
|
|
612
|
+
|
|
613
|
+
const spanMd = Math.max(1, Math.min(12, field.gridCols ?? 1));
|
|
614
|
+
|
|
615
|
+
return {
|
|
616
|
+
key: field.name,
|
|
617
|
+
span: { base: 1, md: spanMd },
|
|
618
|
+
className: field.wrapperClassName,
|
|
619
|
+
hidden: field.hidden,
|
|
620
|
+
content: (
|
|
621
|
+
<FormBuilderField
|
|
622
|
+
key={field.name}
|
|
623
|
+
field={{
|
|
624
|
+
...field,
|
|
625
|
+
disabled: field.disabled || fieldState.disabled,
|
|
626
|
+
}}
|
|
627
|
+
control={control}
|
|
628
|
+
onChange={(value) => {
|
|
629
|
+
handleFieldChange(field, value);
|
|
630
|
+
onFieldChange?.(field.name, value, getValues());
|
|
631
|
+
}}
|
|
632
|
+
onFieldChange={onFieldChange}
|
|
633
|
+
/>
|
|
634
|
+
),
|
|
635
|
+
};
|
|
636
|
+
})
|
|
637
|
+
.filter(Boolean) as SectionNode['children'];
|
|
638
|
+
|
|
639
|
+
const buildSectionNode = (
|
|
640
|
+
section: FormBuilderSectionConfig,
|
|
641
|
+
sectionIndex: number,
|
|
642
|
+
): SectionNode => {
|
|
643
|
+
const baseNode: SectionNode = {
|
|
456
644
|
id: section.id ?? `section-${sectionIndex}`,
|
|
457
645
|
title: section.title,
|
|
458
646
|
subtitle: section.description,
|
|
459
647
|
variant: section.variant ?? 'plain',
|
|
460
648
|
className: section.className,
|
|
461
|
-
layout: section.layout ?? 'grid',
|
|
649
|
+
layout: section.layout ?? (section.tabs && section.tabs.length > 0 ? 'tabs' : 'grid'),
|
|
462
650
|
grid: section.grid ?? { cols: 1, mdCols: 2, gap: 'gap-4' },
|
|
463
651
|
flex: section.flex,
|
|
464
652
|
hidden: section.hidden,
|
|
465
|
-
children: section.fields
|
|
466
|
-
.map((field) => {
|
|
467
|
-
const fieldState = handleFieldDependencies(field);
|
|
468
|
-
if (field.hidden || fieldState.hidden) return null;
|
|
469
|
-
|
|
470
|
-
const spanMd = Math.max(1, Math.min(12, field.gridCols ?? 1));
|
|
471
|
-
|
|
472
|
-
return {
|
|
473
|
-
key: field.name,
|
|
474
|
-
span: { base: 1, md: spanMd },
|
|
475
|
-
className: field.wrapperClassName,
|
|
476
|
-
hidden: field.hidden,
|
|
477
|
-
content: (
|
|
478
|
-
<FormBuilderField
|
|
479
|
-
key={field.name}
|
|
480
|
-
field={{ ...field, disabled: field.disabled || fieldState.disabled }}
|
|
481
|
-
control={control}
|
|
482
|
-
onChange={(value) => {
|
|
483
|
-
handleFieldChange(field, value);
|
|
484
|
-
onFieldChange?.(field.name, value, getValues());
|
|
485
|
-
}}
|
|
486
|
-
onFieldChange={onFieldChange}
|
|
487
|
-
/>
|
|
488
|
-
),
|
|
489
|
-
};
|
|
490
|
-
})
|
|
491
|
-
.filter(Boolean) as SectionNode['children'],
|
|
492
653
|
};
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
654
|
+
|
|
655
|
+
// Tabs layout
|
|
656
|
+
if (baseNode.layout === 'tabs' && section.tabs && section.tabs.length > 0) {
|
|
657
|
+
baseNode.defaultTabId = section.defaultTabId ?? section.tabs[0]?.id;
|
|
658
|
+
baseNode.tabsListClassName = section.tabsListClassName;
|
|
659
|
+
baseNode.tabsContentClassName = section.tabsContentClassName;
|
|
660
|
+
baseNode.tabs = section.tabs.map((tab, _tabIdx) => {
|
|
661
|
+
// Each tab can contain multiple sub-sections; wrap them under a container node
|
|
662
|
+
const nestedNodes = tab.sections.map((subSection, subIdx) => buildSectionNode(subSection, subIdx));
|
|
663
|
+
const containerNode: SectionNode = {
|
|
664
|
+
id: `${baseNode.id}-tab-${tab.id}`,
|
|
665
|
+
title: undefined,
|
|
666
|
+
subtitle: undefined,
|
|
667
|
+
variant: 'plain',
|
|
668
|
+
layout: 'grid',
|
|
669
|
+
grid: section.grid ?? { cols: 1, mdCols: 2, gap: 'gap-4' },
|
|
670
|
+
children: nestedNodes,
|
|
671
|
+
} as SectionNode;
|
|
672
|
+
return {
|
|
673
|
+
id: tab.id,
|
|
674
|
+
label: tab.label,
|
|
675
|
+
className: tab.className,
|
|
676
|
+
contentClassName: tab.contentClassName,
|
|
677
|
+
node: containerNode,
|
|
678
|
+
};
|
|
679
|
+
});
|
|
680
|
+
return baseNode;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Regular non-tab section with direct fields
|
|
684
|
+
baseNode.children = buildLeavesFromFields(section.fields);
|
|
685
|
+
return baseNode;
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
return sections.map((section, sectionIndex) => buildSectionNode(section, sectionIndex));
|
|
689
|
+
}, [
|
|
690
|
+
sections,
|
|
691
|
+
control,
|
|
692
|
+
handleFieldDependencies,
|
|
693
|
+
handleFieldChange,
|
|
694
|
+
onFieldChange,
|
|
695
|
+
getValues,
|
|
696
|
+
]);
|
|
496
697
|
|
|
497
698
|
return (
|
|
498
699
|
<div className={cn('space-y-6', className)}>
|
|
499
|
-
<form
|
|
700
|
+
<form
|
|
701
|
+
onSubmit={handleSubmit(handleFormSubmit)}
|
|
702
|
+
className={cn('space-y-6', formClassName)}
|
|
703
|
+
>
|
|
500
704
|
<SectionBuilder sections={sectionNodes} />
|
|
501
705
|
|
|
502
706
|
{showActions && (
|
|
@@ -505,21 +709,35 @@ export function FormBuilder({
|
|
|
505
709
|
'flex flex-col sm:flex-row gap-3',
|
|
506
710
|
showActionsSeparator && 'pt-6',
|
|
507
711
|
showActionsSeparator && 'border-t',
|
|
508
|
-
actionsClassName
|
|
712
|
+
actionsClassName
|
|
509
713
|
)}
|
|
510
714
|
>
|
|
511
|
-
<Button
|
|
715
|
+
<Button
|
|
716
|
+
type="submit"
|
|
717
|
+
disabled={isSubmitting}
|
|
718
|
+
className="sm:order-last"
|
|
719
|
+
>
|
|
512
720
|
{isSubmitting ? 'Submitting...' : submitLabel}
|
|
513
721
|
</Button>
|
|
514
722
|
|
|
515
723
|
{onCancel && (
|
|
516
|
-
<Button
|
|
724
|
+
<Button
|
|
725
|
+
type="button"
|
|
726
|
+
variant="outline"
|
|
727
|
+
onClick={onCancel}
|
|
728
|
+
disabled={isSubmitting}
|
|
729
|
+
>
|
|
517
730
|
{cancelLabel}
|
|
518
731
|
</Button>
|
|
519
732
|
)}
|
|
520
733
|
|
|
521
734
|
{onReset && (
|
|
522
|
-
<Button
|
|
735
|
+
<Button
|
|
736
|
+
type="button"
|
|
737
|
+
variant="outline"
|
|
738
|
+
onClick={handleReset}
|
|
739
|
+
disabled={isSubmitting}
|
|
740
|
+
>
|
|
523
741
|
{resetLabel}
|
|
524
742
|
</Button>
|
|
525
743
|
)}
|