@webiny/app-admin 6.3.0 → 6.4.0-beta.1
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/assets/icons/add-18px.js +20 -0
- package/assets/icons/add-18px.js.map +1 -0
- package/assets/icons/arrow_drop_down-24px.js +20 -0
- package/assets/icons/arrow_drop_down-24px.js.map +1 -0
- package/assets/icons/attach_file_black_24dp.js +20 -0
- package/assets/icons/attach_file_black_24dp.js.map +1 -0
- package/assets/icons/baseline-menu-24px.js +20 -0
- package/assets/icons/baseline-menu-24px.js.map +1 -0
- package/assets/icons/baseline-notification_important-24px.js +19 -0
- package/assets/icons/baseline-notification_important-24px.js.map +1 -0
- package/assets/icons/baseline-security-24px.js +19 -0
- package/assets/icons/baseline-security-24px.js.map +1 -0
- package/assets/icons/file_download.js +19 -0
- package/assets/icons/file_download.js.map +1 -0
- package/assets/icons/file_upload.js +19 -0
- package/assets/icons/file_upload.js.map +1 -0
- package/assets/icons/filter-24px.js +23 -0
- package/assets/icons/filter-24px.js.map +1 -0
- package/assets/icons/github-brands.js +19 -0
- package/assets/icons/github-brands.js.map +1 -0
- package/assets/icons/highlight-24px.js +19 -0
- package/assets/icons/highlight-24px.js.map +1 -0
- package/assets/icons/icon-community.js +18 -0
- package/assets/icons/icon-community.js.map +1 -0
- package/assets/icons/icon-documentation.js +18 -0
- package/assets/icons/icon-documentation.js.map +1 -0
- package/assets/icons/info.js +19 -0
- package/assets/icons/info.js.map +1 -0
- package/assets/icons/insert_drive_file-24px.js +19 -0
- package/assets/icons/insert_drive_file-24px.js.map +1 -0
- package/assets/icons/insert_photo-24px.js +19 -0
- package/assets/icons/insert_photo-24px.js.map +1 -0
- package/assets/icons/label-24px.js +19 -0
- package/assets/icons/label-24px.js.map +1 -0
- package/assets/icons/round-account_circle-24px.js +19 -0
- package/assets/icons/round-account_circle-24px.js.map +1 -0
- package/assets/icons/round-add-24px.js +20 -0
- package/assets/icons/round-add-24px.js.map +1 -0
- package/assets/icons/round-arrow_drop_down-24px.js +19 -0
- package/assets/icons/round-arrow_drop_down-24px.js.map +1 -0
- package/assets/icons/round-chevron_right-24px.js +20 -0
- package/assets/icons/round-chevron_right-24px.js.map +1 -0
- package/assets/icons/round-feedback-24px.js +20 -0
- package/assets/icons/round-feedback-24px.js.map +1 -0
- package/assets/icons/round-help-24px.js +19 -0
- package/assets/icons/round-help-24px.js.map +1 -0
- package/assets/icons/round-invert_colors-24px.js +20 -0
- package/assets/icons/round-invert_colors-24px.js.map +1 -0
- package/assets/icons/round-keyboard_arrow_down-24px.js +17 -0
- package/assets/icons/round-keyboard_arrow_down-24px.js.map +1 -0
- package/assets/icons/round-keyboard_arrow_up-24px.js +17 -0
- package/assets/icons/round-keyboard_arrow_up-24px.js.map +1 -0
- package/assets/icons/round-lock_open-24px.js +22 -0
- package/assets/icons/round-lock_open-24px.js.map +1 -0
- package/assets/icons/round-more_vert-24px.js +20 -0
- package/assets/icons/round-more_vert-24px.js.map +1 -0
- package/assets/icons/round-open_in_new-24px.js +20 -0
- package/assets/icons/round-open_in_new-24px.js.map +1 -0
- package/assets/icons/round-settings-24px.js +20 -0
- package/assets/icons/round-settings-24px.js.map +1 -0
- package/assets/icons/search-24px.js +21 -0
- package/assets/icons/search-24px.js.map +1 -0
- package/assets/icons/slack-logo.js +14 -0
- package/assets/icons/slack-logo.js.map +1 -0
- package/assets/icons/today-24px.js +19 -0
- package/assets/icons/today-24px.js.map +1 -0
- package/assets/icons/touch_app.js +20 -0
- package/assets/icons/touch_app.js.map +1 -0
- package/assets/images/webiny-logo.js +34 -0
- package/assets/images/webiny-logo.js.map +1 -0
- package/assets/images/webiny-orange-logo.js +34 -0
- package/assets/images/webiny-orange-logo.js.map +1 -0
- package/base/Admin.js +37 -28
- package/base/Admin.js.map +1 -1
- package/base/Base/DefaultFieldRenderers.js +73 -70
- package/base/Base/DefaultFieldRenderers.js.map +1 -1
- package/base/Base/DefaultLayoutRenderers.js +9 -10
- package/base/Base/DefaultLayoutRenderers.js.map +1 -1
- package/base/Base/FieldRenderers/CheckboxesRenderer.js +22 -23
- package/base/Base/FieldRenderers/CheckboxesRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/CodeEditorRenderer.js +10 -13
- package/base/Base/FieldRenderers/CodeEditorRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/DateTimeInputsRenderer.js +60 -60
- package/base/Base/FieldRenderers/DateTimeInputsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/DateTimeRenderer.js +38 -39
- package/base/Base/FieldRenderers/DateTimeRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/FilePickerRenderer.d.ts +2 -1
- package/base/Base/FieldRenderers/FilePickerRenderer.js +37 -40
- package/base/Base/FieldRenderers/FilePickerRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/FileUrlPickerRenderer.js +15 -20
- package/base/Base/FieldRenderers/FileUrlPickerRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/HiddenRenderer.js +3 -3
- package/base/Base/FieldRenderers/HiddenRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/HorizontalTabsRenderer.js +20 -21
- package/base/Base/FieldRenderers/HorizontalTabsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/InputRenderer.js +16 -20
- package/base/Base/FieldRenderers/InputRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/MultiFilePickerRenderer.d.ts +13 -0
- package/base/Base/FieldRenderers/MultiFilePickerRenderer.js +70 -0
- package/base/Base/FieldRenderers/MultiFilePickerRenderer.js.map +1 -0
- package/base/Base/FieldRenderers/NumberInputRenderer.js +16 -19
- package/base/Base/FieldRenderers/NumberInputRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/NumberInputsRenderer.js +45 -44
- package/base/Base/FieldRenderers/NumberInputsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/DynamicZoneRenderer.js +10 -13
- package/base/Base/FieldRenderers/ObjectRenderer/DynamicZoneRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/KeyValueTagsRenderer.js +50 -56
- package/base/Base/FieldRenderers/ObjectRenderer/KeyValueTagsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone.js +87 -99
- package/base/Base/FieldRenderers/ObjectRenderer/MultiValueDynamicZone.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectAccordionMultipleRenderer.js +41 -48
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectAccordionMultipleRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.d.ts +1 -2
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.js +62 -78
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectFieldComponents.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectRenderer.js +12 -15
- package/base/Base/FieldRenderers/ObjectRenderer/ObjectRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js +48 -54
- package/base/Base/FieldRenderers/ObjectRenderer/SingleValueDynamicZone.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js +62 -79
- package/base/Base/FieldRenderers/ObjectRenderer/TemplatePicker.js.map +1 -1
- package/base/Base/FieldRenderers/ObjectRenderer/resolveItemTitle.js +14 -17
- package/base/Base/FieldRenderers/ObjectRenderer/resolveItemTitle.js.map +1 -1
- package/base/Base/FieldRenderers/PassthroughRenderer.js +8 -11
- package/base/Base/FieldRenderers/PassthroughRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/RadioButtonsRenderer.js +21 -22
- package/base/Base/FieldRenderers/RadioButtonsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/SelectRenderer.js +23 -24
- package/base/Base/FieldRenderers/SelectRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/SwitchRenderer.js +12 -15
- package/base/Base/FieldRenderers/SwitchRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/TagsRenderer.js +15 -16
- package/base/Base/FieldRenderers/TagsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/TextInputsRenderer.js +44 -43
- package/base/Base/FieldRenderers/TextInputsRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/TextareaRenderer.js +17 -21
- package/base/Base/FieldRenderers/TextareaRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/TextareasRenderer.js +47 -46
- package/base/Base/FieldRenderers/TextareasRenderer.js.map +1 -1
- package/base/Base/FieldRenderers/VerticalTabsRenderer.js +35 -36
- package/base/Base/FieldRenderers/VerticalTabsRenderer.js.map +1 -1
- package/base/Base/LexicalPreset.js +56 -60
- package/base/Base/LexicalPreset.js.map +1 -1
- package/base/Base/Menus/SupportMenuItems.js +9 -13
- package/base/Base/Menus/SupportMenuItems.js.map +1 -1
- package/base/Base/Menus/WebinyVersion.js +19 -20
- package/base/Base/Menus/WebinyVersion.js.map +1 -1
- package/base/Base/Menus.js +52 -66
- package/base/Base/Menus.js.map +1 -1
- package/base/Base/RoutesConfig.js +21 -29
- package/base/Base/RoutesConfig.js.map +1 -1
- package/base/Base/Tenant/wby-horizontal.js +33 -0
- package/base/Base/Tenant/wby-horizontal.js.map +1 -0
- package/base/Base/Tenant/wby-square.js +20 -0
- package/base/Base/Tenant/wby-square.js.map +1 -0
- package/base/Base/Tenant.js +17 -19
- package/base/Base/Tenant.js.map +1 -1
- package/base/Base/UserMenu/ExitTenant.js +18 -29
- package/base/Base/UserMenu/ExitTenant.js.map +1 -1
- package/base/Base/UserMenu/SignOut.js +13 -14
- package/base/Base/UserMenu/SignOut.js.map +1 -1
- package/base/Base/UserMenu/UserInfo.js +23 -36
- package/base/Base/UserMenu/UserInfo.js.map +1 -1
- package/base/Base/UserMenu.js +12 -13
- package/base/Base/UserMenu.js.map +1 -1
- package/base/Base.js +4 -5
- package/base/Base.js.map +1 -1
- package/base/TelemetryAdminAppStart.js +9 -12
- package/base/TelemetryAdminAppStart.js.map +1 -1
- package/base/WebinyVersion.js +19 -20
- package/base/WebinyVersion.js.map +1 -1
- package/base/createRootContainer.js +42 -40
- package/base/createRootContainer.js.map +1 -1
- package/base/plugins/AddGraphQLQuerySelection.js +12 -11
- package/base/plugins/AddGraphQLQuerySelection.js.map +1 -1
- package/base/providers/AdminUiStateProvider.js +5 -10
- package/base/providers/AdminUiStateProvider.js.map +1 -1
- package/base/providers/ApolloProvider.js +8 -11
- package/base/providers/ApolloProvider.js.map +1 -1
- package/base/providers/UiProviders.js +18 -27
- package/base/providers/UiProviders.js.map +1 -1
- package/base/providers/UiStateProvider.js +5 -10
- package/base/providers/UiStateProvider.js.map +1 -1
- package/base/ui/Brand.js +4 -5
- package/base/ui/Brand.js.map +1 -1
- package/base/ui/CenteredView.d.ts +1 -1
- package/base/ui/CenteredView.js +9 -13
- package/base/ui/CenteredView.js.map +1 -1
- package/base/ui/Dashboard.js +4 -5
- package/base/ui/Dashboard.js.map +1 -1
- package/base/ui/FileManager.js +38 -60
- package/base/ui/FileManager.js.map +1 -1
- package/base/ui/Layout.js +4 -8
- package/base/ui/Layout.js.map +1 -1
- package/base/ui/LoginScreen.js +16 -21
- package/base/ui/LoginScreen.js.map +1 -1
- package/base/ui/Logo.js +4 -5
- package/base/ui/Logo.js.map +1 -1
- package/base/ui/Navigation.js +11 -14
- package/base/ui/Navigation.js.map +1 -1
- package/base/ui/NotFound.js +4 -5
- package/base/ui/NotFound.js.map +1 -1
- package/base/ui/Tags.js +12 -16
- package/base/ui/Tags.js.map +1 -1
- package/base/ui/TenantSelector.js +4 -5
- package/base/ui/TenantSelector.js.map +1 -1
- package/base/ui/UserMenu/UserMenu.js +4 -5
- package/base/ui/UserMenu/UserMenu.js.map +1 -1
- package/base/ui/UserMenu/UserMenuHandle.js +4 -5
- package/base/ui/UserMenu/UserMenuHandle.js.map +1 -1
- package/base/ui/UserMenu/UserMenuItem.d.ts +4 -4
- package/base/ui/UserMenu/UserMenuItem.js +5 -15
- package/base/ui/UserMenu/UserMenuItem.js.map +1 -1
- package/base/ui/UserMenu/UserMenuLink.d.ts +4 -4
- package/base/ui/UserMenu/UserMenuLink.js +5 -15
- package/base/ui/UserMenu/UserMenuLink.js.map +1 -1
- package/base/ui/UserMenu/UserMenuSeparator.d.ts +2 -2
- package/base/ui/UserMenu/UserMenuSeparator.js +3 -5
- package/base/ui/UserMenu/UserMenuSeparator.js.map +1 -1
- package/base/ui/UserMenu.js +6 -13
- package/base/ui/UserMenu.js.map +1 -1
- package/components/AdminLayout.js +6 -10
- package/components/AdminLayout.js.map +1 -1
- package/components/BulkActions/Worker.js +57 -120
- package/components/BulkActions/Worker.js.map +1 -1
- package/components/BulkActions/index.js +0 -2
- package/components/BulkActions/useDialogWithReport/DialogMessage.js +17 -21
- package/components/BulkActions/useDialogWithReport/DialogMessage.js.map +1 -1
- package/components/BulkActions/useDialogWithReport/index.js +0 -2
- package/components/BulkActions/useDialogWithReport/useDialogWithReport.js +33 -44
- package/components/BulkActions/useDialogWithReport/useDialogWithReport.js.map +1 -1
- package/components/Buttons/Buttons.js +44 -71
- package/components/Buttons/Buttons.js.map +1 -1
- package/components/Buttons/Buttons.styles.js +9 -15
- package/components/Buttons/Buttons.styles.js.map +1 -1
- package/components/Buttons/index.js +1 -3
- package/components/Buttons/useButtons.js +15 -20
- package/components/Buttons/useButtons.js.map +1 -1
- package/components/DeveloperMode/DeveloperMode.js +5 -14
- package/components/DeveloperMode/DeveloperMode.js.map +1 -1
- package/components/DeveloperMode/index.js +0 -2
- package/components/Dialogs/Dialog.d.ts +2 -2
- package/components/Dialogs/Dialog.js +46 -59
- package/components/Dialogs/Dialog.js.map +1 -1
- package/components/Dialogs/DialogParamsContext.js +6 -7
- package/components/Dialogs/DialogParamsContext.js.map +1 -1
- package/components/Dialogs/DialogsContext.d.ts +2 -2
- package/components/Dialogs/DialogsContext.js +129 -149
- package/components/Dialogs/DialogsContext.js.map +1 -1
- package/components/Dialogs/useDialogs.js +5 -6
- package/components/Dialogs/useDialogs.js.map +1 -1
- package/components/EmptyView.js +26 -31
- package/components/EmptyView.js.map +1 -1
- package/components/Filters/Filters.js +15 -16
- package/components/Filters/Filters.js.map +1 -1
- package/components/Filters/FiltersToggle.js +18 -23
- package/components/Filters/FiltersToggle.js.map +1 -1
- package/components/Filters/index.js +0 -2
- package/components/FloatingActionButton.js +13 -15
- package/components/FloatingActionButton.js.map +1 -1
- package/components/IconPicker/IconPicker.js +24 -26
- package/components/IconPicker/IconPicker.js.map +1 -1
- package/components/IconPicker/IconPickerComponent.js +56 -72
- package/components/IconPicker/IconPickerComponent.js.map +1 -1
- package/components/IconPicker/IconPickerPresenter.js +64 -70
- package/components/IconPicker/IconPickerPresenter.js.map +1 -1
- package/components/IconPicker/IconPickerPresenter.test.js +79 -105
- package/components/IconPicker/IconPickerPresenter.test.js.map +1 -1
- package/components/IconPicker/IconPickerPresenterProvider.js +10 -16
- package/components/IconPicker/IconPickerPresenterProvider.js.map +1 -1
- package/components/IconPicker/IconPickerTab.js +97 -140
- package/components/IconPicker/IconPickerTab.js.map +1 -1
- package/components/IconPicker/IconRenderer.js +15 -23
- package/components/IconPicker/IconRenderer.js.map +1 -1
- package/components/IconPicker/IconRepository.js +41 -40
- package/components/IconPicker/IconRepository.js.map +1 -1
- package/components/IconPicker/IconRepository.test.js +56 -63
- package/components/IconPicker/IconRepository.test.js.map +1 -1
- package/components/IconPicker/IconRepositoryFactory.js +15 -11
- package/components/IconPicker/IconRepositoryFactory.js.map +1 -1
- package/components/IconPicker/Loading.js +47 -46
- package/components/IconPicker/Loading.js.map +1 -1
- package/components/IconPicker/components/IconPickerCell.js +18 -20
- package/components/IconPicker/components/IconPickerCell.js.map +1 -1
- package/components/IconPicker/components/IconPickerContent.js +27 -35
- package/components/IconPicker/components/IconPickerContent.js.map +1 -1
- package/components/IconPicker/components/IconPickerRow.js +5 -10
- package/components/IconPicker/components/IconPickerRow.js.map +1 -1
- package/components/IconPicker/components/IconPickerTrigger.js +42 -44
- package/components/IconPicker/components/IconPickerTrigger.js.map +1 -1
- package/components/IconPicker/components/index.js +0 -2
- package/components/IconPicker/config/Emojis.js +19 -21
- package/components/IconPicker/config/Emojis.js.map +1 -1
- package/components/IconPicker/config/FontAwesomeIcons.js +54 -58
- package/components/IconPicker/config/FontAwesomeIcons.js.map +1 -1
- package/components/IconPicker/config/IconPackProvider.js +17 -19
- package/components/IconPicker/config/IconPackProvider.js.map +1 -1
- package/components/IconPicker/config/IconType.js +48 -80
- package/components/IconPicker/config/IconType.js.map +1 -1
- package/components/IconPicker/config/index.js +28 -31
- package/components/IconPicker/config/index.js.map +1 -1
- package/components/IconPicker/defaultIcon.js +6 -5
- package/components/IconPicker/defaultIcon.js.map +1 -1
- package/components/IconPicker/index.js +0 -2
- package/components/IconPicker/plugins/customPlugin.js +87 -110
- package/components/IconPicker/plugins/customPlugin.js.map +1 -1
- package/components/IconPicker/plugins/emojisPlugin.js +90 -115
- package/components/IconPicker/plugins/emojisPlugin.js.map +1 -1
- package/components/IconPicker/plugins/graphql.js +3 -8
- package/components/IconPicker/plugins/graphql.js.map +1 -1
- package/components/IconPicker/plugins/iconsPlugin.js +73 -104
- package/components/IconPicker/plugins/iconsPlugin.js.map +1 -1
- package/components/IconPicker/types.js +4 -7
- package/components/IconPicker/types.js.map +1 -1
- package/components/LexicalEditor/LexicalEditor.js +40 -38
- package/components/LexicalEditor/LexicalEditor.js.map +1 -1
- package/components/LexicalEditor/LexicalLinkForm.js +80 -86
- package/components/LexicalEditor/LexicalLinkForm.js.map +1 -1
- package/components/LexicalEditor/index.js +0 -2
- package/components/LexicalEditor/lexicalValueFromHtml.js +21 -28
- package/components/LexicalEditor/lexicalValueFromHtml.js.map +1 -1
- package/components/LexicalEditor/lexicalValueWithHtml.js +24 -30
- package/components/LexicalEditor/lexicalValueWithHtml.js.map +1 -1
- package/components/MultiImageUpload.js +4 -13
- package/components/MultiImageUpload.js.map +1 -1
- package/components/NotAuthorizedError/NotAuthorizedError.js +16 -17
- package/components/NotAuthorizedError/NotAuthorizedError.js.map +1 -1
- package/components/NotAuthorizedError/SecureRouteError.js +297 -0
- package/components/NotAuthorizedError/SecureRouteError.js.map +1 -0
- package/components/NotAuthorizedError/index.js +0 -2
- package/components/OptionsMenu/OptionsMenu.js +20 -19
- package/components/OptionsMenu/OptionsMenu.js.map +1 -1
- package/components/OptionsMenu/OptionsMenuItem.js +15 -14
- package/components/OptionsMenu/OptionsMenuItem.js.map +1 -1
- package/components/OptionsMenu/OptionsMenuLink.js +13 -14
- package/components/OptionsMenu/OptionsMenuLink.js.map +1 -1
- package/components/OptionsMenu/index.js +0 -2
- package/components/OptionsMenu/useOptionsMenuItem.js +13 -18
- package/components/OptionsMenu/useOptionsMenuItem.js.map +1 -1
- package/components/OverlayLayout/OverlayLayout.js +35 -38
- package/components/OverlayLayout/OverlayLayout.js.map +1 -1
- package/components/OverlayLayout/components/OverlayBackdrop.js +6 -11
- package/components/OverlayLayout/components/OverlayBackdrop.js.map +1 -1
- package/components/OverlayLayout/components/OverlayContent.js +18 -17
- package/components/OverlayLayout/components/OverlayContent.js.map +1 -1
- package/components/OverlayLayout/components/OverlayHeader.js +30 -37
- package/components/OverlayLayout/components/OverlayHeader.js.map +1 -1
- package/components/OverlayLayout/components/OverlayRoot.js +13 -17
- package/components/OverlayLayout/components/OverlayRoot.js.map +1 -1
- package/components/OverlayLayout/components/index.js +0 -2
- package/components/OverlayLayout/index.js +0 -2
- package/components/Permissions/CannotUseAaclAlert.js +10 -11
- package/components/Permissions/CannotUseAaclAlert.js.map +1 -1
- package/components/Permissions/Permissions.js +32 -41
- package/components/Permissions/Permissions.js.map +1 -1
- package/components/Permissions/PermissionsGroup.js +9 -15
- package/components/Permissions/PermissionsGroup.js.map +1 -1
- package/components/Permissions/StyledComponents.js +9 -16
- package/components/Permissions/StyledComponents.js.map +1 -1
- package/components/Permissions/index.js +1 -3
- package/components/RegisterFeature.js +14 -21
- package/components/RegisterFeature.js.map +1 -1
- package/components/ResizablePanels/index.js +0 -2
- package/components/RoleAutocomplete/graphql.js +3 -2
- package/components/RoleAutocomplete/graphql.js.map +1 -1
- package/components/RoleAutocomplete/index.d.ts +5 -3
- package/components/RoleAutocomplete/index.js +21 -13
- package/components/RoleAutocomplete/index.js.map +1 -1
- package/components/RolesMultiAutocomplete/graphql.js +3 -2
- package/components/RolesMultiAutocomplete/graphql.js.map +1 -1
- package/components/RolesMultiAutocomplete/index.d.ts +5 -3
- package/components/RolesMultiAutocomplete/index.js +21 -14
- package/components/RolesMultiAutocomplete/index.js.map +1 -1
- package/components/SearchUI.js +18 -25
- package/components/SearchUI.js.map +1 -1
- package/components/SimpleForm/SimpleForm.d.ts +1 -1
- package/components/SimpleForm/SimpleForm.js +54 -73
- package/components/SimpleForm/SimpleForm.js.map +1 -1
- package/components/SimpleForm/index.js +1 -3
- package/components/SimpleUI/InputField.js +71 -64
- package/components/SimpleUI/InputField.js.map +1 -1
- package/components/SingleImageUpload.d.ts +2 -2
- package/components/SingleImageUpload.js +37 -58
- package/components/SingleImageUpload.js.map +1 -1
- package/components/SplitView/SplitView.js +47 -57
- package/components/SplitView/SplitView.js.map +1 -1
- package/components/SplitView/index.js +1 -3
- package/components/TeamAutocomplete/graphql.js +3 -2
- package/components/TeamAutocomplete/graphql.js.map +1 -1
- package/components/TeamAutocomplete/index.d.ts +5 -3
- package/components/TeamAutocomplete/index.js +21 -13
- package/components/TeamAutocomplete/index.js.map +1 -1
- package/components/TeamsMultiAutocomplete/graphql.js +3 -2
- package/components/TeamsMultiAutocomplete/graphql.js.map +1 -1
- package/components/TeamsMultiAutocomplete/index.d.ts +5 -3
- package/components/TeamsMultiAutocomplete/index.js +21 -14
- package/components/TeamsMultiAutocomplete/index.js.map +1 -1
- package/components/Wcp.js +27 -38
- package/components/Wcp.js.map +1 -1
- package/components/index.js +10 -13
- package/config/AdminConfig/Dashboard.js +3 -2
- package/config/AdminConfig/Dashboard.js.map +1 -1
- package/config/AdminConfig/Dialog.js +15 -17
- package/config/AdminConfig/Dialog.js.map +1 -1
- package/config/AdminConfig/FieldRenderer.js +15 -17
- package/config/AdminConfig/FieldRenderer.js.map +1 -1
- package/config/AdminConfig/Form.js +4 -3
- package/config/AdminConfig/Form.js.map +1 -1
- package/config/AdminConfig/LayoutRenderer.js +15 -17
- package/config/AdminConfig/LayoutRenderer.js.map +1 -1
- package/config/AdminConfig/LexicalTheme/Color.js +34 -41
- package/config/AdminConfig/LexicalTheme/Color.js.map +1 -1
- package/config/AdminConfig/LexicalTheme/Typography.js +61 -74
- package/config/AdminConfig/LexicalTheme/Typography.js.map +1 -1
- package/config/AdminConfig/LexicalTheme.js +4 -3
- package/config/AdminConfig/LexicalTheme.js.map +1 -1
- package/config/AdminConfig/Logo.d.ts +1 -1
- package/config/AdminConfig/Logo.js +15 -17
- package/config/AdminConfig/Logo.js.map +1 -1
- package/config/AdminConfig/Menu/MenuGroup.d.ts +3 -3
- package/config/AdminConfig/Menu/MenuGroup.js +7 -9
- package/config/AdminConfig/Menu/MenuGroup.js.map +1 -1
- package/config/AdminConfig/Menu/MenuItem.d.ts +2 -2
- package/config/AdminConfig/Menu/MenuItem.js +5 -7
- package/config/AdminConfig/Menu/MenuItem.js.map +1 -1
- package/config/AdminConfig/Menu/MenuLink.d.ts +2 -2
- package/config/AdminConfig/Menu/MenuLink.js +12 -15
- package/config/AdminConfig/Menu/MenuLink.js.map +1 -1
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuItem.d.ts +2 -2
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuItem.js +6 -8
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuItem.js.map +1 -1
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuLink.d.ts +1 -1
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuLink.js +4 -6
- package/config/AdminConfig/Menu/SupportMenu/SupportMenuLink.js.map +1 -1
- package/config/AdminConfig/Menu/SupportMenu.d.ts +3 -3
- package/config/AdminConfig/Menu/SupportMenu.js +30 -41
- package/config/AdminConfig/Menu/SupportMenu.js.map +1 -1
- package/config/AdminConfig/Menu/UserMenu/UserMenuItem.js +4 -4
- package/config/AdminConfig/Menu/UserMenu/UserMenuItem.js.map +1 -1
- package/config/AdminConfig/Menu/UserMenu/UserMenuLink.js +4 -4
- package/config/AdminConfig/Menu/UserMenu/UserMenuLink.js.map +1 -1
- package/config/AdminConfig/Menu/UserMenu/UserMenuSeparator.js +0 -2
- package/config/AdminConfig/Menu/UserMenu/types.js +0 -3
- package/config/AdminConfig/Menu/UserMenu.d.ts +31 -31
- package/config/AdminConfig/Menu/UserMenu.js +39 -52
- package/config/AdminConfig/Menu/UserMenu.js.map +1 -1
- package/config/AdminConfig/Menu/types.js +0 -3
- package/config/AdminConfig/Menu.d.ts +42 -42
- package/config/AdminConfig/Menu.js +57 -73
- package/config/AdminConfig/Menu.js.map +1 -1
- package/config/AdminConfig/Route.js +4 -5
- package/config/AdminConfig/Route.js.map +1 -1
- package/config/AdminConfig/Security.js +3 -2
- package/config/AdminConfig/Security.js.map +1 -1
- package/config/AdminConfig/SecurityPermissions.js +20 -27
- package/config/AdminConfig/SecurityPermissions.js.map +1 -1
- package/config/AdminConfig/Tenant/TenantLogo.d.ts +1 -1
- package/config/AdminConfig/Tenant/TenantLogo.js +18 -20
- package/config/AdminConfig/Tenant/TenantLogo.js.map +1 -1
- package/config/AdminConfig/Tenant/TenantName.d.ts +1 -1
- package/config/AdminConfig/Tenant/TenantName.js +14 -15
- package/config/AdminConfig/Tenant/TenantName.js.map +1 -1
- package/config/AdminConfig/Tenant.js +6 -9
- package/config/AdminConfig/Tenant.js.map +1 -1
- package/config/AdminConfig/Theme/assignColor.js +51 -18
- package/config/AdminConfig/Theme/assignColor.js.map +1 -1
- package/config/AdminConfig/Theme/consts.js +20 -2
- package/config/AdminConfig/Theme/consts.js.map +1 -1
- package/config/AdminConfig/Theme/types.js +0 -3
- package/config/AdminConfig/Theme.js +8 -15
- package/config/AdminConfig/Theme.js.map +1 -1
- package/config/AdminConfig/Title.d.ts +1 -1
- package/config/AdminConfig/Title.js +11 -12
- package/config/AdminConfig/Title.js.map +1 -1
- package/config/AdminConfig/Widget.js +24 -31
- package/config/AdminConfig/Widget.js.map +1 -1
- package/config/AdminConfig.js +47 -59
- package/config/AdminConfig.js.map +1 -1
- package/config/createAdminConfig.js +55 -86
- package/config/createAdminConfig.js.map +1 -1
- package/domain/Identity.js +78 -88
- package/domain/Identity.js.map +1 -1
- package/errors/ErrorOverlayNetworkErrorHandler.js +37 -52
- package/errors/ErrorOverlayNetworkErrorHandler.js.map +1 -1
- package/errors/TenantIsDisabled.js +19 -20
- package/errors/TenantIsDisabled.js.map +1 -1
- package/exports/admin/build-params.js +0 -5
- package/exports/admin/configs.js +0 -2
- package/exports/admin/form.js +3 -18
- package/exports/admin/security.js +1 -7
- package/exports/admin/tenancy.js +0 -2
- package/exports/admin/ui.js +1 -4
- package/exports/admin.js +1 -4
- package/features/apolloClient/abstraction.js +2 -1
- package/features/apolloClient/abstraction.js.map +1 -1
- package/features/apolloClient/feature.js +22 -30
- package/features/apolloClient/feature.js.map +1 -1
- package/features/buildParams/BuildParams.js +20 -14
- package/features/buildParams/BuildParams.js.map +1 -1
- package/features/buildParams/abstractions.js +3 -2
- package/features/buildParams/abstractions.js.map +1 -1
- package/features/buildParams/feature.js +11 -10
- package/features/buildParams/feature.js.map +1 -1
- package/features/buildParams/index.js +0 -2
- package/features/formModel/ConditionRuleEvaluator.js +39 -46
- package/features/formModel/ConditionRuleEvaluator.js.map +1 -1
- package/features/formModel/Field.d.ts +1 -0
- package/features/formModel/Field.js +334 -411
- package/features/formModel/Field.js.map +1 -1
- package/features/formModel/FieldBuilder.d.ts +2 -1
- package/features/formModel/FieldBuilder.js +148 -171
- package/features/formModel/FieldBuilder.js.map +1 -1
- package/features/formModel/FieldBuilder.test.js +217 -201
- package/features/formModel/FieldBuilder.test.js.map +1 -1
- package/features/formModel/FieldBuilderRegistry.js +23 -25
- package/features/formModel/FieldBuilderRegistry.js.map +1 -1
- package/features/formModel/FocusManager.js +69 -95
- package/features/formModel/FocusManager.js.map +1 -1
- package/features/formModel/FormErrors.d.ts +9 -0
- package/features/formModel/FormErrors.js +35 -0
- package/features/formModel/FormErrors.js.map +1 -0
- package/features/formModel/FormModel.d.ts +2 -0
- package/features/formModel/FormModel.js +391 -396
- package/features/formModel/FormModel.js.map +1 -1
- package/features/formModel/FormModel.test.js +3791 -3354
- package/features/formModel/FormModel.test.js.map +1 -1
- package/features/formModel/FormModelFactory.js +27 -17
- package/features/formModel/FormModelFactory.js.map +1 -1
- package/features/formModel/FormView.d.ts +2 -1
- package/features/formModel/FormView.js +168 -156
- package/features/formModel/FormView.js.map +1 -1
- package/features/formModel/LayoutBuilderFactory.js +300 -370
- package/features/formModel/LayoutBuilderFactory.js.map +1 -1
- package/features/formModel/LayoutMutator.js +118 -125
- package/features/formModel/LayoutMutator.js.map +1 -1
- package/features/formModel/LayoutResolver.js +174 -214
- package/features/formModel/LayoutResolver.js.map +1 -1
- package/features/formModel/ObjectField.js +524 -724
- package/features/formModel/ObjectField.js.map +1 -1
- package/features/formModel/PresenterErrors.d.ts +9 -0
- package/features/formModel/PresenterErrors.js +32 -0
- package/features/formModel/PresenterErrors.js.map +1 -0
- package/features/formModel/Rules.test.js +311 -276
- package/features/formModel/Rules.test.js.map +1 -1
- package/features/formModel/abstractions.d.ts +10 -0
- package/features/formModel/abstractions.js +5 -114
- package/features/formModel/abstractions.js.map +1 -1
- package/features/formModel/createFieldRenderer.js +33 -10
- package/features/formModel/createFieldRenderer.js.map +1 -1
- package/features/formModel/demo/FieldRenderersDemoPresenter.js +289 -220
- package/features/formModel/demo/FieldRenderersDemoPresenter.js.map +1 -1
- package/features/formModel/demo/FormModelDemo.js +191 -215
- package/features/formModel/demo/FormModelDemo.js.map +1 -1
- package/features/formModel/demo/FormModelDemoPresenter.js +132 -113
- package/features/formModel/demo/FormModelDemoPresenter.js.map +1 -1
- package/features/formModel/demo/FormModelPhase11Presenter.js +101 -98
- package/features/formModel/demo/FormModelPhase11Presenter.js.map +1 -1
- package/features/formModel/demo/FormModelPhase8c1Presenter.js +64 -57
- package/features/formModel/demo/FormModelPhase8c1Presenter.js.map +1 -1
- package/features/formModel/feature.js +23 -22
- package/features/formModel/feature.js.map +1 -1
- package/features/formModel/fieldTypes/BooleanFieldType.js +18 -15
- package/features/formModel/fieldTypes/BooleanFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/DateTimeFieldType.js +218 -341
- package/features/formModel/fieldTypes/DateTimeFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/FileFieldType.d.ts +12 -1
- package/features/formModel/fieldTypes/FileFieldType.js +48 -12
- package/features/formModel/fieldTypes/FileFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/FileUrlFieldType.js +15 -12
- package/features/formModel/fieldTypes/FileUrlFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/NumberFieldType.js +19 -18
- package/features/formModel/fieldTypes/NumberFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/ObjectFieldType.js +80 -94
- package/features/formModel/fieldTypes/ObjectFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/TextFieldType.js +15 -12
- package/features/formModel/fieldTypes/TextFieldType.js.map +1 -1
- package/features/formModel/fieldTypes/index.js +7 -9
- package/features/formModel/index.d.ts +2 -0
- package/features/formModel/index.js +11 -29
- package/features/formModel/renderers.js +0 -4
- package/features/formModel/useFieldRenderers.js +10 -14
- package/features/formModel/useFieldRenderers.js.map +1 -1
- package/features/formModel/useLayoutRenderers.js +10 -14
- package/features/formModel/useLayoutRenderers.js.map +1 -1
- package/features/listCache/ListCache.d.ts +28 -0
- package/features/listCache/ListCache.js +48 -0
- package/features/listCache/ListCache.js.map +1 -0
- package/features/listCache/index.d.ts +2 -0
- package/features/listCache/index.js +1 -0
- package/features/security/AuthenticationContext/AuthenticationContext.js +27 -26
- package/features/security/AuthenticationContext/AuthenticationContext.js.map +1 -1
- package/features/security/AuthenticationContext/GraphQLClientDecorator.js +23 -22
- package/features/security/AuthenticationContext/GraphQLClientDecorator.js.map +1 -1
- package/features/security/AuthenticationContext/InternalIdTokenProvider.js +15 -12
- package/features/security/AuthenticationContext/InternalIdTokenProvider.js.map +1 -1
- package/features/security/AuthenticationContext/abstractions.js +3 -2
- package/features/security/AuthenticationContext/abstractions.js.map +1 -1
- package/features/security/AuthenticationContext/feature.js +15 -14
- package/features/security/AuthenticationContext/feature.js.map +1 -1
- package/features/security/AuthenticationContext/index.js +0 -2
- package/features/security/AuthenticationContext/types.js +0 -3
- package/features/security/IdentityContext/IdentityContext.js +18 -17
- package/features/security/IdentityContext/IdentityContext.js.map +1 -1
- package/features/security/IdentityContext/abstractions.js +2 -1
- package/features/security/IdentityContext/abstractions.js.map +1 -1
- package/features/security/IdentityContext/feature.js +13 -12
- package/features/security/IdentityContext/feature.js.map +1 -1
- package/features/security/IdentityContext/index.js +0 -2
- package/features/security/LogIn/IdentityMapper.js +8 -7
- package/features/security/LogIn/IdentityMapper.js.map +1 -1
- package/features/security/LogIn/LogInGateway.js +17 -19
- package/features/security/LogIn/LogInGateway.js.map +1 -1
- package/features/security/LogIn/LogInRepository.js +16 -14
- package/features/security/LogIn/LogInRepository.js.map +1 -1
- package/features/security/LogIn/LogInUseCase.js +23 -31
- package/features/security/LogIn/LogInUseCase.js.map +1 -1
- package/features/security/LogIn/abstractions.js +5 -16
- package/features/security/LogIn/abstractions.js.map +1 -1
- package/features/security/LogIn/createLoginMutation.js +2 -3
- package/features/security/LogIn/createLoginMutation.js.map +1 -1
- package/features/security/LogIn/feature.js +16 -15
- package/features/security/LogIn/feature.js.map +1 -1
- package/features/security/LogIn/index.js +0 -2
- package/features/security/LogOut/LogOutUseCase.js +18 -16
- package/features/security/LogOut/LogOutUseCase.js.map +1 -1
- package/features/security/LogOut/abstractions.js +2 -1
- package/features/security/LogOut/abstractions.js.map +1 -1
- package/features/security/LogOut/feature.js +12 -11
- package/features/security/LogOut/feature.js.map +1 -1
- package/features/security/LogOut/index.js +0 -2
- package/features/security/SecurityFeature.js +9 -8
- package/features/security/SecurityFeature.js.map +1 -1
- package/features/telemetry/TelemetryService.js +11 -12
- package/features/telemetry/TelemetryService.js.map +1 -1
- package/features/telemetry/abstractions.js +2 -1
- package/features/telemetry/abstractions.js.map +1 -1
- package/features/telemetry/feature.js +13 -12
- package/features/telemetry/feature.js.map +1 -1
- package/features/telemetry/index.js +0 -2
- package/features/tenancy/GraphQLClientDecorator.js +23 -20
- package/features/tenancy/GraphQLClientDecorator.js.map +1 -1
- package/features/tenancy/TenantContext.js +46 -50
- package/features/tenancy/TenantContext.js.map +1 -1
- package/features/tenancy/abstractions.js +2 -1
- package/features/tenancy/abstractions.js.map +1 -1
- package/features/tenancy/feature.js +25 -35
- package/features/tenancy/feature.js.map +1 -1
- package/features/tenancy/types.js +0 -3
- package/features/tools/LexicalContext/LexicalContext.js +20 -17
- package/features/tools/LexicalContext/LexicalContext.js.map +1 -1
- package/features/tools/LexicalContext/abstractions.js +2 -1
- package/features/tools/LexicalContext/abstractions.js.map +1 -1
- package/features/tools/LexicalContext/index.js +0 -2
- package/features/tools/ToolPipelineRunner.js +26 -24
- package/features/tools/ToolPipelineRunner.js.map +1 -1
- package/features/tools/ToolRegistry.js +32 -23
- package/features/tools/ToolRegistry.js.map +1 -1
- package/features/tools/abstractions.js +4 -3
- package/features/tools/abstractions.js.map +1 -1
- package/features/tools/feature.js +17 -16
- package/features/tools/feature.js.map +1 -1
- package/features/tools/index.js +1 -3
- package/features/wcp/ReactLicense.js +53 -52
- package/features/wcp/ReactLicense.js.map +1 -1
- package/features/wcp/WcpGateway.js +21 -20
- package/features/wcp/WcpGateway.js.map +1 -1
- package/features/wcp/WcpService.js +57 -67
- package/features/wcp/WcpService.js.map +1 -1
- package/features/wcp/abstractions.js +3 -2
- package/features/wcp/abstractions.js.map +1 -1
- package/features/wcp/feature.js +14 -13
- package/features/wcp/feature.js.map +1 -1
- package/features/wcp/types.js +0 -3
- package/features/webinySdk/WebinySdk.js +19 -18
- package/features/webinySdk/WebinySdk.js.map +1 -1
- package/features/webinySdk/abstractions.js +2 -5
- package/features/webinySdk/abstractions.js.map +1 -1
- package/features/webinySdk/feature.js +13 -12
- package/features/webinySdk/feature.js.map +1 -1
- package/features/webinySdk/index.js +0 -2
- package/hooks/index.js +0 -2
- package/hooks/useConfirmationDialog.d.ts +1 -1
- package/hooks/useConfirmationDialog.js +31 -38
- package/hooks/useConfirmationDialog.js.map +1 -1
- package/hooks/useDialog.js +14 -15
- package/hooks/useDialog.js.map +1 -1
- package/hooks/useHotkeys.js +52 -85
- package/hooks/useHotkeys.js.map +1 -1
- package/hooks/useIsMounted.js +12 -11
- package/hooks/useIsMounted.js.map +1 -1
- package/hooks/useKeyHandler.js +45 -53
- package/hooks/useKeyHandler.js.map +1 -1
- package/hooks/useModKey.js +20 -25
- package/hooks/useModKey.js.map +1 -1
- package/hooks/useOpenDialog.js +13 -13
- package/hooks/useOpenDialog.js.map +1 -1
- package/hooks/useShiftKey.d.ts +5 -1
- package/hooks/useShiftKey.js +38 -29
- package/hooks/useShiftKey.js.map +1 -1
- package/hooks/useSnackbar.d.ts +3 -0
- package/hooks/useSnackbar.js +26 -28
- package/hooks/useSnackbar.js.map +1 -1
- package/hooks/useStateIfMounted.js +14 -12
- package/hooks/useStateIfMounted.js.map +1 -1
- package/hooks/useStateWithCallback.js +18 -14
- package/hooks/useStateWithCallback.js.map +1 -1
- package/hooks/useToggler.js +12 -11
- package/hooks/useToggler.js.map +1 -1
- package/index.d.ts +4 -1
- package/index.js +15 -31
- package/package.json +29 -29
- package/permissions/PermissionRenderer.js +179 -193
- package/permissions/PermissionRenderer.js.map +1 -1
- package/permissions/PermissionValueContext.js +13 -20
- package/permissions/PermissionValueContext.js.map +1 -1
- package/permissions/createHasPermission.js +32 -40
- package/permissions/createHasPermission.js.map +1 -1
- package/permissions/createPermissionSchema.js +6 -5
- package/permissions/createPermissionSchema.js.map +1 -1
- package/permissions/createPermissions.js +125 -185
- package/permissions/createPermissions.js.map +1 -1
- package/permissions/createPermissions.test.js +190 -158
- package/permissions/createPermissions.test.js.map +1 -1
- package/permissions/index.js +2 -4
- package/permissions/types.js +0 -3
- package/permissions/usePermissionForm.js +133 -232
- package/permissions/usePermissionForm.js.map +1 -1
- package/permissions/usePermissions.js +6 -5
- package/permissions/usePermissions.js.map +1 -1
- package/plugins/MenuPlugin.js +15 -14
- package/plugins/MenuPlugin.js.map +1 -1
- package/presentation/browserFilePicker/BrowserFilePicker.d.ts +3 -0
- package/presentation/browserFilePicker/BrowserFilePicker.js +88 -0
- package/presentation/browserFilePicker/BrowserFilePicker.js.map +1 -0
- package/presentation/browserFilePicker/BrowserFilePickerPresenter.d.ts +10 -0
- package/presentation/browserFilePicker/BrowserFilePickerPresenter.js +84 -0
- package/presentation/browserFilePicker/BrowserFilePickerPresenter.js.map +1 -0
- package/presentation/browserFilePicker/index.d.ts +3 -0
- package/presentation/browserFilePicker/index.js +2 -0
- package/presentation/browserFilePicker/types.d.ts +53 -0
- package/presentation/browserFilePicker/types.js +0 -0
- package/presentation/browserFilePicker/utils.d.ts +2 -0
- package/presentation/browserFilePicker/utils.js +16 -0
- package/presentation/browserFilePicker/utils.js.map +1 -0
- package/presentation/buildParams/useBuildParams.js +2 -3
- package/presentation/buildParams/useBuildParams.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/SystemInstaller.js +46 -53
- package/presentation/installation/components/SystemInstaller/SystemInstaller.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/SystemInstallerProvider.js +9 -14
- package/presentation/installation/components/SystemInstaller/SystemInstallerProvider.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/index.js +0 -2
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep/createPasswordValidator.js +14 -29
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep/createPasswordValidator.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep/usePasswordValidator.js +11 -10
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep/usePasswordValidator.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep.js +60 -60
- package/presentation/installation/components/SystemInstaller/steps/AdminUserStep.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/BasicInfoStep.js +75 -85
- package/presentation/installation/components/SystemInstaller/steps/BasicInfoStep.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/Center.js +5 -8
- package/presentation/installation/components/SystemInstaller/steps/Center.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/Container.js +18 -24
- package/presentation/installation/components/SystemInstaller/steps/Container.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/FinishSetup.js +48 -53
- package/presentation/installation/components/SystemInstaller/steps/FinishSetup.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/IntroductionStep.js +13 -16
- package/presentation/installation/components/SystemInstaller/steps/IntroductionStep.js.map +1 -1
- package/presentation/installation/components/SystemInstaller/steps/introduction.js +723 -0
- package/presentation/installation/components/SystemInstaller/steps/introduction.js.map +1 -0
- package/presentation/installation/components/SystemInstaller/steps/referralSources.js +14 -1
- package/presentation/installation/components/SystemInstaller/steps/referralSources.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js +27 -28
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerGateway.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerPresenter.js +117 -124
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerPresenter.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerRepository.js +23 -21
- package/presentation/installation/presenters/SystemInstaller/SystemInstallerRepository.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/abstractions.js +4 -3
- package/presentation/installation/presenters/SystemInstaller/abstractions.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/feature.js +15 -14
- package/presentation/installation/presenters/SystemInstaller/feature.js.map +1 -1
- package/presentation/installation/presenters/SystemInstaller/index.js +0 -2
- package/presentation/lexicalContext/useLexicalContext.js +11 -8
- package/presentation/lexicalContext/useLexicalContext.js.map +1 -1
- package/presentation/listPresenter/ListPresenter.d.ts +30 -0
- package/presentation/listPresenter/ListPresenter.js +216 -0
- package/presentation/listPresenter/ListPresenter.js.map +1 -0
- package/presentation/listPresenter/ListPresenter.test.d.ts +1 -0
- package/presentation/listPresenter/ListPresenter.test.js +816 -0
- package/presentation/listPresenter/ListPresenter.test.js.map +1 -0
- package/presentation/listPresenter/SelectionController.d.ts +21 -0
- package/presentation/listPresenter/SelectionController.js +74 -0
- package/presentation/listPresenter/SelectionController.js.map +1 -0
- package/presentation/listPresenter/abstractions.d.ts +107 -0
- package/presentation/listPresenter/abstractions.js +5 -0
- package/presentation/listPresenter/abstractions.js.map +1 -0
- package/presentation/listPresenter/feature.d.ts +3 -0
- package/presentation/listPresenter/feature.js +17 -0
- package/presentation/listPresenter/feature.js.map +1 -0
- package/presentation/listPresenter/index.d.ts +3 -0
- package/presentation/listPresenter/index.js +2 -0
- package/presentation/security/components/HasPermission.js +15 -25
- package/presentation/security/components/HasPermission.js.map +1 -1
- package/presentation/security/components/SecureRoute.js +6 -12
- package/presentation/security/components/SecureRoute.js.map +1 -1
- package/presentation/security/hooks/useAuthentication.js +11 -17
- package/presentation/security/hooks/useAuthentication.js.map +1 -1
- package/presentation/security/hooks/useIdentity.js +19 -18
- package/presentation/security/hooks/useIdentity.js.map +1 -1
- package/presentation/security/hooks/useSecurity.js +14 -24
- package/presentation/security/hooks/useSecurity.js.map +1 -1
- package/presentation/tenancy/TenancyProvider.js +23 -36
- package/presentation/tenancy/TenancyProvider.js.map +1 -1
- package/presentation/tenancy/createTenancyProvider.js +6 -11
- package/presentation/tenancy/createTenancyProvider.js.map +1 -1
- package/presentation/tenancy/useTenantContext.js +17 -18
- package/presentation/tenancy/useTenantContext.js.map +1 -1
- package/presentation/textToLexicalTool/TextToLexicalTool.js +20 -18
- package/presentation/textToLexicalTool/TextToLexicalTool.js.map +1 -1
- package/presentation/textToLexicalTool/feature.js +6 -5
- package/presentation/textToLexicalTool/feature.js.map +1 -1
- package/presentation/textToLexicalTool/textToLexicalState.js +28 -28
- package/presentation/textToLexicalTool/textToLexicalState.js.map +1 -1
- package/presentation/wcp/WcpProvider.js +16 -26
- package/presentation/wcp/WcpProvider.js.map +1 -1
- package/presentation/wcp/useWcp.js +11 -12
- package/presentation/wcp/useWcp.js.map +1 -1
- package/routes.d.ts +0 -1
- package/routes.js +14 -17
- package/routes.js.map +1 -1
- package/static/svg/SecureRouteError.e8b15981.svg +1 -0
- package/static/svg/add-18px.b3062af6.svg +3 -0
- package/static/svg/arrow_drop_down-24px.da74d713.svg +4 -0
- package/static/svg/attach_file_black_24dp.7fb13a7e.svg +1 -0
- package/static/svg/baseline-menu-24px.071b179d.svg +4 -0
- package/static/svg/baseline-notification_important-24px.29277e73.svg +4 -0
- package/static/svg/baseline-security-24px.12e519cc.svg +4 -0
- package/static/svg/file_download.afe3fbec.svg +1 -0
- package/static/svg/file_upload.6865d820.svg +1 -0
- package/static/svg/filter-24px.886d9ff0.svg +8 -0
- package/static/svg/github-brands.6311f0fa.svg +1 -0
- package/static/svg/highlight-24px.959a97f7.svg +1 -0
- package/static/svg/icon-community.cd087355.svg +16 -0
- package/static/svg/icon-documentation.a189d24c.svg +16 -0
- package/static/svg/info.fe810b72.svg +1 -0
- package/static/svg/insert_drive_file-24px.39d490eb.svg +1 -0
- package/static/svg/insert_photo-24px.81a5f945.svg +1 -0
- package/static/svg/introduction.108720aa.svg +154 -0
- package/static/svg/label-24px.9deafa4f.svg +1 -0
- package/static/svg/round-account_circle-24px.f0b48cb7.svg +1 -0
- package/static/svg/round-add-24px.4a5219b4.svg +16 -0
- package/static/svg/round-arrow_drop_down-24px.5fdf92d1.svg +1 -0
- package/static/svg/round-chevron_right-24px.34936511.svg +12 -0
- package/static/svg/round-feedback-24px.4dae7231.svg +54 -0
- package/static/svg/round-help-24px.a61b1d66.svg +1 -0
- package/static/svg/round-invert_colors-24px.a229a1dd.svg +52 -0
- package/static/svg/round-keyboard_arrow_down-24px.6febe804.svg +16 -0
- package/static/svg/round-keyboard_arrow_up-24px.b1f7db34.svg +16 -0
- package/static/svg/round-lock_open-24px.d527f6a5.svg +60 -0
- package/static/svg/round-more_vert-24px.68d41b07.svg +12 -0
- package/static/svg/round-open_in_new-24px.be5b4ddd.svg +44 -0
- package/static/svg/round-settings-24px.c0b3056f.svg +4 -0
- package/static/svg/search-24px.3c0f88dd.svg +20 -0
- package/static/svg/slack-logo.7ee35e7f.svg +1 -0
- package/static/svg/today-24px.df206362.svg +1 -0
- package/static/svg/touch_app.debf3744.svg +1 -0
- package/static/svg/wby-horizontal.03327bf6.svg +23 -0
- package/static/svg/wby-square.ff8f47c3.svg +3 -0
- package/static/svg/webiny-logo.ef56725c.svg +20 -0
- package/static/svg/webiny-orange-logo.4eccf0f2.svg +20 -0
- package/types.js +0 -3
- package/components/BulkActions/index.js.map +0 -1
- package/components/BulkActions/useDialogWithReport/index.js.map +0 -1
- package/components/Buttons/index.js.map +0 -1
- package/components/DeveloperMode/index.js.map +0 -1
- package/components/Filters/index.js.map +0 -1
- package/components/IconPicker/components/index.js.map +0 -1
- package/components/IconPicker/index.js.map +0 -1
- package/components/LexicalEditor/index.js.map +0 -1
- package/components/NotAuthorizedError/index.js.map +0 -1
- package/components/OptionsMenu/index.js.map +0 -1
- package/components/OverlayLayout/components/index.js.map +0 -1
- package/components/OverlayLayout/index.js.map +0 -1
- package/components/Permissions/index.js.map +0 -1
- package/components/ResizablePanels/index.js.map +0 -1
- package/components/SimpleForm/index.js.map +0 -1
- package/components/SplitView/index.js.map +0 -1
- package/components/index.js.map +0 -1
- package/config/AdminConfig/Menu/UserMenu/UserMenuSeparator.js.map +0 -1
- package/config/AdminConfig/Menu/UserMenu/types.js.map +0 -1
- package/config/AdminConfig/Menu/types.js.map +0 -1
- package/config/AdminConfig/Theme/types.js.map +0 -1
- package/exports/admin/build-params.js.map +0 -1
- package/exports/admin/configs.js.map +0 -1
- package/exports/admin/form.js.map +0 -1
- package/exports/admin/security.js.map +0 -1
- package/exports/admin/tenancy.js.map +0 -1
- package/exports/admin/ui.js.map +0 -1
- package/exports/admin.js.map +0 -1
- package/features/buildParams/index.js.map +0 -1
- package/features/formModel/fieldTypes/index.js.map +0 -1
- package/features/formModel/index.js.map +0 -1
- package/features/formModel/renderers.js.map +0 -1
- package/features/security/AuthenticationContext/index.js.map +0 -1
- package/features/security/AuthenticationContext/types.js.map +0 -1
- package/features/security/IdentityContext/index.js.map +0 -1
- package/features/security/LogIn/index.js.map +0 -1
- package/features/security/LogOut/index.js.map +0 -1
- package/features/telemetry/index.js.map +0 -1
- package/features/tenancy/types.js.map +0 -1
- package/features/tools/LexicalContext/index.js.map +0 -1
- package/features/tools/index.js.map +0 -1
- package/features/wcp/types.js.map +0 -1
- package/features/webinySdk/index.js.map +0 -1
- package/hooks/index.js.map +0 -1
- package/index.js.map +0 -1
- package/permissions/index.js.map +0 -1
- package/permissions/types.js.map +0 -1
- package/presentation/installation/components/SystemInstaller/index.js.map +0 -1
- package/presentation/installation/presenters/SystemInstaller/index.js.map +0 -1
- package/types.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["describe","it","expect","Container","FormModelFeature","ConditionRuleEvaluator","FormModelFactory","createForm","config","container","register","resolve","create","fields","layout","ruleEvaluators","extraEvaluators","form","title","text","label","subtitle","rules","type","target","operator","value","action","field","visible","toBe","vm","setValue","country","city","disabled","plan","enterpriseOnly","toggle","required","valid","validate","valid2","errors","some","e","path","trigger","general","seo","row","tabs","tab","hiddenField","tabsVm","find","n","toBeUndefined","inner","toBeDefined","AccessControlEvaluator","constructor","userTeams","canEvaluate","rule","evaluate","scope","id","split","includes","adminField","weird","mkForm","getValue","undefined"],"sources":["Rules.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"./feature.js\";\nimport { ConditionRuleEvaluator } from \"./ConditionRuleEvaluator.js\";\nimport {\n FormModelFactory,\n type IRule,\n type IRuleEvaluator,\n type ITabsNodeVM,\n type IFormModel,\n type IFormModelConfig\n} from \"./abstractions.js\";\n\nfunction createForm(config: {\n extraEvaluators?: IRuleEvaluator[];\n fields: IFormModelConfig[\"fields\"];\n layout?: IFormModelConfig[\"layout\"];\n}) {\n const container = new Container();\n FormModelFeature.register(container);\n return container.resolve(FormModelFactory).create({\n fields: config.fields,\n layout: config.layout,\n ruleEvaluators: config.extraEvaluators\n });\n}\n\ndescribe(\"Rules system\", () => {\n describe(\"condition rule on a field\", () => {\n it(\"hides a field when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n title: fields.text().label(\"Title\"),\n subtitle: fields\n .text()\n .label(\"Subtitle\")\n .rules([\n {\n type: \"condition\",\n target: \"title\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n expect(form.field(\"subtitle\").visible).toBe(false);\n expect(form.field(\"subtitle\").vm.visible).toBe(false);\n\n form.field(\"title\").setValue(\"Hello\");\n expect(form.field(\"subtitle\").visible).toBe(true);\n expect(form.field(\"subtitle\").vm.visible).toBe(true);\n });\n\n it(\"disables a field when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n country: fields.text().label(\"Country\"),\n city: fields\n .text()\n .label(\"City\")\n .rules([\n {\n type: \"condition\",\n target: \"country\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n })\n });\n\n expect(form.field(\"city\").vm.disabled).toBe(true);\n\n form.field(\"country\").setValue(\"US\");\n expect(form.field(\"city\").vm.disabled).toBe(false);\n });\n\n it(\"supports eq operator\", () => {\n const form = createForm({\n fields: fields => ({\n plan: fields.text().label(\"Plan\"),\n enterpriseOnly: fields\n .text()\n .label(\"Enterprise\")\n .rules([\n {\n type: \"condition\",\n target: \"plan\",\n operator: \"eq\",\n value: \"enterprise\",\n action: \"hide\"\n }\n ])\n })\n });\n\n form.field(\"plan\").setValue(\"starter\");\n expect(form.field(\"enterpriseOnly\").visible).toBe(true);\n\n form.field(\"plan\").setValue(\"enterprise\");\n expect(form.field(\"enterpriseOnly\").visible).toBe(false);\n });\n\n it(\"excludes hidden fields from validation\", async () => {\n const form = createForm({\n fields: fields => ({\n toggle: fields.text().label(\"Toggle\"),\n required: fields\n .text()\n .label(\"Required\")\n .required(\"Must fill\")\n .rules([\n {\n type: \"condition\",\n target: \"toggle\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n // toggle is empty → \"required\" is hidden → should not count as invalid\n const valid = await form.validate();\n expect(valid).toBe(true);\n\n // Fill toggle → \"required\" becomes visible → fails without a value\n form.field(\"toggle\").setValue(\"anything\");\n const valid2 = await form.validate();\n expect(valid2).toBe(false);\n expect(form.errors.some(e => e.path === \"required\")).toBe(true);\n });\n });\n\n describe(\"rules on layout elements\", () => {\n it(\"cascades disable from tabs container to contained fields\", () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n general: fields.text().label(\"General\"),\n seo: fields.text().label(\"SEO\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout\n .tabs(\"settings\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n .tab(\"general\", tab => {\n tab.label(\"General\").layout(layout => [layout.row(\"general\")]);\n })\n .tab(\"seo\", tab => {\n tab.label(\"SEO\").layout(layout => [layout.row(\"seo\")]);\n })\n ]\n });\n\n expect(form.field(\"general\").vm.disabled).toBe(true);\n expect(form.field(\"seo\").vm.disabled).toBe(true);\n\n const tabs = form.vm.layout[1] as ITabsNodeVM;\n expect(tabs.disabled).toBe(true);\n expect(tabs.tabs[0].disabled).toBe(true);\n\n form.field(\"trigger\").setValue(\"go\");\n expect(form.field(\"general\").vm.disabled).toBe(false);\n expect(form.field(\"seo\").vm.disabled).toBe(false);\n });\n\n it(\"cascades disable from a single tab to its fields only\", () => {\n const form = createForm({\n fields: fields => ({\n title: fields.text().label(\"Title\"),\n general: fields.text().label(\"General\"),\n seo: fields.text().label(\"SEO\")\n }),\n layout: layout => [\n layout\n .tabs(\"settings\")\n .tab(\"general\", tab => {\n tab.label(\"General\").layout(layout => [layout.row(\"general\")]);\n })\n .tab(\"seo\", tab => {\n tab.label(\"SEO\")\n .rules([\n {\n type: \"condition\",\n target: \"title\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n .layout(layout => [layout.row(\"seo\")]);\n })\n ]\n });\n\n expect(form.field(\"general\").vm.disabled).toBe(false);\n expect(form.field(\"seo\").vm.disabled).toBe(true);\n\n const tabs = form.vm.layout[0] as ITabsNodeVM;\n expect(tabs.tabs[0].disabled).toBe(false);\n expect(tabs.tabs[1].disabled).toBe(true);\n });\n\n it(\"hides a tab and its fields when the tab has a hide rule\", async () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n hiddenField: fields.text().label(\"Hidden\").required(\"needed\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout.tabs(\"settings\").tab(\"secret\", tab => {\n tab.label(\"Secret\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n .layout(layout => [layout.row(\"hiddenField\")]);\n })\n ]\n });\n\n // Tab is hidden → field inside is hidden → not validated\n const valid = await form.validate();\n expect(valid).toBe(true);\n\n // Form VM should not expose this tabs node (all tabs hidden = no tabs node)\n const tabsVm = form.vm.layout.find(n => n.type === \"tabs\");\n expect(tabsVm).toBeUndefined();\n });\n\n it(\"hides the entire tabs container when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n inner: fields.text().label(\"Inner\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout\n .tabs(\"settings\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n .tab(\"tab1\", tab => {\n tab.label(\"Tab 1\").layout(layout => [layout.row(\"inner\")]);\n })\n ]\n });\n\n expect(form.vm.layout.find(n => n.type === \"tabs\")).toBeUndefined();\n expect(form.field(\"inner\").visible).toBe(false);\n\n form.field(\"trigger\").setValue(\"yes\");\n expect(form.field(\"inner\").visible).toBe(true);\n expect(form.vm.layout.find(n => n.type === \"tabs\")).toBeDefined();\n });\n });\n\n describe(\"custom rule evaluators\", () => {\n it(\"uses externally registered evaluators for custom rule types\", () => {\n class AccessControlEvaluator implements IRuleEvaluator {\n constructor(private userTeams: string[]) {}\n canEvaluate(rule: IRule) {\n return rule.type === \"accessControl\";\n }\n evaluate(rule: IRule): boolean {\n if (!rule.value) {\n return false;\n }\n const [scope, id] = rule.value.split(\":\");\n return scope === \"team\" && this.userTeams.includes(id);\n }\n }\n\n const form = createForm({\n extraEvaluators: [new AccessControlEvaluator([\"admins\"])],\n fields: fields => ({\n adminField: fields\n .text()\n .label(\"Admin Only\")\n .rules([\n {\n type: \"accessControl\",\n target: \"identity\",\n operator: \"matches\",\n value: \"team:admins\",\n action: \"disable\"\n }\n ])\n })\n });\n\n expect(form.field(\"adminField\").vm.disabled).toBe(true);\n });\n\n it(\"ignores rules with unknown types (no evaluator)\", () => {\n const form = createForm({\n fields: fields => ({\n weird: fields\n .text()\n .label(\"Weird\")\n .rules([\n {\n type: \"bogusType\",\n target: \"x\",\n operator: \"noop\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n // Unknown rule types are ignored — field remains visible\n expect(form.field(\"weird\").visible).toBe(true);\n expect(form.field(\"weird\").vm.disabled).toBe(false);\n });\n });\n\n describe(\"ConditionRuleEvaluator\", () => {\n it(\"canEvaluate returns true only for condition rules\", () => {\n const e = new ConditionRuleEvaluator();\n expect(\n e.canEvaluate({\n type: \"condition\",\n target: \"x\",\n operator: \"eq\",\n value: \"y\",\n action: \"hide\"\n })\n ).toBe(true);\n expect(\n e.canEvaluate({\n type: \"accessControl\",\n target: \"identity\",\n operator: \"matches\",\n value: \"team:x\",\n action: \"hide\"\n })\n ).toBe(false);\n });\n\n it(\"isEmpty matches null, undefined, empty string, empty array\", () => {\n const e = new ConditionRuleEvaluator();\n const mkForm = (value: unknown): IFormModel =>\n ({\n field: () => ({ getValue: () => value })\n }) as unknown as IFormModel;\n\n const rule: IRule = {\n type: \"condition\",\n target: \"x\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n };\n\n expect(e.evaluate(rule, mkForm(null))).toBe(true);\n expect(e.evaluate(rule, mkForm(undefined))).toBe(true);\n expect(e.evaluate(rule, mkForm(\"\"))).toBe(true);\n expect(e.evaluate(rule, mkForm([]))).toBe(true);\n expect(e.evaluate(rule, mkForm(\"hello\"))).toBe(false);\n expect(e.evaluate(rule, mkForm(0))).toBe(false);\n });\n });\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"features/formModel/Rules.test.js","sources":["../../../src/features/formModel/Rules.test.ts"],"sourcesContent":["import { describe, it, expect } from \"vitest\";\nimport { Container } from \"@webiny/di\";\nimport { FormModelFeature } from \"./feature.js\";\nimport { ConditionRuleEvaluator } from \"./ConditionRuleEvaluator.js\";\nimport {\n FormModelFactory,\n type IRule,\n type IRuleEvaluator,\n type ITabsNodeVM,\n type IFormModel,\n type IFormModelConfig\n} from \"./abstractions.js\";\n\nfunction createForm(config: {\n extraEvaluators?: IRuleEvaluator[];\n fields: IFormModelConfig[\"fields\"];\n layout?: IFormModelConfig[\"layout\"];\n}) {\n const container = new Container();\n FormModelFeature.register(container);\n return container.resolve(FormModelFactory).create({\n fields: config.fields,\n layout: config.layout,\n ruleEvaluators: config.extraEvaluators\n });\n}\n\ndescribe(\"Rules system\", () => {\n describe(\"condition rule on a field\", () => {\n it(\"hides a field when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n title: fields.text().label(\"Title\"),\n subtitle: fields\n .text()\n .label(\"Subtitle\")\n .rules([\n {\n type: \"condition\",\n target: \"title\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n expect(form.field(\"subtitle\").visible).toBe(false);\n expect(form.field(\"subtitle\").vm.visible).toBe(false);\n\n form.field(\"title\").setValue(\"Hello\");\n expect(form.field(\"subtitle\").visible).toBe(true);\n expect(form.field(\"subtitle\").vm.visible).toBe(true);\n });\n\n it(\"disables a field when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n country: fields.text().label(\"Country\"),\n city: fields\n .text()\n .label(\"City\")\n .rules([\n {\n type: \"condition\",\n target: \"country\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n })\n });\n\n expect(form.field(\"city\").vm.disabled).toBe(true);\n\n form.field(\"country\").setValue(\"US\");\n expect(form.field(\"city\").vm.disabled).toBe(false);\n });\n\n it(\"supports eq operator\", () => {\n const form = createForm({\n fields: fields => ({\n plan: fields.text().label(\"Plan\"),\n enterpriseOnly: fields\n .text()\n .label(\"Enterprise\")\n .rules([\n {\n type: \"condition\",\n target: \"plan\",\n operator: \"eq\",\n value: \"enterprise\",\n action: \"hide\"\n }\n ])\n })\n });\n\n form.field(\"plan\").setValue(\"starter\");\n expect(form.field(\"enterpriseOnly\").visible).toBe(true);\n\n form.field(\"plan\").setValue(\"enterprise\");\n expect(form.field(\"enterpriseOnly\").visible).toBe(false);\n });\n\n it(\"excludes hidden fields from validation\", async () => {\n const form = createForm({\n fields: fields => ({\n toggle: fields.text().label(\"Toggle\"),\n required: fields\n .text()\n .label(\"Required\")\n .required(\"Must fill\")\n .rules([\n {\n type: \"condition\",\n target: \"toggle\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n // toggle is empty → \"required\" is hidden → should not count as invalid\n const valid = await form.validate();\n expect(valid).toBe(true);\n\n // Fill toggle → \"required\" becomes visible → fails without a value\n form.field(\"toggle\").setValue(\"anything\");\n const valid2 = await form.validate();\n expect(valid2).toBe(false);\n expect(form.errors.some(e => e.path === \"required\")).toBe(true);\n });\n });\n\n describe(\"rules on layout elements\", () => {\n it(\"cascades disable from tabs container to contained fields\", () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n general: fields.text().label(\"General\"),\n seo: fields.text().label(\"SEO\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout\n .tabs(\"settings\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n .tab(\"general\", tab => {\n tab.label(\"General\").layout(layout => [layout.row(\"general\")]);\n })\n .tab(\"seo\", tab => {\n tab.label(\"SEO\").layout(layout => [layout.row(\"seo\")]);\n })\n ]\n });\n\n expect(form.field(\"general\").vm.disabled).toBe(true);\n expect(form.field(\"seo\").vm.disabled).toBe(true);\n\n const tabs = form.vm.layout[1] as ITabsNodeVM;\n expect(tabs.disabled).toBe(true);\n expect(tabs.tabs[0].disabled).toBe(true);\n\n form.field(\"trigger\").setValue(\"go\");\n expect(form.field(\"general\").vm.disabled).toBe(false);\n expect(form.field(\"seo\").vm.disabled).toBe(false);\n });\n\n it(\"cascades disable from a single tab to its fields only\", () => {\n const form = createForm({\n fields: fields => ({\n title: fields.text().label(\"Title\"),\n general: fields.text().label(\"General\"),\n seo: fields.text().label(\"SEO\")\n }),\n layout: layout => [\n layout\n .tabs(\"settings\")\n .tab(\"general\", tab => {\n tab.label(\"General\").layout(layout => [layout.row(\"general\")]);\n })\n .tab(\"seo\", tab => {\n tab.label(\"SEO\")\n .rules([\n {\n type: \"condition\",\n target: \"title\",\n operator: \"isEmpty\",\n value: null,\n action: \"disable\"\n }\n ])\n .layout(layout => [layout.row(\"seo\")]);\n })\n ]\n });\n\n expect(form.field(\"general\").vm.disabled).toBe(false);\n expect(form.field(\"seo\").vm.disabled).toBe(true);\n\n const tabs = form.vm.layout[0] as ITabsNodeVM;\n expect(tabs.tabs[0].disabled).toBe(false);\n expect(tabs.tabs[1].disabled).toBe(true);\n });\n\n it(\"hides a tab and its fields when the tab has a hide rule\", async () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n hiddenField: fields.text().label(\"Hidden\").required(\"needed\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout.tabs(\"settings\").tab(\"secret\", tab => {\n tab.label(\"Secret\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n .layout(layout => [layout.row(\"hiddenField\")]);\n })\n ]\n });\n\n // Tab is hidden → field inside is hidden → not validated\n const valid = await form.validate();\n expect(valid).toBe(true);\n\n // Form VM should not expose this tabs node (all tabs hidden = no tabs node)\n const tabsVm = form.vm.layout.find(n => n.type === \"tabs\");\n expect(tabsVm).toBeUndefined();\n });\n\n it(\"hides the entire tabs container when its rule matches\", () => {\n const form = createForm({\n fields: fields => ({\n trigger: fields.text().label(\"Trigger\"),\n inner: fields.text().label(\"Inner\")\n }),\n layout: layout => [\n layout.row(\"trigger\"),\n layout\n .tabs(\"settings\")\n .rules([\n {\n type: \"condition\",\n target: \"trigger\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n }\n ])\n .tab(\"tab1\", tab => {\n tab.label(\"Tab 1\").layout(layout => [layout.row(\"inner\")]);\n })\n ]\n });\n\n expect(form.vm.layout.find(n => n.type === \"tabs\")).toBeUndefined();\n expect(form.field(\"inner\").visible).toBe(false);\n\n form.field(\"trigger\").setValue(\"yes\");\n expect(form.field(\"inner\").visible).toBe(true);\n expect(form.vm.layout.find(n => n.type === \"tabs\")).toBeDefined();\n });\n });\n\n describe(\"custom rule evaluators\", () => {\n it(\"uses externally registered evaluators for custom rule types\", () => {\n class AccessControlEvaluator implements IRuleEvaluator {\n constructor(private userTeams: string[]) {}\n canEvaluate(rule: IRule) {\n return rule.type === \"accessControl\";\n }\n evaluate(rule: IRule): boolean {\n if (!rule.value) {\n return false;\n }\n const [scope, id] = rule.value.split(\":\");\n return scope === \"team\" && this.userTeams.includes(id);\n }\n }\n\n const form = createForm({\n extraEvaluators: [new AccessControlEvaluator([\"admins\"])],\n fields: fields => ({\n adminField: fields\n .text()\n .label(\"Admin Only\")\n .rules([\n {\n type: \"accessControl\",\n target: \"identity\",\n operator: \"matches\",\n value: \"team:admins\",\n action: \"disable\"\n }\n ])\n })\n });\n\n expect(form.field(\"adminField\").vm.disabled).toBe(true);\n });\n\n it(\"ignores rules with unknown types (no evaluator)\", () => {\n const form = createForm({\n fields: fields => ({\n weird: fields\n .text()\n .label(\"Weird\")\n .rules([\n {\n type: \"bogusType\",\n target: \"x\",\n operator: \"noop\",\n value: null,\n action: \"hide\"\n }\n ])\n })\n });\n\n // Unknown rule types are ignored — field remains visible\n expect(form.field(\"weird\").visible).toBe(true);\n expect(form.field(\"weird\").vm.disabled).toBe(false);\n });\n });\n\n describe(\"ConditionRuleEvaluator\", () => {\n it(\"canEvaluate returns true only for condition rules\", () => {\n const e = new ConditionRuleEvaluator();\n expect(\n e.canEvaluate({\n type: \"condition\",\n target: \"x\",\n operator: \"eq\",\n value: \"y\",\n action: \"hide\"\n })\n ).toBe(true);\n expect(\n e.canEvaluate({\n type: \"accessControl\",\n target: \"identity\",\n operator: \"matches\",\n value: \"team:x\",\n action: \"hide\"\n })\n ).toBe(false);\n });\n\n it(\"isEmpty matches null, undefined, empty string, empty array\", () => {\n const e = new ConditionRuleEvaluator();\n const mkForm = (value: unknown): IFormModel =>\n ({\n field: () => ({ getValue: () => value })\n }) as unknown as IFormModel;\n\n const rule: IRule = {\n type: \"condition\",\n target: \"x\",\n operator: \"isEmpty\",\n value: null,\n action: \"hide\"\n };\n\n expect(e.evaluate(rule, mkForm(null))).toBe(true);\n expect(e.evaluate(rule, mkForm(undefined))).toBe(true);\n expect(e.evaluate(rule, mkForm(\"\"))).toBe(true);\n expect(e.evaluate(rule, mkForm([]))).toBe(true);\n expect(e.evaluate(rule, mkForm(\"hello\"))).toBe(false);\n expect(e.evaluate(rule, mkForm(0))).toBe(false);\n });\n });\n});\n"],"names":["createForm","config","container","Container","FormModelFeature","FormModelFactory","describe","it","form","fields","expect","valid","valid2","e","layout","tab","tabs","tabsVm","n","AccessControlEvaluator","userTeams","rule","scope","id","ConditionRuleEvaluator","mkForm","value","undefined"],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ export interface IFieldConfig {
|
|
|
34
34
|
afterSetValueCallbacks?: AfterSetValueCallback[];
|
|
35
35
|
onBlurCallbacks?: OnBlurCallback[];
|
|
36
36
|
requiredWhenCallbacks?: RequiredWhenCallback[];
|
|
37
|
+
hiddenWhenCallbacks?: HiddenWhenCallback[];
|
|
37
38
|
computed?: ComputedFieldCallback;
|
|
38
39
|
computedUntilDirty?: ComputedFieldCallback;
|
|
39
40
|
tags?: string[];
|
|
@@ -45,6 +46,7 @@ export interface IRequiredWhenCallbackConfig {
|
|
|
45
46
|
message?: string;
|
|
46
47
|
}
|
|
47
48
|
export type RequiredWhenCallback = IRequiredWhenCallbackConfig;
|
|
49
|
+
export type HiddenWhenCallback = (form: IFormModel) => boolean;
|
|
48
50
|
export type ComputedFieldCallback = (form: IFormModel) => unknown;
|
|
49
51
|
export type RuleAction = "hide" | "disable";
|
|
50
52
|
export type RuleOperator = "eq" | "neq" | "isEmpty" | "isNotEmpty" | "isTruthy" | "isFalsy" | "matches";
|
|
@@ -482,6 +484,7 @@ export interface ILayoutModifier {
|
|
|
482
484
|
export interface IFormError {
|
|
483
485
|
path: string;
|
|
484
486
|
label?: string;
|
|
487
|
+
breadcrumb?: string[];
|
|
485
488
|
message: string;
|
|
486
489
|
}
|
|
487
490
|
export interface IFormVM {
|
|
@@ -489,6 +492,10 @@ export interface IFormVM {
|
|
|
489
492
|
errors: IFormError[];
|
|
490
493
|
isDirty: boolean;
|
|
491
494
|
isValid: boolean | null;
|
|
495
|
+
submitCount: number;
|
|
496
|
+
focusField(path: string): void;
|
|
497
|
+
getData(): Record<string, unknown>;
|
|
498
|
+
setData(data: Record<string, unknown>): void;
|
|
492
499
|
}
|
|
493
500
|
/**
|
|
494
501
|
* Imperative form-level rule. Receives the live form and may return a flat
|
|
@@ -531,6 +538,7 @@ export interface IFormModel<T = Record<string, any>> {
|
|
|
531
538
|
readonly isDirty: boolean;
|
|
532
539
|
readonly isValid: boolean | null;
|
|
533
540
|
readonly submitted: boolean;
|
|
541
|
+
readonly submitCount: number;
|
|
534
542
|
readonly errors: IFormError[];
|
|
535
543
|
readonly vm: IFormVM;
|
|
536
544
|
getFieldBuilders(predicate?: (builder: IFieldBuilder) => boolean): IFieldBuilder[];
|
|
@@ -590,6 +598,7 @@ export declare namespace FormModel {
|
|
|
590
598
|
type FormRuleFunction = FormRuleFn;
|
|
591
599
|
type FormRuleType = FormRule;
|
|
592
600
|
type RequiredWhen = (form: IFormModel) => boolean;
|
|
601
|
+
type HiddenWhen = HiddenWhenCallback;
|
|
593
602
|
type Computed = ComputedFieldCallback;
|
|
594
603
|
}
|
|
595
604
|
export interface IFormModelFactory {
|
|
@@ -629,6 +638,7 @@ export interface IFieldBuilder<TType extends string = string, TOptions extends b
|
|
|
629
638
|
defaultValue(value: unknown): this;
|
|
630
639
|
renderer<TName extends FieldRendererName<TType, TOptions>>(name: TName, ...args: undefined extends FieldRendererSettings<TName> ? [settings?: FieldRendererSettings<TName>] : FieldRendererSettings<TName> extends undefined ? [] : [settings: FieldRendererSettings<TName>]): this;
|
|
631
640
|
hidden(): this;
|
|
641
|
+
hiddenWhen(fn: (form: IFormModel) => boolean): this;
|
|
632
642
|
required(message?: string): this;
|
|
633
643
|
/**
|
|
634
644
|
* Conditional required check. Multiple `requiredWhen()` calls chain — the
|
|
@@ -1,117 +1,8 @@
|
|
|
1
1
|
import { createAbstraction } from "@webiny/feature/admin";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
// Field types
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Rules system
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* VM exposed for each available template in the picker.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Maps field type strings to their typed field interfaces.
|
|
21
|
-
* Extended via module augmentation when new field types are registered.
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// Object / List field types
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Callback types
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
// Layout types
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
|
|
36
|
-
/** @deprecated Use IRowBuilder instead */
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* User-facing tab spec accepted by `layout.tabs(...)`. The layout is supplied
|
|
40
|
-
* as a callback receiving the layout builder, mirroring `layout.object(...)`.
|
|
41
|
-
* Resolved to `ITabDefinition` (with `layout: LayoutNode[]`) at build time.
|
|
42
|
-
*/
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Layout node that references an object field and registers an inner layout
|
|
46
|
-
* on it. Resolved as a single-field row in the outer layout — the inner
|
|
47
|
-
* layout is exposed on the field's VM (`field.layout` for single objects,
|
|
48
|
-
* `item.layout` for list items).
|
|
49
|
-
*
|
|
50
|
-
* - For non-templated objects, `inner` is `LayoutNode[]` (one layout, applied
|
|
51
|
-
* to the single object or every list item).
|
|
52
|
-
* - For templated objects, `inner` is `Record<templateId, LayoutNode[]>` —
|
|
53
|
-
* each entry is the layout used when that template is active (or for each
|
|
54
|
-
* list item with that template).
|
|
55
|
-
*/
|
|
56
|
-
|
|
57
|
-
// ---------------------------------------------------------------------------
|
|
58
|
-
// Layout node builders
|
|
59
|
-
// ---------------------------------------------------------------------------
|
|
60
|
-
|
|
61
|
-
// ---------------------------------------------------------------------------
|
|
62
|
-
// Layout VM types
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
|
-
// Layout modifier types
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Chainable handle returned by modifier layout.row().
|
|
71
|
-
* Can be used as-is (appended) or positioned via .before()/.after()/.replace().
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
// ---------------------------------------------------------------------------
|
|
75
|
-
// Named layout node access types
|
|
76
|
-
// ---------------------------------------------------------------------------
|
|
77
|
-
|
|
78
|
-
/** @deprecated Use ITabsBuilder instead */
|
|
79
|
-
|
|
80
|
-
/** @deprecated Use ITabBuilder instead */
|
|
81
|
-
|
|
82
|
-
// ---------------------------------------------------------------------------
|
|
83
|
-
// Modifier types
|
|
84
|
-
// ---------------------------------------------------------------------------
|
|
85
|
-
|
|
86
|
-
// ---------------------------------------------------------------------------
|
|
87
|
-
// Form types
|
|
88
|
-
// ---------------------------------------------------------------------------
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Imperative form-level rule. Receives the live form and may return a flat
|
|
92
|
-
* list of errors (sync or async). Errors are merged into `form.errors` and
|
|
93
|
-
* surfaced on per-field validation when their `path` matches a known field.
|
|
94
|
-
*/
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* A form-level rule. Either a Zod schema (validated against `form.getData()`)
|
|
98
|
-
* or an imperative function returning an error list.
|
|
99
|
-
*/
|
|
100
|
-
// ---------------------------------------------------------------------------
|
|
101
|
-
// FormModel namespace — groups all public types under one import
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
|
-
export let FormModel;
|
|
104
|
-
// ---------------------------------------------------------------------------
|
|
105
|
-
// FormModelFactory abstraction
|
|
106
|
-
// ---------------------------------------------------------------------------
|
|
107
|
-
|
|
108
|
-
// ---------------------------------------------------------------------------
|
|
109
|
-
// Field type plugin system
|
|
110
|
-
// ---------------------------------------------------------------------------
|
|
111
|
-
|
|
112
|
-
export const FieldType = createAbstraction("FormModel/FieldType");
|
|
113
|
-
export const FieldBuilderRegistry = createAbstraction("FormModel/FieldBuilderRegistry");
|
|
114
|
-
export const FormModelFactory = createAbstraction("FormModelFactory");
|
|
115
|
-
export const RuleEvaluator = createAbstraction("FormModelRuleEvaluator");
|
|
2
|
+
const FieldType = createAbstraction("FormModel/FieldType");
|
|
3
|
+
const FieldBuilderRegistry = createAbstraction("FormModel/FieldBuilderRegistry");
|
|
4
|
+
const FormModelFactory = createAbstraction("FormModelFactory");
|
|
5
|
+
const RuleEvaluator = createAbstraction("FormModelRuleEvaluator");
|
|
6
|
+
export { FieldBuilderRegistry, FieldType, FormModelFactory, RuleEvaluator };
|
|
116
7
|
|
|
117
8
|
//# sourceMappingURL=abstractions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createAbstraction","FormModel","FieldType","FieldBuilderRegistry","FormModelFactory","RuleEvaluator"],"sources":["abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { z } from \"zod\";\nimport type { Icon } from \"~/components/IconPicker/types.js\";\n\n// ---------------------------------------------------------------------------\n// Renderer registry — augmented by each renderer via declare module\n// ---------------------------------------------------------------------------\n\nexport interface IFieldRendererRegistry {}\n\nexport type FieldRendererName<\n TType extends string = string,\n TOptions extends boolean = boolean\n> = string extends TType\n ? keyof IFieldRendererRegistry & string\n : {\n [K in keyof IFieldRendererRegistry]: TType extends IFieldRendererRegistry[K][\"fieldType\"]\n ? boolean extends TOptions\n ? K\n : TOptions extends true\n ? IFieldRendererRegistry[K] extends { options: true }\n ? K\n : never\n : IFieldRendererRegistry[K] extends { options: true }\n ? never\n : K\n : never;\n }[keyof IFieldRendererRegistry] &\n string;\n\nexport type FieldRendererSettings<TName extends string> = TName extends keyof IFieldRendererRegistry\n ? IFieldRendererRegistry[TName][\"settings\"]\n : Record<string, unknown> | undefined;\n\n// ---------------------------------------------------------------------------\n// Field types\n// ---------------------------------------------------------------------------\n\nexport interface IFieldConfig {\n name: string;\n type: string;\n label?: string;\n help?: string;\n description?: string;\n note?: string;\n placeholder?: string;\n defaultValue?: unknown;\n renderer?: string;\n rendererSettings?: Record<string, unknown>;\n isList?: boolean;\n hidden: boolean;\n required: boolean;\n requiredMessage?: string;\n disabled: boolean;\n schema?: z.ZodTypeAny;\n options?: IValueOption[] | ((form: IFormModel) => IValueOption[]);\n normalizeValue?: (value: unknown) => unknown;\n beforeChangeCallbacks?: BeforeChangeCallback[];\n afterChangeCallbacks?: AfterChangeCallback[];\n afterSetValueCallbacks?: AfterSetValueCallback[];\n onBlurCallbacks?: OnBlurCallback[];\n requiredWhenCallbacks?: RequiredWhenCallback[];\n computed?: ComputedFieldCallback;\n computedUntilDirty?: ComputedFieldCallback;\n tags?: string[];\n cloneValue?: CloneValueCallback;\n rules?: IRule[];\n}\n\nexport interface IRequiredWhenCallbackConfig {\n fn: (form: IFormModel) => boolean;\n message?: string;\n}\n\nexport type RequiredWhenCallback = IRequiredWhenCallbackConfig;\n\nexport type ComputedFieldCallback = (form: IFormModel) => unknown;\n\n// ---------------------------------------------------------------------------\n// Rules system\n// ---------------------------------------------------------------------------\n\nexport type RuleAction = \"hide\" | \"disable\";\n\nexport type RuleOperator =\n | \"eq\"\n | \"neq\"\n | \"isEmpty\"\n | \"isNotEmpty\"\n | \"isTruthy\"\n | \"isFalsy\"\n | \"matches\";\n\nexport interface IRule {\n type: string;\n target: string;\n operator: RuleOperator | (string & {});\n value: string | null;\n action: RuleAction;\n}\n\nexport interface IRuleEvaluator {\n canEvaluate(rule: IRule): boolean;\n evaluate(rule: IRule, form: IFormModel): boolean;\n}\n\nexport interface IValueOption<V extends string | number = string | number> {\n label: string;\n value: V;\n disabled?: boolean;\n}\n\nexport type OptionValueType<TType extends string> = TType extends \"number\" ? number : string;\n\nexport interface IFieldValidation {\n isValid: boolean | null;\n message?: string;\n}\n\nexport interface IFieldVM {\n name: string;\n type: string;\n label?: string;\n help?: string;\n description?: string;\n note?: string;\n placeholder?: string;\n value: unknown;\n validation: IFieldValidation;\n validating: boolean;\n required: boolean;\n visible: boolean;\n disabled: boolean;\n renderer?: string;\n rendererSettings?: Record<string, unknown>;\n isList?: boolean;\n options?: IValueOption[];\n onChange: (value: unknown) => void;\n onBlur: () => void;\n addItem: (value?: unknown) => void;\n removeItem: (index: number) => void;\n focusRequested: boolean;\n clearFocusRequest: () => void;\n}\n\nexport interface IObjectFieldVM extends IFieldVM {\n type: \"object\";\n isList: boolean;\n /** Child field VMs for non-list object fields. */\n fields: IFieldVM[];\n /**\n * Resolved layout for non-list object fields. For templated objects, resolves\n * against the active template's per-template layout (if registered via\n * `layout.object()`), otherwise defaults to one row per visible child.\n * For list-mode fields, see `items[].layout`.\n */\n layout: LayoutNodeVM[];\n /** Items for list-mode object fields. */\n items: IObjectFieldItemVM[];\n /** Append a new item. Templated lists require a template id. */\n addItem: (value?: unknown) => void;\n moveItem: (fromIndex: number, toIndex: number) => void;\n /** Duplicate a list item (including its `_templateId` when templated) and insert it after the source. */\n duplicateItem: (index: number) => void;\n /** True when the object has templates defined. */\n isTemplated: boolean;\n /** Templates visible in the picker (filtered by each template's reactive `visible`). */\n availableTemplates: ITemplateVM[];\n /** Currently active template id (single-object mode), or null if no template picked. */\n activeTemplateId: string | null;\n /** Switch to a different template. Discards values not present in the new template. */\n setTemplate: (templateId: string) => void;\n}\n\nexport interface IObjectFieldItemVM {\n key: string;\n fields: IFieldVM[];\n /**\n * Resolved layout for this item. For templated lists, resolves against the\n * item's template-specific layout (if registered via `layout.object()`),\n * otherwise defaults to one row per visible child.\n */\n layout: LayoutNodeVM[];\n remove: () => void;\n moveUp: () => void;\n moveDown: () => void;\n duplicate: () => void;\n /** The template id of this item, if the parent list is templated. */\n templateId?: string;\n}\n\n/**\n * VM exposed for each available template in the picker.\n */\nexport interface ITemplateIcon {\n type: string;\n name: string;\n}\n\nexport interface ITemplateVM {\n id: string;\n label: string;\n icon?: ITemplateIcon;\n}\n\nexport interface IField {\n readonly name: string;\n readonly type: string;\n readonly visible: boolean;\n readonly disabled: boolean;\n readonly vm: IFieldVM;\n readonly config: IFieldConfig;\n getValue<T = unknown>(): T;\n setValue(value: unknown): void;\n setValueSilent(value: unknown): void;\n setDisabled(value: boolean): void;\n setVisible(value: boolean): void;\n setForm(form: IFormModel, parentPath?: string): void;\n setAncestorRules(rules: IRule[]): void;\n setValidation(validation: IFieldValidation): void;\n resetValidation(): void;\n validate(options?: { force?: boolean }): Promise<boolean>;\n remove(): void;\n addBeforeChange(cb: BeforeChangeCallback): void;\n addAfterChange(cb: AfterChangeCallback): void;\n addAfterSetValue(cb: AfterSetValueCallback): void;\n addOnBlur(cb: OnBlurCallback): void;\n /**\n * Append a conditional required check. Multiple callbacks chain additively;\n * the first one returning `true` makes the field required for the current\n * form state. The built-in `.required()` flag (if set) always counts as a\n * truthy check and cannot be overridden.\n */\n addRequiredWhen(fn: (form: IFormModel) => boolean, message?: string): void;\n /**\n * Mark this field as a derived value computed from `fn(form)`. The field\n * stays editable (no auto-disable) and is excluded from `isDirty` while\n * still tracking the computed value. Validation continues to apply.\n */\n setComputed(fn: ComputedFieldCallback): void;\n /**\n * Same as `setComputed`, but the field switches to manual mode the first\n * time the user edits its value. After that, the computed callback no\n * longer overrides user input.\n */\n setComputedUntilDirty(fn: ComputedFieldCallback): void;\n blur(): void;\n as<T extends keyof FieldTypeMap>(type: T): FieldTypeMap[T];\n readonly qualifiedName: string;\n focus(): void;\n requestFocus(): void;\n clearFocusRequest(): void;\n}\n\n/**\n * Maps field type strings to their typed field interfaces.\n * Extended via module augmentation when new field types are registered.\n */\nexport interface ITypedField<V> extends IField {\n getValue<T = V>(): T;\n}\n\ntype InferFieldTypeMap = {\n [K in keyof IFieldBuilderRegistry]: ReturnType<\n IFieldBuilderRegistry[K]\n > extends IObjectFieldBuilder\n ? IObjectField\n : ReturnType<IFieldBuilderRegistry[K]> extends { readonly __valueType?: infer V }\n ? ITypedField<V>\n : IField;\n};\n\nexport type FieldTypeMap = { [K in keyof InferFieldTypeMap]: InferFieldTypeMap[K] };\n\nexport type FileValue = {\n id: string;\n name: string;\n size: number;\n mimeType: string;\n src: string;\n width: number | undefined;\n height: number | undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Object / List field types\n// ---------------------------------------------------------------------------\n\nexport interface IObjectFieldConfig extends IFieldConfig {\n childBuilders: Record<string, IFieldBuilder>;\n isList: boolean;\n listSchema?: z.ZodTypeAny;\n templates?: ITemplateConfig[];\n}\n\nexport interface ITemplateBuilder {\n label(text: string): this;\n icon(icon: ITemplateIcon): this;\n fields(factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>): this;\n visible(predicate: (form: IFormModel) => boolean): this;\n}\n\nexport interface ITemplateConfig {\n id: string;\n label: string;\n icon?: ITemplateIcon;\n childBuilders: Record<string, IFieldBuilder>;\n visible?: (form: IFormModel) => boolean;\n}\n\nexport interface IObjectField extends ITypedField<Record<string, unknown> | null> {\n readonly isList: boolean;\n readonly children: Map<string, IField>;\n readonly items: IListItemField[];\n readonly isTemplated: boolean;\n readonly activeTemplateId: string | null;\n readonly availableTemplates: ITemplateVM[];\n /**\n * Add, replace, or remove children on this object field at runtime.\n * Mirrors `form.fields()` but scoped to this object's children. Existing\n * keys are replaced; new keys are appended; passing `undefined` removes.\n * Throws on templated objects — each template owns its own fields.\n */\n fields(\n factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder | undefined>\n ): void;\n /**\n * Register an inner layout used by the field's VM (`field.layout` for\n * single objects, `item.layout` for list items).\n *\n * Pass `LayoutNode[]` for non-templated objects (the layout applies to the\n * single object or every list item). Pass `Record<templateId, LayoutNode[]>`\n * for templated objects (each entry applies when that template is active\n * or for each list item with that template). Templates without an entry\n * fall back to default one-row-per-visible-child.\n */\n setInnerLayout(layout: LayoutNode[] | Record<string, LayoutNode[]>): void;\n /**\n * Append a new list item.\n * - Non-templated list: `addItem(data?)` — data hydrates the new item.\n * - Templated list: `addItem(templateId, data?)` — templateId picks the variant.\n */\n addItem(\n templateIdOrData?: string | Record<string, unknown>,\n data?: Record<string, unknown>\n ): void;\n removeItem(index: number): void;\n moveItem(fromIndex: number, toIndex: number): void;\n /** Duplicate a list item (including its `_templateId`) and insert after the source. */\n duplicateItem(index: number): void;\n setTemplate(templateId: string): void;\n /**\n * Runtime template management. Available on every object field but throws\n * when called on a non-templated field (`isTemplated === false`).\n */\n readonly templates: IObjectFieldTemplates;\n getInnerLayout(): LayoutNode[] | null;\n getData(): Record<string, unknown> | Record<string, unknown>[];\n}\n\nexport interface IObjectFieldTemplates {\n add(id: string, configure: (t: ITemplateBuilder) => void): void;\n remove(templateId: string): void;\n}\n\nexport interface IListItemField {\n readonly key: string;\n readonly children: Map<string, IField>;\n readonly templateId?: string;\n getData(): Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Callback types\n// ---------------------------------------------------------------------------\n\nexport type BeforeChangeCallback = (value: unknown, form: IFormModel) => unknown;\nexport type AfterChangeCallback = (value: unknown, form: IFormModel) => void;\nexport type AfterSetValueCallback = (value: unknown, form: IFormModel) => void;\nexport type OnBlurCallback = (value: unknown, form: IFormModel) => void;\nexport type CloneValueCallback = (value: unknown) => unknown;\n\n// ---------------------------------------------------------------------------\n// Layout types\n// ---------------------------------------------------------------------------\n\nexport type LayoutNode = IRowNode | ISeparatorNode | ITabsNode | IElementNode | IObjectNode;\n\nexport interface IRowNode {\n type: \"row\";\n fieldIds: string[];\n position?: LayoutPosition;\n}\n\n/** @deprecated Use IRowBuilder instead */\nexport type IRowNodeHandle = IRowBuilder;\n\nexport interface ISeparatorNode {\n type: \"separator\";\n}\n\nexport interface ITabDefinition {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n layout: LayoutNode[];\n rules?: IRule[];\n}\n\n/**\n * User-facing tab spec accepted by `layout.tabs(...)`. The layout is supplied\n * as a callback receiving the layout builder, mirroring `layout.object(...)`.\n * Resolved to `ITabDefinition` (with `layout: LayoutNode[]`) at build time.\n */\nexport interface ITabDefinitionInput {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[];\n rules?: IRule[];\n}\n\nexport interface ITabsNode {\n type: \"tabs\";\n id?: string;\n renderer?: string;\n tabs: ITabDefinition[];\n rules?: IRule[];\n}\n\nexport interface IElementNode {\n type: \"element\";\n id?: string;\n renderer: string;\n props?: Record<string, unknown>;\n}\n\n/**\n * Layout node that references an object field and registers an inner layout\n * on it. Resolved as a single-field row in the outer layout — the inner\n * layout is exposed on the field's VM (`field.layout` for single objects,\n * `item.layout` for list items).\n *\n * - For non-templated objects, `inner` is `LayoutNode[]` (one layout, applied\n * to the single object or every list item).\n * - For templated objects, `inner` is `Record<templateId, LayoutNode[]>` —\n * each entry is the layout used when that template is active (or for each\n * list item with that template).\n */\nexport interface IObjectNode {\n type: \"object\";\n fieldName: string;\n inner: LayoutNode[] | Record<string, LayoutNode[]>;\n}\n\n// ---------------------------------------------------------------------------\n// Layout node builders\n// ---------------------------------------------------------------------------\n\nexport interface ILayoutNodeBuilder {\n build(): LayoutNode;\n}\n\nexport interface IRowBuilder extends ILayoutNodeBuilder {\n before(target: string): IRowBuilder;\n after(target: string): IRowBuilder;\n build(): IRowNode;\n}\n\nexport interface ISeparatorBuilder extends ILayoutNodeBuilder {\n build(): ISeparatorNode;\n}\n\nexport interface ITabBuilder {\n label(text: string): this;\n description(text: string): this;\n icon(icon: Icon): this;\n layout(factory: (l: ILayoutBuilder) => ILayoutNodeBuilder[]): this;\n rules(rules: IRule[]): this;\n}\n\nexport interface ITabsBuilder extends ILayoutNodeBuilder {\n renderer(name: string): this;\n tab(id: string, configure: (tab: ITabBuilder) => void): this;\n before(target: string): this;\n after(target: string): this;\n rules(rules: IRule[]): this;\n build(): ITabsNode;\n}\n\nexport interface IElementBuilder extends ILayoutNodeBuilder {\n build(): IElementNode;\n}\n\nexport interface IObjectBuilder extends ILayoutNodeBuilder {\n build(): IObjectNode;\n}\n\n// ---------------------------------------------------------------------------\n// Layout VM types\n// ---------------------------------------------------------------------------\n\nexport type LayoutNodeVM = IRowNodeVM | ISeparatorNodeVM | ITabsNodeVM | IElementNodeVM;\n\nexport interface IRowNodeVM {\n type: \"row\";\n fields: IFieldVM[];\n}\n\nexport interface ISeparatorNodeVM {\n type: \"separator\";\n}\n\nexport interface ITabDefinitionVM {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n hasErrors: boolean;\n disabled: boolean;\n layout: LayoutNodeVM[];\n}\n\nexport interface ITabsNodeVM {\n type: \"tabs\";\n id?: string;\n renderer?: string;\n tabs: ITabDefinitionVM[];\n disabled: boolean;\n activeTabId: string;\n setActiveTab: (id: string) => void;\n}\n\nexport interface IElementNodeVM {\n type: \"element\";\n renderer: string;\n props?: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Layout modifier types\n// ---------------------------------------------------------------------------\n\nexport type LayoutPosition =\n | { type: \"before\"; target: string }\n | { type: \"after\"; target: string }\n | { type: \"replace\"; target: string };\n\nexport interface IPositionedLayoutNode {\n node: LayoutNode;\n position?: LayoutPosition;\n}\n\n/**\n * Chainable handle returned by modifier layout.row().\n * Can be used as-is (appended) or positioned via .before()/.after()/.replace().\n */\nexport interface ILayoutNodeHandle extends IPositionedLayoutNode {\n before(target: string): IPositionedLayoutNode;\n after(target: string): IPositionedLayoutNode;\n replace(target: string): IPositionedLayoutNode;\n}\n\n// ---------------------------------------------------------------------------\n// Named layout node access types\n// ---------------------------------------------------------------------------\n\nexport interface LayoutNodeHandleMap {\n tabs: ITabsBuilder;\n element: IElementNode;\n object: IObjectNode;\n}\n\nexport interface ILayoutNodeAccessHandle {\n as<T extends keyof LayoutNodeHandleMap>(type: T): LayoutNodeHandleMap[T];\n}\n\n/** @deprecated Use ITabsBuilder instead */\nexport type ITabsHandle = ITabsBuilder;\n\n/** @deprecated Use ITabBuilder instead */\nexport type ITabHandle = ITabBuilder;\n\n// ---------------------------------------------------------------------------\n// Modifier types\n// ---------------------------------------------------------------------------\n\nexport interface IFormModifier {\n modify(form: IFormModel): void;\n}\n\nexport interface ILayoutModifier {\n row(...fieldIds: string[]): ILayoutNodeHandle;\n separator(): ILayoutNodeHandle;\n tabs(config: {\n id?: string;\n renderer?: string;\n tabs: ITabDefinitionInput[];\n rules?: IRule[];\n }): ILayoutNodeHandle;\n element(renderer: string, props?: Record<string, unknown>): ILayoutNodeHandle;\n object(\n fieldName: string,\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]\n ): ILayoutNodeHandle;\n object(\n fieldName: string,\n templateLayouts: Record<string, (layout: ILayoutBuilder) => ILayoutNodeBuilder[]>\n ): ILayoutNodeHandle;\n remove(target: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Form types\n// ---------------------------------------------------------------------------\n\nexport interface IFormError {\n path: string;\n label?: string;\n message: string;\n}\n\nexport interface IFormVM {\n layout: LayoutNodeVM[];\n errors: IFormError[];\n isDirty: boolean;\n isValid: boolean | null;\n}\n\n/**\n * Imperative form-level rule. Receives the live form and may return a flat\n * list of errors (sync or async). Errors are merged into `form.errors` and\n * surfaced on per-field validation when their `path` matches a known field.\n */\nexport type FormRuleFn = (\n form: IFormModel\n) => IFormError[] | undefined | void | Promise<IFormError[] | undefined | void>;\n\n/**\n * A form-level rule. Either a Zod schema (validated against `form.getData()`)\n * or an imperative function returning an error list.\n */\nexport type FormRule = z.ZodTypeAny | FormRuleFn;\n\nexport interface IFormModel<T = Record<string, any>> {\n field(name: string): IField;\n fields(\n factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder | undefined>\n ): void;\n layout(factory: (layout: ILayoutModifier) => (LayoutNode | IPositionedLayoutNode)[]): void;\n layout(nodeId: string): ILayoutNodeAccessHandle;\n /**\n * Replace the entire layout. Re-registers per-field inner layouts and\n * propagates ancestor rules. Use `layout()` (modifier form) for additive\n * changes.\n */\n setLayout(factory: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]): void;\n /**\n * Append a form-level validation rule. Runs after per-field validation.\n * Accepts a Zod schema (validated against `getData()`) or an imperative\n * function returning a list of errors.\n */\n addRule(rule: FormRule): void;\n getData(): T;\n setData(data: T): void;\n reset(): void;\n validate(): Promise<boolean>;\n submit<T = Record<string, unknown>>(): Promise<T | false>;\n evaluateRules(rules: IRule[] | undefined): { visible: boolean; disabled: boolean };\n focusField(name: string): void;\n readonly isDirty: boolean;\n readonly isValid: boolean | null;\n readonly submitted: boolean;\n readonly errors: IFormError[];\n readonly vm: IFormVM;\n getFieldBuilders(predicate?: (builder: IFieldBuilder) => boolean): IFieldBuilder[];\n resolveChildLayout(layout: LayoutNode[], children: Map<string, IField>): LayoutNodeVM[];\n readonly registry: IFieldBuilderRegistry;\n}\n\n// ---------------------------------------------------------------------------\n// FormModel namespace — groups all public types under one import\n// ---------------------------------------------------------------------------\n\nexport namespace FormModel {\n export type FieldConfig = IFieldConfig;\n export type ValueOption = IValueOption;\n export type FieldValidation = IFieldValidation;\n export type FieldVM = IFieldVM;\n export type Field = IField;\n export type ObjectField = IObjectField;\n export type ObjectFieldConfig = IObjectFieldConfig;\n export type BeforeChange = BeforeChangeCallback;\n export type AfterChange = AfterChangeCallback;\n export type AfterSetValue = AfterSetValueCallback;\n export type OnBlur = OnBlurCallback;\n export type CloneValue = CloneValueCallback;\n export type LayoutNodeBuilder = ILayoutNodeBuilder;\n export type RowBuilder = IRowBuilder;\n export type SeparatorBuilder = ISeparatorBuilder;\n export type TabBuilder = ITabBuilder;\n export type TabsBuilder = ITabsBuilder;\n export type ElementBuilder = IElementBuilder;\n export type ObjectBuilder = IObjectBuilder;\n export type RowNode = IRowNode;\n /** @deprecated Use RowBuilder instead */\n export type RowNodeHandle = IRowNodeHandle;\n export type RowNodeVM = IRowNodeVM;\n export type SeparatorNode = ISeparatorNode;\n export type SeparatorNodeVM = ISeparatorNodeVM;\n export type TabsNode = ITabsNode;\n export type TabDefinition = ITabDefinition;\n export type TabDefinitionInput = ITabDefinitionInput;\n export type TabsNodeVM = ITabsNodeVM;\n export type TabDefinitionVM = ITabDefinitionVM;\n export type TabIcon = Icon;\n export type ElementNode = IElementNode;\n export type ElementNodeVM = IElementNodeVM;\n export type ObjectNode = IObjectNode;\n export type ObjectFieldVM = IObjectFieldVM;\n export type ObjectFieldItemVM = IObjectFieldItemVM;\n export type TemplateBuilder = ITemplateBuilder;\n export type TemplateConfig = ITemplateConfig;\n export type TemplateIcon = ITemplateIcon;\n export type TemplateVM = ITemplateVM;\n export type ObjectFieldTemplatesAPI = IObjectFieldTemplates;\n export type FormError = IFormError;\n export type FormVM = IFormVM;\n export type Interface<T = Record<string, any>> = IFormModel<T>;\n export type Modifier = IFormModifier;\n export type LayoutModifier = ILayoutModifier;\n export type Rule = IRule;\n export type Action = RuleAction;\n export type RuleEvaluator = IRuleEvaluator;\n export type FormRuleFunction = FormRuleFn;\n export type FormRuleType = FormRule;\n export type RequiredWhen = (form: IFormModel) => boolean;\n export type Computed = ComputedFieldCallback;\n}\n\n// ---------------------------------------------------------------------------\n// FormModelFactory abstraction\n// ---------------------------------------------------------------------------\n\nexport interface IFormModelFactory {\n create<T = Record<string, any>>(config: IFormModelConfig): IFormModel<T>;\n}\n\nexport interface IFormModelConfig {\n fields: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>;\n layout?: (layout: ILayoutBuilder) => ILayoutNodeBuilder[];\n validateOnSubmit?: boolean;\n ruleEvaluators?: IRuleEvaluator[];\n}\n\nexport interface ILayoutBuilder {\n row(...fieldIds: string[]): IRowBuilder;\n separator(): ISeparatorBuilder;\n tabs(id?: string): ITabsBuilder;\n element(renderer: string, props?: Record<string, unknown>): IElementBuilder;\n /**\n * Reference an object field and register its inner layout.\n *\n * Non-templated: pass a single layout factory; the layout applies to the\n * single object or to every list item. Templated: pass a map of factories\n * keyed by template id; each entry applies when that template is active\n * (or for each list item with that template). Templates without an entry\n * fall back to default one-row-per-visible-child.\n */\n object(\n fieldName: string,\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]\n ): IObjectBuilder;\n object(\n fieldName: string,\n templateLayouts: Record<string, (layout: ILayoutBuilder) => ILayoutNodeBuilder[]>\n ): IObjectBuilder;\n}\n\nexport interface IFieldBuilder<\n TType extends string = string,\n TOptions extends boolean = false,\n TValue = unknown\n> {\n readonly __valueType?: TValue;\n label(text: string): this;\n help(text: string): this;\n description(text: string): this;\n note(text: string): this;\n placeholder(text: string): this;\n schema(zodSchema: z.ZodTypeAny): this;\n defaultValue(value: unknown): this;\n renderer<TName extends FieldRendererName<TType, TOptions>>(\n name: TName,\n ...args: undefined extends FieldRendererSettings<TName>\n ? [settings?: FieldRendererSettings<TName>]\n : FieldRendererSettings<TName> extends undefined\n ? []\n : [settings: FieldRendererSettings<TName>]\n ): this;\n hidden(): this;\n required(message?: string): this;\n /**\n * Conditional required check. Multiple `requiredWhen()` calls chain — the\n * first one to return `true` for the current form state makes the field\n * required. Built-in `.required()` (if set) is evaluated alongside.\n */\n requiredWhen(fn: (form: IFormModel) => boolean, message?: string): this;\n list(): this;\n disabled(value?: boolean): this;\n rules(rules: IRule[]): this;\n beforeChange(fn: BeforeChangeCallback): this;\n afterChange(fn: AfterChangeCallback): this;\n afterSetValue(fn: AfterSetValueCallback): this;\n onBlur(fn: OnBlurCallback): this;\n cloneValue(fn: CloneValueCallback): this;\n getTags(): string[];\n tags(tags: string[]): this;\n /**\n * Mark this field as a derived value computed from `fn(form)`. The field\n * stays editable; user edits are accepted but the computed value continues\n * to flow whenever a dependency changes. To make the user \"win\", use\n * `computedUntilDirty()` instead.\n */\n computed(fn: ComputedFieldCallback): this;\n /**\n * Same as `computed`, but the field switches to manual mode the first time\n * its value is changed via the UI. After that, `fn(form)` no longer\n * overrides user input.\n */\n computedUntilDirty(fn: ComputedFieldCallback): this;\n build(name: string): IFieldConfig;\n}\n\nexport interface IOptionsFieldBuilder<TType extends string, TValue = unknown> extends IFieldBuilder<\n TType,\n false,\n TValue\n> {\n options(\n opts:\n | IValueOption<OptionValueType<TType>>[]\n | ((form: IFormModel) => IValueOption<OptionValueType<TType>>[])\n ): IFieldBuilder<TType, true, TValue>;\n}\n\nexport interface IObjectFieldBuilder extends IFieldBuilder<\n \"object\",\n false,\n Record<string, unknown> | null\n> {\n fields(fn: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>): this;\n list(): this;\n listSchema(schema: z.ZodTypeAny): this;\n template(id: string, configure: (t: ITemplateBuilder) => void): this;\n}\n\nexport interface IFieldBuilderRegistry {}\n\n// ---------------------------------------------------------------------------\n// Field type plugin system\n// ---------------------------------------------------------------------------\n\nexport interface IFieldTypeFactory {\n readonly type: string;\n create(registry: IFieldBuilderRegistry): IFieldBuilder;\n}\n\nexport const FieldType = createAbstraction<IFieldTypeFactory>(\"FormModel/FieldType\");\n\nexport namespace FieldType {\n export type Interface = IFieldTypeFactory;\n export type FieldBuilder = IFieldBuilder;\n export type FieldBuilderRegistry = IFieldBuilderRegistry;\n}\n\nexport const FieldBuilderRegistry = createAbstraction<IFieldBuilderRegistry>(\n \"FormModel/FieldBuilderRegistry\"\n);\n\nexport namespace FieldBuilderRegistry {\n export type Interface = IFieldBuilderRegistry;\n}\n\nexport const FormModelFactory = createAbstraction<IFormModelFactory>(\"FormModelFactory\");\n\nexport namespace FormModelFactory {\n export type Interface = IFormModelFactory;\n export type Config = IFormModelConfig;\n export type LayoutBuilder = ILayoutBuilder;\n export type FieldBuilder = IFieldBuilder;\n export type OptionsFieldBuilder<TType extends string> = IOptionsFieldBuilder<TType>;\n export type ObjectFieldBuilder = IObjectFieldBuilder;\n export type FieldBuilderRegistry = IFieldBuilderRegistry;\n}\n\nexport const RuleEvaluator = createAbstraction<IRuleEvaluator>(\"FormModelRuleEvaluator\");\n\nexport namespace RuleEvaluator {\n export type Interface = IRuleEvaluator;\n export type Rule = IRule;\n export type Action = RuleAction;\n}\n"],"mappings":"AAAA,SAASA,iBAAiB,QAAQ,uBAAuB;;AAIzD;AACA;AACA;;AA4BA;AACA;AACA;;AA0CA;AACA;AACA;;AA+GA;AACA;AACA;;AA6DA;AACA;AACA;AACA;;AA2BA;AACA;AACA;;AAsFA;AACA;AACA;;AAQA;AACA;AACA;;AAUA;;AAgBA;AACA;AACA;AACA;AACA;;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;;AAyCA;AACA;AACA;;AAuCA;AACA;AACA;;AAYA;AACA;AACA;AACA;;AAOA;AACA;AACA;;AAYA;;AAGA;;AAGA;AACA;AACA;;AA2BA;AACA;AACA;;AAeA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AAuCA;AACA;AACA;AAAA,WAEiBC,SAAS;AAwD1B;AACA;AACA;;AAqHA;AACA;AACA;;AAOA,OAAO,MAAMC,SAAS,GAAGF,iBAAiB,CAAoB,qBAAqB,CAAC;AAQpF,OAAO,MAAMG,oBAAoB,GAAGH,iBAAiB,CACjD,gCACJ,CAAC;AAMD,OAAO,MAAMI,gBAAgB,GAAGJ,iBAAiB,CAAoB,kBAAkB,CAAC;AAYxF,OAAO,MAAMK,aAAa,GAAGL,iBAAiB,CAAiB,wBAAwB,CAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"features/formModel/abstractions.js","sources":["../../../src/features/formModel/abstractions.ts"],"sourcesContent":["import { createAbstraction } from \"@webiny/feature/admin\";\nimport type { z } from \"zod\";\nimport type { Icon } from \"~/components/IconPicker/types.js\";\n\n// ---------------------------------------------------------------------------\n// Renderer registry — augmented by each renderer via declare module\n// ---------------------------------------------------------------------------\n\nexport interface IFieldRendererRegistry {}\n\nexport type FieldRendererName<\n TType extends string = string,\n TOptions extends boolean = boolean\n> = string extends TType\n ? keyof IFieldRendererRegistry & string\n : {\n [K in keyof IFieldRendererRegistry]: TType extends IFieldRendererRegistry[K][\"fieldType\"]\n ? boolean extends TOptions\n ? K\n : TOptions extends true\n ? IFieldRendererRegistry[K] extends { options: true }\n ? K\n : never\n : IFieldRendererRegistry[K] extends { options: true }\n ? never\n : K\n : never;\n }[keyof IFieldRendererRegistry] &\n string;\n\nexport type FieldRendererSettings<TName extends string> = TName extends keyof IFieldRendererRegistry\n ? IFieldRendererRegistry[TName][\"settings\"]\n : Record<string, unknown> | undefined;\n\n// ---------------------------------------------------------------------------\n// Field types\n// ---------------------------------------------------------------------------\n\nexport interface IFieldConfig {\n name: string;\n type: string;\n label?: string;\n help?: string;\n description?: string;\n note?: string;\n placeholder?: string;\n defaultValue?: unknown;\n renderer?: string;\n rendererSettings?: Record<string, unknown>;\n isList?: boolean;\n hidden: boolean;\n required: boolean;\n requiredMessage?: string;\n disabled: boolean;\n schema?: z.ZodTypeAny;\n options?: IValueOption[] | ((form: IFormModel) => IValueOption[]);\n normalizeValue?: (value: unknown) => unknown;\n beforeChangeCallbacks?: BeforeChangeCallback[];\n afterChangeCallbacks?: AfterChangeCallback[];\n afterSetValueCallbacks?: AfterSetValueCallback[];\n onBlurCallbacks?: OnBlurCallback[];\n requiredWhenCallbacks?: RequiredWhenCallback[];\n hiddenWhenCallbacks?: HiddenWhenCallback[];\n computed?: ComputedFieldCallback;\n computedUntilDirty?: ComputedFieldCallback;\n tags?: string[];\n cloneValue?: CloneValueCallback;\n rules?: IRule[];\n}\n\nexport interface IRequiredWhenCallbackConfig {\n fn: (form: IFormModel) => boolean;\n message?: string;\n}\n\nexport type RequiredWhenCallback = IRequiredWhenCallbackConfig;\n\nexport type HiddenWhenCallback = (form: IFormModel) => boolean;\n\nexport type ComputedFieldCallback = (form: IFormModel) => unknown;\n\n// ---------------------------------------------------------------------------\n// Rules system\n// ---------------------------------------------------------------------------\n\nexport type RuleAction = \"hide\" | \"disable\";\n\nexport type RuleOperator =\n | \"eq\"\n | \"neq\"\n | \"isEmpty\"\n | \"isNotEmpty\"\n | \"isTruthy\"\n | \"isFalsy\"\n | \"matches\";\n\nexport interface IRule {\n type: string;\n target: string;\n operator: RuleOperator | (string & {});\n value: string | null;\n action: RuleAction;\n}\n\nexport interface IRuleEvaluator {\n canEvaluate(rule: IRule): boolean;\n evaluate(rule: IRule, form: IFormModel): boolean;\n}\n\nexport interface IValueOption<V extends string | number = string | number> {\n label: string;\n value: V;\n disabled?: boolean;\n}\n\nexport type OptionValueType<TType extends string> = TType extends \"number\" ? number : string;\n\nexport interface IFieldValidation {\n isValid: boolean | null;\n message?: string;\n}\n\nexport interface IFieldVM {\n name: string;\n type: string;\n label?: string;\n help?: string;\n description?: string;\n note?: string;\n placeholder?: string;\n value: unknown;\n validation: IFieldValidation;\n validating: boolean;\n required: boolean;\n visible: boolean;\n disabled: boolean;\n renderer?: string;\n rendererSettings?: Record<string, unknown>;\n isList?: boolean;\n options?: IValueOption[];\n onChange: (value: unknown) => void;\n onBlur: () => void;\n addItem: (value?: unknown) => void;\n removeItem: (index: number) => void;\n focusRequested: boolean;\n clearFocusRequest: () => void;\n}\n\nexport interface IObjectFieldVM extends IFieldVM {\n type: \"object\";\n isList: boolean;\n /** Child field VMs for non-list object fields. */\n fields: IFieldVM[];\n /**\n * Resolved layout for non-list object fields. For templated objects, resolves\n * against the active template's per-template layout (if registered via\n * `layout.object()`), otherwise defaults to one row per visible child.\n * For list-mode fields, see `items[].layout`.\n */\n layout: LayoutNodeVM[];\n /** Items for list-mode object fields. */\n items: IObjectFieldItemVM[];\n /** Append a new item. Templated lists require a template id. */\n addItem: (value?: unknown) => void;\n moveItem: (fromIndex: number, toIndex: number) => void;\n /** Duplicate a list item (including its `_templateId` when templated) and insert it after the source. */\n duplicateItem: (index: number) => void;\n /** True when the object has templates defined. */\n isTemplated: boolean;\n /** Templates visible in the picker (filtered by each template's reactive `visible`). */\n availableTemplates: ITemplateVM[];\n /** Currently active template id (single-object mode), or null if no template picked. */\n activeTemplateId: string | null;\n /** Switch to a different template. Discards values not present in the new template. */\n setTemplate: (templateId: string) => void;\n}\n\nexport interface IObjectFieldItemVM {\n key: string;\n fields: IFieldVM[];\n /**\n * Resolved layout for this item. For templated lists, resolves against the\n * item's template-specific layout (if registered via `layout.object()`),\n * otherwise defaults to one row per visible child.\n */\n layout: LayoutNodeVM[];\n remove: () => void;\n moveUp: () => void;\n moveDown: () => void;\n duplicate: () => void;\n /** The template id of this item, if the parent list is templated. */\n templateId?: string;\n}\n\n/**\n * VM exposed for each available template in the picker.\n */\nexport interface ITemplateIcon {\n type: string;\n name: string;\n}\n\nexport interface ITemplateVM {\n id: string;\n label: string;\n icon?: ITemplateIcon;\n}\n\nexport interface IField {\n readonly name: string;\n readonly type: string;\n readonly visible: boolean;\n readonly disabled: boolean;\n readonly vm: IFieldVM;\n readonly config: IFieldConfig;\n getValue<T = unknown>(): T;\n setValue(value: unknown): void;\n setValueSilent(value: unknown): void;\n setDisabled(value: boolean): void;\n setVisible(value: boolean): void;\n setForm(form: IFormModel, parentPath?: string): void;\n setAncestorRules(rules: IRule[]): void;\n setValidation(validation: IFieldValidation): void;\n resetValidation(): void;\n validate(options?: { force?: boolean }): Promise<boolean>;\n remove(): void;\n addBeforeChange(cb: BeforeChangeCallback): void;\n addAfterChange(cb: AfterChangeCallback): void;\n addAfterSetValue(cb: AfterSetValueCallback): void;\n addOnBlur(cb: OnBlurCallback): void;\n /**\n * Append a conditional required check. Multiple callbacks chain additively;\n * the first one returning `true` makes the field required for the current\n * form state. The built-in `.required()` flag (if set) always counts as a\n * truthy check and cannot be overridden.\n */\n addRequiredWhen(fn: (form: IFormModel) => boolean, message?: string): void;\n /**\n * Mark this field as a derived value computed from `fn(form)`. The field\n * stays editable (no auto-disable) and is excluded from `isDirty` while\n * still tracking the computed value. Validation continues to apply.\n */\n setComputed(fn: ComputedFieldCallback): void;\n /**\n * Same as `setComputed`, but the field switches to manual mode the first\n * time the user edits its value. After that, the computed callback no\n * longer overrides user input.\n */\n setComputedUntilDirty(fn: ComputedFieldCallback): void;\n blur(): void;\n as<T extends keyof FieldTypeMap>(type: T): FieldTypeMap[T];\n readonly qualifiedName: string;\n focus(): void;\n requestFocus(): void;\n clearFocusRequest(): void;\n}\n\n/**\n * Maps field type strings to their typed field interfaces.\n * Extended via module augmentation when new field types are registered.\n */\nexport interface ITypedField<V> extends IField {\n getValue<T = V>(): T;\n}\n\ntype InferFieldTypeMap = {\n [K in keyof IFieldBuilderRegistry]: ReturnType<\n IFieldBuilderRegistry[K]\n > extends IObjectFieldBuilder\n ? IObjectField\n : ReturnType<IFieldBuilderRegistry[K]> extends { readonly __valueType?: infer V }\n ? ITypedField<V>\n : IField;\n};\n\nexport type FieldTypeMap = { [K in keyof InferFieldTypeMap]: InferFieldTypeMap[K] };\n\nexport type FileValue = {\n id: string;\n name: string;\n size: number;\n mimeType: string;\n src: string;\n width: number | undefined;\n height: number | undefined;\n};\n\n// ---------------------------------------------------------------------------\n// Object / List field types\n// ---------------------------------------------------------------------------\n\nexport interface IObjectFieldConfig extends IFieldConfig {\n childBuilders: Record<string, IFieldBuilder>;\n isList: boolean;\n listSchema?: z.ZodTypeAny;\n templates?: ITemplateConfig[];\n}\n\nexport interface ITemplateBuilder {\n label(text: string): this;\n icon(icon: ITemplateIcon): this;\n fields(factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>): this;\n visible(predicate: (form: IFormModel) => boolean): this;\n}\n\nexport interface ITemplateConfig {\n id: string;\n label: string;\n icon?: ITemplateIcon;\n childBuilders: Record<string, IFieldBuilder>;\n visible?: (form: IFormModel) => boolean;\n}\n\nexport interface IObjectField extends ITypedField<Record<string, unknown> | null> {\n readonly isList: boolean;\n readonly children: Map<string, IField>;\n readonly items: IListItemField[];\n readonly isTemplated: boolean;\n readonly activeTemplateId: string | null;\n readonly availableTemplates: ITemplateVM[];\n /**\n * Add, replace, or remove children on this object field at runtime.\n * Mirrors `form.fields()` but scoped to this object's children. Existing\n * keys are replaced; new keys are appended; passing `undefined` removes.\n * Throws on templated objects — each template owns its own fields.\n */\n fields(\n factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder | undefined>\n ): void;\n /**\n * Register an inner layout used by the field's VM (`field.layout` for\n * single objects, `item.layout` for list items).\n *\n * Pass `LayoutNode[]` for non-templated objects (the layout applies to the\n * single object or every list item). Pass `Record<templateId, LayoutNode[]>`\n * for templated objects (each entry applies when that template is active\n * or for each list item with that template). Templates without an entry\n * fall back to default one-row-per-visible-child.\n */\n setInnerLayout(layout: LayoutNode[] | Record<string, LayoutNode[]>): void;\n /**\n * Append a new list item.\n * - Non-templated list: `addItem(data?)` — data hydrates the new item.\n * - Templated list: `addItem(templateId, data?)` — templateId picks the variant.\n */\n addItem(\n templateIdOrData?: string | Record<string, unknown>,\n data?: Record<string, unknown>\n ): void;\n removeItem(index: number): void;\n moveItem(fromIndex: number, toIndex: number): void;\n /** Duplicate a list item (including its `_templateId`) and insert after the source. */\n duplicateItem(index: number): void;\n setTemplate(templateId: string): void;\n /**\n * Runtime template management. Available on every object field but throws\n * when called on a non-templated field (`isTemplated === false`).\n */\n readonly templates: IObjectFieldTemplates;\n getInnerLayout(): LayoutNode[] | null;\n getData(): Record<string, unknown> | Record<string, unknown>[];\n}\n\nexport interface IObjectFieldTemplates {\n add(id: string, configure: (t: ITemplateBuilder) => void): void;\n remove(templateId: string): void;\n}\n\nexport interface IListItemField {\n readonly key: string;\n readonly children: Map<string, IField>;\n readonly templateId?: string;\n getData(): Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Callback types\n// ---------------------------------------------------------------------------\n\nexport type BeforeChangeCallback = (value: unknown, form: IFormModel) => unknown;\nexport type AfterChangeCallback = (value: unknown, form: IFormModel) => void;\nexport type AfterSetValueCallback = (value: unknown, form: IFormModel) => void;\nexport type OnBlurCallback = (value: unknown, form: IFormModel) => void;\nexport type CloneValueCallback = (value: unknown) => unknown;\n\n// ---------------------------------------------------------------------------\n// Layout types\n// ---------------------------------------------------------------------------\n\nexport type LayoutNode = IRowNode | ISeparatorNode | ITabsNode | IElementNode | IObjectNode;\n\nexport interface IRowNode {\n type: \"row\";\n fieldIds: string[];\n position?: LayoutPosition;\n}\n\n/** @deprecated Use IRowBuilder instead */\nexport type IRowNodeHandle = IRowBuilder;\n\nexport interface ISeparatorNode {\n type: \"separator\";\n}\n\nexport interface ITabDefinition {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n layout: LayoutNode[];\n rules?: IRule[];\n}\n\n/**\n * User-facing tab spec accepted by `layout.tabs(...)`. The layout is supplied\n * as a callback receiving the layout builder, mirroring `layout.object(...)`.\n * Resolved to `ITabDefinition` (with `layout: LayoutNode[]`) at build time.\n */\nexport interface ITabDefinitionInput {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[];\n rules?: IRule[];\n}\n\nexport interface ITabsNode {\n type: \"tabs\";\n id?: string;\n renderer?: string;\n tabs: ITabDefinition[];\n rules?: IRule[];\n}\n\nexport interface IElementNode {\n type: \"element\";\n id?: string;\n renderer: string;\n props?: Record<string, unknown>;\n}\n\n/**\n * Layout node that references an object field and registers an inner layout\n * on it. Resolved as a single-field row in the outer layout — the inner\n * layout is exposed on the field's VM (`field.layout` for single objects,\n * `item.layout` for list items).\n *\n * - For non-templated objects, `inner` is `LayoutNode[]` (one layout, applied\n * to the single object or every list item).\n * - For templated objects, `inner` is `Record<templateId, LayoutNode[]>` —\n * each entry is the layout used when that template is active (or for each\n * list item with that template).\n */\nexport interface IObjectNode {\n type: \"object\";\n fieldName: string;\n inner: LayoutNode[] | Record<string, LayoutNode[]>;\n}\n\n// ---------------------------------------------------------------------------\n// Layout node builders\n// ---------------------------------------------------------------------------\n\nexport interface ILayoutNodeBuilder {\n build(): LayoutNode;\n}\n\nexport interface IRowBuilder extends ILayoutNodeBuilder {\n before(target: string): IRowBuilder;\n after(target: string): IRowBuilder;\n build(): IRowNode;\n}\n\nexport interface ISeparatorBuilder extends ILayoutNodeBuilder {\n build(): ISeparatorNode;\n}\n\nexport interface ITabBuilder {\n label(text: string): this;\n description(text: string): this;\n icon(icon: Icon): this;\n layout(factory: (l: ILayoutBuilder) => ILayoutNodeBuilder[]): this;\n rules(rules: IRule[]): this;\n}\n\nexport interface ITabsBuilder extends ILayoutNodeBuilder {\n renderer(name: string): this;\n tab(id: string, configure: (tab: ITabBuilder) => void): this;\n before(target: string): this;\n after(target: string): this;\n rules(rules: IRule[]): this;\n build(): ITabsNode;\n}\n\nexport interface IElementBuilder extends ILayoutNodeBuilder {\n build(): IElementNode;\n}\n\nexport interface IObjectBuilder extends ILayoutNodeBuilder {\n build(): IObjectNode;\n}\n\n// ---------------------------------------------------------------------------\n// Layout VM types\n// ---------------------------------------------------------------------------\n\nexport type LayoutNodeVM = IRowNodeVM | ISeparatorNodeVM | ITabsNodeVM | IElementNodeVM;\n\nexport interface IRowNodeVM {\n type: \"row\";\n fields: IFieldVM[];\n}\n\nexport interface ISeparatorNodeVM {\n type: \"separator\";\n}\n\nexport interface ITabDefinitionVM {\n id: string;\n label: string;\n description?: string;\n icon?: Icon;\n hasErrors: boolean;\n disabled: boolean;\n layout: LayoutNodeVM[];\n}\n\nexport interface ITabsNodeVM {\n type: \"tabs\";\n id?: string;\n renderer?: string;\n tabs: ITabDefinitionVM[];\n disabled: boolean;\n activeTabId: string;\n setActiveTab: (id: string) => void;\n}\n\nexport interface IElementNodeVM {\n type: \"element\";\n renderer: string;\n props?: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Layout modifier types\n// ---------------------------------------------------------------------------\n\nexport type LayoutPosition =\n | { type: \"before\"; target: string }\n | { type: \"after\"; target: string }\n | { type: \"replace\"; target: string };\n\nexport interface IPositionedLayoutNode {\n node: LayoutNode;\n position?: LayoutPosition;\n}\n\n/**\n * Chainable handle returned by modifier layout.row().\n * Can be used as-is (appended) or positioned via .before()/.after()/.replace().\n */\nexport interface ILayoutNodeHandle extends IPositionedLayoutNode {\n before(target: string): IPositionedLayoutNode;\n after(target: string): IPositionedLayoutNode;\n replace(target: string): IPositionedLayoutNode;\n}\n\n// ---------------------------------------------------------------------------\n// Named layout node access types\n// ---------------------------------------------------------------------------\n\nexport interface LayoutNodeHandleMap {\n tabs: ITabsBuilder;\n element: IElementNode;\n object: IObjectNode;\n}\n\nexport interface ILayoutNodeAccessHandle {\n as<T extends keyof LayoutNodeHandleMap>(type: T): LayoutNodeHandleMap[T];\n}\n\n/** @deprecated Use ITabsBuilder instead */\nexport type ITabsHandle = ITabsBuilder;\n\n/** @deprecated Use ITabBuilder instead */\nexport type ITabHandle = ITabBuilder;\n\n// ---------------------------------------------------------------------------\n// Modifier types\n// ---------------------------------------------------------------------------\n\nexport interface IFormModifier {\n modify(form: IFormModel): void;\n}\n\nexport interface ILayoutModifier {\n row(...fieldIds: string[]): ILayoutNodeHandle;\n separator(): ILayoutNodeHandle;\n tabs(config: {\n id?: string;\n renderer?: string;\n tabs: ITabDefinitionInput[];\n rules?: IRule[];\n }): ILayoutNodeHandle;\n element(renderer: string, props?: Record<string, unknown>): ILayoutNodeHandle;\n object(\n fieldName: string,\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]\n ): ILayoutNodeHandle;\n object(\n fieldName: string,\n templateLayouts: Record<string, (layout: ILayoutBuilder) => ILayoutNodeBuilder[]>\n ): ILayoutNodeHandle;\n remove(target: string): void;\n}\n\n// ---------------------------------------------------------------------------\n// Form types\n// ---------------------------------------------------------------------------\n\nexport interface IFormError {\n path: string;\n label?: string;\n breadcrumb?: string[];\n message: string;\n}\n\nexport interface IFormVM {\n layout: LayoutNodeVM[];\n errors: IFormError[];\n isDirty: boolean;\n isValid: boolean | null;\n submitCount: number;\n focusField(path: string): void;\n getData(): Record<string, unknown>;\n setData(data: Record<string, unknown>): void;\n}\n\n/**\n * Imperative form-level rule. Receives the live form and may return a flat\n * list of errors (sync or async). Errors are merged into `form.errors` and\n * surfaced on per-field validation when their `path` matches a known field.\n */\nexport type FormRuleFn = (\n form: IFormModel\n) => IFormError[] | undefined | void | Promise<IFormError[] | undefined | void>;\n\n/**\n * A form-level rule. Either a Zod schema (validated against `form.getData()`)\n * or an imperative function returning an error list.\n */\nexport type FormRule = z.ZodTypeAny | FormRuleFn;\n\nexport interface IFormModel<T = Record<string, any>> {\n field(name: string): IField;\n fields(\n factory: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder | undefined>\n ): void;\n layout(factory: (layout: ILayoutModifier) => (LayoutNode | IPositionedLayoutNode)[]): void;\n layout(nodeId: string): ILayoutNodeAccessHandle;\n /**\n * Replace the entire layout. Re-registers per-field inner layouts and\n * propagates ancestor rules. Use `layout()` (modifier form) for additive\n * changes.\n */\n setLayout(factory: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]): void;\n /**\n * Append a form-level validation rule. Runs after per-field validation.\n * Accepts a Zod schema (validated against `getData()`) or an imperative\n * function returning a list of errors.\n */\n addRule(rule: FormRule): void;\n getData(): T;\n setData(data: T): void;\n reset(): void;\n validate(): Promise<boolean>;\n submit<T = Record<string, unknown>>(): Promise<T | false>;\n evaluateRules(rules: IRule[] | undefined): { visible: boolean; disabled: boolean };\n focusField(name: string): void;\n readonly isDirty: boolean;\n readonly isValid: boolean | null;\n readonly submitted: boolean;\n readonly submitCount: number;\n readonly errors: IFormError[];\n readonly vm: IFormVM;\n getFieldBuilders(predicate?: (builder: IFieldBuilder) => boolean): IFieldBuilder[];\n resolveChildLayout(layout: LayoutNode[], children: Map<string, IField>): LayoutNodeVM[];\n readonly registry: IFieldBuilderRegistry;\n}\n\n// ---------------------------------------------------------------------------\n// FormModel namespace — groups all public types under one import\n// ---------------------------------------------------------------------------\n\nexport namespace FormModel {\n export type FieldConfig = IFieldConfig;\n export type ValueOption = IValueOption;\n export type FieldValidation = IFieldValidation;\n export type FieldVM = IFieldVM;\n export type Field = IField;\n export type ObjectField = IObjectField;\n export type ObjectFieldConfig = IObjectFieldConfig;\n export type BeforeChange = BeforeChangeCallback;\n export type AfterChange = AfterChangeCallback;\n export type AfterSetValue = AfterSetValueCallback;\n export type OnBlur = OnBlurCallback;\n export type CloneValue = CloneValueCallback;\n export type LayoutNodeBuilder = ILayoutNodeBuilder;\n export type RowBuilder = IRowBuilder;\n export type SeparatorBuilder = ISeparatorBuilder;\n export type TabBuilder = ITabBuilder;\n export type TabsBuilder = ITabsBuilder;\n export type ElementBuilder = IElementBuilder;\n export type ObjectBuilder = IObjectBuilder;\n export type RowNode = IRowNode;\n /** @deprecated Use RowBuilder instead */\n export type RowNodeHandle = IRowNodeHandle;\n export type RowNodeVM = IRowNodeVM;\n export type SeparatorNode = ISeparatorNode;\n export type SeparatorNodeVM = ISeparatorNodeVM;\n export type TabsNode = ITabsNode;\n export type TabDefinition = ITabDefinition;\n export type TabDefinitionInput = ITabDefinitionInput;\n export type TabsNodeVM = ITabsNodeVM;\n export type TabDefinitionVM = ITabDefinitionVM;\n export type TabIcon = Icon;\n export type ElementNode = IElementNode;\n export type ElementNodeVM = IElementNodeVM;\n export type ObjectNode = IObjectNode;\n export type ObjectFieldVM = IObjectFieldVM;\n export type ObjectFieldItemVM = IObjectFieldItemVM;\n export type TemplateBuilder = ITemplateBuilder;\n export type TemplateConfig = ITemplateConfig;\n export type TemplateIcon = ITemplateIcon;\n export type TemplateVM = ITemplateVM;\n export type ObjectFieldTemplatesAPI = IObjectFieldTemplates;\n export type FormError = IFormError;\n export type FormVM = IFormVM;\n export type Interface<T = Record<string, any>> = IFormModel<T>;\n export type Modifier = IFormModifier;\n export type LayoutModifier = ILayoutModifier;\n export type Rule = IRule;\n export type Action = RuleAction;\n export type RuleEvaluator = IRuleEvaluator;\n export type FormRuleFunction = FormRuleFn;\n export type FormRuleType = FormRule;\n export type RequiredWhen = (form: IFormModel) => boolean;\n export type HiddenWhen = HiddenWhenCallback;\n export type Computed = ComputedFieldCallback;\n}\n\n// ---------------------------------------------------------------------------\n// FormModelFactory abstraction\n// ---------------------------------------------------------------------------\n\nexport interface IFormModelFactory {\n create<T = Record<string, any>>(config: IFormModelConfig): IFormModel<T>;\n}\n\nexport interface IFormModelConfig {\n fields: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>;\n layout?: (layout: ILayoutBuilder) => ILayoutNodeBuilder[];\n validateOnSubmit?: boolean;\n ruleEvaluators?: IRuleEvaluator[];\n}\n\nexport interface ILayoutBuilder {\n row(...fieldIds: string[]): IRowBuilder;\n separator(): ISeparatorBuilder;\n tabs(id?: string): ITabsBuilder;\n element(renderer: string, props?: Record<string, unknown>): IElementBuilder;\n /**\n * Reference an object field and register its inner layout.\n *\n * Non-templated: pass a single layout factory; the layout applies to the\n * single object or to every list item. Templated: pass a map of factories\n * keyed by template id; each entry applies when that template is active\n * (or for each list item with that template). Templates without an entry\n * fall back to default one-row-per-visible-child.\n */\n object(\n fieldName: string,\n layout: (layout: ILayoutBuilder) => ILayoutNodeBuilder[]\n ): IObjectBuilder;\n object(\n fieldName: string,\n templateLayouts: Record<string, (layout: ILayoutBuilder) => ILayoutNodeBuilder[]>\n ): IObjectBuilder;\n}\n\nexport interface IFieldBuilder<\n TType extends string = string,\n TOptions extends boolean = false,\n TValue = unknown\n> {\n readonly __valueType?: TValue;\n label(text: string): this;\n help(text: string): this;\n description(text: string): this;\n note(text: string): this;\n placeholder(text: string): this;\n schema(zodSchema: z.ZodTypeAny): this;\n defaultValue(value: unknown): this;\n renderer<TName extends FieldRendererName<TType, TOptions>>(\n name: TName,\n ...args: undefined extends FieldRendererSettings<TName>\n ? [settings?: FieldRendererSettings<TName>]\n : FieldRendererSettings<TName> extends undefined\n ? []\n : [settings: FieldRendererSettings<TName>]\n ): this;\n hidden(): this;\n hiddenWhen(fn: (form: IFormModel) => boolean): this;\n required(message?: string): this;\n /**\n * Conditional required check. Multiple `requiredWhen()` calls chain — the\n * first one to return `true` for the current form state makes the field\n * required. Built-in `.required()` (if set) is evaluated alongside.\n */\n requiredWhen(fn: (form: IFormModel) => boolean, message?: string): this;\n list(): this;\n disabled(value?: boolean): this;\n rules(rules: IRule[]): this;\n beforeChange(fn: BeforeChangeCallback): this;\n afterChange(fn: AfterChangeCallback): this;\n afterSetValue(fn: AfterSetValueCallback): this;\n onBlur(fn: OnBlurCallback): this;\n cloneValue(fn: CloneValueCallback): this;\n getTags(): string[];\n tags(tags: string[]): this;\n /**\n * Mark this field as a derived value computed from `fn(form)`. The field\n * stays editable; user edits are accepted but the computed value continues\n * to flow whenever a dependency changes. To make the user \"win\", use\n * `computedUntilDirty()` instead.\n */\n computed(fn: ComputedFieldCallback): this;\n /**\n * Same as `computed`, but the field switches to manual mode the first time\n * its value is changed via the UI. After that, `fn(form)` no longer\n * overrides user input.\n */\n computedUntilDirty(fn: ComputedFieldCallback): this;\n build(name: string): IFieldConfig;\n}\n\nexport interface IOptionsFieldBuilder<TType extends string, TValue = unknown> extends IFieldBuilder<\n TType,\n false,\n TValue\n> {\n options(\n opts:\n | IValueOption<OptionValueType<TType>>[]\n | ((form: IFormModel) => IValueOption<OptionValueType<TType>>[])\n ): IFieldBuilder<TType, true, TValue>;\n}\n\nexport interface IObjectFieldBuilder extends IFieldBuilder<\n \"object\",\n false,\n Record<string, unknown> | null\n> {\n fields(fn: (registry: IFieldBuilderRegistry) => Record<string, IFieldBuilder>): this;\n list(): this;\n listSchema(schema: z.ZodTypeAny): this;\n template(id: string, configure: (t: ITemplateBuilder) => void): this;\n}\n\nexport interface IFieldBuilderRegistry {}\n\n// ---------------------------------------------------------------------------\n// Field type plugin system\n// ---------------------------------------------------------------------------\n\nexport interface IFieldTypeFactory {\n readonly type: string;\n create(registry: IFieldBuilderRegistry): IFieldBuilder;\n}\n\nexport const FieldType = createAbstraction<IFieldTypeFactory>(\"FormModel/FieldType\");\n\nexport namespace FieldType {\n export type Interface = IFieldTypeFactory;\n export type FieldBuilder = IFieldBuilder;\n export type FieldBuilderRegistry = IFieldBuilderRegistry;\n}\n\nexport const FieldBuilderRegistry = createAbstraction<IFieldBuilderRegistry>(\n \"FormModel/FieldBuilderRegistry\"\n);\n\nexport namespace FieldBuilderRegistry {\n export type Interface = IFieldBuilderRegistry;\n}\n\nexport const FormModelFactory = createAbstraction<IFormModelFactory>(\"FormModelFactory\");\n\nexport namespace FormModelFactory {\n export type Interface = IFormModelFactory;\n export type Config = IFormModelConfig;\n export type LayoutBuilder = ILayoutBuilder;\n export type FieldBuilder = IFieldBuilder;\n export type OptionsFieldBuilder<TType extends string> = IOptionsFieldBuilder<TType>;\n export type ObjectFieldBuilder = IObjectFieldBuilder;\n export type FieldBuilderRegistry = IFieldBuilderRegistry;\n}\n\nexport const RuleEvaluator = createAbstraction<IRuleEvaluator>(\"FormModelRuleEvaluator\");\n\nexport namespace RuleEvaluator {\n export type Interface = IRuleEvaluator;\n export type Rule = IRule;\n export type Action = RuleAction;\n}\n"],"names":["FieldType","createAbstraction","FieldBuilderRegistry","FormModelFactory","RuleEvaluator"],"mappings":";AAi3BO,MAAMA,YAAYC,kBAAqC;AAQvD,MAAMC,uBAAuBD,kBAChC;AAOG,MAAME,mBAAmBF,kBAAqC;AAY9D,MAAMG,gBAAgBH,kBAAkC"}
|
|
@@ -1,15 +1,38 @@
|
|
|
1
|
+
import react, { useEffect, useRef } from "react";
|
|
1
2
|
import { observer } from "mobx-react-lite";
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
const ScrollOnFocus = observer(({ field, children })=>{
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
useEffect(()=>{
|
|
6
|
+
if (field.focusRequested && ref.current) setTimeout(()=>{
|
|
7
|
+
ref.current?.scrollIntoView({
|
|
8
|
+
behavior: "smooth",
|
|
9
|
+
block: "center"
|
|
10
|
+
});
|
|
11
|
+
}, 150);
|
|
12
|
+
field.clearFocusRequest();
|
|
13
|
+
}, [
|
|
14
|
+
field.focusRequested
|
|
15
|
+
]);
|
|
16
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
17
|
+
ref: ref
|
|
18
|
+
}, children);
|
|
19
|
+
});
|
|
20
|
+
function createFieldRenderer(render) {
|
|
21
|
+
const Inner = observer(render);
|
|
22
|
+
const Wrapper = observer(({ field })=>/*#__PURE__*/ react.createElement(ScrollOnFocus, {
|
|
23
|
+
field: field
|
|
24
|
+
}, /*#__PURE__*/ react.createElement(Inner, {
|
|
25
|
+
field: field
|
|
26
|
+
})));
|
|
27
|
+
return Wrapper;
|
|
4
28
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
return
|
|
11
|
-
};
|
|
12
|
-
return observer(Wrapped);
|
|
29
|
+
function createObjectFieldRenderer(render) {
|
|
30
|
+
const Wrapped = (props)=>{
|
|
31
|
+
if ("object" !== props.field.type) return null;
|
|
32
|
+
return render(props);
|
|
33
|
+
};
|
|
34
|
+
return observer(Wrapped);
|
|
13
35
|
}
|
|
36
|
+
export { createFieldRenderer, createObjectFieldRenderer };
|
|
14
37
|
|
|
15
38
|
//# sourceMappingURL=createFieldRenderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"features/formModel/createFieldRenderer.js","sources":["../../../src/features/formModel/createFieldRenderer.tsx"],"sourcesContent":["import React, { useEffect, useRef } from \"react\";\nimport { observer } from \"mobx-react-lite\";\nimport type { IFieldVM, IObjectFieldVM, FieldRendererSettings } from \"./abstractions.js\";\n\ntype RendererField<TName extends string> = IFieldVM & {\n rendererSettings: FieldRendererSettings<TName>;\n};\n\ntype ObjectRendererField<TName extends string> = IObjectFieldVM & {\n rendererSettings: FieldRendererSettings<TName>;\n};\n\ntype FieldRendererFn<TName extends string> = (props: {\n field: RendererField<TName>;\n}) => React.ReactNode;\n\nconst ScrollOnFocus = observer(\n ({ field, children }: { field: IFieldVM; children: React.ReactNode }) => {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (field.focusRequested && ref.current) {\n setTimeout(() => {\n ref.current?.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }, 150);\n }\n field.clearFocusRequest();\n }, [field.focusRequested]);\n\n return <div ref={ref}>{children}</div>;\n }\n);\n\nexport function createFieldRenderer<TName extends string = string>(\n render: FieldRendererFn<TName>\n): React.ComponentType<{ field: IFieldVM }> {\n const Inner = observer(render as FieldRendererFn<string>) as unknown as React.ComponentType<{\n field: IFieldVM;\n }>;\n\n const Wrapper = observer(({ field }: { field: IFieldVM }) => (\n <ScrollOnFocus field={field}>\n <Inner field={field} />\n </ScrollOnFocus>\n ));\n\n return Wrapper as unknown as React.ComponentType<{ field: IFieldVM }>;\n}\n\nexport function createObjectFieldRenderer<TName extends string = string>(\n render: (props: { field: ObjectRendererField<TName> }) => React.ReactNode\n): React.ComponentType<{ field: IFieldVM }> {\n const Wrapped = (props: { field: IFieldVM }) => {\n if (props.field.type !== \"object\") {\n return null;\n }\n return (render as (p: { field: IFieldVM }) => React.ReactNode)(props);\n };\n return observer(Wrapped) as unknown as React.ComponentType<{ field: IFieldVM }>;\n}\n"],"names":["ScrollOnFocus","observer","field","children","ref","useRef","useEffect","setTimeout","createFieldRenderer","render","Inner","Wrapper","createObjectFieldRenderer","Wrapped","props"],"mappings":";;AAgBA,MAAMA,gBAAgBC,SAClB,CAAC,EAAEC,KAAK,EAAEC,QAAQ,EAAkD;IAChE,MAAMC,MAAMC,OAAuB;IAEnCC,UAAU;QACN,IAAIJ,MAAM,cAAc,IAAIE,IAAI,OAAO,EACnCG,WAAW;YACPH,IAAI,OAAO,EAAE,eAAe;gBAAE,UAAU;gBAAU,OAAO;YAAS;QACtE,GAAG;QAEPF,MAAM,iBAAiB;IAC3B,GAAG;QAACA,MAAM,cAAc;KAAC;IAEzB,OAAO,WAAP,GAAO,oBAAC;QAAI,KAAKE;OAAMD;AAC3B;AAGG,SAASK,oBACZC,MAA8B;IAE9B,MAAMC,QAAQT,SAASQ;IAIvB,MAAME,UAAUV,SAAS,CAAC,EAAEC,KAAK,EAAuB,iBACpD,oBAACF,eAAaA;YAAC,OAAOE;yBAClB,oBAACQ,OAAAA;YAAM,OAAOR;;IAItB,OAAOS;AACX;AAEO,SAASC,0BACZH,MAAyE;IAEzE,MAAMI,UAAU,CAACC;QACb,IAAIA,AAAqB,aAArBA,MAAM,KAAK,CAAC,IAAI,EAChB,OAAO;QAEX,OAAQL,OAAuDK;IACnE;IACA,OAAOb,SAASY;AACpB"}
|