@keboola/design 11.0.0 → 11.2.0
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/AGENTS.md +16 -1
- package/CHANGELOG.md +2138 -0
- package/COMPONENT-API.md +40 -1
- package/dist/AIKit-DiS0CVOW.js +1320 -0
- package/dist/AIKit-DiS0CVOW.js.map +1 -0
- package/dist/Alert-DfZq9kGe.js +133 -0
- package/dist/Alert-DfZq9kGe.js.map +1 -0
- package/dist/AlertModal-Dp_XuJBW.js +219 -0
- package/dist/AlertModal-Dp_XuJBW.js.map +1 -0
- package/dist/AppShell-B5GQN6Zs.js +143 -0
- package/dist/AppShell-B5GQN6Zs.js.map +1 -0
- package/dist/AutoSaveTextarea-BeuWuszr.js +58 -0
- package/dist/{chunk-UGT6DKWM.js.map → AutoSaveTextarea-BeuWuszr.js.map} +1 -1
- package/dist/Badge-Ch26CXoP.js +195 -0
- package/dist/Badge-Ch26CXoP.js.map +1 -0
- package/dist/BrandEditor-DyzgfVkl.js +903 -0
- package/dist/BrandEditor-DyzgfVkl.js.map +1 -0
- package/dist/BrandLogo-CJkRd0F8.js +46 -0
- package/dist/BrandLogo-CJkRd0F8.js.map +1 -0
- package/dist/Breadcrumb-Frst8MTA.js +330 -0
- package/dist/Breadcrumb-Frst8MTA.js.map +1 -0
- package/dist/Button-6xBX0nNl.js +391 -0
- package/dist/Button-6xBX0nNl.js.map +1 -0
- package/dist/Calendar-cG5NIJ4O.js +6768 -0
- package/dist/Calendar-cG5NIJ4O.js.map +1 -0
- package/dist/Card-BAoZ35CV.js +105 -0
- package/dist/Card-BAoZ35CV.js.map +1 -0
- package/dist/Checkbox-GJ8-srt4.js +97 -0
- package/dist/Checkbox-GJ8-srt4.js.map +1 -0
- package/dist/Clipboard-CBJZiviP.js +58 -0
- package/dist/Clipboard-CBJZiviP.js.map +1 -0
- package/dist/ClipboardButton-ClcluT0C.js +43 -0
- package/dist/ClipboardButton-ClcluT0C.js.map +1 -0
- package/dist/CodeEditor-DyaN-Ij2.js +1000 -0
- package/dist/CodeEditor-DyaN-Ij2.js.map +1 -0
- package/dist/Collapsible-BQXWEOBC.js +34 -0
- package/dist/Collapsible-BQXWEOBC.js.map +1 -0
- package/dist/ColorInput-B8z4j4Y_.js +180 -0
- package/dist/ColorInput-B8z4j4Y_.js.map +1 -0
- package/dist/ColorModeSwitch-dZFZyqy1.js +77 -0
- package/dist/ColorModeSwitch-dZFZyqy1.js.map +1 -0
- package/dist/Combobox-Dgm6Z4ib.js +443 -0
- package/dist/Combobox-Dgm6Z4ib.js.map +1 -0
- package/dist/Command-C0aZfVTq.js +102 -0
- package/dist/Command-C0aZfVTq.js.map +1 -0
- package/dist/CopyField-BJ96zvXs.js +322 -0
- package/dist/CopyField-BJ96zvXs.js.map +1 -0
- package/dist/DateInput-B3UdzRfW.js +141 -0
- package/dist/DateInput-B3UdzRfW.js.map +1 -0
- package/dist/DatePicker-Dw3DpbUh.js +24 -0
- package/dist/DatePicker-Dw3DpbUh.js.map +1 -0
- package/dist/DateRangeInput-DTuySEiq.js +139 -0
- package/dist/DateRangeInput-DTuySEiq.js.map +1 -0
- package/dist/DateRangePicker-DCmMHg4s.js +159 -0
- package/dist/DateRangePicker-DCmMHg4s.js.map +1 -0
- package/dist/DiagramSkeleton-lwBS2YBa.js +11 -0
- package/dist/DiagramSkeleton-lwBS2YBa.js.map +1 -0
- package/dist/DiffView-ppTIzh2h.js +429 -0
- package/dist/DiffView-ppTIzh2h.js.map +1 -0
- package/dist/DropdownMenu-t90tVw6l.js +327 -0
- package/dist/DropdownMenu-t90tVw6l.js.map +1 -0
- package/dist/FieldBox-D7DYtX_m.js +70 -0
- package/dist/FieldBox-D7DYtX_m.js.map +1 -0
- package/dist/FieldItem-CAPj9lj3.d.ts +111 -0
- package/dist/FieldItem-D-h1NeBo.js +108 -0
- package/dist/FieldItem-D-h1NeBo.js.map +1 -0
- package/dist/FileUpload-BRv0TaZk.js +2527 -0
- package/dist/FileUpload-BRv0TaZk.js.map +1 -0
- package/dist/Form-DHvcFoEi.js +311 -0
- package/dist/Form-DHvcFoEi.js.map +1 -0
- package/dist/FormGroup-C41n65cE.js +124 -0
- package/dist/FormGroup-C41n65cE.js.map +1 -0
- package/dist/FullScreenModal-Cb3PGgh4.js +96 -0
- package/dist/FullScreenModal-Cb3PGgh4.js.map +1 -0
- package/dist/HoverCard-WfDkLK1s.js +31 -0
- package/dist/HoverCard-WfDkLK1s.js.map +1 -0
- package/dist/InputGroup-CdTq8H7c.js +292 -0
- package/dist/InputGroup-CdTq8H7c.js.map +1 -0
- package/dist/Kbd-CxHAo1oo.js +111 -0
- package/dist/Kbd-CxHAo1oo.js.map +1 -0
- package/dist/MarkedText-Ckbft5mw.js +44 -0
- package/dist/MarkedText-Ckbft5mw.js.map +1 -0
- package/dist/MermaidDiagram-ChL3WIQT.js +399 -0
- package/dist/MermaidDiagram-ChL3WIQT.js.map +1 -0
- package/dist/Modal-wqG8nJiK.js +185 -0
- package/dist/Modal-wqG8nJiK.js.map +1 -0
- package/dist/ModalTitle-C76ke2eo.js +28 -0
- package/dist/ModalTitle-C76ke2eo.js.map +1 -0
- package/dist/MultiActionButtonGroup-BiIIubiL.js +33 -0
- package/dist/MultiActionButtonGroup-BiIIubiL.js.map +1 -0
- package/dist/Navbar-BfaPeLUL.js +325 -0
- package/dist/Navbar-BfaPeLUL.js.map +1 -0
- package/dist/OtpInput-CbbymqYs.js +93 -0
- package/dist/OtpInput-CbbymqYs.js.map +1 -0
- package/dist/PageHeader-Q3IpCnQd.js +177 -0
- package/dist/PageHeader-Q3IpCnQd.js.map +1 -0
- package/dist/PageLayout-DSVM-ASz.js +176 -0
- package/dist/PageLayout-DSVM-ASz.js.map +1 -0
- package/dist/PageToolbar-OQg3mPF-.js +153 -0
- package/dist/PageToolbar-OQg3mPF-.js.map +1 -0
- package/dist/Pagination-Cjfda8KG.js +70 -0
- package/dist/Pagination-Cjfda8KG.js.map +1 -0
- package/dist/Popconfirm-D7_vfxFd.js +167 -0
- package/dist/Popconfirm-D7_vfxFd.js.map +1 -0
- package/dist/Popover-CzeHjvrB.js +85 -0
- package/dist/Popover-CzeHjvrB.js.map +1 -0
- package/dist/RadioGroup-sIveSsNa.js +233 -0
- package/dist/RadioGroup-sIveSsNa.js.map +1 -0
- package/dist/Resizable-D3vYToZH.js +52 -0
- package/dist/Resizable-D3vYToZH.js.map +1 -0
- package/dist/Search-3UiqNZRj.js +184 -0
- package/dist/Search-3UiqNZRj.js.map +1 -0
- package/dist/SearchInput-C7dF_Ir-.js +102 -0
- package/dist/SearchInput-C7dF_Ir-.js.map +1 -0
- package/dist/SectionNav-8NoTOKO8.js +276 -0
- package/dist/SectionNav-8NoTOKO8.js.map +1 -0
- package/dist/Select-Is0VkePH.js +181 -0
- package/dist/Select-Is0VkePH.js.map +1 -0
- package/dist/Sheet-Dw9BDvjI.js +169 -0
- package/dist/Sheet-Dw9BDvjI.js.map +1 -0
- package/dist/Sidebar-Dcb4rinA.js +799 -0
- package/dist/Sidebar-Dcb4rinA.js.map +1 -0
- package/dist/Slider-BOPfMOMm.js +127 -0
- package/dist/Slider-BOPfMOMm.js.map +1 -0
- package/dist/Stepper-C8sm9ZFM.js +325 -0
- package/dist/Stepper-C8sm9ZFM.js.map +1 -0
- package/dist/Switch-CX2A0v50.js +201 -0
- package/dist/Switch-CX2A0v50.js.map +1 -0
- package/dist/Table-CvYuTuNU.js +104 -0
- package/dist/Table-CvYuTuNU.js.map +1 -0
- package/dist/Tabs-UMQuDoW8.js +74 -0
- package/dist/Tabs-UMQuDoW8.js.map +1 -0
- package/dist/TextInput-CMuN1WfY.js +110 -0
- package/dist/TextInput-CMuN1WfY.js.map +1 -0
- package/dist/ThemeProvider-QncUrfJn.js +203 -0
- package/dist/ThemeProvider-QncUrfJn.js.map +1 -0
- package/dist/TimePicker-D9zktB8A.js +98 -0
- package/dist/TimePicker-D9zktB8A.js.map +1 -0
- package/dist/Timeline-6btyJl4D.js +154 -0
- package/dist/Timeline-6btyJl4D.js.map +1 -0
- package/dist/Toast-DQSbs3oA.js +49 -0
- package/dist/Toast-DQSbs3oA.js.map +1 -0
- package/dist/ToggleGroup-Cy_10Mvu.js +47 -0
- package/dist/ToggleGroup-Cy_10Mvu.js.map +1 -0
- package/dist/Workbench-BzE-Vvd9.js +293 -0
- package/dist/Workbench-BzE-Vvd9.js.map +1 -0
- package/dist/ZoomableSvg-CZEu6sAq.js +248 -0
- package/dist/ZoomableSvg-CZEu6sAq.js.map +1 -0
- package/dist/charts.d.ts +110 -103
- package/dist/charts.js +303 -254
- package/dist/charts.js.map +1 -1
- package/dist/classNames-BzrkDnOD.js +9 -0
- package/dist/classNames-BzrkDnOD.js.map +1 -0
- package/dist/context-KxxeMHbR.js +62 -0
- package/dist/context-KxxeMHbR.js.map +1 -0
- package/dist/editors.d.ts +244 -175
- package/dist/editors.js +802 -428
- package/dist/editors.js.map +1 -1
- package/dist/escapeStringRegexp-8MxP2knR.js +6 -0
- package/dist/escapeStringRegexp-8MxP2knR.js.map +1 -0
- package/dist/icons-Cek151jC.js +640 -0
- package/dist/icons-Cek151jC.js.map +1 -0
- package/dist/icons.d.ts +2 -41
- package/dist/icons.js +2 -9
- package/dist/index-m-kQEWiY.d.ts +54 -0
- package/dist/index.d.ts +6191 -9891
- package/dist/index.js +113 -124
- package/dist/internal/blocks/AIKit.js +2 -30
- package/dist/internal/blocks/AppShell.js +2 -11
- package/dist/internal/blocks/AutoSaveTextarea.js +2 -14
- package/dist/internal/blocks/BrandEditor.js +2 -23
- package/dist/internal/blocks/ChartPanel.js +45 -9
- package/dist/internal/blocks/ChartPanel.js.map +1 -1
- package/dist/internal/blocks/ClipboardButton.js +2 -12
- package/dist/internal/blocks/ColorInput.js +2 -13
- package/dist/internal/blocks/ColorModeSwitch.js +2 -13
- package/dist/internal/blocks/Command.js +2 -15
- package/dist/internal/blocks/CopyField.js +2 -11
- package/dist/internal/blocks/DashboardHero.js +58 -8
- package/dist/internal/blocks/DashboardHero.js.map +1 -1
- package/dist/internal/blocks/DateInput.js +2 -16
- package/dist/internal/blocks/DateRangeInput.js +2 -16
- package/dist/internal/blocks/EmptyConfigurationActionCard.js +15 -9
- package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -1
- package/dist/internal/blocks/EmptyState.js +141 -3
- package/dist/internal/blocks/EmptyState.js.map +1 -1
- package/dist/internal/blocks/ErrorState.js +178 -4
- package/dist/internal/blocks/ErrorState.js.map +1 -1
- package/dist/internal/blocks/ExportMenu.js +40 -12
- package/dist/internal/blocks/ExportMenu.js.map +1 -1
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +56 -0
- package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -0
- package/dist/internal/blocks/Form.js +2 -29
- package/dist/internal/blocks/FormGroup.js +2 -18
- package/dist/internal/blocks/GoogleButton.js +94 -9
- package/dist/internal/blocks/GoogleButton.js.map +1 -1
- package/dist/internal/blocks/MicrosoftButton.js +63 -9
- package/dist/internal/blocks/MicrosoftButton.js.map +1 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js +2 -12
- package/dist/internal/blocks/MultiCombobox.js +192 -13
- package/dist/internal/blocks/MultiCombobox.js.map +1 -1
- package/dist/internal/blocks/NumberInput.js +43 -11
- package/dist/internal/blocks/NumberInput.js.map +1 -1
- package/dist/internal/blocks/OtpInput.js +2 -10
- package/dist/internal/blocks/PageHeader.js +2 -9
- package/dist/internal/blocks/PageLayout.js +2 -9
- package/dist/internal/blocks/PageToolbar.js +2 -13
- package/dist/internal/blocks/PasswordInput.js +96 -12
- package/dist/internal/blocks/PasswordInput.js.map +1 -1
- package/dist/internal/blocks/SearchInput.js +2 -12
- package/dist/internal/blocks/SearchInputWithNavigation.js +64 -15
- package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -1
- package/dist/internal/blocks/SectionNav.js +2 -15
- package/dist/internal/blocks/SplitButton.js +45 -13
- package/dist/internal/blocks/SplitButton.js.map +1 -1
- package/dist/internal/blocks/StatCard.js +96 -9
- package/dist/internal/blocks/StatCard.js.map +1 -1
- package/dist/internal/blocks/TextInput.js +2 -13
- package/dist/internal/blocks/Textarea.js +31 -12
- package/dist/internal/blocks/Textarea.js.map +1 -1
- package/dist/internal/blocks/TimeInput.js +76 -16
- package/dist/internal/blocks/TimeInput.js.map +1 -1
- package/dist/internal/components/Alert.js +2 -11
- package/dist/internal/components/AlertModal.js +2 -11
- package/dist/internal/components/Avatar.js +52 -8
- package/dist/internal/components/Avatar.js.map +1 -1
- package/dist/internal/components/Badge.js +2 -9
- package/dist/internal/components/BrandLogo.js +2 -11
- package/dist/internal/components/Breadcrumb.js +2 -14
- package/dist/internal/components/Button.js +2 -10
- package/dist/internal/components/ButtonGroup.js +65 -8
- package/dist/internal/components/ButtonGroup.js.map +1 -1
- package/dist/internal/components/Calendar.js +2 -9
- package/dist/internal/components/Card.js +2 -9
- package/dist/internal/components/Checkbox.js +2 -11
- package/dist/internal/components/Clipboard.js +2 -9
- package/dist/internal/components/Collapsible.js +2 -9
- package/dist/internal/components/CollapsiblePanel.js +86 -10
- package/dist/internal/components/CollapsiblePanel.js.map +1 -1
- package/dist/internal/components/Combobox.js +2 -13
- package/dist/internal/components/DatePicker.js +2 -11
- package/dist/internal/components/DateRangePicker.js +2 -17
- package/dist/internal/components/DiffView.js +2 -9
- package/dist/internal/components/DotsLoader.js +17 -4
- package/dist/internal/components/DotsLoader.js.map +1 -1
- package/dist/internal/components/DropdownMenu.js +2 -11
- package/dist/internal/components/EmptySearchContent.js +11 -3
- package/dist/internal/components/EmptySearchContent.js.map +1 -1
- package/dist/internal/components/FileUpload.js +2 -11
- package/dist/internal/components/FullScreenModal.js +2 -12
- package/dist/internal/components/HelpBlock.js +24 -3
- package/dist/internal/components/HelpBlock.js.map +1 -1
- package/dist/internal/components/HoverCard.js +2 -9
- package/dist/internal/components/InputGroup.js +2 -11
- package/dist/internal/components/Kbd.js +2 -9
- package/dist/internal/components/Label.js +38 -8
- package/dist/internal/components/Label.js.map +1 -1
- package/dist/internal/components/Link.js +21 -8
- package/dist/internal/components/Link.js.map +1 -1
- package/dist/internal/components/MarkedText.js +2 -5
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +19 -9
- package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -1
- package/dist/internal/components/MergeEditor/PaneHeader.js +12 -3
- package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -1
- package/dist/internal/components/MergeEditor/constants.js +17 -3
- package/dist/internal/components/MergeEditor/constants.js.map +1 -1
- package/dist/internal/components/MergeEditor/useMergeDiff.js +2 -5
- package/dist/internal/components/Modal.js +2 -13
- package/dist/internal/components/Navbar.js +2 -14
- package/dist/internal/components/Pagination.js +2 -11
- package/dist/internal/components/PanelWithDetails.js +30 -10
- package/dist/internal/components/PanelWithDetails.js.map +1 -1
- package/dist/internal/components/Popconfirm.js +2 -12
- package/dist/internal/components/Popover.js +2 -9
- package/dist/internal/components/Progress.js +46 -8
- package/dist/internal/components/Progress.js.map +1 -1
- package/dist/internal/components/RadioGroup.js +2 -12
- package/dist/internal/components/Resizable.js +2 -9
- package/dist/internal/components/ScrollArea.js +41 -8
- package/dist/internal/components/ScrollArea.js.map +1 -1
- package/dist/internal/components/Search.js +2 -10
- package/dist/internal/components/Select.js +2 -12
- package/dist/internal/components/Separator.js +83 -8
- package/dist/internal/components/Separator.js.map +1 -1
- package/dist/internal/components/Sheet.js +2 -12
- package/dist/internal/components/Sidebar.js +2 -20
- package/dist/internal/components/Skeleton/Skeleton.js +38 -8
- package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
- package/dist/internal/components/Skeleton/SkeletonList.js +40 -9
- package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -1
- package/dist/internal/components/Slider.js +2 -11
- package/dist/internal/components/SpotlightBackdrop.js +131 -8
- package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
- package/dist/internal/components/Stepper.js +2 -10
- package/dist/internal/components/Switch.js +2 -10
- package/dist/internal/components/Table.js +2 -10
- package/dist/internal/components/Tabs.js +2 -12
- package/dist/internal/components/ThemeProvider.js +3 -10
- package/dist/internal/components/TimePicker.js +2 -12
- package/dist/internal/components/Timeline.js +2 -10
- package/dist/internal/components/Toast.js +3 -11
- package/dist/internal/components/Toggle.js +168 -8
- package/dist/internal/components/Toggle.js.map +1 -1
- package/dist/internal/components/ToggleGroup.js +2 -9
- package/dist/internal/components/Tooltip.js +2 -8
- package/dist/internal/components/Truncated.js +44 -8
- package/dist/internal/components/Truncated.js.map +1 -1
- package/dist/internal/components/Workbench.js +2 -11
- package/dist/internal/components/ZoomableSvg.js +2 -13
- package/dist/internal/hooks/useAutosizeInput.js +76 -3
- package/dist/internal/hooks/useAutosizeInput.js.map +1 -1
- package/dist/internal/hooks/useScrollbarPosition.js +44 -4
- package/dist/internal/hooks/useScrollbarPosition.js.map +1 -1
- package/dist/internal/hooks/useStableCallback.js +28 -3
- package/dist/internal/hooks/useStableCallback.js.map +1 -1
- package/dist/internal/utils/mergeRefs.js +19 -3
- package/dist/internal/utils/mergeRefs.js.map +1 -1
- package/dist/internal/utils.js +5 -8
- package/dist/markdown-editor.d.ts +72 -72
- package/dist/markdown-editor.js +1122 -1207
- package/dist/markdown-editor.js.map +1 -1
- package/dist/mermaid.d.ts +12 -12
- package/dist/mermaid.js +2 -18
- package/dist/rjsf.d.ts +45 -34
- package/dist/rjsf.js +1601 -1671
- package/dist/rjsf.js.map +1 -1
- package/dist/rolldown-runtime-Bdc48AWt.js +33 -0
- package/dist/styles-DSUP_-9Z.js +158 -0
- package/dist/styles-DSUP_-9Z.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/testing.d.ts +8 -7
- package/dist/testing.js +36 -21
- package/dist/testing.js.map +1 -1
- package/dist/themeTokens-BNg98Mu9.js +85 -0
- package/dist/themeTokens-BNg98Mu9.js.map +1 -0
- package/dist/toast-CjkURw0M.js +184 -0
- package/dist/toast-CjkURw0M.js.map +1 -0
- package/dist/useColorSchemeState-CYqcUfSH.js +61 -0
- package/dist/useColorSchemeState-CYqcUfSH.js.map +1 -0
- package/dist/useControllableState-M6494mCT.js +31 -0
- package/dist/useControllableState-M6494mCT.js.map +1 -0
- package/dist/useElement-DkF6esWL.js +15 -0
- package/dist/useElement-DkF6esWL.js.map +1 -0
- package/dist/useMergeDiff-CvowEXJ1.js +465 -0
- package/dist/useMergeDiff-CvowEXJ1.js.map +1 -0
- package/dist/utils-D0c5VAyF.js +308 -0
- package/dist/utils-D0c5VAyF.js.map +1 -0
- package/package.json +11 -10
- package/dist/MermaidDiagram-ZU5KAVRT.js +0 -18
- package/dist/MermaidDiagram-ZU5KAVRT.js.map +0 -1
- package/dist/chunk-2YYJDKSP.js +0 -51
- package/dist/chunk-2YYJDKSP.js.map +0 -1
- package/dist/chunk-3P5UUCFI.js +0 -385
- package/dist/chunk-3P5UUCFI.js.map +0 -1
- package/dist/chunk-3QDFDDWZ.js +0 -99
- package/dist/chunk-3QDFDDWZ.js.map +0 -1
- package/dist/chunk-3W27OLK5.js +0 -15
- package/dist/chunk-3W27OLK5.js.map +0 -1
- package/dist/chunk-4FIZZONW.js +0 -40
- package/dist/chunk-4FIZZONW.js.map +0 -1
- package/dist/chunk-4GIAXOJG.js +0 -133
- package/dist/chunk-4GIAXOJG.js.map +0 -1
- package/dist/chunk-52NDNMK7.js +0 -99
- package/dist/chunk-52NDNMK7.js.map +0 -1
- package/dist/chunk-576G5OES.js +0 -201
- package/dist/chunk-576G5OES.js.map +0 -1
- package/dist/chunk-5AIE6SET.js +0 -659
- package/dist/chunk-5AIE6SET.js.map +0 -1
- package/dist/chunk-5FTNAZRW.js +0 -327
- package/dist/chunk-5FTNAZRW.js.map +0 -1
- package/dist/chunk-5IG2S7ZY.js +0 -70
- package/dist/chunk-5IG2S7ZY.js.map +0 -1
- package/dist/chunk-5QCXHNCW.js +0 -404
- package/dist/chunk-5QCXHNCW.js.map +0 -1
- package/dist/chunk-6DUMGC7Y.js +0 -105
- package/dist/chunk-6DUMGC7Y.js.map +0 -1
- package/dist/chunk-6J25CVST.js +0 -174
- package/dist/chunk-6J25CVST.js.map +0 -1
- package/dist/chunk-6NN35XOP.js +0 -120
- package/dist/chunk-6NN35XOP.js.map +0 -1
- package/dist/chunk-6NZBVA4T.js +0 -24
- package/dist/chunk-6NZBVA4T.js.map +0 -1
- package/dist/chunk-6W5BHRCL.js +0 -295
- package/dist/chunk-6W5BHRCL.js.map +0 -1
- package/dist/chunk-72BKRCEG.js +0 -409
- package/dist/chunk-72BKRCEG.js.map +0 -1
- package/dist/chunk-7GTI3PPI.js +0 -95
- package/dist/chunk-7GTI3PPI.js.map +0 -1
- package/dist/chunk-7P6PLZ4B.js +0 -74
- package/dist/chunk-7P6PLZ4B.js.map +0 -1
- package/dist/chunk-7WZWY5IA.js +0 -46
- package/dist/chunk-7WZWY5IA.js.map +0 -1
- package/dist/chunk-AIYO2632.js +0 -489
- package/dist/chunk-AIYO2632.js.map +0 -1
- package/dist/chunk-ANFZWPNE.js +0 -112
- package/dist/chunk-ANFZWPNE.js.map +0 -1
- package/dist/chunk-ANZTVAJU.js +0 -73
- package/dist/chunk-ANZTVAJU.js.map +0 -1
- package/dist/chunk-BD5BTJKX.js +0 -166
- package/dist/chunk-BD5BTJKX.js.map +0 -1
- package/dist/chunk-BHGIDSRJ.js +0 -140
- package/dist/chunk-BHGIDSRJ.js.map +0 -1
- package/dist/chunk-BSQWZITZ.js +0 -507
- package/dist/chunk-BSQWZITZ.js.map +0 -1
- package/dist/chunk-D3LAIK62.js +0 -23
- package/dist/chunk-D3LAIK62.js.map +0 -1
- package/dist/chunk-DODCR43C.js +0 -155
- package/dist/chunk-DODCR43C.js.map +0 -1
- package/dist/chunk-EEK5NGZF.js +0 -40
- package/dist/chunk-EEK5NGZF.js.map +0 -1
- package/dist/chunk-ENRG7TXA.js +0 -11
- package/dist/chunk-ENRG7TXA.js.map +0 -1
- package/dist/chunk-EQRMGIGY.js +0 -239
- package/dist/chunk-EQRMGIGY.js.map +0 -1
- package/dist/chunk-ERAHK5YQ.js +0 -495
- package/dist/chunk-ERAHK5YQ.js.map +0 -1
- package/dist/chunk-F3FOFY2P.js +0 -124
- package/dist/chunk-F3FOFY2P.js.map +0 -1
- package/dist/chunk-F6BTWFOC.js +0 -507
- package/dist/chunk-F6BTWFOC.js.map +0 -1
- package/dist/chunk-F6J6NNAL.js +0 -34
- package/dist/chunk-F6J6NNAL.js.map +0 -1
- package/dist/chunk-FCHJ7D5O.js +0 -59
- package/dist/chunk-FCHJ7D5O.js.map +0 -1
- package/dist/chunk-FFJTEQCC.js +0 -80
- package/dist/chunk-FFJTEQCC.js.map +0 -1
- package/dist/chunk-FUFMVW7O.js +0 -64
- package/dist/chunk-FUFMVW7O.js.map +0 -1
- package/dist/chunk-FVPGQ6UE.js +0 -25
- package/dist/chunk-FVPGQ6UE.js.map +0 -1
- package/dist/chunk-G3PMV62Z.js +0 -33
- package/dist/chunk-G3PMV62Z.js.map +0 -1
- package/dist/chunk-GACFOW3E.js +0 -51
- package/dist/chunk-GACFOW3E.js.map +0 -1
- package/dist/chunk-GDT6HQMK.js +0 -42
- package/dist/chunk-GDT6HQMK.js.map +0 -1
- package/dist/chunk-HLGU22C6.js +0 -2589
- package/dist/chunk-HLGU22C6.js.map +0 -1
- package/dist/chunk-HPMYYGP7.js +0 -134
- package/dist/chunk-HPMYYGP7.js.map +0 -1
- package/dist/chunk-I2UCOD45.js +0 -197
- package/dist/chunk-I2UCOD45.js.map +0 -1
- package/dist/chunk-IEGDZUVM.js +0 -75
- package/dist/chunk-IEGDZUVM.js.map +0 -1
- package/dist/chunk-IIS7INHF.js +0 -47
- package/dist/chunk-IIS7INHF.js.map +0 -1
- package/dist/chunk-ITELSEFU.js +0 -256
- package/dist/chunk-ITELSEFU.js.map +0 -1
- package/dist/chunk-IXAYNBOY.js +0 -407
- package/dist/chunk-IXAYNBOY.js.map +0 -1
- package/dist/chunk-JUW2ETEI.js +0 -191
- package/dist/chunk-JUW2ETEI.js.map +0 -1
- package/dist/chunk-K65C7CVE.js +0 -127
- package/dist/chunk-K65C7CVE.js.map +0 -1
- package/dist/chunk-KDI64MCY.js +0 -189
- package/dist/chunk-KDI64MCY.js.map +0 -1
- package/dist/chunk-KN4ASMH5.js +0 -160
- package/dist/chunk-KN4ASMH5.js.map +0 -1
- package/dist/chunk-KQW7QNTU.js +0 -1549
- package/dist/chunk-KQW7QNTU.js.map +0 -1
- package/dist/chunk-KR7NXXHC.js +0 -66
- package/dist/chunk-KR7NXXHC.js.map +0 -1
- package/dist/chunk-KRZKIVMA.js +0 -142
- package/dist/chunk-KRZKIVMA.js.map +0 -1
- package/dist/chunk-KTTLLKGQ.js +0 -185
- package/dist/chunk-KTTLLKGQ.js.map +0 -1
- package/dist/chunk-KWKSHPDP.js +0 -234
- package/dist/chunk-KWKSHPDP.js.map +0 -1
- package/dist/chunk-KZVC7OYG.js +0 -57
- package/dist/chunk-KZVC7OYG.js.map +0 -1
- package/dist/chunk-L5DHUN2V.js +0 -204
- package/dist/chunk-L5DHUN2V.js.map +0 -1
- package/dist/chunk-LCTGEH57.js +0 -1376
- package/dist/chunk-LCTGEH57.js.map +0 -1
- package/dist/chunk-LXLIQ2D6.js +0 -12
- package/dist/chunk-LXLIQ2D6.js.map +0 -1
- package/dist/chunk-M4CTURKX.js +0 -84
- package/dist/chunk-M4CTURKX.js.map +0 -1
- package/dist/chunk-M6LTUPVP.js +0 -301
- package/dist/chunk-M6LTUPVP.js.map +0 -1
- package/dist/chunk-MA6RRHDT.js +0 -291
- package/dist/chunk-MA6RRHDT.js.map +0 -1
- package/dist/chunk-MODE4QIA.js +0 -6
- package/dist/chunk-MODE4QIA.js.map +0 -1
- package/dist/chunk-MVILMVGG.js +0 -118
- package/dist/chunk-MVILMVGG.js.map +0 -1
- package/dist/chunk-MWS4VCLV.js +0 -17
- package/dist/chunk-MWS4VCLV.js.map +0 -1
- package/dist/chunk-NEUX74SO.js +0 -315
- package/dist/chunk-NEUX74SO.js.map +0 -1
- package/dist/chunk-NFHKYBRD.js +0 -156
- package/dist/chunk-NFHKYBRD.js.map +0 -1
- package/dist/chunk-NHJNNXD3.js +0 -89
- package/dist/chunk-NHJNNXD3.js.map +0 -1
- package/dist/chunk-O2BF3HZL.js +0 -33
- package/dist/chunk-O2BF3HZL.js.map +0 -1
- package/dist/chunk-OANXCZYD.js +0 -212
- package/dist/chunk-OANXCZYD.js.map +0 -1
- package/dist/chunk-ODJF7YIP.js +0 -230
- package/dist/chunk-ODJF7YIP.js.map +0 -1
- package/dist/chunk-ON4BJTHI.js +0 -101
- package/dist/chunk-ON4BJTHI.js.map +0 -1
- package/dist/chunk-OTL5WXIJ.js +0 -16
- package/dist/chunk-OTL5WXIJ.js.map +0 -1
- package/dist/chunk-PACNBKJV.js +0 -47
- package/dist/chunk-PACNBKJV.js.map +0 -1
- package/dist/chunk-PROCA7K7.js +0 -23
- package/dist/chunk-PROCA7K7.js.map +0 -1
- package/dist/chunk-QGMIPA67.js +0 -85
- package/dist/chunk-QGMIPA67.js.map +0 -1
- package/dist/chunk-QQA37LFB.js +0 -190
- package/dist/chunk-QQA37LFB.js.map +0 -1
- package/dist/chunk-QZAWRSEB.js +0 -61
- package/dist/chunk-QZAWRSEB.js.map +0 -1
- package/dist/chunk-R74KGWNS.js +0 -699
- package/dist/chunk-R74KGWNS.js.map +0 -1
- package/dist/chunk-RFDLHMKL.js +0 -110
- package/dist/chunk-RFDLHMKL.js.map +0 -1
- package/dist/chunk-RL64HN7S.js +0 -40
- package/dist/chunk-RL64HN7S.js.map +0 -1
- package/dist/chunk-RMRQKPL7.js +0 -115
- package/dist/chunk-RMRQKPL7.js.map +0 -1
- package/dist/chunk-RQVK4IYC.js +0 -606
- package/dist/chunk-RQVK4IYC.js.map +0 -1
- package/dist/chunk-RTW56PWZ.js +0 -59
- package/dist/chunk-RTW56PWZ.js.map +0 -1
- package/dist/chunk-RUTPQNLR.js +0 -266
- package/dist/chunk-RUTPQNLR.js.map +0 -1
- package/dist/chunk-S6TAF63G.js +0 -25
- package/dist/chunk-S6TAF63G.js.map +0 -1
- package/dist/chunk-SBGAUGXY.js +0 -224
- package/dist/chunk-SBGAUGXY.js.map +0 -1
- package/dist/chunk-SC275NHZ.js +0 -407
- package/dist/chunk-SC275NHZ.js.map +0 -1
- package/dist/chunk-SCQPU4UE.js +0 -97
- package/dist/chunk-SCQPU4UE.js.map +0 -1
- package/dist/chunk-SFFF2WQP.js +0 -8
- package/dist/chunk-SFFF2WQP.js.map +0 -1
- package/dist/chunk-SJYMHZKA.js +0 -36
- package/dist/chunk-SJYMHZKA.js.map +0 -1
- package/dist/chunk-SLCCUJVN.js +0 -125
- package/dist/chunk-SLCCUJVN.js.map +0 -1
- package/dist/chunk-SVBSNSD4.js +0 -259
- package/dist/chunk-SVBSNSD4.js.map +0 -1
- package/dist/chunk-SVPLTL35.js +0 -62
- package/dist/chunk-SVPLTL35.js.map +0 -1
- package/dist/chunk-SWQFYNYG.js +0 -338
- package/dist/chunk-SWQFYNYG.js.map +0 -1
- package/dist/chunk-THHB4EWS.js +0 -72
- package/dist/chunk-THHB4EWS.js.map +0 -1
- package/dist/chunk-TUCDD33E.js +0 -246
- package/dist/chunk-TUCDD33E.js.map +0 -1
- package/dist/chunk-TV4WAP2R.js +0 -14
- package/dist/chunk-TV4WAP2R.js.map +0 -1
- package/dist/chunk-U3A6YBTZ.js +0 -134
- package/dist/chunk-U3A6YBTZ.js.map +0 -1
- package/dist/chunk-UGT6DKWM.js +0 -95
- package/dist/chunk-VSERHUWD.js +0 -212
- package/dist/chunk-VSERHUWD.js.map +0 -1
- package/dist/chunk-VYG7BDXC.js +0 -49
- package/dist/chunk-VYG7BDXC.js.map +0 -1
- package/dist/chunk-WETKNYZX.js +0 -52
- package/dist/chunk-WETKNYZX.js.map +0 -1
- package/dist/chunk-WGG4AML3.js +0 -216
- package/dist/chunk-WGG4AML3.js.map +0 -1
- package/dist/chunk-WKAUEL6I.js +0 -30
- package/dist/chunk-WKAUEL6I.js.map +0 -1
- package/dist/chunk-WPOLA5CG.js +0 -81
- package/dist/chunk-WPOLA5CG.js.map +0 -1
- package/dist/chunk-WPVETCGJ.js +0 -254
- package/dist/chunk-WPVETCGJ.js.map +0 -1
- package/dist/chunk-WTSM3A7E.js +0 -13
- package/dist/chunk-WTSM3A7E.js.map +0 -1
- package/dist/chunk-WU3F2K3T.js +0 -148
- package/dist/chunk-WU3F2K3T.js.map +0 -1
- package/dist/chunk-WZZK2DTZ.js +0 -39
- package/dist/chunk-WZZK2DTZ.js.map +0 -1
- package/dist/chunk-X4IHLKRD.js +0 -42
- package/dist/chunk-X4IHLKRD.js.map +0 -1
- package/dist/chunk-XAHEXZJC.js +0 -80
- package/dist/chunk-XAHEXZJC.js.map +0 -1
- package/dist/chunk-XCYGJDUX.js +0 -31
- package/dist/chunk-XCYGJDUX.js.map +0 -1
- package/dist/chunk-Y4W3JORC.js +0 -104
- package/dist/chunk-Y4W3JORC.js.map +0 -1
- package/dist/chunk-YFZJ3ZLG.js +0 -1297
- package/dist/chunk-YFZJ3ZLG.js.map +0 -1
- package/dist/chunk-YI3WLXEN.js +0 -4387
- package/dist/chunk-YI3WLXEN.js.map +0 -1
- package/dist/chunk-ZBKFSPD3.js +0 -29
- package/dist/chunk-ZBKFSPD3.js.map +0 -1
- package/dist/chunk-ZOERRQ6A.js +0 -79
- package/dist/chunk-ZOERRQ6A.js.map +0 -1
- package/dist/chunk-ZSTGUKHU.js +0 -10
- package/dist/chunk-ZSTGUKHU.js.map +0 -1
- package/dist/chunk-ZUEHDL27.js +0 -65
- package/dist/chunk-ZUEHDL27.js.map +0 -1
- package/dist/constants-D3gaMY-W.d.ts +0 -39
- package/dist/icons.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal/blocks/AIKit.js.map +0 -1
- package/dist/internal/blocks/AppShell.js.map +0 -1
- package/dist/internal/blocks/AutoSaveTextarea.js.map +0 -1
- package/dist/internal/blocks/BrandEditor.js.map +0 -1
- package/dist/internal/blocks/ClipboardButton.js.map +0 -1
- package/dist/internal/blocks/ColorInput.js.map +0 -1
- package/dist/internal/blocks/ColorModeSwitch.js.map +0 -1
- package/dist/internal/blocks/Command.js.map +0 -1
- package/dist/internal/blocks/CopyField.js.map +0 -1
- package/dist/internal/blocks/DateInput.js.map +0 -1
- package/dist/internal/blocks/DateRangeInput.js.map +0 -1
- package/dist/internal/blocks/Form.js.map +0 -1
- package/dist/internal/blocks/FormGroup.js.map +0 -1
- package/dist/internal/blocks/MultiActionButtonGroup.js.map +0 -1
- package/dist/internal/blocks/OtpInput.js.map +0 -1
- package/dist/internal/blocks/PageHeader.js.map +0 -1
- package/dist/internal/blocks/PageLayout.js.map +0 -1
- package/dist/internal/blocks/PageToolbar.js.map +0 -1
- package/dist/internal/blocks/SearchInput.js.map +0 -1
- package/dist/internal/blocks/SectionNav.js.map +0 -1
- package/dist/internal/blocks/TextInput.js.map +0 -1
- package/dist/internal/components/Alert.js.map +0 -1
- package/dist/internal/components/AlertModal.js.map +0 -1
- package/dist/internal/components/Badge.js.map +0 -1
- package/dist/internal/components/BrandLogo.js.map +0 -1
- package/dist/internal/components/Breadcrumb.js.map +0 -1
- package/dist/internal/components/Button.js.map +0 -1
- package/dist/internal/components/Calendar.js.map +0 -1
- package/dist/internal/components/Card.js.map +0 -1
- package/dist/internal/components/Checkbox.js.map +0 -1
- package/dist/internal/components/Clipboard.js.map +0 -1
- package/dist/internal/components/Collapsible.js.map +0 -1
- package/dist/internal/components/Combobox.js.map +0 -1
- package/dist/internal/components/DatePicker.js.map +0 -1
- package/dist/internal/components/DateRangePicker.js.map +0 -1
- package/dist/internal/components/DiffView.js.map +0 -1
- package/dist/internal/components/DropdownMenu.js.map +0 -1
- package/dist/internal/components/FileUpload.js.map +0 -1
- package/dist/internal/components/FullScreenModal.js.map +0 -1
- package/dist/internal/components/HoverCard.js.map +0 -1
- package/dist/internal/components/InputGroup.js.map +0 -1
- package/dist/internal/components/Kbd.js.map +0 -1
- package/dist/internal/components/MarkedText.js.map +0 -1
- package/dist/internal/components/MergeEditor/useMergeDiff.js.map +0 -1
- package/dist/internal/components/Modal.js.map +0 -1
- package/dist/internal/components/Navbar.js.map +0 -1
- package/dist/internal/components/Pagination.js.map +0 -1
- package/dist/internal/components/Popconfirm.js.map +0 -1
- package/dist/internal/components/Popover.js.map +0 -1
- package/dist/internal/components/RadioGroup.js.map +0 -1
- package/dist/internal/components/Resizable.js.map +0 -1
- package/dist/internal/components/Search.js.map +0 -1
- package/dist/internal/components/Select.js.map +0 -1
- package/dist/internal/components/Sheet.js.map +0 -1
- package/dist/internal/components/Sidebar.js.map +0 -1
- package/dist/internal/components/Slider.js.map +0 -1
- package/dist/internal/components/Stepper.js.map +0 -1
- package/dist/internal/components/Switch.js.map +0 -1
- package/dist/internal/components/Table.js.map +0 -1
- package/dist/internal/components/Tabs.js.map +0 -1
- package/dist/internal/components/ThemeProvider.js.map +0 -1
- package/dist/internal/components/TimePicker.js.map +0 -1
- package/dist/internal/components/Timeline.js.map +0 -1
- package/dist/internal/components/Toast.js.map +0 -1
- package/dist/internal/components/ToggleGroup.js.map +0 -1
- package/dist/internal/components/Tooltip.js.map +0 -1
- package/dist/internal/components/Workbench.js.map +0 -1
- package/dist/internal/components/ZoomableSvg.js.map +0 -1
- package/dist/internal/utils.js.map +0 -1
- package/dist/mermaid.js.map +0 -1
package/dist/rjsf.js
CHANGED
|
@@ -1,1728 +1,1658 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
import './chunk-KR7NXXHC.js';
|
|
36
|
-
import { debounce, Tooltip } from './chunk-SWQFYNYG.js';
|
|
37
|
-
import './chunk-3W27OLK5.js';
|
|
38
|
-
import './chunk-MODE4QIA.js';
|
|
39
|
-
import './chunk-WETKNYZX.js';
|
|
40
|
-
import './chunk-LXLIQ2D6.js';
|
|
41
|
-
import './chunk-G3PMV62Z.js';
|
|
42
|
-
import { createContext, use, useMemo, useRef, useState, useEffect, useCallback, isValidElement } from 'react';
|
|
43
|
-
import Form from '@rjsf/core';
|
|
44
|
-
import validator from '@rjsf/validator-ajv8';
|
|
45
|
-
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
46
|
-
import DOMPurify from 'dompurify';
|
|
47
|
-
|
|
48
|
-
var RenderMarkdownContext = createContext((source) => source);
|
|
49
|
-
var RenderMarkdownProvider = RenderMarkdownContext;
|
|
50
|
-
var useRenderMarkdown = () => use(RenderMarkdownContext);
|
|
51
|
-
var isValidJson = (raw) => {
|
|
52
|
-
try {
|
|
53
|
-
const parsed = JSON.parse(raw);
|
|
54
|
-
return Boolean(parsed && typeof parsed === "object");
|
|
55
|
-
} catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
1
|
+
import { Tooltip, debounce } from "./utils-D0c5VAyF.js";
|
|
2
|
+
import { BookOpen, Info, Trash2 } from "./icons-Cek151jC.js";
|
|
3
|
+
import { Button } from "./Button-6xBX0nNl.js";
|
|
4
|
+
import { Label } from "./internal/components/Label.js";
|
|
5
|
+
import { Link } from "./internal/components/Link.js";
|
|
6
|
+
import { TextInput } from "./TextInput-CMuN1WfY.js";
|
|
7
|
+
import { RadioGroup } from "./RadioGroup-sIveSsNa.js";
|
|
8
|
+
import { Checkbox } from "./Checkbox-GJ8-srt4.js";
|
|
9
|
+
import { Combobox } from "./Combobox-Dgm6Z4ib.js";
|
|
10
|
+
import { FormGroup } from "./FormGroup-C41n65cE.js";
|
|
11
|
+
import { NumberInput } from "./internal/blocks/NumberInput.js";
|
|
12
|
+
import { Textarea } from "./internal/blocks/Textarea.js";
|
|
13
|
+
import { DateInput } from "./DateInput-B3UdzRfW.js";
|
|
14
|
+
import { PasswordInput } from "./internal/blocks/PasswordInput.js";
|
|
15
|
+
import { Alert } from "./Alert-DfZq9kGe.js";
|
|
16
|
+
import { CollapsiblePanel } from "./internal/components/CollapsiblePanel.js";
|
|
17
|
+
import { Tabs, TabsContent } from "./Tabs-UMQuDoW8.js";
|
|
18
|
+
import { CodeEditor, isLanguageMode } from "./CodeEditor-DyaN-Ij2.js";
|
|
19
|
+
import { createContext, isValidElement, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
20
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
import DOMPurify from "dompurify";
|
|
22
|
+
import Form from "@rjsf/core";
|
|
23
|
+
import validator from "@rjsf/validator-ajv8";
|
|
24
|
+
//#region src/blocks/RjsfSchemaEditor/fieldHelpers.ts
|
|
25
|
+
/** No-op function reused as onBlur/onFocus stub in custom fields. */
|
|
26
|
+
const noop = () => {};
|
|
27
|
+
const NullField = () => null;
|
|
28
|
+
/** RJSF always registers SchemaField; the fallback only satisfies the indexed-access type. */
|
|
29
|
+
const getSchemaField = (registry) => registry.fields.SchemaField ?? NullField;
|
|
30
|
+
/** Stub props shared by all custom SchemaField call-sites (onBlur, onFocus, errorSchema). */
|
|
31
|
+
const SCHEMA_FIELD_STUBS = {
|
|
32
|
+
onBlur: noop,
|
|
33
|
+
onFocus: noop,
|
|
34
|
+
errorSchema: {}
|
|
58
35
|
};
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
36
|
+
/** Whether a value is a keyed namespace — an object that is neither `null` nor an array. */
|
|
37
|
+
const isRecord = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
38
|
+
/**
|
|
39
|
+
* Resolves a dot-path against an object (e.g. "_metadata_.table.columns").
|
|
40
|
+
*
|
|
41
|
+
* json-editor watch paths may be prefixed with the schema `id` (e.g.
|
|
42
|
+
* "rootschema.endpoints.contact"). The prefix is not a real data key — it
|
|
43
|
+
* identifies the schema root. When the first segment doesn't exist in `data`
|
|
44
|
+
* we retry without it so components using this convention still resolve.
|
|
45
|
+
*/
|
|
46
|
+
const resolveByPath = (path, data) => {
|
|
47
|
+
const parts = path.split(".");
|
|
48
|
+
const walk = (segments) => {
|
|
49
|
+
let current = data;
|
|
50
|
+
for (const part of segments) {
|
|
51
|
+
if (current == null || typeof current !== "object") return void 0;
|
|
52
|
+
current = current[part];
|
|
53
|
+
}
|
|
54
|
+
return current;
|
|
55
|
+
};
|
|
56
|
+
const result = walk(parts);
|
|
57
|
+
const [first] = parts;
|
|
58
|
+
if (result !== void 0 || first === void 0 || parts.length <= 1) return result;
|
|
59
|
+
if (!(first in data)) return walk(parts.slice(1));
|
|
60
|
+
return result;
|
|
62
61
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
options
|
|
70
|
-
}) => {
|
|
71
|
-
const editorOptions = options.editor ?? {};
|
|
72
|
-
const rawMode = editorOptions.mode ?? "application/json";
|
|
73
|
-
const mode = isLanguageMode(rawMode) ? rawMode : "application/json";
|
|
74
|
-
const isJsonMode = mode === "application/json";
|
|
75
|
-
const isReadOnly = disabled || readonly || !!editorOptions.readOnly;
|
|
76
|
-
const [text, setText] = useState(() => sanitize(value));
|
|
77
|
-
useEffect(() => {
|
|
78
|
-
setText((currentText) => {
|
|
79
|
-
const sanitized = sanitize(value);
|
|
80
|
-
if (currentText === sanitized) return currentText;
|
|
81
|
-
if (isJsonMode && isValidJson(currentText)) {
|
|
82
|
-
try {
|
|
83
|
-
if (JSON.stringify(JSON.parse(currentText)) === JSON.stringify(typeof value === "object" ? value : JSON.parse(sanitized))) {
|
|
84
|
-
return currentText;
|
|
85
|
-
}
|
|
86
|
-
} catch {
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return sanitized;
|
|
90
|
-
});
|
|
91
|
-
}, [value, isJsonMode]);
|
|
92
|
-
const handleChange = (raw) => {
|
|
93
|
-
setText(raw);
|
|
94
|
-
if (isJsonMode && isValidJson(raw)) {
|
|
95
|
-
onChange(JSON.parse(raw));
|
|
96
|
-
} else {
|
|
97
|
-
onChange(raw);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
const help = isJsonMode && !isReadOnly && options.encryptionHint !== false ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
101
|
-
"Properties prefixed with ",
|
|
102
|
-
/* @__PURE__ */ jsx("code", { children: "#" }),
|
|
103
|
-
" sign will be encrypted on save. Already encrypted strings will persist."
|
|
104
|
-
] }) : null;
|
|
105
|
-
return /* @__PURE__ */ jsx("div", { id, children: isReadOnly ? /* @__PURE__ */ jsx(
|
|
106
|
-
CodeEditor,
|
|
107
|
-
{
|
|
108
|
-
variant: "field",
|
|
109
|
-
value: text,
|
|
110
|
-
mode,
|
|
111
|
-
readOnly: true,
|
|
112
|
-
withCopyButton: true,
|
|
113
|
-
withLineNumbers: editorOptions.lineNumbers !== false
|
|
114
|
-
}
|
|
115
|
-
) : /* @__PURE__ */ jsx(
|
|
116
|
-
CodeEditor,
|
|
117
|
-
{
|
|
118
|
-
variant: "field",
|
|
119
|
-
value: text,
|
|
120
|
-
mode,
|
|
121
|
-
onChange: handleChange,
|
|
122
|
-
withCopyButton: true,
|
|
123
|
-
withLineNumbers: editorOptions.lineNumbers !== false,
|
|
124
|
-
help
|
|
125
|
-
}
|
|
126
|
-
) });
|
|
62
|
+
/**
|
|
63
|
+
* Extracts a property name from a simple Mustache-like template.
|
|
64
|
+
* e.g. "{{item.field_name}}" → "field_name"
|
|
65
|
+
*/
|
|
66
|
+
const extractProperty = (template) => {
|
|
67
|
+
return /\{\{item\.(\w+)\}\}/.exec(template)?.[1] ?? "";
|
|
127
68
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Builds select options from watched form data and enumSource config.
|
|
71
|
+
*
|
|
72
|
+
* Supports two json-editor enumSource formats:
|
|
73
|
+
* 1. String: `enumSource: "varName"` — use the watched array directly as string values
|
|
74
|
+
* 2. Array: `enumSource: [{ source, value, title }]` — map items through templates
|
|
75
|
+
*/
|
|
76
|
+
const buildDynamicOptions = (watch, enumSource, rootFormData) => {
|
|
77
|
+
if (typeof enumSource === "string") {
|
|
78
|
+
const watchPath = watch[enumSource];
|
|
79
|
+
if (!watchPath) return [];
|
|
80
|
+
const sourceData = resolveByPath(watchPath, rootFormData);
|
|
81
|
+
if (!Array.isArray(sourceData)) return [];
|
|
82
|
+
return sourceData.map((item) => {
|
|
83
|
+
const val = String(item ?? "");
|
|
84
|
+
return {
|
|
85
|
+
value: val,
|
|
86
|
+
label: val
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(enumSource) && enumSource.length > 0) {
|
|
91
|
+
if (enumSource.length > 1) console.warn("[RJSF] Multiple enumSource entries are not supported, only the first is used.");
|
|
92
|
+
const source = enumSource[0];
|
|
93
|
+
const watchPath = watch[source.source];
|
|
94
|
+
if (!watchPath) return [];
|
|
95
|
+
const sourceData = resolveByPath(watchPath, rootFormData);
|
|
96
|
+
if (!Array.isArray(sourceData)) return [];
|
|
97
|
+
const valueProp = extractProperty(source.value);
|
|
98
|
+
const titleProp = extractProperty(source.title);
|
|
99
|
+
return sourceData.filter((item) => item != null && typeof item === "object").map((item) => ({
|
|
100
|
+
value: String(item[valueProp] ?? ""),
|
|
101
|
+
label: String(item[titleProp] ?? item[valueProp] ?? "")
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
return [];
|
|
148
105
|
};
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Builds a child `fieldPathId` for a nested SchemaField.
|
|
108
|
+
* Joins segments with "_" for the $id and appends them to the path array.
|
|
109
|
+
*/
|
|
110
|
+
const childFieldPathId = (parentFieldPathId, ...segments) => ({
|
|
111
|
+
$id: [parentFieldPathId?.$id ?? "root", ...segments].join("_"),
|
|
112
|
+
path: [...parentFieldPathId?.path ?? [], ...segments]
|
|
113
|
+
});
|
|
114
|
+
/**
|
|
115
|
+
* Sorts object entries by `propertyOrder`, falling back to MAX_SAFE_INTEGER
|
|
116
|
+
* for properties without an explicit order.
|
|
117
|
+
*/
|
|
118
|
+
const sortByPropertyOrder = (properties) => Object.entries(properties).sort(([, a], [, b]) => (a.propertyOrder ?? Number.MAX_SAFE_INTEGER) - (b.propertyOrder ?? Number.MAX_SAFE_INTEGER)).map(([key]) => key);
|
|
119
|
+
/**
|
|
120
|
+
* Whether the schema asked for this field to be hidden.
|
|
121
|
+
*
|
|
122
|
+
* - `ui:widget: 'hidden'` is what RJSF itself reads, but any widget branch in
|
|
123
|
+
* `generateUiSchema` that runs later claims the slot and erases it.
|
|
124
|
+
* - `ui:options.hidden` is the copy written last, so it survives all of them.
|
|
125
|
+
*/
|
|
126
|
+
const isHiddenField = (fieldUiSchema) => fieldUiSchema?.["ui:widget"] === "hidden" || !!fieldUiSchema?.["ui:options"]?.hidden;
|
|
127
|
+
/**
|
|
128
|
+
* Whether a schema node holds children.
|
|
129
|
+
*
|
|
130
|
+
* - `properties`, `additionalProperties`, `patternProperties` or `items` alone qualify —
|
|
131
|
+
* json-editor infers the container type from them and omits `type`.
|
|
132
|
+
* - `type` may be a union (`['object', 'null']`).
|
|
133
|
+
*/
|
|
134
|
+
const isContainerSchema = (schema) => {
|
|
135
|
+
if (!schema) return false;
|
|
136
|
+
if (schema.properties || schema.additionalProperties || schema.patternProperties) return true;
|
|
137
|
+
if (schema.items) return true;
|
|
138
|
+
if (Array.isArray(schema.type)) return schema.type.includes("object") || schema.type.includes("array");
|
|
139
|
+
return schema.type === "object" || schema.type === "array";
|
|
152
140
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
141
|
+
/**
|
|
142
|
+
* Whether a hidden field's whole subtree should leave the form.
|
|
143
|
+
*
|
|
144
|
+
* - Hidden containers mount nothing. RJSF recurses into objects and arrays regardless of
|
|
145
|
+
* hiddenness, so a `_metadata_` subtree costs hundreds of fields for no visible output.
|
|
146
|
+
* - Hidden leaves are kept, wrapped in `tw:hidden`: their mount-phase onChange writes the
|
|
147
|
+
* schema default that sibling `options.dependencies` resolve against.
|
|
148
|
+
*/
|
|
149
|
+
const isHiddenContainer = (fieldUiSchema, schema) => isHiddenField(fieldUiSchema) && isContainerSchema(schema);
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/blocks/RjsfSchemaEditor/markdownContext.ts
|
|
152
|
+
/** Falls back to plain text when the host app doesn't provide a markdown renderer. */
|
|
153
|
+
const RenderMarkdownContext = createContext((source) => source);
|
|
154
|
+
const RenderMarkdownProvider = RenderMarkdownContext;
|
|
155
|
+
const useRenderMarkdown = () => use(RenderMarkdownContext);
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/CodeEditorWidget.tsx
|
|
158
|
+
const isValidJson = (raw) => {
|
|
159
|
+
try {
|
|
160
|
+
const parsed = JSON.parse(raw);
|
|
161
|
+
return Boolean(parsed && typeof parsed === "object");
|
|
162
|
+
} catch {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
159
165
|
};
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
let current = data;
|
|
164
|
-
for (const part of segments) {
|
|
165
|
-
if (current == null || typeof current !== "object") return void 0;
|
|
166
|
-
current = current[part];
|
|
167
|
-
}
|
|
168
|
-
return current;
|
|
169
|
-
};
|
|
170
|
-
const result = walk(parts);
|
|
171
|
-
const [first] = parts;
|
|
172
|
-
if (result !== void 0 || first === void 0 || parts.length <= 1) return result;
|
|
173
|
-
if (!(first in data)) return walk(parts.slice(1));
|
|
174
|
-
return result;
|
|
166
|
+
const sanitize = (val) => {
|
|
167
|
+
if (typeof val === "object" && val !== null) return JSON.stringify(val, null, " ");
|
|
168
|
+
return String(val ?? "");
|
|
175
169
|
};
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
170
|
+
const CodeEditorWidget = ({ id, value, onChange, disabled, readonly, options }) => {
|
|
171
|
+
const editorOptions = options.editor ?? {};
|
|
172
|
+
const rawMode = editorOptions.mode ?? "application/json";
|
|
173
|
+
const mode = isLanguageMode(rawMode) ? rawMode : "application/json";
|
|
174
|
+
const isJsonMode = mode === "application/json";
|
|
175
|
+
const isReadOnly = disabled || readonly || !!editorOptions.readOnly;
|
|
176
|
+
const [text, setText] = useState(() => sanitize(value));
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
setText((currentText) => {
|
|
179
|
+
const sanitized = sanitize(value);
|
|
180
|
+
if (currentText === sanitized) return currentText;
|
|
181
|
+
if (isJsonMode && isValidJson(currentText)) try {
|
|
182
|
+
if (JSON.stringify(JSON.parse(currentText)) === JSON.stringify(typeof value === "object" ? value : JSON.parse(sanitized))) return currentText;
|
|
183
|
+
} catch {}
|
|
184
|
+
return sanitized;
|
|
185
|
+
});
|
|
186
|
+
}, [value, isJsonMode]);
|
|
187
|
+
const handleChange = (raw) => {
|
|
188
|
+
setText(raw);
|
|
189
|
+
if (isJsonMode && isValidJson(raw)) onChange(JSON.parse(raw));
|
|
190
|
+
else onChange(raw);
|
|
191
|
+
};
|
|
192
|
+
const help = isJsonMode && !isReadOnly && options.encryptionHint !== false ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
193
|
+
"Properties prefixed with ",
|
|
194
|
+
/* @__PURE__ */ jsx("code", { children: "#" }),
|
|
195
|
+
" sign will be encrypted on save. Already encrypted strings will persist."
|
|
196
|
+
] }) : null;
|
|
197
|
+
return /* @__PURE__ */ jsx("div", {
|
|
198
|
+
id,
|
|
199
|
+
children: isReadOnly ? /* @__PURE__ */ jsx(CodeEditor, {
|
|
200
|
+
variant: "field",
|
|
201
|
+
value: text,
|
|
202
|
+
mode,
|
|
203
|
+
readOnly: true,
|
|
204
|
+
withCopyButton: true,
|
|
205
|
+
withLineNumbers: editorOptions.lineNumbers !== false
|
|
206
|
+
}) : /* @__PURE__ */ jsx(CodeEditor, {
|
|
207
|
+
variant: "field",
|
|
208
|
+
value: text,
|
|
209
|
+
mode,
|
|
210
|
+
onChange: handleChange,
|
|
211
|
+
withCopyButton: true,
|
|
212
|
+
withLineNumbers: editorOptions.lineNumbers !== false,
|
|
213
|
+
help
|
|
214
|
+
})
|
|
215
|
+
});
|
|
179
216
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
217
|
+
//#endregion
|
|
218
|
+
//#region src/blocks/RjsfSchemaEditor/fields/CodeEditorField.tsx
|
|
219
|
+
/**
|
|
220
|
+
* Field wrapper for CodeEditorWidget when used with type: "object".
|
|
221
|
+
* RJSF only applies ui:widget to primitive types, so object-typed
|
|
222
|
+
* code editors need a custom field that delegates to the widget.
|
|
223
|
+
*/
|
|
224
|
+
const CodeEditorField = ({ fieldPathId, formData, onChange, disabled, readonly, uiSchema }) => {
|
|
225
|
+
const uiOptions = uiSchema?.["ui:options"];
|
|
226
|
+
return /* @__PURE__ */ jsx(CodeEditorWidget, {
|
|
227
|
+
id: fieldPathId.$id,
|
|
228
|
+
value: formData,
|
|
229
|
+
onChange: (val) => onChange(val, fieldPathId.path),
|
|
230
|
+
disabled: !!disabled,
|
|
231
|
+
readonly: !!readonly,
|
|
232
|
+
options: uiOptions ?? {}
|
|
233
|
+
});
|
|
183
234
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
if (Array.isArray(enumSource) && enumSource.length > 0) {
|
|
196
|
-
if (enumSource.length > 1) {
|
|
197
|
-
console.warn("[RJSF] Multiple enumSource entries are not supported, only the first is used.");
|
|
198
|
-
}
|
|
199
|
-
const source = enumSource[0];
|
|
200
|
-
const watchPath = watch[source.source];
|
|
201
|
-
if (!watchPath) return [];
|
|
202
|
-
const sourceData = resolveByPath(watchPath, rootFormData);
|
|
203
|
-
if (!Array.isArray(sourceData)) return [];
|
|
204
|
-
const valueProp = extractProperty(source.value);
|
|
205
|
-
const titleProp = extractProperty(source.title);
|
|
206
|
-
return sourceData.filter((item) => item != null && typeof item === "object").map((item) => ({
|
|
207
|
-
value: String(item[valueProp] ?? ""),
|
|
208
|
-
label: String(item[titleProp] ?? item[valueProp] ?? "")
|
|
209
|
-
}));
|
|
210
|
-
}
|
|
211
|
-
return [];
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/blocks/RjsfSchemaEditor/SchemaDescription.tsx
|
|
237
|
+
/** Renders a schema description with sanitized HTML support (links, formatting, etc.). */
|
|
238
|
+
const SchemaDescription = ({ description }) => {
|
|
239
|
+
if (!description) return null;
|
|
240
|
+
return /* @__PURE__ */ jsx("p", {
|
|
241
|
+
className: "tw:text-xs tw:text-neutral-400",
|
|
242
|
+
dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(description) }
|
|
243
|
+
});
|
|
212
244
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
245
|
+
//#endregion
|
|
246
|
+
//#region src/blocks/RjsfSchemaEditor/fields/GridObjectField.tsx
|
|
247
|
+
/**
|
|
248
|
+
* Custom field that renders an object's properties in a responsive grid layout.
|
|
249
|
+
* Used for schema objects with `format: "grid"` or `"grid-strict"`.
|
|
250
|
+
* json-editor uses a 12-column grid; each property can specify `options.grid_columns`.
|
|
251
|
+
* Supports `options.collapsed` for collapsible sections.
|
|
252
|
+
*/
|
|
253
|
+
const GridObjectField = ({ schema, uiSchema = {}, formData, onChange, disabled, readonly, registry, fieldPathId }) => {
|
|
254
|
+
const properties = schema.properties ?? {};
|
|
255
|
+
const data = formData ?? {};
|
|
256
|
+
const SchemaField = getSchemaField(registry);
|
|
257
|
+
const dataRef = useRef(data);
|
|
258
|
+
dataRef.current = data;
|
|
259
|
+
const fieldPath = fieldPathId?.path;
|
|
260
|
+
const onPropertyChange = useCallback((key) => (value, _childPath, errorSchema, id) => {
|
|
261
|
+
onChange({
|
|
262
|
+
...dataRef.current,
|
|
263
|
+
[key]: value
|
|
264
|
+
}, fieldPath, errorSchema, id);
|
|
265
|
+
}, [onChange, fieldPath]);
|
|
266
|
+
const uiOptions = uiSchema["ui:options"];
|
|
267
|
+
const hasCollapsed = uiOptions?.collapsed !== void 0;
|
|
268
|
+
const collapsed = !!uiOptions?.collapsed;
|
|
269
|
+
const disableCollapse = !!uiOptions?.disableCollapse;
|
|
270
|
+
const mountedKeys = sortByPropertyOrder(properties).filter((key) => !isHiddenContainer(uiSchema[key], properties[key]));
|
|
271
|
+
if (mountedKeys.length === 0) return null;
|
|
272
|
+
const gridContent = /* @__PURE__ */ jsx("div", {
|
|
273
|
+
className: "tw:grid tw:grid-cols-12 tw:gap-4 tw:[&>div:empty]:hidden",
|
|
274
|
+
children: mountedKeys.map((key) => {
|
|
275
|
+
const gridCols = properties[key]?.options?.grid_columns ?? 12;
|
|
276
|
+
const gridBreak = !!properties[key]?.options?.grid_break;
|
|
277
|
+
return /* @__PURE__ */ jsx("div", {
|
|
278
|
+
className: isHiddenField(uiSchema[key]) ? "tw:hidden" : void 0,
|
|
279
|
+
style: { gridColumn: gridBreak ? "1 / -1" : `span ${Math.min(gridCols, 12)}` },
|
|
280
|
+
children: /* @__PURE__ */ jsx(SchemaField, {
|
|
281
|
+
name: key,
|
|
282
|
+
schema: schema.properties[key],
|
|
283
|
+
uiSchema: uiSchema[key] ?? {},
|
|
284
|
+
formData: data[key],
|
|
285
|
+
...SCHEMA_FIELD_STUBS,
|
|
286
|
+
fieldPathId: childFieldPathId(fieldPathId, key),
|
|
287
|
+
registry,
|
|
288
|
+
onChange: onPropertyChange(key),
|
|
289
|
+
disabled: !!disabled,
|
|
290
|
+
readonly: !!readonly
|
|
291
|
+
})
|
|
292
|
+
}, key);
|
|
293
|
+
})
|
|
294
|
+
});
|
|
295
|
+
if (hasCollapsed && !disableCollapse) {
|
|
296
|
+
const defaultExpanded = Object.values(data).some((v) => v !== void 0 && v !== null && v !== "" && v !== false) ? !collapsed : true;
|
|
297
|
+
return /* @__PURE__ */ jsxs(CollapsiblePanel, {
|
|
298
|
+
className: "tw:rounded-lg",
|
|
299
|
+
header: schema.title || "Settings",
|
|
300
|
+
defaultExpanded,
|
|
301
|
+
headerClassName: "tw:rounded-lg",
|
|
302
|
+
bodyClassName: "tw:flex tw:flex-col tw:gap-4",
|
|
303
|
+
children: [/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }), gridContent]
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
if (schema.title) return /* @__PURE__ */ jsxs("div", {
|
|
307
|
+
className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:p-4",
|
|
308
|
+
children: [
|
|
309
|
+
/* @__PURE__ */ jsx("h3", {
|
|
310
|
+
className: "tw:mb-3 tw:text-base tw:font-medium tw:text-neutral-800",
|
|
311
|
+
children: schema.title
|
|
312
|
+
}),
|
|
313
|
+
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
314
|
+
gridContent
|
|
315
|
+
]
|
|
316
|
+
});
|
|
317
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
318
|
+
className: "tw:flex tw:flex-col tw:gap-4",
|
|
319
|
+
children: [/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }), gridContent]
|
|
320
|
+
});
|
|
229
321
|
};
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (sortedKeys.length === 0) return null;
|
|
259
|
-
const gridContent = /* @__PURE__ */ jsx("div", { className: "tw:grid tw:grid-cols-12 tw:gap-4 tw:[&>div:empty]:hidden", children: sortedKeys.map((key) => {
|
|
260
|
-
const gridCols = properties[key]?.options?.grid_columns ?? 12;
|
|
261
|
-
const gridBreak = !!properties[key]?.options?.grid_break;
|
|
262
|
-
return /* @__PURE__ */ jsx(
|
|
263
|
-
"div",
|
|
264
|
-
{
|
|
265
|
-
style: {
|
|
266
|
-
gridColumn: gridBreak ? "1 / -1" : `span ${Math.min(gridCols, 12)}`
|
|
267
|
-
},
|
|
268
|
-
children: /* @__PURE__ */ jsx(
|
|
269
|
-
SchemaField,
|
|
270
|
-
{
|
|
271
|
-
name: key,
|
|
272
|
-
schema: schema.properties[key],
|
|
273
|
-
uiSchema: uiSchema[key] ?? {},
|
|
274
|
-
formData: data[key],
|
|
275
|
-
...SCHEMA_FIELD_STUBS,
|
|
276
|
-
fieldPathId: childFieldPathId(fieldPathId, key),
|
|
277
|
-
registry,
|
|
278
|
-
onChange: onPropertyChange(key),
|
|
279
|
-
disabled: !!disabled,
|
|
280
|
-
readonly: !!readonly
|
|
281
|
-
}
|
|
282
|
-
)
|
|
283
|
-
},
|
|
284
|
-
key
|
|
285
|
-
);
|
|
286
|
-
}) });
|
|
287
|
-
if (hasCollapsed && !disableCollapse) {
|
|
288
|
-
const hasValues = Object.values(data).some(
|
|
289
|
-
(v) => v !== void 0 && v !== null && v !== "" && v !== false
|
|
290
|
-
);
|
|
291
|
-
const defaultExpanded = hasValues ? !collapsed : true;
|
|
292
|
-
return /* @__PURE__ */ jsxs(
|
|
293
|
-
CollapsiblePanel,
|
|
294
|
-
{
|
|
295
|
-
className: "tw:rounded-lg",
|
|
296
|
-
header: schema.title || "Settings",
|
|
297
|
-
defaultExpanded,
|
|
298
|
-
headerClassName: "tw:rounded-lg",
|
|
299
|
-
bodyClassName: "tw:flex tw:flex-col tw:gap-4",
|
|
300
|
-
children: [
|
|
301
|
-
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
302
|
-
gridContent
|
|
303
|
-
]
|
|
304
|
-
}
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
if (schema.title) {
|
|
308
|
-
return /* @__PURE__ */ jsxs("div", { className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:p-4", children: [
|
|
309
|
-
/* @__PURE__ */ jsx("h3", { className: "tw:mb-3 tw:text-base tw:font-medium tw:text-neutral-800", children: schema.title }),
|
|
310
|
-
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
311
|
-
gridContent
|
|
312
|
-
] });
|
|
313
|
-
}
|
|
314
|
-
return /* @__PURE__ */ jsxs("div", { className: "tw:flex tw:flex-col tw:gap-4", children: [
|
|
315
|
-
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
316
|
-
gridContent
|
|
317
|
-
] });
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/blocks/RjsfSchemaEditor/fields/InfoField.tsx
|
|
324
|
+
const VALID_ALERT_TYPES = /* @__PURE__ */ new Set([
|
|
325
|
+
"info",
|
|
326
|
+
"warning",
|
|
327
|
+
"error",
|
|
328
|
+
"success"
|
|
329
|
+
]);
|
|
330
|
+
/**
|
|
331
|
+
* Custom field that renders static informational text.
|
|
332
|
+
* Used for schema properties with `format: "info"`.
|
|
333
|
+
* Displays title and description as a read-only alert.
|
|
334
|
+
* Supports `options.alert_type` to control the alert variant
|
|
335
|
+
* (`"info"` (default), `"warning"`, `"error"`, `"success"`).
|
|
336
|
+
*/
|
|
337
|
+
const InfoField = ({ schema, uiSchema }) => {
|
|
338
|
+
if (!schema.title && !schema.description) return null;
|
|
339
|
+
const uiOptions = uiSchema?.["ui:options"];
|
|
340
|
+
const alertType = String(uiOptions?.alertType ?? "info");
|
|
341
|
+
const variant = VALID_ALERT_TYPES.has(alertType) ? alertType : "info";
|
|
342
|
+
return /* @__PURE__ */ jsx("div", {
|
|
343
|
+
className: "tw:my-3",
|
|
344
|
+
children: /* @__PURE__ */ jsx(Alert, {
|
|
345
|
+
variant,
|
|
346
|
+
title: schema.title,
|
|
347
|
+
children: schema.description
|
|
348
|
+
})
|
|
349
|
+
});
|
|
318
350
|
};
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/blocks/RjsfSchemaEditor/TooltipIcon.tsx
|
|
353
|
+
const TooltipIcon = ({ rawHelp }) => {
|
|
354
|
+
const renderMarkdown = useRenderMarkdown();
|
|
355
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
356
|
+
placement: "top",
|
|
357
|
+
variant: "explanatory",
|
|
358
|
+
tooltip: renderMarkdown(rawHelp),
|
|
359
|
+
triggerAsChild: true,
|
|
360
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
361
|
+
className: "tw:cursor-help tw:text-neutral-400",
|
|
362
|
+
children: /* @__PURE__ */ jsx(Info, { className: "tw:size-4" })
|
|
363
|
+
})
|
|
364
|
+
});
|
|
326
365
|
};
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region src/blocks/RjsfSchemaEditor/fields/TableArrayField.tsx
|
|
368
|
+
/** Default value for a freshly added cell/item, honouring the schema default. */
|
|
369
|
+
const defaultValueFor = (prop) => {
|
|
370
|
+
if (prop.default !== void 0) return prop.default;
|
|
371
|
+
if (prop.type === "boolean") return false;
|
|
372
|
+
if (prop.type === "string") return "";
|
|
330
373
|
};
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
374
|
+
/**
|
|
375
|
+
* Custom field that renders an array as a table.
|
|
376
|
+
* Used for schema arrays with `format: "table"`.
|
|
377
|
+
*
|
|
378
|
+
* - Array of objects: each item is a row, each property a column.
|
|
379
|
+
* - Array of primitives (e.g. `items: { type: 'string' }`): each item is a
|
|
380
|
+
* single-column row holding the value itself.
|
|
381
|
+
*
|
|
382
|
+
* Cells are rendered via RJSF's SchemaField so all registered widgets are used.
|
|
383
|
+
*/
|
|
384
|
+
const TableArrayField = ({ schema, uiSchema = {}, formData, onChange, disabled, readonly, registry, fieldPathId }) => {
|
|
385
|
+
const items = formData ?? [];
|
|
386
|
+
const itemSchema = schema.items;
|
|
387
|
+
const properties = itemSchema?.properties ?? {};
|
|
388
|
+
const itemUiSchema = uiSchema.items ?? {};
|
|
389
|
+
const SchemaField = getSchemaField(registry);
|
|
390
|
+
const allKeys = sortByPropertyOrder(properties);
|
|
391
|
+
const columnKeys = allKeys.filter((key) => !isHiddenField(itemUiSchema[key]));
|
|
392
|
+
const isPrimitiveItems = allKeys.length === 0 && itemSchema != null;
|
|
393
|
+
const isReadOnly = disabled || readonly;
|
|
394
|
+
const fieldPath = fieldPathId?.path ?? [];
|
|
395
|
+
const itemsRef = useRef(items);
|
|
396
|
+
itemsRef.current = items;
|
|
397
|
+
const handleCellChange = (rowIndex, key, value) => {
|
|
398
|
+
const newItems = [...itemsRef.current];
|
|
399
|
+
newItems[rowIndex] = {
|
|
400
|
+
...newItems[rowIndex],
|
|
401
|
+
[key]: value
|
|
402
|
+
};
|
|
403
|
+
onChange(newItems, fieldPath);
|
|
404
|
+
};
|
|
405
|
+
const handleItemChange = (rowIndex, value) => {
|
|
406
|
+
const newItems = [...itemsRef.current];
|
|
407
|
+
newItems[rowIndex] = value;
|
|
408
|
+
onChange(newItems, fieldPath);
|
|
409
|
+
};
|
|
410
|
+
const handleRemoveRow = (rowIndex) => {
|
|
411
|
+
onChange(itemsRef.current.filter((_, i) => i !== rowIndex), fieldPath);
|
|
412
|
+
};
|
|
413
|
+
const handleAddRow = () => {
|
|
414
|
+
if (isPrimitiveItems) {
|
|
415
|
+
onChange([...itemsRef.current, defaultValueFor({
|
|
416
|
+
type: itemSchema?.type,
|
|
417
|
+
default: itemSchema?.default
|
|
418
|
+
})], fieldPath);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const newItem = {};
|
|
422
|
+
for (const key of allKeys) newItem[key] = defaultValueFor(properties[key] ?? {});
|
|
423
|
+
onChange([...itemsRef.current, newItem], fieldPath);
|
|
424
|
+
};
|
|
425
|
+
const withHiddenLabel = (base) => ({
|
|
426
|
+
...base,
|
|
427
|
+
"ui:options": {
|
|
428
|
+
...base["ui:options"],
|
|
429
|
+
label: false
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
const getCellUiSchema = (key) => withHiddenLabel(itemUiSchema[key] ?? {});
|
|
433
|
+
const table = items.length > 0 && /* @__PURE__ */ jsxs("table", {
|
|
434
|
+
className: "tw:w-full tw:table-fixed tw:border-collapse tw:text-sm",
|
|
435
|
+
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [isPrimitiveItems ? /* @__PURE__ */ jsx("th", {
|
|
436
|
+
className: "tw:border-b tw:border-neutral-200 tw:p-2 tw:text-left tw:text-xs tw:font-medium tw:text-neutral-600",
|
|
437
|
+
children: itemSchema?.title ?? ""
|
|
438
|
+
}) : columnKeys.map((key) => /* @__PURE__ */ jsx("th", {
|
|
439
|
+
className: "tw:border-b tw:border-neutral-200 tw:p-2 tw:text-left tw:text-xs tw:font-medium tw:text-neutral-600",
|
|
440
|
+
children: properties[key]?.title ?? key
|
|
441
|
+
}, key)), !isReadOnly && /* @__PURE__ */ jsx("th", { className: "tw:w-20" })] }) }), /* @__PURE__ */ jsx("tbody", { children: items.map((item, rowIndex) => /* @__PURE__ */ jsxs("tr", {
|
|
442
|
+
className: "tw:border-b tw:border-neutral-100",
|
|
443
|
+
children: [isPrimitiveItems ? /* @__PURE__ */ jsx("td", {
|
|
444
|
+
className: "tw:px-2 tw:py-1.5 tw:[&>div]:mb-0",
|
|
445
|
+
children: /* @__PURE__ */ jsx(SchemaField, {
|
|
446
|
+
name: String(rowIndex),
|
|
447
|
+
schema: itemSchema,
|
|
448
|
+
uiSchema: withHiddenLabel(itemUiSchema),
|
|
449
|
+
formData: item,
|
|
450
|
+
...SCHEMA_FIELD_STUBS,
|
|
451
|
+
fieldPathId: childFieldPathId(fieldPathId, rowIndex),
|
|
452
|
+
registry,
|
|
453
|
+
onChange: (val) => handleItemChange(rowIndex, val),
|
|
454
|
+
disabled: !!disabled,
|
|
455
|
+
readonly: !!readonly
|
|
456
|
+
})
|
|
457
|
+
}) : columnKeys.map((key) => /* @__PURE__ */ jsx("td", {
|
|
458
|
+
className: "tw:px-2 tw:py-1.5 tw:[&>div]:mb-0",
|
|
459
|
+
children: /* @__PURE__ */ jsx(SchemaField, {
|
|
460
|
+
name: key,
|
|
461
|
+
schema: properties[key],
|
|
462
|
+
uiSchema: getCellUiSchema(key),
|
|
463
|
+
formData: item[key],
|
|
464
|
+
...SCHEMA_FIELD_STUBS,
|
|
465
|
+
fieldPathId: childFieldPathId(fieldPathId, rowIndex, key),
|
|
466
|
+
registry,
|
|
467
|
+
onChange: (val) => handleCellChange(rowIndex, key, val),
|
|
468
|
+
disabled: !!disabled,
|
|
469
|
+
readonly: !!readonly
|
|
470
|
+
})
|
|
471
|
+
}, key)), !isReadOnly && /* @__PURE__ */ jsx("td", {
|
|
472
|
+
className: "tw:px-2 tw:py-1.5 tw:text-right",
|
|
473
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
474
|
+
variant: "invisible",
|
|
475
|
+
size: "icon",
|
|
476
|
+
onClick: () => handleRemoveRow(rowIndex),
|
|
477
|
+
"aria-label": "Remove row",
|
|
478
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "tw:size-4" })
|
|
479
|
+
})
|
|
480
|
+
})]
|
|
481
|
+
}, rowIndex)) })]
|
|
482
|
+
});
|
|
483
|
+
const addButton = !isReadOnly && /* @__PURE__ */ jsxs(Button, {
|
|
484
|
+
variant: "outline",
|
|
485
|
+
onClick: handleAddRow,
|
|
486
|
+
children: ["Add ", itemSchema?.title || "Item"]
|
|
487
|
+
});
|
|
488
|
+
if (schema.title) {
|
|
489
|
+
const tooltip = uiSchema["ui:help"];
|
|
490
|
+
return /* @__PURE__ */ jsxs(CollapsiblePanel, {
|
|
491
|
+
className: "tw:rounded-lg",
|
|
492
|
+
headerClassName: "tw:rounded-lg",
|
|
493
|
+
header: /* @__PURE__ */ jsxs("span", {
|
|
494
|
+
className: "tw:inline-flex tw:items-center tw:gap-1",
|
|
495
|
+
children: [schema.title, tooltip && /* @__PURE__ */ jsx(TooltipIcon, { rawHelp: tooltip })]
|
|
496
|
+
}),
|
|
497
|
+
defaultExpanded: true,
|
|
498
|
+
bodyClassName: "tw:flex tw:flex-col tw:gap-4",
|
|
499
|
+
children: [
|
|
500
|
+
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
501
|
+
table,
|
|
502
|
+
addButton
|
|
503
|
+
]
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
507
|
+
className: "tw:flex tw:flex-col tw:gap-4",
|
|
508
|
+
children: [
|
|
509
|
+
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
510
|
+
table,
|
|
511
|
+
addButton
|
|
512
|
+
]
|
|
513
|
+
});
|
|
336
514
|
};
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
label: false
|
|
399
|
-
}
|
|
400
|
-
});
|
|
401
|
-
const getCellUiSchema = (key) => withHiddenLabel(itemUiSchema[key] ?? {});
|
|
402
|
-
const table = items.length > 0 && /* @__PURE__ */ jsxs("table", { className: "tw:w-full tw:table-fixed tw:border-collapse tw:text-sm", children: [
|
|
403
|
-
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
404
|
-
isPrimitiveItems ? /* @__PURE__ */ jsx("th", { className: "tw:border-b tw:border-neutral-200 tw:p-2 tw:text-left tw:text-xs tw:font-medium tw:text-neutral-600", children: itemSchema?.title ?? "" }) : sortedKeys.map((key) => /* @__PURE__ */ jsx(
|
|
405
|
-
"th",
|
|
406
|
-
{
|
|
407
|
-
className: "tw:border-b tw:border-neutral-200 tw:p-2 tw:text-left tw:text-xs tw:font-medium tw:text-neutral-600",
|
|
408
|
-
children: properties[key]?.title ?? key
|
|
409
|
-
},
|
|
410
|
-
key
|
|
411
|
-
)),
|
|
412
|
-
!isReadOnly && /* @__PURE__ */ jsx("th", { className: "tw:w-20" })
|
|
413
|
-
] }) }),
|
|
414
|
-
/* @__PURE__ */ jsx("tbody", { children: items.map((item, rowIndex) => /* @__PURE__ */ jsxs("tr", { className: "tw:border-b tw:border-neutral-100", children: [
|
|
415
|
-
isPrimitiveItems ? /* @__PURE__ */ jsx("td", { className: "tw:px-2 tw:py-1.5 tw:[&>div]:mb-0", children: /* @__PURE__ */ jsx(
|
|
416
|
-
SchemaField,
|
|
417
|
-
{
|
|
418
|
-
name: String(rowIndex),
|
|
419
|
-
schema: itemSchema,
|
|
420
|
-
uiSchema: withHiddenLabel(itemUiSchema),
|
|
421
|
-
formData: item,
|
|
422
|
-
...SCHEMA_FIELD_STUBS,
|
|
423
|
-
fieldPathId: childFieldPathId(fieldPathId, rowIndex),
|
|
424
|
-
registry,
|
|
425
|
-
onChange: (val) => handleItemChange(rowIndex, val),
|
|
426
|
-
disabled: !!disabled,
|
|
427
|
-
readonly: !!readonly
|
|
428
|
-
}
|
|
429
|
-
) }) : sortedKeys.map((key) => /* @__PURE__ */ jsx("td", { className: "tw:px-2 tw:py-1.5 tw:[&>div]:mb-0", children: /* @__PURE__ */ jsx(
|
|
430
|
-
SchemaField,
|
|
431
|
-
{
|
|
432
|
-
name: key,
|
|
433
|
-
schema: properties[key],
|
|
434
|
-
uiSchema: getCellUiSchema(key),
|
|
435
|
-
formData: item[key],
|
|
436
|
-
...SCHEMA_FIELD_STUBS,
|
|
437
|
-
fieldPathId: childFieldPathId(fieldPathId, rowIndex, key),
|
|
438
|
-
registry,
|
|
439
|
-
onChange: (val) => handleCellChange(rowIndex, key, val),
|
|
440
|
-
disabled: !!disabled,
|
|
441
|
-
readonly: !!readonly
|
|
442
|
-
}
|
|
443
|
-
) }, key)),
|
|
444
|
-
!isReadOnly && /* @__PURE__ */ jsx("td", { className: "tw:px-2 tw:py-1.5 tw:text-right", children: /* @__PURE__ */ jsx(
|
|
445
|
-
Button,
|
|
446
|
-
{
|
|
447
|
-
variant: "invisible",
|
|
448
|
-
size: "icon",
|
|
449
|
-
onClick: () => handleRemoveRow(rowIndex),
|
|
450
|
-
"aria-label": "Remove row",
|
|
451
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "tw:size-4" })
|
|
452
|
-
}
|
|
453
|
-
) })
|
|
454
|
-
] }, rowIndex)) })
|
|
455
|
-
] });
|
|
456
|
-
const addButton = !isReadOnly && /* @__PURE__ */ jsxs(Button, { variant: "outline", onClick: handleAddRow, children: [
|
|
457
|
-
"Add ",
|
|
458
|
-
itemSchema?.title || "Item"
|
|
459
|
-
] });
|
|
460
|
-
if (schema.title) {
|
|
461
|
-
const tooltip = uiSchema["ui:help"];
|
|
462
|
-
return /* @__PURE__ */ jsxs(
|
|
463
|
-
CollapsiblePanel,
|
|
464
|
-
{
|
|
465
|
-
className: "tw:rounded-lg",
|
|
466
|
-
headerClassName: "tw:rounded-lg",
|
|
467
|
-
header: /* @__PURE__ */ jsxs("span", { className: "tw:inline-flex tw:items-center tw:gap-1", children: [
|
|
468
|
-
schema.title,
|
|
469
|
-
tooltip && /* @__PURE__ */ jsx(TooltipIcon, { rawHelp: tooltip })
|
|
470
|
-
] }),
|
|
471
|
-
defaultExpanded: true,
|
|
472
|
-
bodyClassName: "tw:flex tw:flex-col tw:gap-4",
|
|
473
|
-
children: [
|
|
474
|
-
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
475
|
-
table,
|
|
476
|
-
addButton
|
|
477
|
-
]
|
|
478
|
-
}
|
|
479
|
-
);
|
|
480
|
-
}
|
|
481
|
-
return /* @__PURE__ */ jsxs("div", { className: "tw:flex tw:flex-col tw:gap-4", children: [
|
|
482
|
-
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
483
|
-
table,
|
|
484
|
-
addButton
|
|
485
|
-
] });
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region src/blocks/RjsfSchemaEditor/fields/TabsObjectField.tsx
|
|
517
|
+
/**
|
|
518
|
+
* Custom field that renders an object's properties as tabs.
|
|
519
|
+
* Used for schema objects with `format: "tabs"`, `"tabs-top"`, or `"categories"`.
|
|
520
|
+
* Each property becomes a tab panel.
|
|
521
|
+
*/
|
|
522
|
+
const TabsObjectField = ({ schema, uiSchema = {}, formData, onChange, disabled, readonly, registry, fieldPathId }) => {
|
|
523
|
+
const properties = schema.properties ?? {};
|
|
524
|
+
const data = formData ?? {};
|
|
525
|
+
const SchemaField = getSchemaField(registry);
|
|
526
|
+
const dataRef = useRef(data);
|
|
527
|
+
dataRef.current = data;
|
|
528
|
+
const onPropertyChange = useCallback((key) => (value, path, errorSchema, id) => {
|
|
529
|
+
onChange({
|
|
530
|
+
...dataRef.current,
|
|
531
|
+
[key]: value
|
|
532
|
+
}, path, errorSchema, id);
|
|
533
|
+
}, [onChange]);
|
|
534
|
+
const mountedKeys = sortByPropertyOrder(properties).filter((key) => !isHiddenContainer(uiSchema[key], properties[key]));
|
|
535
|
+
const tabKeys = mountedKeys.filter((key) => !isHiddenField(uiSchema[key]));
|
|
536
|
+
const hiddenLeafKeys = mountedKeys.filter((key) => isHiddenField(uiSchema[key]));
|
|
537
|
+
const [activeTab, setActiveTab] = useState(tabKeys[0] ?? "");
|
|
538
|
+
if (mountedKeys.length === 0) return null;
|
|
539
|
+
const triggers = tabKeys.map((key) => ({
|
|
540
|
+
value: key,
|
|
541
|
+
title: properties[key]?.title ?? key
|
|
542
|
+
}));
|
|
543
|
+
const renderField = (key) => /* @__PURE__ */ jsx(SchemaField, {
|
|
544
|
+
name: key,
|
|
545
|
+
schema: schema.properties[key],
|
|
546
|
+
uiSchema: uiSchema[key] ?? {},
|
|
547
|
+
formData: data[key],
|
|
548
|
+
...SCHEMA_FIELD_STUBS,
|
|
549
|
+
fieldPathId: childFieldPathId(fieldPathId, key),
|
|
550
|
+
registry,
|
|
551
|
+
onChange: onPropertyChange(key),
|
|
552
|
+
disabled: !!disabled,
|
|
553
|
+
readonly: !!readonly
|
|
554
|
+
}, key);
|
|
555
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
556
|
+
className: "tw:flex tw:flex-col tw:gap-4",
|
|
557
|
+
children: [
|
|
558
|
+
schema.title && /* @__PURE__ */ jsx("h3", {
|
|
559
|
+
className: "tw:text-base tw:font-medium tw:text-neutral-800",
|
|
560
|
+
children: schema.title
|
|
561
|
+
}),
|
|
562
|
+
/* @__PURE__ */ jsx(SchemaDescription, { description: schema.description }),
|
|
563
|
+
tabKeys.length > 0 && /* @__PURE__ */ jsx(Tabs, {
|
|
564
|
+
triggers,
|
|
565
|
+
value: activeTab,
|
|
566
|
+
onValueChange: setActiveTab,
|
|
567
|
+
compact: true,
|
|
568
|
+
children: tabKeys.map((key) => /* @__PURE__ */ jsx(TabsContent, {
|
|
569
|
+
value: key,
|
|
570
|
+
children: renderField(key)
|
|
571
|
+
}, key))
|
|
572
|
+
}),
|
|
573
|
+
hiddenLeafKeys.map(renderField)
|
|
574
|
+
]
|
|
575
|
+
});
|
|
486
576
|
};
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
577
|
+
//#endregion
|
|
578
|
+
//#region src/blocks/RjsfSchemaEditor/templates/ArrayFieldItemTemplate.tsx
|
|
579
|
+
const ArrayFieldItemTemplate = ({ children, index, totalItems, schema, hasToolbar, disabled, readonly, buttonsProps }) => {
|
|
580
|
+
const isObject = schema.type === "object";
|
|
581
|
+
const canRemove = hasToolbar && buttonsProps.hasRemove && !disabled && !readonly;
|
|
582
|
+
if (isObject) {
|
|
583
|
+
const itemTitle = `${schema.title || "Item"} ${index + 1}`;
|
|
584
|
+
const defaultExpanded = totalItems <= 1;
|
|
585
|
+
return /* @__PURE__ */ jsx(CollapsiblePanel, {
|
|
586
|
+
className: "tw:rounded-lg",
|
|
587
|
+
headerClassName: "tw:rounded-lg",
|
|
588
|
+
header: /* @__PURE__ */ jsxs("div", {
|
|
589
|
+
className: "tw:flex tw:w-full tw:items-center tw:justify-between",
|
|
590
|
+
children: [/* @__PURE__ */ jsx("span", { children: itemTitle }), canRemove && /* @__PURE__ */ jsx("div", {
|
|
591
|
+
role: "presentation",
|
|
592
|
+
onClick: (e) => e.stopPropagation(),
|
|
593
|
+
onKeyUp: (e) => e.stopPropagation(),
|
|
594
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
595
|
+
variant: "invisible",
|
|
596
|
+
size: "icon",
|
|
597
|
+
"aria-label": `Remove ${itemTitle}`,
|
|
598
|
+
onClick: buttonsProps.onRemoveItem,
|
|
599
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "tw:size-4" })
|
|
600
|
+
})
|
|
601
|
+
})]
|
|
602
|
+
}),
|
|
603
|
+
defaultExpanded,
|
|
604
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
605
|
+
className: "tw:flex tw:flex-col tw:gap-4",
|
|
606
|
+
children
|
|
607
|
+
})
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
return /* @__PURE__ */ jsx("div", {
|
|
611
|
+
className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:bg-white tw:p-4",
|
|
612
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
613
|
+
className: "tw:flex tw:items-start tw:gap-3",
|
|
614
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
615
|
+
className: "tw:flex tw:flex-1 tw:flex-col tw:gap-4",
|
|
616
|
+
children
|
|
617
|
+
}), canRemove && /* @__PURE__ */ jsx(Button, {
|
|
618
|
+
variant: "outline",
|
|
619
|
+
size: "small",
|
|
620
|
+
className: "tw:mt-5 tw:shrink-0",
|
|
621
|
+
onClick: buttonsProps.onRemoveItem,
|
|
622
|
+
children: "Delete"
|
|
623
|
+
})]
|
|
624
|
+
})
|
|
625
|
+
});
|
|
535
626
|
};
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
"div",
|
|
560
|
-
{
|
|
561
|
-
role: "presentation",
|
|
562
|
-
onClick: (e) => e.stopPropagation(),
|
|
563
|
-
onKeyUp: (e) => e.stopPropagation(),
|
|
564
|
-
children: /* @__PURE__ */ jsx(
|
|
565
|
-
Button,
|
|
566
|
-
{
|
|
567
|
-
variant: "invisible",
|
|
568
|
-
size: "icon",
|
|
569
|
-
"aria-label": `Remove ${itemTitle}`,
|
|
570
|
-
onClick: buttonsProps.onRemoveItem,
|
|
571
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "tw:size-4" })
|
|
572
|
-
}
|
|
573
|
-
)
|
|
574
|
-
}
|
|
575
|
-
)
|
|
576
|
-
] }),
|
|
577
|
-
defaultExpanded,
|
|
578
|
-
children: /* @__PURE__ */ jsx("div", { className: "tw:flex tw:flex-col tw:gap-4", children })
|
|
579
|
-
}
|
|
580
|
-
);
|
|
581
|
-
}
|
|
582
|
-
return /* @__PURE__ */ jsx("div", { className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:bg-white tw:p-4", children: /* @__PURE__ */ jsxs("div", { className: "tw:flex tw:items-start tw:gap-3", children: [
|
|
583
|
-
/* @__PURE__ */ jsx("div", { className: "tw:flex tw:flex-1 tw:flex-col tw:gap-4", children }),
|
|
584
|
-
canRemove && /* @__PURE__ */ jsx(
|
|
585
|
-
Button,
|
|
586
|
-
{
|
|
587
|
-
variant: "outline",
|
|
588
|
-
size: "small",
|
|
589
|
-
className: "tw:mt-5 tw:shrink-0",
|
|
590
|
-
onClick: buttonsProps.onRemoveItem,
|
|
591
|
-
children: "Delete"
|
|
592
|
-
}
|
|
593
|
-
)
|
|
594
|
-
] }) });
|
|
627
|
+
//#endregion
|
|
628
|
+
//#region src/blocks/RjsfSchemaEditor/templates/ArrayFieldTemplate.tsx
|
|
629
|
+
const ArrayFieldTemplate = ({ items, canAdd, onAddClick, title, schema, disabled, readonly }) => {
|
|
630
|
+
const isReadOnly = disabled || readonly;
|
|
631
|
+
const itemLabel = typeof schema.items === "object" && schema.items !== null && !Array.isArray(schema.items) ? schema.items.title || "Item" : "Item";
|
|
632
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
633
|
+
className: "tw:flex tw:flex-col tw:gap-4",
|
|
634
|
+
children: [
|
|
635
|
+
(title || schema.description) && /* @__PURE__ */ jsxs("div", { children: [title && /* @__PURE__ */ jsx("h3", {
|
|
636
|
+
className: "tw:text-base tw:font-medium tw:text-neutral-800",
|
|
637
|
+
children: title
|
|
638
|
+
}), schema.description && /* @__PURE__ */ jsx("p", {
|
|
639
|
+
className: "tw:mt-1 tw:text-xs tw:text-neutral-400",
|
|
640
|
+
children: schema.description
|
|
641
|
+
})] }),
|
|
642
|
+
items,
|
|
643
|
+
canAdd && !isReadOnly && /* @__PURE__ */ jsxs(Button, {
|
|
644
|
+
variant: "outline",
|
|
645
|
+
onClick: onAddClick,
|
|
646
|
+
children: ["Add ", itemLabel]
|
|
647
|
+
})
|
|
648
|
+
]
|
|
649
|
+
});
|
|
595
650
|
};
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}) => {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
itemLabel
|
|
616
|
-
] })
|
|
617
|
-
] });
|
|
651
|
+
//#endregion
|
|
652
|
+
//#region src/blocks/RjsfSchemaEditor/templates/DescriptionFieldTemplate.tsx
|
|
653
|
+
/**
|
|
654
|
+
* Custom description template that renders HTML in schema descriptions.
|
|
655
|
+
* Uses DOMPurify to sanitize the HTML before rendering.
|
|
656
|
+
* Schema descriptions are authored by component developers and may contain
|
|
657
|
+
* links (<a>), formatting (<strong>, <code>, <br>), etc.
|
|
658
|
+
*/
|
|
659
|
+
const DescriptionFieldTemplate = ({ description, id }) => {
|
|
660
|
+
if (!description) return null;
|
|
661
|
+
if (isValidElement(description)) return /* @__PURE__ */ jsx("div", {
|
|
662
|
+
id,
|
|
663
|
+
children: description
|
|
664
|
+
});
|
|
665
|
+
return /* @__PURE__ */ jsx("p", {
|
|
666
|
+
id,
|
|
667
|
+
className: "tw:text-xs tw:text-neutral-400",
|
|
668
|
+
dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(String(description)) }
|
|
669
|
+
});
|
|
618
670
|
};
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
);
|
|
671
|
+
//#endregion
|
|
672
|
+
//#region src/blocks/RjsfSchemaEditor/templates/ErrorListTemplate.tsx
|
|
673
|
+
const ErrorListTemplate = ({ errors }) => {
|
|
674
|
+
if (!errors.length) return null;
|
|
675
|
+
return /* @__PURE__ */ jsx("div", {
|
|
676
|
+
className: "tw:mb-4",
|
|
677
|
+
children: errors.map((error) => /* @__PURE__ */ jsx("p", {
|
|
678
|
+
className: "tw:text-xs tw:text-error-500",
|
|
679
|
+
children: error.message
|
|
680
|
+
}, `${error.property}:${error.message}`))
|
|
681
|
+
});
|
|
632
682
|
};
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region src/blocks/RjsfSchemaEditor/RootFormDataContext.ts
|
|
685
|
+
const RootFormDataContext = createContext({
|
|
686
|
+
data: {},
|
|
687
|
+
context: {}
|
|
688
|
+
});
|
|
689
|
+
const RootFormDataProvider = RootFormDataContext;
|
|
690
|
+
const useRootFormData = () => use(RootFormDataContext).data;
|
|
691
|
+
const useRootContext = () => use(RootFormDataContext).context;
|
|
692
|
+
//#endregion
|
|
693
|
+
//#region src/blocks/RjsfSchemaEditor/templates/FieldTemplate.tsx
|
|
694
|
+
/**
|
|
695
|
+
* Resolves a dot-path against an object.
|
|
696
|
+
*/
|
|
697
|
+
const resolveByPath$1 = (parts, data) => {
|
|
698
|
+
let current = data;
|
|
699
|
+
for (const part of parts) {
|
|
700
|
+
if (current == null || typeof current !== "object") return void 0;
|
|
701
|
+
current = current[part];
|
|
702
|
+
}
|
|
703
|
+
return current;
|
|
636
704
|
};
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
705
|
+
/**
|
|
706
|
+
* Resolves a dependency path against form data.
|
|
707
|
+
*
|
|
708
|
+
* - Paths starting with "root." are resolved from the root form data
|
|
709
|
+
* - Other paths are resolved as siblings (relative to the parent object)
|
|
710
|
+
*/
|
|
711
|
+
const resolveDependencyValue = (path, formData, parentPath) => {
|
|
712
|
+
if (path.startsWith("root.")) return resolveByPath$1(path.replace(/^root\./, "").split("."), formData);
|
|
713
|
+
const parent = resolveByPath$1(parentPath.map(String), formData);
|
|
714
|
+
if (parent && typeof parent === "object") {
|
|
715
|
+
const sibling = resolveByPath$1(path.split("."), parent);
|
|
716
|
+
if (sibling !== void 0) return sibling;
|
|
717
|
+
}
|
|
718
|
+
return resolveByPath$1(path.split("."), formData);
|
|
647
719
|
};
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
720
|
+
/**
|
|
721
|
+
* Evaluates json-editor `options.dependencies` against current form data.
|
|
722
|
+
* Returns true if the field should be visible.
|
|
723
|
+
*
|
|
724
|
+
* Rules (matching old json-editor behavior):
|
|
725
|
+
* - `{ "field": "value" }` — show when field equals value
|
|
726
|
+
* - `{ "field": ["a", "b"] }` — show when field is one of the values
|
|
727
|
+
* - `{ "field": "" }` — show when field is empty/falsy
|
|
728
|
+
* - Multiple entries are AND-ed: all conditions must match
|
|
729
|
+
*/
|
|
730
|
+
const evaluateDependencies = (dependencies, formData, parentPath) => {
|
|
731
|
+
for (const [path, expected] of Object.entries(dependencies)) {
|
|
732
|
+
const actual = resolveDependencyValue(path, formData, parentPath);
|
|
733
|
+
if (Array.isArray(expected)) {
|
|
734
|
+
if (!expected.includes(actual)) return false;
|
|
735
|
+
} else if (expected === "") {
|
|
736
|
+
if (actual !== "" && actual !== void 0 && actual !== null) return false;
|
|
737
|
+
} else if (actual !== expected) return false;
|
|
738
|
+
}
|
|
739
|
+
return true;
|
|
658
740
|
};
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
741
|
+
const DocumentationLinkIcon = ({ documentation }) => /* @__PURE__ */ jsx(Tooltip, {
|
|
742
|
+
placement: "top",
|
|
743
|
+
variant: "explanatory",
|
|
744
|
+
tooltip: documentation.tooltip ?? "Open documentation",
|
|
745
|
+
triggerAsChild: true,
|
|
746
|
+
children: /* @__PURE__ */ jsx(Link, {
|
|
747
|
+
href: documentation.link,
|
|
748
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
749
|
+
className: "tw:cursor-pointer tw:text-neutral-400 tw:hover:text-neutral-600",
|
|
750
|
+
children: /* @__PURE__ */ jsx(BookOpen, { className: "tw:size-4" })
|
|
751
|
+
})
|
|
752
|
+
})
|
|
753
|
+
});
|
|
754
|
+
/**
|
|
755
|
+
* Renders the field's FormGroup wrapper, label, help, and errors.
|
|
756
|
+
* Does NOT subscribe to RootFormDataContext — that subscription only happens
|
|
757
|
+
* inside FieldTemplateWithDependencies, so fields without dependencies don't
|
|
758
|
+
* re-render on every form-state change.
|
|
759
|
+
*/
|
|
760
|
+
const FieldTemplateBody = ({ id, label, rawHelp, rawDescription, rawErrors, children, schema, uiSchema, displayLabel }) => {
|
|
761
|
+
const widget = uiSchema?.["ui:widget"];
|
|
762
|
+
if (widget === "test-connection" || widget === "sync-action") return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
763
|
+
if (schema.type === "object") return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
764
|
+
if (schema.type === "array" && !uiSchema?.["ui:widget"]) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
765
|
+
const documentation = (uiSchema?.["ui:options"])?.documentation;
|
|
766
|
+
const hasErrors = rawErrors && rawErrors.length > 0;
|
|
767
|
+
const isCheckbox = schema.type === "boolean" && uiSchema?.["ui:widget"] !== "select";
|
|
768
|
+
const showLabel = displayLabel && label && !isCheckbox;
|
|
769
|
+
const hasHelpIcons = Boolean(rawHelp || documentation);
|
|
770
|
+
const helpIcons = /* @__PURE__ */ jsxs(Fragment$1, { children: [rawHelp && /* @__PURE__ */ jsx(TooltipIcon, { rawHelp }), documentation && /* @__PURE__ */ jsx(DocumentationLinkIcon, { documentation })] });
|
|
771
|
+
return /* @__PURE__ */ jsxs(FormGroup, {
|
|
772
|
+
state: hasErrors ? "error" : "default",
|
|
773
|
+
children: [
|
|
774
|
+
showLabel && /* @__PURE__ */ jsx(Label, {
|
|
775
|
+
htmlFor: id,
|
|
776
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
777
|
+
className: "tw:inline-flex tw:items-center tw:gap-1",
|
|
778
|
+
children: [label, helpIcons]
|
|
779
|
+
})
|
|
780
|
+
}),
|
|
781
|
+
!showLabel && !isCheckbox && hasHelpIcons && /* @__PURE__ */ jsx("div", {
|
|
782
|
+
className: "tw:flex tw:items-center tw:gap-1",
|
|
783
|
+
children: helpIcons
|
|
784
|
+
}),
|
|
785
|
+
isCheckbox && hasHelpIcons ? /* @__PURE__ */ jsxs("div", {
|
|
786
|
+
className: "tw:flex tw:items-center tw:gap-1",
|
|
787
|
+
children: [children, helpIcons]
|
|
788
|
+
}) : children,
|
|
789
|
+
rawDescription && /* @__PURE__ */ jsx(FormGroup.Help, { children: /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(rawDescription) } }) }),
|
|
790
|
+
hasErrors && /* @__PURE__ */ jsx(FormGroup.Help, { children: rawErrors.join(". ") })
|
|
791
|
+
]
|
|
792
|
+
});
|
|
671
793
|
};
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
rawHelp,
|
|
688
|
-
rawDescription,
|
|
689
|
-
rawErrors,
|
|
690
|
-
children,
|
|
691
|
-
schema,
|
|
692
|
-
uiSchema,
|
|
693
|
-
displayLabel
|
|
694
|
-
}) => {
|
|
695
|
-
const widget = uiSchema?.["ui:widget"];
|
|
696
|
-
if (widget === "test-connection" || widget === "sync-action") {
|
|
697
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
698
|
-
}
|
|
699
|
-
if (schema.type === "object") {
|
|
700
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
701
|
-
}
|
|
702
|
-
if (schema.type === "array" && !uiSchema?.["ui:widget"]) {
|
|
703
|
-
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
704
|
-
}
|
|
705
|
-
const uiOptions = uiSchema?.["ui:options"];
|
|
706
|
-
const documentation = uiOptions?.documentation;
|
|
707
|
-
const hasErrors = rawErrors && rawErrors.length > 0;
|
|
708
|
-
const isCheckbox = schema.type === "boolean" && uiSchema?.["ui:widget"] !== "select";
|
|
709
|
-
const showLabel = displayLabel && label && !isCheckbox;
|
|
710
|
-
const hasHelpIcons = Boolean(rawHelp || documentation);
|
|
711
|
-
const helpIcons = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
712
|
-
rawHelp && /* @__PURE__ */ jsx(TooltipIcon, { rawHelp }),
|
|
713
|
-
documentation && /* @__PURE__ */ jsx(DocumentationLinkIcon, { documentation })
|
|
714
|
-
] });
|
|
715
|
-
return /* @__PURE__ */ jsxs(FormGroup, { state: hasErrors ? "error" : "default", children: [
|
|
716
|
-
showLabel && /* @__PURE__ */ jsx(Label, { htmlFor: id, children: /* @__PURE__ */ jsxs("span", { className: "tw:inline-flex tw:items-center tw:gap-1", children: [
|
|
717
|
-
label,
|
|
718
|
-
helpIcons
|
|
719
|
-
] }) }),
|
|
720
|
-
!showLabel && !isCheckbox && hasHelpIcons && /* @__PURE__ */ jsx("div", { className: "tw:flex tw:items-center tw:gap-1", children: helpIcons }),
|
|
721
|
-
isCheckbox && hasHelpIcons ? /* @__PURE__ */ jsxs("div", { className: "tw:flex tw:items-center tw:gap-1", children: [
|
|
722
|
-
children,
|
|
723
|
-
helpIcons
|
|
724
|
-
] }) : children,
|
|
725
|
-
rawDescription && /* @__PURE__ */ jsx(FormGroup.Help, { children: /* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(rawDescription) } }) }),
|
|
726
|
-
hasErrors && /* @__PURE__ */ jsx(FormGroup.Help, { children: rawErrors.join(". ") })
|
|
727
|
-
] });
|
|
794
|
+
/**
|
|
795
|
+
* Wraps FieldTemplateBody with a root-form-data subscription used to evaluate
|
|
796
|
+
* conditional visibility (options.dependencies). Subscribing here — instead of
|
|
797
|
+
* unconditionally in FieldTemplate — keeps fields without dependencies out of
|
|
798
|
+
* the RootFormDataContext consumer set, so they don't re-render on every
|
|
799
|
+
* keystroke. Critical for forms with many fields (e.g. column_mapping tables).
|
|
800
|
+
*/
|
|
801
|
+
const FieldTemplateWithDependencies = ({ dependencies, keepMounted, ...props }) => {
|
|
802
|
+
const rootFormData = useRootFormData();
|
|
803
|
+
const parentPath = props.fieldPathId.path.slice(0, -1);
|
|
804
|
+
if (!evaluateDependencies(dependencies, rootFormData, parentPath)) return keepMounted ? /* @__PURE__ */ jsx("div", {
|
|
805
|
+
className: "tw:hidden",
|
|
806
|
+
children: props.children
|
|
807
|
+
}) : null;
|
|
808
|
+
return /* @__PURE__ */ jsx(FieldTemplateBody, { ...props });
|
|
728
809
|
};
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
})
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
810
|
+
const FieldTemplate = (props) => {
|
|
811
|
+
if (isHiddenField(props.uiSchema)) return /* @__PURE__ */ jsx("div", {
|
|
812
|
+
className: "tw:hidden",
|
|
813
|
+
children: props.children
|
|
814
|
+
});
|
|
815
|
+
const dependencies = (props.uiSchema?.["ui:options"])?.dependencies;
|
|
816
|
+
if (dependencies) return /* @__PURE__ */ jsx(FieldTemplateWithDependencies, {
|
|
817
|
+
dependencies,
|
|
818
|
+
keepMounted: props.uiSchema?.["ui:widget"] === "template-watch",
|
|
819
|
+
...props
|
|
820
|
+
});
|
|
821
|
+
return /* @__PURE__ */ jsx(FieldTemplateBody, { ...props });
|
|
740
822
|
};
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
823
|
+
//#endregion
|
|
824
|
+
//#region src/blocks/RjsfSchemaEditor/templates/ObjectFieldTemplate.tsx
|
|
825
|
+
const ObjectFieldTemplate = ({ title, description, properties, formData, uiSchema, schema, fieldPathId }) => {
|
|
826
|
+
const isRoot = !fieldPathId?.path?.length;
|
|
827
|
+
const uiOptions = uiSchema?.["ui:options"];
|
|
828
|
+
const hasCollapsed = uiOptions?.collapsed !== void 0;
|
|
829
|
+
const collapsed = !!uiOptions?.collapsed;
|
|
830
|
+
const disableCollapse = !!uiOptions?.disableCollapse;
|
|
831
|
+
const isArrayItem = typeof fieldPathId?.path?.at(-1) === "number";
|
|
832
|
+
const childSchemas = schema.properties;
|
|
833
|
+
const visibleProperties = properties.filter((prop) => !isHiddenContainer(uiSchema?.[prop.name], childSchemas?.[prop.name]));
|
|
834
|
+
const renderChildren = (props) => props.map((prop) => /* @__PURE__ */ jsx("div", {
|
|
835
|
+
className: isHiddenField(uiSchema?.[prop.name]) ? "tw:hidden" : void 0,
|
|
836
|
+
children: prop.content
|
|
837
|
+
}, prop.name));
|
|
838
|
+
if (isRoot) return /* @__PURE__ */ jsx("div", {
|
|
839
|
+
className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden",
|
|
840
|
+
children: renderChildren(visibleProperties)
|
|
841
|
+
});
|
|
842
|
+
const childrenContent = renderChildren(visibleProperties);
|
|
843
|
+
if (hasCollapsed && !disableCollapse) {
|
|
844
|
+
const defaultExpanded = Object.values(formData ?? {}).some((v) => v !== void 0 && v !== null && v !== "" && v !== false) ? !collapsed : true;
|
|
845
|
+
return /* @__PURE__ */ jsxs(CollapsiblePanel, {
|
|
846
|
+
className: "tw:rounded-lg",
|
|
847
|
+
headerClassName: "tw:rounded-lg",
|
|
848
|
+
header: title || "Settings",
|
|
849
|
+
defaultExpanded,
|
|
850
|
+
bodyClassName: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden",
|
|
851
|
+
children: [description, childrenContent]
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
if (isArrayItem) return /* @__PURE__ */ jsx("div", {
|
|
855
|
+
className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden",
|
|
856
|
+
children: childrenContent
|
|
857
|
+
});
|
|
858
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
859
|
+
className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:bg-white tw:p-4",
|
|
860
|
+
children: [
|
|
861
|
+
title && /* @__PURE__ */ jsx("h3", {
|
|
862
|
+
className: "tw:mb-2 tw:text-base tw:font-medium tw:text-neutral-800",
|
|
863
|
+
children: title
|
|
864
|
+
}),
|
|
865
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
866
|
+
className: "tw:mb-3 tw:text-xs tw:text-neutral-400",
|
|
867
|
+
children: description
|
|
868
|
+
}),
|
|
869
|
+
/* @__PURE__ */ jsx("div", {
|
|
870
|
+
className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden",
|
|
871
|
+
children: childrenContent
|
|
872
|
+
})
|
|
873
|
+
]
|
|
874
|
+
});
|
|
759
875
|
};
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
const uiOptions = uiSchema?.["ui:options"];
|
|
771
|
-
const hasCollapsed = uiOptions?.collapsed !== void 0;
|
|
772
|
-
const collapsed = !!uiOptions?.collapsed;
|
|
773
|
-
const disableCollapse = !!uiOptions?.disableCollapse;
|
|
774
|
-
const lastPathSegment = fieldPathId?.path?.at(-1);
|
|
775
|
-
const isArrayItem = typeof lastPathSegment === "number";
|
|
776
|
-
const childSchemas = schema.properties;
|
|
777
|
-
const isContainerSchema = (s) => {
|
|
778
|
-
if (!s) return false;
|
|
779
|
-
if (s.properties || s.items) return true;
|
|
780
|
-
if (Array.isArray(s.type)) return s.type.includes("object") || s.type.includes("array");
|
|
781
|
-
return s.type === "object" || s.type === "array";
|
|
782
|
-
};
|
|
783
|
-
const visibleProperties = properties.filter((prop) => {
|
|
784
|
-
if (uiSchema?.[prop.name]?.["ui:widget"] !== "hidden") return true;
|
|
785
|
-
return !isContainerSchema(childSchemas?.[prop.name]);
|
|
786
|
-
});
|
|
787
|
-
const isHiddenMount = (name) => {
|
|
788
|
-
const childUi = uiSchema?.[name];
|
|
789
|
-
return childUi?.["ui:widget"] === "hidden" || isHiddenTemplateWatch(childUi);
|
|
790
|
-
};
|
|
791
|
-
const renderChildren = (props) => props.map((prop) => /* @__PURE__ */ jsx("div", { className: isHiddenMount(prop.name) ? "tw:hidden" : void 0, children: prop.content }, prop.name));
|
|
792
|
-
if (isRoot) {
|
|
793
|
-
return /* @__PURE__ */ jsx("div", { className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden", children: renderChildren(visibleProperties) });
|
|
794
|
-
}
|
|
795
|
-
const childrenContent = renderChildren(visibleProperties);
|
|
796
|
-
if (hasCollapsed && !disableCollapse) {
|
|
797
|
-
const data = formData ?? {};
|
|
798
|
-
const hasValues = Object.values(data).some(
|
|
799
|
-
(v) => v !== void 0 && v !== null && v !== "" && v !== false
|
|
800
|
-
);
|
|
801
|
-
const defaultExpanded = hasValues ? !collapsed : true;
|
|
802
|
-
return /* @__PURE__ */ jsxs(
|
|
803
|
-
CollapsiblePanel,
|
|
804
|
-
{
|
|
805
|
-
className: "tw:rounded-lg",
|
|
806
|
-
headerClassName: "tw:rounded-lg",
|
|
807
|
-
header: title || "Settings",
|
|
808
|
-
defaultExpanded,
|
|
809
|
-
bodyClassName: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden",
|
|
810
|
-
children: [
|
|
811
|
-
description,
|
|
812
|
-
childrenContent
|
|
813
|
-
]
|
|
814
|
-
}
|
|
815
|
-
);
|
|
816
|
-
}
|
|
817
|
-
if (isArrayItem) {
|
|
818
|
-
return /* @__PURE__ */ jsx("div", { className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden", children: childrenContent });
|
|
819
|
-
}
|
|
820
|
-
return /* @__PURE__ */ jsxs("div", { className: "tw:rounded-lg tw:border tw:border-solid tw:border-neutral-200 tw:bg-white tw:p-4", children: [
|
|
821
|
-
title && /* @__PURE__ */ jsx("h3", { className: "tw:mb-2 tw:text-base tw:font-medium tw:text-neutral-800", children: title }),
|
|
822
|
-
description && /* @__PURE__ */ jsx("p", { className: "tw:mb-3 tw:text-xs tw:text-neutral-400", children: description }),
|
|
823
|
-
/* @__PURE__ */ jsx("div", { className: "tw:flex tw:flex-col tw:gap-4 tw:[&>div:empty]:hidden", children: childrenContent })
|
|
824
|
-
] });
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/CheckboxWidget.tsx
|
|
878
|
+
const CheckboxWidget = ({ id, value, onChange, disabled, readonly, label, hideLabel }) => {
|
|
879
|
+
return /* @__PURE__ */ jsx(Checkbox, {
|
|
880
|
+
id,
|
|
881
|
+
checked: !!value,
|
|
882
|
+
onCheckedChange: onChange,
|
|
883
|
+
disabled: disabled || readonly,
|
|
884
|
+
children: hideLabel ? void 0 : label
|
|
885
|
+
});
|
|
825
886
|
};
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
887
|
+
//#endregion
|
|
888
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/DateWidget.tsx
|
|
889
|
+
const DateWidget = ({ id, value, onChange, onBlur, onFocus, disabled, readonly, placeholder, rawErrors }) => {
|
|
890
|
+
const dateValue = (() => {
|
|
891
|
+
if (!value) return null;
|
|
892
|
+
const parts = value.split("-").map(Number);
|
|
893
|
+
const [year, month, day] = parts;
|
|
894
|
+
if (parts.length !== 3 || parts.some(Number.isNaN)) return null;
|
|
895
|
+
if (year === void 0 || month === void 0 || day === void 0) return null;
|
|
896
|
+
return new Date(year, month - 1, day);
|
|
897
|
+
})();
|
|
898
|
+
const isValid = dateValue && !Number.isNaN(dateValue.getTime());
|
|
899
|
+
return /* @__PURE__ */ jsx(DateInput, {
|
|
900
|
+
id,
|
|
901
|
+
value: isValid ? dateValue : null,
|
|
902
|
+
onValueChange: (date) => {
|
|
903
|
+
if (!date) {
|
|
904
|
+
onChange(void 0);
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
onChange(`${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`);
|
|
908
|
+
},
|
|
909
|
+
onBlur: () => onBlur(id, value),
|
|
910
|
+
onFocus: () => onFocus(id, value),
|
|
911
|
+
disabled: disabled || readonly,
|
|
912
|
+
placeholder: placeholder || "Select a date",
|
|
913
|
+
state: rawErrors?.length ? "error" : "default",
|
|
914
|
+
variant: "secondary"
|
|
915
|
+
});
|
|
837
916
|
};
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
if (!date) {
|
|
865
|
-
onChange(void 0);
|
|
866
|
-
return;
|
|
867
|
-
}
|
|
868
|
-
const year = date.getFullYear();
|
|
869
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
870
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
871
|
-
onChange(`${year}-${month}-${day}`);
|
|
872
|
-
},
|
|
873
|
-
onBlur: () => onBlur(id, value),
|
|
874
|
-
onFocus: () => onFocus(id, value),
|
|
875
|
-
disabled: disabled || readonly,
|
|
876
|
-
placeholder: placeholder || "Select a date",
|
|
877
|
-
state: rawErrors?.length ? "error" : "default",
|
|
878
|
-
variant: "secondary"
|
|
879
|
-
}
|
|
880
|
-
);
|
|
917
|
+
//#endregion
|
|
918
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/DynamicSelectWidget.tsx
|
|
919
|
+
/**
|
|
920
|
+
* Widget for fields using json-editor's enumSource/watch pattern.
|
|
921
|
+
* Reads options dynamically from the root form data based on watched paths.
|
|
922
|
+
*/
|
|
923
|
+
const DynamicSelectWidget = ({ value, onChange, disabled, readonly, options: widgetOptions }) => {
|
|
924
|
+
const data = useRootFormData();
|
|
925
|
+
const watch = widgetOptions.watch;
|
|
926
|
+
const enumSource = widgetOptions.enumSource;
|
|
927
|
+
const dynamicItems = watch ? buildDynamicOptions(watch, enumSource, data) : [];
|
|
928
|
+
const stringValue = value == null ? "" : String(value);
|
|
929
|
+
const matched = dynamicItems.find((item) => item.value === stringValue);
|
|
930
|
+
const fallbackItem = !matched && stringValue !== "" ? {
|
|
931
|
+
value: stringValue,
|
|
932
|
+
label: stringValue
|
|
933
|
+
} : null;
|
|
934
|
+
const selectedItem = matched ?? fallbackItem;
|
|
935
|
+
const items = fallbackItem ? [fallbackItem, ...dynamicItems] : dynamicItems;
|
|
936
|
+
return /* @__PURE__ */ jsx(Combobox, {
|
|
937
|
+
variant: "secondary",
|
|
938
|
+
items,
|
|
939
|
+
value: selectedItem,
|
|
940
|
+
disabled: disabled || readonly,
|
|
941
|
+
onValueChange: (selected) => onChange(selected?.value ?? "")
|
|
942
|
+
});
|
|
881
943
|
};
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
Combobox,
|
|
900
|
-
{
|
|
901
|
-
variant: "secondary",
|
|
902
|
-
items,
|
|
903
|
-
value: selectedItem,
|
|
904
|
-
disabled: disabled || readonly,
|
|
905
|
-
onValueChange: (selected) => onChange(selected?.value ?? "")
|
|
906
|
-
}
|
|
907
|
-
);
|
|
944
|
+
//#endregion
|
|
945
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/NumberWidget.tsx
|
|
946
|
+
const NumberWidget = ({ id, value, onChange, onBlur, onFocus, disabled, readonly, placeholder, schema, rawErrors }) => {
|
|
947
|
+
return /* @__PURE__ */ jsx(NumberInput, {
|
|
948
|
+
id,
|
|
949
|
+
value: value ?? null,
|
|
950
|
+
onValueChange: (num) => onChange(num ?? void 0),
|
|
951
|
+
onBlur: () => onBlur(id, value),
|
|
952
|
+
onFocus: () => onFocus(id, value),
|
|
953
|
+
disabled: disabled || readonly,
|
|
954
|
+
placeholder,
|
|
955
|
+
min: schema.minimum,
|
|
956
|
+
max: schema.maximum,
|
|
957
|
+
step: schema.multipleOf,
|
|
958
|
+
state: rawErrors?.length ? "error" : "default",
|
|
959
|
+
variant: "secondary"
|
|
960
|
+
});
|
|
908
961
|
};
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
id,
|
|
925
|
-
value: value ?? null,
|
|
926
|
-
onValueChange: (num) => onChange(num ?? void 0),
|
|
927
|
-
onBlur: () => onBlur(id, value),
|
|
928
|
-
onFocus: () => onFocus(id, value),
|
|
929
|
-
disabled: disabled || readonly,
|
|
930
|
-
placeholder,
|
|
931
|
-
min: schema.minimum,
|
|
932
|
-
max: schema.maximum,
|
|
933
|
-
step: schema.multipleOf,
|
|
934
|
-
state: rawErrors?.length ? "error" : "default",
|
|
935
|
-
variant: "secondary"
|
|
936
|
-
}
|
|
937
|
-
);
|
|
962
|
+
//#endregion
|
|
963
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/PasswordWidget.tsx
|
|
964
|
+
const PasswordWidget = ({ id, value, onChange, onBlur, onFocus, disabled, readonly, placeholder, rawErrors }) => {
|
|
965
|
+
return /* @__PURE__ */ jsx(PasswordInput, {
|
|
966
|
+
id,
|
|
967
|
+
value: value == null ? "" : String(value),
|
|
968
|
+
onValueChange: onChange,
|
|
969
|
+
onBlur: () => onBlur(id, value),
|
|
970
|
+
onFocus: () => onFocus(id, value),
|
|
971
|
+
disabled: disabled || readonly,
|
|
972
|
+
placeholder,
|
|
973
|
+
allowPasswordToggle: true,
|
|
974
|
+
state: rawErrors?.length ? "error" : "default",
|
|
975
|
+
variant: "secondary"
|
|
976
|
+
});
|
|
938
977
|
};
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
id,
|
|
955
|
-
value: stringValue,
|
|
956
|
-
onValueChange: onChange,
|
|
957
|
-
onBlur: () => onBlur(id, value),
|
|
958
|
-
onFocus: () => onFocus(id, value),
|
|
959
|
-
disabled: disabled || readonly,
|
|
960
|
-
placeholder,
|
|
961
|
-
allowPasswordToggle: true,
|
|
962
|
-
state: rawErrors?.length ? "error" : "default",
|
|
963
|
-
variant: "secondary"
|
|
964
|
-
}
|
|
965
|
-
);
|
|
978
|
+
//#endregion
|
|
979
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/RadioWidget.tsx
|
|
980
|
+
const RadioWidget = ({ id, value, onChange, disabled, readonly, options }) => {
|
|
981
|
+
const enumOptions = options.enumOptions ?? [];
|
|
982
|
+
return /* @__PURE__ */ jsx(RadioGroup, {
|
|
983
|
+
id,
|
|
984
|
+
value: value ?? "",
|
|
985
|
+
onValueChange: onChange,
|
|
986
|
+
disabled: disabled || readonly,
|
|
987
|
+
orientation: "vertical",
|
|
988
|
+
children: enumOptions.map((opt) => /* @__PURE__ */ jsx(RadioGroup.Item, {
|
|
989
|
+
value: opt.value,
|
|
990
|
+
children: opt.label
|
|
991
|
+
}, opt.value))
|
|
992
|
+
});
|
|
966
993
|
};
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
994
|
+
//#endregion
|
|
995
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/SelectWidget.tsx
|
|
996
|
+
const SelectWidget = ({ value, schema, onChange, disabled, readonly, options, placeholder, required }) => {
|
|
997
|
+
const enumOptions = options.enumOptions ?? [];
|
|
998
|
+
const isBoolean = schema.type === "boolean";
|
|
999
|
+
const items = enumOptions.map((o) => ({
|
|
1000
|
+
value: String(o.value ?? ""),
|
|
1001
|
+
label: o.label
|
|
1002
|
+
}));
|
|
1003
|
+
const selectedItem = items.find((item) => item.value === (value == null ? "" : String(value)));
|
|
1004
|
+
return /* @__PURE__ */ jsx(Combobox, {
|
|
1005
|
+
variant: "secondary",
|
|
1006
|
+
items,
|
|
1007
|
+
value: selectedItem ?? null,
|
|
1008
|
+
allowClear: !required,
|
|
1009
|
+
disabled: disabled || readonly,
|
|
1010
|
+
placeholder,
|
|
1011
|
+
onValueChange: (selected) => {
|
|
1012
|
+
const selectedValue = selected?.value ?? "";
|
|
1013
|
+
if (isBoolean) {
|
|
1014
|
+
onChange(selectedValue === "true");
|
|
1015
|
+
return;
|
|
1016
|
+
}
|
|
1017
|
+
onChange(selectedValue);
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
980
1020
|
};
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
const items = enumOptions.map((o) => ({
|
|
994
|
-
value: String(o.value ?? ""),
|
|
995
|
-
label: o.label
|
|
996
|
-
}));
|
|
997
|
-
const selectedItem = items.find((item) => item.value === (value == null ? "" : String(value)));
|
|
998
|
-
return /* @__PURE__ */ jsx(
|
|
999
|
-
Combobox,
|
|
1000
|
-
{
|
|
1001
|
-
variant: "secondary",
|
|
1002
|
-
items,
|
|
1003
|
-
value: selectedItem ?? null,
|
|
1004
|
-
allowClear: !required,
|
|
1005
|
-
disabled: disabled || readonly,
|
|
1006
|
-
placeholder,
|
|
1007
|
-
onValueChange: (selected) => {
|
|
1008
|
-
const selectedValue = selected?.value ?? "";
|
|
1009
|
-
if (isBoolean) {
|
|
1010
|
-
onChange(selectedValue === "true");
|
|
1011
|
-
return;
|
|
1012
|
-
}
|
|
1013
|
-
onChange(selectedValue);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
);
|
|
1021
|
+
//#endregion
|
|
1022
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/TemplateWatchWidget.tsx
|
|
1023
|
+
/**
|
|
1024
|
+
* Renders a watched value as text.
|
|
1025
|
+
*
|
|
1026
|
+
* - Objects and arrays are serialized as JSON; anything else goes through `String`.
|
|
1027
|
+
* - `null` and `undefined` render as an empty string.
|
|
1028
|
+
*/
|
|
1029
|
+
const stringify = (value) => {
|
|
1030
|
+
if (value == null) return "";
|
|
1031
|
+
if (typeof value === "object") return JSON.stringify(value);
|
|
1032
|
+
return String(value);
|
|
1017
1033
|
};
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1034
|
+
/**
|
|
1035
|
+
* Resolves a json-editor `template` string by substituting watched variables.
|
|
1036
|
+
* e.g. template="{{val}}" with watch={ val: "some.path" } → resolves "some.path" from form data.
|
|
1037
|
+
*/
|
|
1038
|
+
const resolveTemplate = (template, watch, rootFormData) => {
|
|
1039
|
+
return template.replace(/\{\{(\w+)\}\}/g, (_, varName) => {
|
|
1040
|
+
const watchPath = watch[varName];
|
|
1041
|
+
if (!watchPath) return "";
|
|
1042
|
+
return stringify(resolveByPath(watchPath, rootFormData));
|
|
1043
|
+
});
|
|
1022
1044
|
};
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1045
|
+
/**
|
|
1046
|
+
* Whether `rootContext` declares the value a path reads.
|
|
1047
|
+
*
|
|
1048
|
+
* - A context entry shares its top-level key with the form data — a sync action writes its own
|
|
1049
|
+
* keys under the same key — so the entry key alone does not settle it.
|
|
1050
|
+
* - Both the entry and the segment under it must be own properties — plain-object lookups also
|
|
1051
|
+
* answer for `toString` and the rest of the prototype chain.
|
|
1052
|
+
* - A path naming an entry and nothing under it reads the whole namespace, context included.
|
|
1053
|
+
*/
|
|
1054
|
+
const declaresPath = (segments, rootContext) => {
|
|
1055
|
+
const [entryKey = "", key] = segments;
|
|
1056
|
+
const entry = rootContext[entryKey];
|
|
1057
|
+
return isRecord(entry) && (key === void 0 || Object.hasOwn(entry, key));
|
|
1029
1058
|
};
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
const template = widgetOptions.template;
|
|
1042
|
-
const computed = watch && template ? resolveTemplate(template, watch, data) : stringify(value);
|
|
1043
|
-
const lastSetRef = useRef(stringify(value));
|
|
1044
|
-
useEffect(() => {
|
|
1045
|
-
if (computed !== lastSetRef.current) {
|
|
1046
|
-
lastSetRef.current = computed;
|
|
1047
|
-
onChange(computed);
|
|
1048
|
-
}
|
|
1049
|
-
}, [computed, onChange]);
|
|
1050
|
-
if (widgetOptions.hidden) {
|
|
1051
|
-
return null;
|
|
1052
|
-
}
|
|
1053
|
-
return /* @__PURE__ */ jsx(
|
|
1054
|
-
TextInput,
|
|
1055
|
-
{
|
|
1056
|
-
id,
|
|
1057
|
-
value: computed,
|
|
1058
|
-
readOnly: true,
|
|
1059
|
-
disabled: disabled || readonly,
|
|
1060
|
-
state: rawErrors?.length ? "error" : "default",
|
|
1061
|
-
variant: "secondary"
|
|
1062
|
-
}
|
|
1063
|
-
);
|
|
1059
|
+
/**
|
|
1060
|
+
* Whether every watched path reads a value `rootContext` declares.
|
|
1061
|
+
*
|
|
1062
|
+
* - No watched paths means nothing is derived, which is not a context view.
|
|
1063
|
+
*/
|
|
1064
|
+
const readsOnlyContext = (watch, rootContext) => {
|
|
1065
|
+
const paths = Object.values(watch);
|
|
1066
|
+
return paths.length > 0 && paths.every((path) => {
|
|
1067
|
+
const segments = path.split(".");
|
|
1068
|
+
return declaresPath(segments, rootContext) || declaresPath(segments.slice(1), rootContext);
|
|
1069
|
+
});
|
|
1064
1070
|
};
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1071
|
+
/**
|
|
1072
|
+
* Widget for json-editor's `template`/`watch` pattern (without `enumSource`).
|
|
1073
|
+
* Computes a value from watched paths and shows it.
|
|
1074
|
+
*
|
|
1075
|
+
* - With `options.hidden` it renders nothing — a helper for cross-object dependencies.
|
|
1076
|
+
* - Without it, the value is shown in a read-only input; `FieldTemplate` supplies the label.
|
|
1077
|
+
* - It writes the computed value into the form data, so a component reads it back from the
|
|
1078
|
+
* saved configuration.
|
|
1079
|
+
* - It stops writing when every watched path reads `rootContext` — the configuration does not
|
|
1080
|
+
* own that context.
|
|
1081
|
+
* - `options.hidden` fields always write; they exist to feed cross-object dependencies.
|
|
1082
|
+
*/
|
|
1083
|
+
const TemplateWatchWidget = ({ id, value, onChange, disabled, readonly, rawErrors, options: widgetOptions }) => {
|
|
1084
|
+
const data = useRootFormData();
|
|
1085
|
+
const rootContext = useRootContext();
|
|
1086
|
+
const watch = widgetOptions.watch;
|
|
1087
|
+
const template = widgetOptions.template;
|
|
1088
|
+
const isContextView = !widgetOptions.hidden && !!watch && readsOnlyContext(watch, rootContext);
|
|
1089
|
+
const computed = watch && template ? resolveTemplate(template, watch, data) : stringify(value);
|
|
1090
|
+
const lastSetRef = useRef(stringify(value));
|
|
1091
|
+
useEffect(() => {
|
|
1092
|
+
if (isContextView) return;
|
|
1093
|
+
if (computed !== lastSetRef.current) {
|
|
1094
|
+
lastSetRef.current = computed;
|
|
1095
|
+
onChange(computed);
|
|
1096
|
+
}
|
|
1097
|
+
}, [
|
|
1098
|
+
computed,
|
|
1099
|
+
onChange,
|
|
1100
|
+
isContextView
|
|
1101
|
+
]);
|
|
1102
|
+
if (widgetOptions.hidden) return null;
|
|
1103
|
+
return /* @__PURE__ */ jsx(TextInput, {
|
|
1104
|
+
id,
|
|
1105
|
+
value: computed,
|
|
1106
|
+
readOnly: true,
|
|
1107
|
+
disabled: disabled || readonly,
|
|
1108
|
+
state: rawErrors?.length ? "error" : "default",
|
|
1109
|
+
variant: "secondary"
|
|
1110
|
+
});
|
|
1094
1111
|
};
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
TextInput,
|
|
1112
|
-
{
|
|
1113
|
-
id,
|
|
1114
|
-
value: stringValue,
|
|
1115
|
-
onChange: (e) => {
|
|
1116
|
-
const v = e.target.value;
|
|
1117
|
-
onChange(shouldTrim ? v.trim() : v);
|
|
1118
|
-
},
|
|
1119
|
-
onBlur: () => onBlur(id, value),
|
|
1120
|
-
onFocus: () => onFocus(id, value),
|
|
1121
|
-
disabled: disabled || readonly,
|
|
1122
|
-
placeholder,
|
|
1123
|
-
type: schema.format === "email" ? "email" : "text",
|
|
1124
|
-
state: rawErrors?.length ? "error" : "default",
|
|
1125
|
-
variant: "secondary"
|
|
1126
|
-
}
|
|
1127
|
-
);
|
|
1112
|
+
//#endregion
|
|
1113
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/TextareaWidget.tsx
|
|
1114
|
+
const TextareaWidget = ({ id, value, onChange, onBlur, onFocus, disabled, readonly, placeholder, options, rawErrors }) => {
|
|
1115
|
+
const rows = options.rows ?? 5;
|
|
1116
|
+
return /* @__PURE__ */ jsx(Textarea, {
|
|
1117
|
+
id,
|
|
1118
|
+
value: value == null ? "" : String(value),
|
|
1119
|
+
onValueChange: onChange,
|
|
1120
|
+
onBlur: () => onBlur(id, value),
|
|
1121
|
+
onFocus: () => onFocus(id, value),
|
|
1122
|
+
disabled: disabled || readonly,
|
|
1123
|
+
placeholder,
|
|
1124
|
+
minRows: rows,
|
|
1125
|
+
state: rawErrors?.length ? "error" : "default",
|
|
1126
|
+
variant: "secondary"
|
|
1127
|
+
});
|
|
1128
1128
|
};
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/blocks/RjsfSchemaEditor/widgets/TextWidget.tsx
|
|
1131
|
+
const TextWidget = ({ id, value, onChange, onBlur, onFocus, disabled, readonly, placeholder, schema, options, rawErrors }) => {
|
|
1132
|
+
const stringValue = value == null ? "" : typeof value === "object" ? "" : String(value);
|
|
1133
|
+
const shouldTrim = !!options.trim;
|
|
1134
|
+
return /* @__PURE__ */ jsx(TextInput, {
|
|
1135
|
+
id,
|
|
1136
|
+
value: stringValue,
|
|
1137
|
+
onChange: (e) => {
|
|
1138
|
+
const v = e.target.value;
|
|
1139
|
+
onChange(shouldTrim ? v.trim() : v);
|
|
1140
|
+
},
|
|
1141
|
+
onBlur: () => onBlur(id, value),
|
|
1142
|
+
onFocus: () => onFocus(id, value),
|
|
1143
|
+
disabled: disabled || readonly,
|
|
1144
|
+
placeholder,
|
|
1145
|
+
type: schema.format === "email" ? "email" : "text",
|
|
1146
|
+
state: rawErrors?.length ? "error" : "default",
|
|
1147
|
+
variant: "secondary"
|
|
1148
|
+
});
|
|
1140
1149
|
};
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
URLWidget: TextWidget,
|
|
1153
|
-
DateWidget,
|
|
1154
|
-
DateTimeWidget: TextWidget,
|
|
1155
|
-
// Custom widgets mapped via uiSchema
|
|
1156
|
-
"code-editor": CodeEditorWidget,
|
|
1157
|
-
"dynamic-select": DynamicSelectWidget,
|
|
1158
|
-
"template-watch": TemplateWatchWidget,
|
|
1159
|
-
// Host-coupled widgets — injected by the host app
|
|
1160
|
-
"test-connection": StubWidget,
|
|
1161
|
-
"sync-action": StubWidget,
|
|
1162
|
-
"async-select": StubWidget,
|
|
1163
|
-
"async-multi-select": StubWidget
|
|
1150
|
+
//#endregion
|
|
1151
|
+
//#region src/blocks/RjsfSchemaEditor/registry.ts
|
|
1152
|
+
const StubWidget = () => null;
|
|
1153
|
+
const StubField = () => null;
|
|
1154
|
+
const defaultFields = {
|
|
1155
|
+
tableArray: TableArrayField,
|
|
1156
|
+
tabsObject: TabsObjectField,
|
|
1157
|
+
gridObject: GridObjectField,
|
|
1158
|
+
codeEditor: CodeEditorField,
|
|
1159
|
+
info: InfoField,
|
|
1160
|
+
sshForm: StubField
|
|
1164
1161
|
};
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1162
|
+
const defaultWidgets = {
|
|
1163
|
+
TextWidget,
|
|
1164
|
+
UpDownWidget: NumberWidget,
|
|
1165
|
+
TextareaWidget,
|
|
1166
|
+
PasswordWidget,
|
|
1167
|
+
SelectWidget,
|
|
1168
|
+
CheckboxWidget,
|
|
1169
|
+
RadioWidget,
|
|
1170
|
+
EmailWidget: TextWidget,
|
|
1171
|
+
URLWidget: TextWidget,
|
|
1172
|
+
DateWidget,
|
|
1173
|
+
DateTimeWidget: TextWidget,
|
|
1174
|
+
"code-editor": CodeEditorWidget,
|
|
1175
|
+
"dynamic-select": DynamicSelectWidget,
|
|
1176
|
+
"template-watch": TemplateWatchWidget,
|
|
1177
|
+
"test-connection": StubWidget,
|
|
1178
|
+
"sync-action": StubWidget,
|
|
1179
|
+
"async-select": StubWidget,
|
|
1180
|
+
"async-multi-select": StubWidget
|
|
1172
1181
|
};
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
const { $ref, ...overrides } = propSchema;
|
|
1181
|
-
return { ...resolved, ...overrides };
|
|
1182
|
+
const defaultTemplates = {
|
|
1183
|
+
FieldTemplate,
|
|
1184
|
+
ObjectFieldTemplate,
|
|
1185
|
+
DescriptionFieldTemplate,
|
|
1186
|
+
ArrayFieldTemplate,
|
|
1187
|
+
ArrayFieldItemTemplate,
|
|
1188
|
+
ErrorListTemplate
|
|
1182
1189
|
};
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
fieldUi["ui:widget"] = "hidden";
|
|
1199
|
-
}
|
|
1200
|
-
if (type === "array" && format === "table") {
|
|
1201
|
-
fieldUi["ui:field"] = "tableArray";
|
|
1202
|
-
}
|
|
1203
|
-
if (type === "array" && format === "checkbox") {
|
|
1204
|
-
fieldUi["ui:widget"] = "checkboxes";
|
|
1205
|
-
}
|
|
1206
|
-
if (format === "radio" && propSchema.enum) {
|
|
1207
|
-
fieldUi["ui:widget"] = "radio";
|
|
1208
|
-
}
|
|
1209
|
-
if (type === "object" && (format === "tabs" || format === "tabs-top" || format === "categories")) {
|
|
1210
|
-
fieldUi["ui:field"] = "tabsObject";
|
|
1211
|
-
}
|
|
1212
|
-
if (type === "object" && (format === "grid" || format === "grid-strict")) {
|
|
1213
|
-
fieldUi["ui:field"] = "gridObject";
|
|
1214
|
-
}
|
|
1215
|
-
if (format === "info") {
|
|
1216
|
-
fieldUi["ui:field"] = "info";
|
|
1217
|
-
if (options?.alert_type) {
|
|
1218
|
-
fieldUi["ui:options"] = {
|
|
1219
|
-
...fieldUi["ui:options"],
|
|
1220
|
-
alertType: options.alert_type
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
if (type === "button" && format === "test-connection") {
|
|
1225
|
-
fieldUi["ui:widget"] = "test-connection";
|
|
1226
|
-
fieldUi["ui:options"] = options ?? {};
|
|
1227
|
-
} else if (type === "button" && format === "sync-action") {
|
|
1228
|
-
fieldUi["ui:widget"] = "sync-action";
|
|
1229
|
-
fieldUi["ui:options"] = options ?? {};
|
|
1230
|
-
} else if ((type === "string" || type === "object") && format === "editor") {
|
|
1231
|
-
if (type === "object") {
|
|
1232
|
-
fieldUi["ui:field"] = "codeEditor";
|
|
1233
|
-
} else {
|
|
1234
|
-
fieldUi["ui:widget"] = "code-editor";
|
|
1235
|
-
}
|
|
1236
|
-
fieldUi["ui:options"] = {
|
|
1237
|
-
editor: options?.editor ?? {},
|
|
1238
|
-
// A JSON editor stores parsed keys, so `#` prefixes really are encrypted here.
|
|
1239
|
-
// Fields whose JSON is not Keboola configuration (a query filter tree, a payload
|
|
1240
|
-
// template) opt out with `encryption_hint: false` — encrypting a key there would
|
|
1241
|
-
// hand the component ciphertext it cannot use.
|
|
1242
|
-
encryptionHint: options?.encryption_hint !== false
|
|
1243
|
-
};
|
|
1244
|
-
} else if (type === "object" && format === "ssh-editor") {
|
|
1245
|
-
fieldUi["ui:field"] = "sshForm";
|
|
1246
|
-
fieldUi["ui:options"] = { only_keys: !!options?.only_keys };
|
|
1247
|
-
} else if (type === "string" && format === "password") {
|
|
1248
|
-
if (!hasProtectedDefaultBranch) {
|
|
1249
|
-
fieldUi["ui:widget"] = "password";
|
|
1250
|
-
}
|
|
1251
|
-
} else if (type === "string" && format === "textarea") {
|
|
1252
|
-
fieldUi["ui:widget"] = "textarea";
|
|
1253
|
-
if (options?.input_height) {
|
|
1254
|
-
fieldUi["ui:options"] = {
|
|
1255
|
-
...fieldUi["ui:options"],
|
|
1256
|
-
rows: parseInputHeightToRows(String(options.input_height))
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1259
|
-
} else if (type === "string" && format === "trim") {
|
|
1260
|
-
fieldUi["ui:options"] = {
|
|
1261
|
-
...fieldUi["ui:options"],
|
|
1262
|
-
trim: true
|
|
1263
|
-
};
|
|
1264
|
-
} else if (isDynamicSelectSchema(propSchema)) {
|
|
1265
|
-
fieldUi["ui:widget"] = "dynamic-select";
|
|
1266
|
-
fieldUi["ui:options"] = {
|
|
1267
|
-
...fieldUi["ui:options"],
|
|
1268
|
-
watch: propSchema.watch,
|
|
1269
|
-
enumSource: propSchema.enumSource,
|
|
1270
|
-
tags: !!options?.tags
|
|
1271
|
-
};
|
|
1272
|
-
} else if (isMultiSelectSchema(propSchema)) {
|
|
1273
|
-
const items = propSchema.items;
|
|
1274
|
-
const itemsOptions = items?.options;
|
|
1275
|
-
fieldUi["ui:widget"] = "async-multi-select";
|
|
1276
|
-
fieldUi["ui:options"] = {
|
|
1277
|
-
async: options?.async ?? itemsOptions?.async ?? null,
|
|
1278
|
-
creatable: !!options?.creatable || !!options?.tags,
|
|
1279
|
-
placeholder: String(
|
|
1280
|
-
options?.inputAttributes?.placeholder ?? ""
|
|
1281
|
-
),
|
|
1282
|
-
// Pass dynamic source from items for enumSource/watch multi-selects
|
|
1283
|
-
...items?.watch && { watch: items.watch },
|
|
1284
|
-
...items?.enumSource && { enumSource: items.enumSource }
|
|
1285
|
-
};
|
|
1286
|
-
} else if (isAsyncSelectSchema(propSchema)) {
|
|
1287
|
-
fieldUi["ui:widget"] = "async-select";
|
|
1288
|
-
fieldUi["ui:options"] = {
|
|
1289
|
-
async: options?.async ?? null,
|
|
1290
|
-
creatable: !!options?.creatable,
|
|
1291
|
-
placeholder: String(
|
|
1292
|
-
options?.inputAttributes?.placeholder ?? ""
|
|
1293
|
-
)
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
if (isTemplateWatchSchema(propSchema)) {
|
|
1297
|
-
fieldUi["ui:widget"] = "template-watch";
|
|
1298
|
-
fieldUi["ui:options"] = {
|
|
1299
|
-
...fieldUi["ui:options"],
|
|
1300
|
-
watch: propSchema.watch,
|
|
1301
|
-
template: propSchema.template,
|
|
1302
|
-
hidden: !!options?.hidden || isContainerType(propSchema)
|
|
1303
|
-
};
|
|
1304
|
-
}
|
|
1305
|
-
if (type === "boolean" && options?.enum_titles) {
|
|
1306
|
-
fieldUi["ui:widget"] = "select";
|
|
1307
|
-
}
|
|
1308
|
-
if (options?.collapsed !== void 0) {
|
|
1309
|
-
fieldUi["ui:options"] = {
|
|
1310
|
-
...fieldUi["ui:options"],
|
|
1311
|
-
collapsed: !!options.collapsed
|
|
1312
|
-
};
|
|
1313
|
-
}
|
|
1314
|
-
if (options?.disable_collapse) {
|
|
1315
|
-
fieldUi["ui:options"] = {
|
|
1316
|
-
...fieldUi["ui:options"],
|
|
1317
|
-
disableCollapse: true
|
|
1318
|
-
};
|
|
1319
|
-
}
|
|
1320
|
-
if (options?.dependencies) {
|
|
1321
|
-
fieldUi["ui:options"] = {
|
|
1322
|
-
...fieldUi["ui:options"],
|
|
1323
|
-
dependencies: options.dependencies
|
|
1324
|
-
};
|
|
1325
|
-
}
|
|
1326
|
-
if (options?.grid_break) {
|
|
1327
|
-
fieldUi["ui:options"] = {
|
|
1328
|
-
...fieldUi["ui:options"],
|
|
1329
|
-
gridBreak: true
|
|
1330
|
-
};
|
|
1331
|
-
}
|
|
1332
|
-
if (options?.enabled === false) {
|
|
1333
|
-
fieldUi["ui:disabled"] = true;
|
|
1334
|
-
}
|
|
1335
|
-
const globalValue = globalConfig?.[key];
|
|
1336
|
-
if (globalValue !== void 0) {
|
|
1337
|
-
if (typeof globalValue !== "object" || globalValue === null || Array.isArray(globalValue)) {
|
|
1338
|
-
fieldUi["ui:disabled"] = true;
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
if (options?.tooltip) {
|
|
1342
|
-
fieldUi["ui:help"] = String(options.tooltip);
|
|
1343
|
-
}
|
|
1344
|
-
if (options?.documentation?.link) {
|
|
1345
|
-
fieldUi["ui:options"] = {
|
|
1346
|
-
...fieldUi["ui:options"],
|
|
1347
|
-
documentation: options?.documentation
|
|
1348
|
-
};
|
|
1349
|
-
}
|
|
1350
|
-
if (options?.inputAttributes?.placeholder && !fieldUi["ui:widget"]) {
|
|
1351
|
-
fieldUi["ui:placeholder"] = String(
|
|
1352
|
-
options?.inputAttributes?.placeholder
|
|
1353
|
-
);
|
|
1354
|
-
}
|
|
1355
|
-
if (options?.enum_titles && propSchema.enum) {
|
|
1356
|
-
fieldUi["ui:options"] = {
|
|
1357
|
-
...fieldUi["ui:options"],
|
|
1358
|
-
enumNames: options.enum_titles
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
|
-
if (type === "array") {
|
|
1362
|
-
const arrayOpts = {};
|
|
1363
|
-
if (options?.disable_array_add) arrayOpts.addable = false;
|
|
1364
|
-
if (options?.disable_array_delete) arrayOpts.removable = false;
|
|
1365
|
-
if (options?.disable_array_reorder) arrayOpts.orderable = false;
|
|
1366
|
-
if (Object.keys(arrayOpts).length > 0) {
|
|
1367
|
-
fieldUi["ui:options"] = {
|
|
1368
|
-
...fieldUi["ui:options"],
|
|
1369
|
-
...arrayOpts
|
|
1370
|
-
};
|
|
1371
|
-
}
|
|
1372
|
-
const itemsEnumTitles = propSchema.items?.options?.enum_titles;
|
|
1373
|
-
if (Array.isArray(itemsEnumTitles)) {
|
|
1374
|
-
fieldUi.items = { "ui:options": { enumNames: itemsEnumTitles } };
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
if (type === "object" && propSchema.properties) {
|
|
1378
|
-
const nestedGlobal = globalValue && typeof globalValue === "object" && !Array.isArray(globalValue) ? globalValue : void 0;
|
|
1379
|
-
const nested = generateUiSchema(
|
|
1380
|
-
propSchema,
|
|
1381
|
-
readOnly,
|
|
1382
|
-
defs,
|
|
1383
|
-
nestedGlobal,
|
|
1384
|
-
hasProtectedDefaultBranch
|
|
1385
|
-
);
|
|
1386
|
-
Object.assign(fieldUi, nested);
|
|
1387
|
-
}
|
|
1388
|
-
if (type === "array" && propSchema.items?.properties) {
|
|
1389
|
-
const itemsUi = generateUiSchema(
|
|
1390
|
-
propSchema.items,
|
|
1391
|
-
readOnly,
|
|
1392
|
-
defs,
|
|
1393
|
-
void 0,
|
|
1394
|
-
hasProtectedDefaultBranch
|
|
1395
|
-
);
|
|
1396
|
-
if (Object.keys(itemsUi).length > 0) {
|
|
1397
|
-
fieldUi.items = itemsUi;
|
|
1398
|
-
}
|
|
1399
|
-
}
|
|
1400
|
-
if ((propSchema.enumSource || propSchema.watch) && !fieldUi["ui:widget"]) {
|
|
1401
|
-
console.warn(
|
|
1402
|
-
`[RJSF] Property "${key}" uses enumSource/watch which is not yet supported. It will render as a plain input.`
|
|
1403
|
-
);
|
|
1404
|
-
}
|
|
1405
|
-
if (Object.keys(fieldUi).length > 0) {
|
|
1406
|
-
uiSchema[key] = fieldUi;
|
|
1407
|
-
}
|
|
1408
|
-
}
|
|
1409
|
-
const orderedEntries = Object.entries(properties).filter(([, prop]) => prop.propertyOrder !== void 0).sort(
|
|
1410
|
-
([, a], [, b]) => (a.propertyOrder ?? Number.MAX_SAFE_INTEGER) - (b.propertyOrder ?? Number.MAX_SAFE_INTEGER)
|
|
1411
|
-
);
|
|
1412
|
-
if (orderedEntries.length > 0) {
|
|
1413
|
-
uiSchema["ui:order"] = [...orderedEntries.map(([key]) => key), "*"];
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
for (const combiner of ["allOf", "anyOf", "oneOf"]) {
|
|
1417
|
-
const schemas = schema[combiner];
|
|
1418
|
-
if (schemas) {
|
|
1419
|
-
for (const subSchema of schemas) {
|
|
1420
|
-
const subUi = generateUiSchema(
|
|
1421
|
-
subSchema,
|
|
1422
|
-
readOnly,
|
|
1423
|
-
void 0,
|
|
1424
|
-
void 0,
|
|
1425
|
-
hasProtectedDefaultBranch
|
|
1426
|
-
);
|
|
1427
|
-
Object.assign(uiSchema, subUi);
|
|
1428
|
-
}
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
for (const branch of ["if", "then", "else"]) {
|
|
1432
|
-
const branchSchema = schema[branch];
|
|
1433
|
-
if (branchSchema?.properties) {
|
|
1434
|
-
const branchUi = generateUiSchema(
|
|
1435
|
-
branchSchema,
|
|
1436
|
-
readOnly,
|
|
1437
|
-
void 0,
|
|
1438
|
-
void 0,
|
|
1439
|
-
hasProtectedDefaultBranch
|
|
1440
|
-
);
|
|
1441
|
-
Object.assign(uiSchema, branchUi);
|
|
1442
|
-
}
|
|
1443
|
-
}
|
|
1444
|
-
return uiSchema;
|
|
1190
|
+
//#endregion
|
|
1191
|
+
//#region src/blocks/RjsfSchemaEditor/schemaUtils.ts
|
|
1192
|
+
/**
|
|
1193
|
+
* Resolves a $ref reference against the schema definitions, merging any
|
|
1194
|
+
* sibling overrides (title, options, etc.) on top of the resolved schema.
|
|
1195
|
+
*/
|
|
1196
|
+
const resolveRef = (propSchema, definitions) => {
|
|
1197
|
+
if (!propSchema.$ref || !definitions) return propSchema;
|
|
1198
|
+
const resolved = definitions[String(propSchema.$ref).replace("#/definitions/", "")];
|
|
1199
|
+
if (!resolved) return propSchema;
|
|
1200
|
+
const { $ref, ...overrides } = propSchema;
|
|
1201
|
+
return {
|
|
1202
|
+
...resolved,
|
|
1203
|
+
...overrides
|
|
1204
|
+
};
|
|
1445
1205
|
};
|
|
1446
|
-
|
|
1447
|
-
|
|
1206
|
+
/**
|
|
1207
|
+
* Walks a JSON Schema and generates a RJSF uiSchema based on custom `format` and `options` properties.
|
|
1208
|
+
* This maps the legacy @json-editor/json-editor conventions to RJSF widget references.
|
|
1209
|
+
*/
|
|
1210
|
+
const generateUiSchema = (schema, readOnly = false, definitions, globalConfig, hasProtectedDefaultBranch = false) => {
|
|
1211
|
+
const uiSchema = {};
|
|
1212
|
+
const defs = definitions ?? schema.definitions;
|
|
1213
|
+
if (readOnly) uiSchema["ui:disabled"] = true;
|
|
1214
|
+
const properties = schema.properties;
|
|
1215
|
+
if (!properties) {} else {
|
|
1216
|
+
for (const [key, rawPropSchema] of Object.entries(properties)) {
|
|
1217
|
+
const propSchema = resolveRef(rawPropSchema, defs);
|
|
1218
|
+
const format = propSchema.format;
|
|
1219
|
+
const type = propSchema.type ?? (propSchema.properties ? "object" : void 0);
|
|
1220
|
+
const options = propSchema.options;
|
|
1221
|
+
const fieldUi = {};
|
|
1222
|
+
const isHidden = !!options?.hidden;
|
|
1223
|
+
if (isHidden) fieldUi["ui:widget"] = "hidden";
|
|
1224
|
+
if (type === "array" && format === "table") fieldUi["ui:field"] = "tableArray";
|
|
1225
|
+
if (type === "array" && format === "checkbox") fieldUi["ui:widget"] = "checkboxes";
|
|
1226
|
+
if (format === "radio" && propSchema.enum) fieldUi["ui:widget"] = "radio";
|
|
1227
|
+
if (type === "object" && (format === "tabs" || format === "tabs-top" || format === "categories")) fieldUi["ui:field"] = "tabsObject";
|
|
1228
|
+
if (type === "object" && (format === "grid" || format === "grid-strict")) fieldUi["ui:field"] = "gridObject";
|
|
1229
|
+
if (format === "info") {
|
|
1230
|
+
fieldUi["ui:field"] = "info";
|
|
1231
|
+
if (options?.alert_type) fieldUi["ui:options"] = {
|
|
1232
|
+
...fieldUi["ui:options"],
|
|
1233
|
+
alertType: options.alert_type
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
if (type === "button" && format === "test-connection") {
|
|
1237
|
+
fieldUi["ui:widget"] = "test-connection";
|
|
1238
|
+
fieldUi["ui:options"] = options ?? {};
|
|
1239
|
+
} else if (type === "button" && format === "sync-action") {
|
|
1240
|
+
fieldUi["ui:widget"] = "sync-action";
|
|
1241
|
+
fieldUi["ui:options"] = options ?? {};
|
|
1242
|
+
} else if ((type === "string" || type === "object") && format === "editor") {
|
|
1243
|
+
if (type === "object") fieldUi["ui:field"] = "codeEditor";
|
|
1244
|
+
else fieldUi["ui:widget"] = "code-editor";
|
|
1245
|
+
fieldUi["ui:options"] = {
|
|
1246
|
+
editor: options?.editor ?? {},
|
|
1247
|
+
encryptionHint: options?.encryption_hint !== false
|
|
1248
|
+
};
|
|
1249
|
+
} else if (type === "object" && format === "ssh-editor") {
|
|
1250
|
+
fieldUi["ui:field"] = "sshForm";
|
|
1251
|
+
fieldUi["ui:options"] = { only_keys: !!options?.only_keys };
|
|
1252
|
+
} else if (type === "string" && format === "password") {
|
|
1253
|
+
if (!hasProtectedDefaultBranch) fieldUi["ui:widget"] = "password";
|
|
1254
|
+
} else if (type === "string" && format === "textarea") {
|
|
1255
|
+
fieldUi["ui:widget"] = "textarea";
|
|
1256
|
+
if (options?.input_height) fieldUi["ui:options"] = {
|
|
1257
|
+
...fieldUi["ui:options"],
|
|
1258
|
+
rows: parseInputHeightToRows(String(options.input_height))
|
|
1259
|
+
};
|
|
1260
|
+
} else if (type === "string" && format === "trim") fieldUi["ui:options"] = {
|
|
1261
|
+
...fieldUi["ui:options"],
|
|
1262
|
+
trim: true
|
|
1263
|
+
};
|
|
1264
|
+
else if (isDynamicSelectSchema(propSchema)) {
|
|
1265
|
+
fieldUi["ui:widget"] = "dynamic-select";
|
|
1266
|
+
fieldUi["ui:options"] = {
|
|
1267
|
+
...fieldUi["ui:options"],
|
|
1268
|
+
watch: propSchema.watch,
|
|
1269
|
+
enumSource: propSchema.enumSource,
|
|
1270
|
+
tags: !!options?.tags
|
|
1271
|
+
};
|
|
1272
|
+
} else if (isMultiSelectSchema(propSchema)) {
|
|
1273
|
+
const items = propSchema.items;
|
|
1274
|
+
const itemsOptions = items?.options;
|
|
1275
|
+
fieldUi["ui:widget"] = "async-multi-select";
|
|
1276
|
+
fieldUi["ui:options"] = {
|
|
1277
|
+
async: options?.async ?? itemsOptions?.async ?? null,
|
|
1278
|
+
creatable: !!options?.creatable || !!options?.tags,
|
|
1279
|
+
placeholder: String((options?.inputAttributes)?.placeholder ?? ""),
|
|
1280
|
+
...items?.watch && { watch: items.watch },
|
|
1281
|
+
...items?.enumSource && { enumSource: items.enumSource }
|
|
1282
|
+
};
|
|
1283
|
+
} else if (isAsyncSelectSchema(propSchema)) {
|
|
1284
|
+
fieldUi["ui:widget"] = "async-select";
|
|
1285
|
+
fieldUi["ui:options"] = {
|
|
1286
|
+
async: options?.async ?? null,
|
|
1287
|
+
creatable: !!options?.creatable,
|
|
1288
|
+
placeholder: String((options?.inputAttributes)?.placeholder ?? "")
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
if (isTemplateWatchSchema(propSchema)) {
|
|
1292
|
+
fieldUi["ui:widget"] = "template-watch";
|
|
1293
|
+
fieldUi["ui:options"] = {
|
|
1294
|
+
...fieldUi["ui:options"],
|
|
1295
|
+
watch: propSchema.watch,
|
|
1296
|
+
template: propSchema.template,
|
|
1297
|
+
...isContainerSchema(propSchema) && { hidden: true }
|
|
1298
|
+
};
|
|
1299
|
+
}
|
|
1300
|
+
if (type === "boolean" && options?.enum_titles) fieldUi["ui:widget"] = "select";
|
|
1301
|
+
if (options?.collapsed !== void 0) fieldUi["ui:options"] = {
|
|
1302
|
+
...fieldUi["ui:options"],
|
|
1303
|
+
collapsed: !!options.collapsed
|
|
1304
|
+
};
|
|
1305
|
+
if (options?.disable_collapse) fieldUi["ui:options"] = {
|
|
1306
|
+
...fieldUi["ui:options"],
|
|
1307
|
+
disableCollapse: true
|
|
1308
|
+
};
|
|
1309
|
+
if (options?.dependencies) fieldUi["ui:options"] = {
|
|
1310
|
+
...fieldUi["ui:options"],
|
|
1311
|
+
dependencies: options.dependencies
|
|
1312
|
+
};
|
|
1313
|
+
if (options?.grid_break) fieldUi["ui:options"] = {
|
|
1314
|
+
...fieldUi["ui:options"],
|
|
1315
|
+
gridBreak: true
|
|
1316
|
+
};
|
|
1317
|
+
if (options?.enabled === false) fieldUi["ui:disabled"] = true;
|
|
1318
|
+
const globalValue = globalConfig?.[key];
|
|
1319
|
+
if (globalValue !== void 0) {
|
|
1320
|
+
if (typeof globalValue !== "object" || globalValue === null || Array.isArray(globalValue)) fieldUi["ui:disabled"] = true;
|
|
1321
|
+
}
|
|
1322
|
+
if (options?.tooltip) fieldUi["ui:help"] = String(options.tooltip);
|
|
1323
|
+
if ((options?.documentation)?.link) fieldUi["ui:options"] = {
|
|
1324
|
+
...fieldUi["ui:options"],
|
|
1325
|
+
documentation: options?.documentation
|
|
1326
|
+
};
|
|
1327
|
+
if ((options?.inputAttributes)?.placeholder && !fieldUi["ui:widget"]) fieldUi["ui:placeholder"] = String((options?.inputAttributes)?.placeholder);
|
|
1328
|
+
if (options?.enum_titles && propSchema.enum) fieldUi["ui:options"] = {
|
|
1329
|
+
...fieldUi["ui:options"],
|
|
1330
|
+
enumNames: options.enum_titles
|
|
1331
|
+
};
|
|
1332
|
+
if (type === "array") {
|
|
1333
|
+
const arrayOpts = {};
|
|
1334
|
+
if (options?.disable_array_add) arrayOpts.addable = false;
|
|
1335
|
+
if (options?.disable_array_delete) arrayOpts.removable = false;
|
|
1336
|
+
if (options?.disable_array_reorder) arrayOpts.orderable = false;
|
|
1337
|
+
if (Object.keys(arrayOpts).length > 0) fieldUi["ui:options"] = {
|
|
1338
|
+
...fieldUi["ui:options"],
|
|
1339
|
+
...arrayOpts
|
|
1340
|
+
};
|
|
1341
|
+
const itemsEnumTitles = (propSchema.items?.options)?.enum_titles;
|
|
1342
|
+
if (Array.isArray(itemsEnumTitles)) fieldUi.items = { "ui:options": { enumNames: itemsEnumTitles } };
|
|
1343
|
+
}
|
|
1344
|
+
if (type === "object" && propSchema.properties) {
|
|
1345
|
+
const nested = generateUiSchema(propSchema, readOnly, defs, globalValue && typeof globalValue === "object" && !Array.isArray(globalValue) ? globalValue : void 0, hasProtectedDefaultBranch);
|
|
1346
|
+
Object.assign(fieldUi, nested);
|
|
1347
|
+
}
|
|
1348
|
+
if (type === "array" && propSchema.items?.properties) {
|
|
1349
|
+
const itemsUi = generateUiSchema(propSchema.items, readOnly, defs, void 0, hasProtectedDefaultBranch);
|
|
1350
|
+
if (Object.keys(itemsUi).length > 0) fieldUi.items = itemsUi;
|
|
1351
|
+
}
|
|
1352
|
+
if ((propSchema.enumSource || propSchema.watch) && !fieldUi["ui:widget"]) console.warn(`[RJSF] Property "${key}" uses enumSource/watch which is not yet supported. It will render as a plain input.`);
|
|
1353
|
+
if (isHidden) fieldUi["ui:options"] = {
|
|
1354
|
+
...fieldUi["ui:options"],
|
|
1355
|
+
hidden: true
|
|
1356
|
+
};
|
|
1357
|
+
if (Object.keys(fieldUi).length > 0) uiSchema[key] = fieldUi;
|
|
1358
|
+
}
|
|
1359
|
+
const orderedEntries = Object.entries(properties).filter(([, prop]) => prop.propertyOrder !== void 0).sort(([, a], [, b]) => (a.propertyOrder ?? Number.MAX_SAFE_INTEGER) - (b.propertyOrder ?? Number.MAX_SAFE_INTEGER));
|
|
1360
|
+
if (orderedEntries.length > 0) uiSchema["ui:order"] = [...orderedEntries.map(([key]) => key), "*"];
|
|
1361
|
+
}
|
|
1362
|
+
for (const combiner of [
|
|
1363
|
+
"allOf",
|
|
1364
|
+
"anyOf",
|
|
1365
|
+
"oneOf"
|
|
1366
|
+
]) {
|
|
1367
|
+
const schemas = schema[combiner];
|
|
1368
|
+
if (schemas) for (const subSchema of schemas) {
|
|
1369
|
+
const subUi = generateUiSchema(subSchema, readOnly, void 0, void 0, hasProtectedDefaultBranch);
|
|
1370
|
+
Object.assign(uiSchema, subUi);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
for (const branch of [
|
|
1374
|
+
"if",
|
|
1375
|
+
"then",
|
|
1376
|
+
"else"
|
|
1377
|
+
]) {
|
|
1378
|
+
const branchSchema = schema[branch];
|
|
1379
|
+
if (branchSchema?.properties) {
|
|
1380
|
+
const branchUi = generateUiSchema(branchSchema, readOnly, void 0, void 0, hasProtectedDefaultBranch);
|
|
1381
|
+
Object.assign(uiSchema, branchUi);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
return uiSchema;
|
|
1448
1385
|
};
|
|
1449
|
-
|
|
1450
|
-
|
|
1386
|
+
const isDynamicSelectSchema = (schema) => {
|
|
1387
|
+
return !!(schema.enumSource && schema.watch && schema.type === "string");
|
|
1451
1388
|
};
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
const { type } = schema;
|
|
1455
|
-
if (Array.isArray(type)) return type.includes("object") || type.includes("array");
|
|
1456
|
-
return type === "object" || type === "array";
|
|
1389
|
+
const isTemplateWatchSchema = (schema) => {
|
|
1390
|
+
return !!(schema.template && schema.watch && !schema.enumSource);
|
|
1457
1391
|
};
|
|
1458
|
-
|
|
1459
|
-
|
|
1392
|
+
const isAsyncSelectSchema = (schema) => {
|
|
1393
|
+
return !!(schema.options?.async || schema.options?.creatable);
|
|
1460
1394
|
};
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1395
|
+
const isMultiSelectSchema = (schema) => {
|
|
1396
|
+
const items = schema.items;
|
|
1397
|
+
return !!(items && schema.uniqueItems && schema.type === "array" && schema.format !== "checkbox" && !Array.isArray(items) && [
|
|
1398
|
+
"string",
|
|
1399
|
+
"number",
|
|
1400
|
+
"integer"
|
|
1401
|
+
].includes(items.type) && (items.enum || items.enumSource || schema.options?.tags));
|
|
1464
1402
|
};
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1403
|
+
/**
|
|
1404
|
+
* Cleans up non-standard properties from a schema before passing to RJSF/AJV.
|
|
1405
|
+
* RJSF is strict about unknown keywords, and our schemas contain json-editor-specific
|
|
1406
|
+
* extensions (format: 'button', options, etc.).
|
|
1407
|
+
*/
|
|
1408
|
+
/** Convert CSS height like "100px" to approximate textarea rows */
|
|
1409
|
+
const parseInputHeightToRows = (height) => {
|
|
1410
|
+
const px = parseInt(height, 10);
|
|
1411
|
+
if (Number.isNaN(px) || px <= 0) return 5;
|
|
1412
|
+
return Math.max(2, Math.round(px / 20));
|
|
1469
1413
|
};
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1414
|
+
const CUSTOM_FORMATS = [
|
|
1415
|
+
"table",
|
|
1416
|
+
"editor",
|
|
1417
|
+
"ssh-editor",
|
|
1418
|
+
"trim",
|
|
1419
|
+
"textarea",
|
|
1420
|
+
"grid",
|
|
1421
|
+
"grid-strict",
|
|
1422
|
+
"tabs",
|
|
1423
|
+
"tabs-top",
|
|
1424
|
+
"categories",
|
|
1425
|
+
"info",
|
|
1426
|
+
"select",
|
|
1427
|
+
"checkbox",
|
|
1428
|
+
"json",
|
|
1429
|
+
"button",
|
|
1430
|
+
"radio"
|
|
1487
1431
|
];
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
for (const combiner of ["allOf", "anyOf", "oneOf"]) {
|
|
1556
|
-
const schemas = cleaned[combiner];
|
|
1557
|
-
if (schemas) {
|
|
1558
|
-
cleaned[combiner] = schemas.map((s) => sanitizeSchema(s, defs));
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
for (const branch of ["if", "then", "else"]) {
|
|
1562
|
-
const branchSchema = cleaned[branch];
|
|
1563
|
-
if (branchSchema) {
|
|
1564
|
-
cleaned[branch] = sanitizeSchema(branchSchema, defs, true);
|
|
1565
|
-
}
|
|
1566
|
-
}
|
|
1567
|
-
if (cleaned.items && typeof cleaned.items === "object" && !Array.isArray(cleaned.items)) {
|
|
1568
|
-
cleaned.items = sanitizeSchema(cleaned.items, defs);
|
|
1569
|
-
}
|
|
1570
|
-
return cleaned;
|
|
1432
|
+
const sanitizeSchema = (schema, definitions, isConditionalBranch = false) => {
|
|
1433
|
+
const cleaned = { ...schema };
|
|
1434
|
+
const defs = definitions ?? cleaned.definitions;
|
|
1435
|
+
if (Array.isArray(cleaned.enum) && cleaned.enum.length === 0) delete cleaned.enum;
|
|
1436
|
+
if (Array.isArray(cleaned.enum) && cleaned.enum.length > 0 && (cleaned.type === "string" || cleaned.type === "integer" || cleaned.type === "number")) {
|
|
1437
|
+
if (cleaned.default === void 0) cleaned.default = cleaned.enum[0];
|
|
1438
|
+
else if (!cleaned.enum.includes(cleaned.default)) delete cleaned.default;
|
|
1439
|
+
}
|
|
1440
|
+
if (cleaned.properties && !cleaned.type) cleaned.type = "object";
|
|
1441
|
+
if (cleaned.required === true) delete cleaned.required;
|
|
1442
|
+
if (CUSTOM_FORMATS.includes(cleaned.format)) delete cleaned.format;
|
|
1443
|
+
const properties = cleaned.properties;
|
|
1444
|
+
if (properties) {
|
|
1445
|
+
const sanitizedProps = {};
|
|
1446
|
+
const required = cleaned.required ?? [];
|
|
1447
|
+
const sanitizedRequired = [];
|
|
1448
|
+
for (const [key, rawPropSchema] of Object.entries(properties)) {
|
|
1449
|
+
const propSchema = resolveRef(rawPropSchema, defs);
|
|
1450
|
+
if (propSchema.type === "button") {
|
|
1451
|
+
sanitizedProps[key] = {
|
|
1452
|
+
type: "string",
|
|
1453
|
+
title: propSchema.title,
|
|
1454
|
+
...propSchema.propertyOrder !== void 0 && { propertyOrder: propSchema.propertyOrder },
|
|
1455
|
+
...propSchema.description !== void 0 && { description: propSchema.description }
|
|
1456
|
+
};
|
|
1457
|
+
continue;
|
|
1458
|
+
}
|
|
1459
|
+
if (propSchema.type === "boolean" && propSchema.options?.enum_titles) {
|
|
1460
|
+
const titles = propSchema.options.enum_titles;
|
|
1461
|
+
const sanitized = sanitizeSchema(propSchema, defs);
|
|
1462
|
+
sanitized.oneOf = (propSchema.enum ?? [true, false]).map((value, index) => ({
|
|
1463
|
+
const: value,
|
|
1464
|
+
title: titles[index] ?? (value ? "Yes" : "No")
|
|
1465
|
+
}));
|
|
1466
|
+
sanitizedProps[key] = sanitized;
|
|
1467
|
+
if (required.includes(key) || propSchema.required === true) {
|
|
1468
|
+
if (!sanitizedRequired.includes(key)) sanitizedRequired.push(key);
|
|
1469
|
+
}
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
sanitizedProps[key] = sanitizeSchema(propSchema, defs);
|
|
1473
|
+
if (required.includes(key) || propSchema.required === true) {
|
|
1474
|
+
if (!sanitizedRequired.includes(key)) sanitizedRequired.push(key);
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
cleaned.properties = sanitizedProps;
|
|
1478
|
+
if (sanitizedRequired.length > 0) cleaned.required = sanitizedRequired;
|
|
1479
|
+
if (!isConditionalBranch && cleaned.additionalProperties === void 0 && !cleaned.if) cleaned.additionalProperties = false;
|
|
1480
|
+
}
|
|
1481
|
+
for (const combiner of [
|
|
1482
|
+
"allOf",
|
|
1483
|
+
"anyOf",
|
|
1484
|
+
"oneOf"
|
|
1485
|
+
]) {
|
|
1486
|
+
const schemas = cleaned[combiner];
|
|
1487
|
+
if (schemas) cleaned[combiner] = schemas.map((s) => sanitizeSchema(s, defs));
|
|
1488
|
+
}
|
|
1489
|
+
for (const branch of [
|
|
1490
|
+
"if",
|
|
1491
|
+
"then",
|
|
1492
|
+
"else"
|
|
1493
|
+
]) {
|
|
1494
|
+
const branchSchema = cleaned[branch];
|
|
1495
|
+
if (branchSchema) cleaned[branch] = sanitizeSchema(branchSchema, defs, true);
|
|
1496
|
+
}
|
|
1497
|
+
if (cleaned.items && typeof cleaned.items === "object" && !Array.isArray(cleaned.items)) cleaned.items = sanitizeSchema(cleaned.items, defs);
|
|
1498
|
+
return cleaned;
|
|
1571
1499
|
};
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1500
|
+
//#endregion
|
|
1501
|
+
//#region src/blocks/RjsfSchemaEditor/RjsfSchemaEditor.tsx
|
|
1502
|
+
const defaultRenderMarkdown = (source) => source;
|
|
1503
|
+
/**
|
|
1504
|
+
* Produces a canonical JSON string with sorted keys at every level.
|
|
1505
|
+
* This ensures two objects with the same data but different key ordering
|
|
1506
|
+
* produce the same string. Also normalizes undefined → omitted (via JSON.stringify).
|
|
1507
|
+
*/
|
|
1508
|
+
const stableStringify = (obj) => JSON.stringify(obj, (_key, val) => {
|
|
1509
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
1510
|
+
const sorted = {};
|
|
1511
|
+
for (const key of Object.keys(val).sort()) sorted[key] = val[key];
|
|
1512
|
+
return sorted;
|
|
1513
|
+
}
|
|
1514
|
+
return val;
|
|
1582
1515
|
});
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
},
|
|
1722
|
-
formKey
|
|
1723
|
-
) }) }) });
|
|
1516
|
+
const RjsfSchemaEditor = ({ schema, value, onChange, readOnly, inForm, globalConfig, rootContext, onRegisterValidate, widgets, fields, renderMarkdown, hasProtectedDefaultBranch = false }) => {
|
|
1517
|
+
const schemaJs = useMemo(() => sanitizeSchema(schema), [schema]);
|
|
1518
|
+
const uiSchema = useMemo(() => generateUiSchema(schema, readOnly, void 0, globalConfig ?? void 0, hasProtectedDefaultBranch), [
|
|
1519
|
+
schema,
|
|
1520
|
+
readOnly,
|
|
1521
|
+
globalConfig,
|
|
1522
|
+
hasProtectedDefaultBranch
|
|
1523
|
+
]);
|
|
1524
|
+
const mergedWidgets = useMemo(() => ({
|
|
1525
|
+
...defaultWidgets,
|
|
1526
|
+
...widgets
|
|
1527
|
+
}), [widgets]);
|
|
1528
|
+
const mergedFields = useMemo(() => ({
|
|
1529
|
+
...defaultFields,
|
|
1530
|
+
...fields
|
|
1531
|
+
}), [fields]);
|
|
1532
|
+
const initialDataRef = useRef(value);
|
|
1533
|
+
const formDataRef = useRef(initialDataRef.current);
|
|
1534
|
+
const [formKey, setFormKey] = useState(0);
|
|
1535
|
+
const [hasValidated, setHasValidated] = useState(false);
|
|
1536
|
+
const [rootFormData, setRootFormData] = useState(initialDataRef.current);
|
|
1537
|
+
const mountedFormDataJsonRef = useRef(null);
|
|
1538
|
+
const isInitialMountRef = useRef(true);
|
|
1539
|
+
useEffect(() => {
|
|
1540
|
+
isInitialMountRef.current = false;
|
|
1541
|
+
}, [formKey]);
|
|
1542
|
+
const onChangeRef = useRef(onChange);
|
|
1543
|
+
onChangeRef.current = onChange;
|
|
1544
|
+
const valueRef = useRef(value);
|
|
1545
|
+
valueRef.current = value;
|
|
1546
|
+
const lastSentJsonRef = useRef(null);
|
|
1547
|
+
const debouncedOnChange = useMemo(() => debounce((data) => {
|
|
1548
|
+
const dataJson = stableStringify(data);
|
|
1549
|
+
if (dataJson !== stableStringify(valueRef.current)) {
|
|
1550
|
+
if (lastSentJsonRef.current === null && mountedFormDataJsonRef.current && dataJson === mountedFormDataJsonRef.current) return;
|
|
1551
|
+
lastSentJsonRef.current = dataJson;
|
|
1552
|
+
onChangeRef.current(data);
|
|
1553
|
+
}
|
|
1554
|
+
}, 100), []);
|
|
1555
|
+
useEffect(() => () => debouncedOnChange.cancel(), [debouncedOnChange]);
|
|
1556
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
1557
|
+
if (value !== prevValue) {
|
|
1558
|
+
setPrevValue(value);
|
|
1559
|
+
const incomingJson = stableStringify(value);
|
|
1560
|
+
if (incomingJson !== stableStringify(prevValue)) {
|
|
1561
|
+
if (lastSentJsonRef.current && lastSentJsonRef.current === incomingJson) lastSentJsonRef.current = null;
|
|
1562
|
+
else {
|
|
1563
|
+
debouncedOnChange.cancel();
|
|
1564
|
+
lastSentJsonRef.current = null;
|
|
1565
|
+
initialDataRef.current = value;
|
|
1566
|
+
formDataRef.current = value;
|
|
1567
|
+
isInitialMountRef.current = true;
|
|
1568
|
+
mountedFormDataJsonRef.current = null;
|
|
1569
|
+
setFormKey((k) => k + 1);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
const handleChange = useCallback((e) => {
|
|
1574
|
+
if (!e.formData) return;
|
|
1575
|
+
formDataRef.current = e.formData;
|
|
1576
|
+
setRootFormData(e.formData);
|
|
1577
|
+
if (isInitialMountRef.current) {
|
|
1578
|
+
mountedFormDataJsonRef.current = stableStringify(e.formData);
|
|
1579
|
+
return;
|
|
1580
|
+
}
|
|
1581
|
+
debouncedOnChange(e.formData);
|
|
1582
|
+
}, [debouncedOnChange]);
|
|
1583
|
+
const debouncedOnChangeRef = useRef(debouncedOnChange);
|
|
1584
|
+
debouncedOnChangeRef.current = debouncedOnChange;
|
|
1585
|
+
const setRootFormDataRef = useRef(setRootFormData);
|
|
1586
|
+
setRootFormDataRef.current = setRootFormData;
|
|
1587
|
+
const formContext = useMemo(() => ({
|
|
1588
|
+
setFormData: (data) => {
|
|
1589
|
+
const merged = {
|
|
1590
|
+
...formDataRef.current,
|
|
1591
|
+
...data
|
|
1592
|
+
};
|
|
1593
|
+
initialDataRef.current = merged;
|
|
1594
|
+
formDataRef.current = merged;
|
|
1595
|
+
setRootFormDataRef.current(merged);
|
|
1596
|
+
debouncedOnChangeRef.current.cancel();
|
|
1597
|
+
lastSentJsonRef.current = stableStringify(merged);
|
|
1598
|
+
onChangeRef.current(merged);
|
|
1599
|
+
isInitialMountRef.current = true;
|
|
1600
|
+
mountedFormDataJsonRef.current = null;
|
|
1601
|
+
setFormKey((k) => k + 1);
|
|
1602
|
+
},
|
|
1603
|
+
getFormData: () => formDataRef.current
|
|
1604
|
+
}), []);
|
|
1605
|
+
const formRef = useRef(null);
|
|
1606
|
+
useEffect(() => {
|
|
1607
|
+
if (onRegisterValidate) onRegisterValidate(() => {
|
|
1608
|
+
setHasValidated(true);
|
|
1609
|
+
return formRef.current?.validateForm() ?? true;
|
|
1610
|
+
});
|
|
1611
|
+
}, [onRegisterValidate, formKey]);
|
|
1612
|
+
const rootFormDataValue = useMemo(() => {
|
|
1613
|
+
const context = rootContext ?? {};
|
|
1614
|
+
const merged = { ...rootFormData };
|
|
1615
|
+
for (const [key, entry] of Object.entries(context)) {
|
|
1616
|
+
const existing = merged[key];
|
|
1617
|
+
merged[key] = isRecord(existing) ? {
|
|
1618
|
+
...existing,
|
|
1619
|
+
...entry
|
|
1620
|
+
} : entry;
|
|
1621
|
+
}
|
|
1622
|
+
return {
|
|
1623
|
+
data: merged,
|
|
1624
|
+
context
|
|
1625
|
+
};
|
|
1626
|
+
}, [rootFormData, rootContext]);
|
|
1627
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1628
|
+
className: "json-editor",
|
|
1629
|
+
children: /* @__PURE__ */ jsx(RenderMarkdownProvider, {
|
|
1630
|
+
value: renderMarkdown ?? defaultRenderMarkdown,
|
|
1631
|
+
children: /* @__PURE__ */ jsx(RootFormDataProvider, {
|
|
1632
|
+
value: rootFormDataValue,
|
|
1633
|
+
children: /* @__PURE__ */ jsx(Form, {
|
|
1634
|
+
ref: formRef,
|
|
1635
|
+
schema: schemaJs,
|
|
1636
|
+
initialFormData: initialDataRef.current,
|
|
1637
|
+
uiSchema,
|
|
1638
|
+
validator,
|
|
1639
|
+
onChange: handleChange,
|
|
1640
|
+
widgets: mergedWidgets,
|
|
1641
|
+
fields: mergedFields,
|
|
1642
|
+
templates: defaultTemplates,
|
|
1643
|
+
formContext,
|
|
1644
|
+
disabled: readOnly,
|
|
1645
|
+
liveValidate: hasValidated ? "onBlur" : void 0,
|
|
1646
|
+
showErrorList: false,
|
|
1647
|
+
noHtml5Validate: true,
|
|
1648
|
+
tagName: inForm ? "div" : "form",
|
|
1649
|
+
children: /* @__PURE__ */ jsx(Fragment$1, {})
|
|
1650
|
+
}, formKey)
|
|
1651
|
+
})
|
|
1652
|
+
})
|
|
1653
|
+
});
|
|
1724
1654
|
};
|
|
1725
|
-
|
|
1655
|
+
//#endregion
|
|
1726
1656
|
export { RjsfSchemaEditor, buildDynamicOptions, resolveByPath, useRootFormData };
|
|
1727
|
-
|
|
1657
|
+
|
|
1728
1658
|
//# sourceMappingURL=rjsf.js.map
|