@cosmicdrift/kumiko-renderer 0.374.0 → 0.377.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/app/action-form-support.d.ts +9 -2
- package/dist/app/action-form-support.js +24 -2
- package/dist/app/client-actions.d.ts +2 -2
- package/dist/app/column-renderers.js +1 -1
- package/dist/app/config-edit-shim.js +1 -1
- package/dist/app/content-preview.js +1 -6
- package/dist/app/custom-screens.js +1 -1
- package/dist/app/dashboard-body.d.ts +1 -1
- package/dist/app/entity-list-expanded-row.d.ts +1 -1
- package/dist/app/form-schema.d.ts +1 -1
- package/dist/app/form-schema.js +2 -2
- package/dist/app/kumiko-screen.d.ts +1 -1
- package/dist/app/kumiko-screen.js +7 -6
- package/dist/app/list-empty-content.d.ts +1 -1
- package/dist/app/list-facets.d.ts +1 -1
- package/dist/app/nav.js +2 -2
- package/dist/app/query-state-banners.d.ts +1 -1
- package/dist/app/reference-link.d.ts +1 -1
- package/dist/app/row-actions.d.ts +1 -1
- package/dist/app/secret-mint-body.d.ts +1 -1
- package/dist/app/secrets-edit-body.d.ts +1 -1
- package/dist/app/use-record-actions.d.ts +1 -1
- package/dist/app/write-failed-error.d.ts +1 -1
- package/dist/components/availability-options-select.d.ts +1 -1
- package/dist/components/embedded-list-field.d.ts +1 -1
- package/dist/components/embedded-list-field.js +1 -1
- package/dist/components/file-list-field.d.ts +1 -1
- package/dist/components/grid-cell-for-field.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.d.ts +1 -1
- package/dist/components/multi-select-checkboxes.js +1 -1
- package/dist/components/query-options-select.d.ts +1 -1
- package/dist/components/related-list-section.d.ts +1 -1
- package/dist/components/render-edit-logic.d.ts +1 -1
- package/dist/components/render-edit-types.d.ts +2 -2
- package/dist/components/render-edit.d.ts +1 -1
- package/dist/components/render-edit.js +4 -2
- package/dist/components/render-field.d.ts +1 -1
- package/dist/components/render-field.js +4 -1
- package/dist/components/render-list.d.ts +1 -1
- package/dist/components/render-list.js +20 -4
- package/dist/components/write-form-section.d.ts +1 -1
- package/dist/components/write-form-section.js +1 -1
- package/dist/context/dispatcher-context.d.ts +1 -1
- package/dist/format-when.js +1 -1
- package/dist/headless/apex/css.d.ts +3 -0
- package/dist/headless/apex/css.js +298 -0
- package/dist/headless/apex/index.d.ts +236 -0
- package/dist/headless/apex/index.js +377 -0
- package/dist/headless/apex/lightbox.d.ts +4 -0
- package/dist/headless/apex/lightbox.js +81 -0
- package/dist/headless/contracts/asset.d.ts +15 -0
- package/dist/headless/contracts/asset.js +17 -0
- package/dist/headless/contracts/index.d.ts +3 -0
- package/dist/headless/contracts/index.js +1 -0
- package/dist/headless/contracts/locale.d.ts +7 -0
- package/dist/headless/contracts/locale.js +11 -0
- package/dist/headless/contracts/primitives.d.ts +93 -0
- package/dist/headless/contracts/primitives.js +21 -0
- package/dist/headless/dispatcher/index.d.ts +2 -0
- package/dist/headless/dispatcher/index.js +1 -0
- package/dist/headless/dispatcher/types.d.ts +86 -0
- package/dist/headless/dispatcher/types.js +34 -0
- package/dist/headless/form/form-controller.d.ts +2 -0
- package/dist/headless/form/form-controller.js +409 -0
- package/dist/headless/form/index.d.ts +3 -0
- package/dist/headless/form/index.js +2 -0
- package/dist/headless/form/types.d.ts +76 -0
- package/dist/headless/form/types.js +1 -0
- package/dist/headless/form/zod-bridge.d.ts +10 -0
- package/dist/headless/form/zod-bridge.js +103 -0
- package/dist/headless/format/document-values.d.ts +12 -0
- package/dist/headless/format/document-values.js +70 -0
- package/dist/headless/format/escape.d.ts +5 -0
- package/dist/headless/format/escape.js +75 -0
- package/dist/headless/format/html-template.d.ts +9 -0
- package/dist/headless/format/html-template.js +39 -0
- package/dist/headless/format/index.d.ts +12 -0
- package/dist/headless/format/index.js +237 -0
- package/dist/headless/format/money.d.ts +3 -0
- package/dist/headless/format/money.js +39 -0
- package/dist/headless/index.d.ts +14 -0
- package/dist/headless/index.js +9 -0
- package/dist/headless/locale-routing/index.d.ts +41 -0
- package/dist/headless/locale-routing/index.js +145 -0
- package/dist/headless/nav/index.d.ts +2 -0
- package/dist/headless/nav/index.js +1 -0
- package/dist/headless/nav/resolve.d.ts +2 -0
- package/dist/headless/nav/resolve.js +71 -0
- package/dist/headless/nav/types.d.ts +26 -0
- package/dist/headless/nav/types.js +1 -0
- package/dist/headless/store/create-store.d.ts +2 -0
- package/dist/headless/store/create-store.js +43 -0
- package/dist/headless/store/equality.d.ts +1 -0
- package/dist/headless/store/equality.js +34 -0
- package/dist/headless/store/index.d.ts +3 -0
- package/dist/headless/store/index.js +2 -0
- package/dist/headless/store/types.d.ts +7 -0
- package/dist/headless/store/types.js +10 -0
- package/dist/headless/view-model/edit.d.ts +18 -0
- package/dist/headless/view-model/edit.js +501 -0
- package/dist/headless/view-model/embedded-list.d.ts +27 -0
- package/dist/headless/view-model/embedded-list.js +63 -0
- package/dist/headless/view-model/index.d.ts +7 -0
- package/dist/headless/view-model/index.js +3 -0
- package/dist/headless/view-model/list-file-display.d.ts +3 -0
- package/dist/headless/view-model/list-file-display.js +27 -0
- package/dist/headless/view-model/list.d.ts +16 -0
- package/dist/headless/view-model/list.js +229 -0
- package/dist/headless/view-model/types.d.ts +382 -0
- package/dist/headless/view-model/types.js +1 -0
- package/dist/hooks/use-ai-text.d.ts +1 -1
- package/dist/hooks/use-form.d.ts +1 -1
- package/dist/hooks/use-form.js +1 -1
- package/dist/hooks/use-mutation.d.ts +1 -1
- package/dist/hooks/use-query.d.ts +1 -1
- package/dist/hooks/use-store.d.ts +1 -1
- package/dist/hooks/use-store.js +7 -7
- package/dist/hooks/use-stream-handler.d.ts +1 -1
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/index.js +4 -4
- package/dist/live/csrf.d.ts +2 -0
- package/dist/live/csrf.js +60 -0
- package/dist/live/dispatcher-live.d.ts +7 -0
- package/dist/live/dispatcher-live.js +286 -0
- package/dist/live/envelopes.d.ts +101 -0
- package/dist/live/envelopes.js +35 -0
- package/dist/live/error-mapping.d.ts +16 -0
- package/dist/live/error-mapping.js +82 -0
- package/dist/live/index.d.ts +7 -0
- package/dist/live/index.js +5 -0
- package/dist/live/locale.d.ts +2 -0
- package/dist/live/locale.js +25 -0
- package/dist/live/sse-stream.d.ts +14 -0
- package/dist/live/sse-stream.js +128 -0
- package/dist/primitives.d.ts +35 -36
- package/dist/primitives.js +1 -1
- package/dist/session/session-ended.d.ts +1 -1
- package/dist/tokens.d.ts +3 -4
- package/dist/tokens.js +4 -5
- package/dist/web/app/app-schema-boot.d.ts +19 -0
- package/dist/web/app/app-schema-boot.js +124 -0
- package/dist/web/app/browser-locale.d.ts +22 -0
- package/dist/web/app/browser-locale.js +78 -0
- package/dist/web/app/client-plugin.d.ts +106 -0
- package/dist/web/app/client-plugin.js +12 -0
- package/dist/web/app/create-app.d.ts +104 -0
- package/dist/web/app/create-app.js +498 -0
- package/dist/web/app/create-public-surface.d.ts +36 -0
- package/dist/web/app/create-public-surface.js +40 -0
- package/dist/web/app/dashboard-body.d.ts +3 -0
- package/dist/web/app/dashboard-body.js +865 -0
- package/dist/web/app/dashboard-refresh.d.ts +6 -0
- package/dist/web/app/dashboard-refresh.js +15 -0
- package/dist/web/app/document-lang-sync.d.ts +4 -0
- package/dist/web/app/document-lang-sync.js +27 -0
- package/dist/web/app/draft-storage.d.ts +11 -0
- package/dist/web/app/draft-storage.js +53 -0
- package/dist/web/app/nav-providers-context.d.ts +13 -0
- package/dist/web/app/nav-providers-context.js +18 -0
- package/dist/web/app/nav.d.ts +40 -0
- package/dist/web/app/nav.js +231 -0
- package/dist/web/app/plain-content-editor.d.ts +3 -0
- package/dist/web/app/plain-content-editor.js +30 -0
- package/dist/web/app/relative-time.d.ts +10 -0
- package/dist/web/app/relative-time.js +56 -0
- package/dist/web/app/resolvers-context.d.ts +12 -0
- package/dist/web/app/resolvers-context.js +10 -0
- package/dist/web/app/rich-content-editor.d.ts +3 -0
- package/dist/web/app/rich-content-editor.js +15 -0
- package/dist/web/app/root-error-fallback.d.ts +2 -0
- package/dist/web/app/root-error-fallback.js +21 -0
- package/dist/web/app/screen-error-fallback.d.ts +6 -0
- package/dist/web/app/screen-error-fallback.js +17 -0
- package/dist/web/app/tiptap-editor.d.ts +3 -0
- package/dist/web/app/tiptap-editor.js +120 -0
- package/dist/web/app/toast-action-notifier.d.ts +5 -0
- package/dist/web/app/toast-action-notifier.js +17 -0
- package/dist/web/components/config-cascade.d.ts +13 -0
- package/dist/web/components/config-cascade.js +155 -0
- package/dist/web/components/config-source-badge.d.ts +6 -0
- package/dist/web/components/config-source-badge.js +55 -0
- package/dist/web/default-color-scheme.d.ts +2 -0
- package/dist/web/default-color-scheme.js +3 -0
- package/dist/web/icons.d.ts +94 -0
- package/dist/web/icons.js +100 -0
- package/dist/web/index.d.ts +78 -0
- package/dist/web/index.js +53 -0
- package/dist/web/layout/app-layout.d.ts +21 -0
- package/dist/web/layout/app-layout.js +8 -0
- package/dist/web/layout/avatar.d.ts +12 -0
- package/dist/web/layout/avatar.js +63 -0
- package/dist/web/layout/default-app-shell.d.ts +41 -0
- package/dist/web/layout/default-app-shell.js +16 -0
- package/dist/web/layout/editor-panel.d.ts +10 -0
- package/dist/web/layout/editor-panel.js +29 -0
- package/dist/web/layout/fill-classes.d.ts +9 -0
- package/dist/web/layout/fill-classes.js +15 -0
- package/dist/web/layout/filter-app-schema-navs.d.ts +7 -0
- package/dist/web/layout/filter-app-schema-navs.js +68 -0
- package/dist/web/layout/header-action-group.d.ts +6 -0
- package/dist/web/layout/header-action-group.js +8 -0
- package/dist/web/layout/header-overflow-menu.d.ts +4 -0
- package/dist/web/layout/header-overflow-menu.js +8 -0
- package/dist/web/layout/language-menu-items.d.ts +8 -0
- package/dist/web/layout/language-menu-items.js +16 -0
- package/dist/web/layout/language-switcher.d.ts +25 -0
- package/dist/web/layout/language-switcher.js +46 -0
- package/dist/web/layout/nav-tree.d.ts +19 -0
- package/dist/web/layout/nav-tree.js +536 -0
- package/dist/web/layout/page-header-slot.d.ts +25 -0
- package/dist/web/layout/page-header-slot.js +50 -0
- package/dist/web/layout/profile-menu.d.ts +13 -0
- package/dist/web/layout/profile-menu.js +6 -0
- package/dist/web/layout/shell-breadcrumb.d.ts +11 -0
- package/dist/web/layout/shell-breadcrumb.js +34 -0
- package/dist/web/layout/shell-header.d.ts +12 -0
- package/dist/web/layout/shell-header.js +159 -0
- package/dist/web/layout/sidebar-brand.d.ts +15 -0
- package/dist/web/layout/sidebar-brand.js +9 -0
- package/dist/web/layout/sidebar-panel.d.ts +41 -0
- package/dist/web/layout/sidebar-panel.js +107 -0
- package/dist/web/layout/sidebar-user.d.ts +8 -0
- package/dist/web/layout/sidebar-user.js +17 -0
- package/dist/web/layout/sidebar.d.ts +17 -0
- package/dist/web/layout/sidebar.js +11 -0
- package/dist/web/layout/target-resolver-stub.d.ts +13 -0
- package/dist/web/layout/target-resolver-stub.js +61 -0
- package/dist/web/layout/target-url.d.ts +12 -0
- package/dist/web/layout/target-url.js +77 -0
- package/dist/web/layout/theme-label.d.ts +15 -0
- package/dist/web/layout/theme-label.js +35 -0
- package/dist/web/layout/theme-menu-item.d.ts +12 -0
- package/dist/web/layout/theme-menu-item.js +16 -0
- package/dist/web/layout/theme-toggle.d.ts +17 -0
- package/dist/web/layout/theme-toggle.js +22 -0
- package/dist/web/layout/topbar.d.ts +8 -0
- package/dist/web/layout/topbar.js +4 -0
- package/dist/web/layout/workspace-shell.d.ts +63 -0
- package/dist/web/layout/workspace-shell.js +220 -0
- package/dist/web/layout/workspace-switcher.d.ts +15 -0
- package/dist/web/layout/workspace-switcher.js +36 -0
- package/dist/web/lib/accept-attr.d.ts +1 -0
- package/dist/web/lib/accept-attr.js +6 -0
- package/dist/web/lib/clamp.d.ts +1 -0
- package/dist/web/lib/clamp.js +3 -0
- package/dist/web/lib/cn.d.ts +6 -0
- package/dist/web/lib/cn.js +9 -0
- package/dist/web/lib/download.d.ts +2 -0
- package/dist/web/lib/download.js +24 -0
- package/dist/web/lib/file-ref-download.d.ts +15 -0
- package/dist/web/lib/file-ref-download.js +62 -0
- package/dist/web/lib/file-upload-form-data.d.ts +7 -0
- package/dist/web/lib/file-upload-form-data.js +11 -0
- package/dist/web/lib/resize-image.d.ts +1 -0
- package/dist/web/lib/resize-image.js +66 -0
- package/dist/web/lib/upload-file-ref.d.ts +9 -0
- package/dist/web/lib/upload-file-ref.js +29 -0
- package/dist/web/primitives/action-menu.d.ts +34 -0
- package/dist/web/primitives/action-menu.js +30 -0
- package/dist/web/primitives/calendar-popover.d.ts +13 -0
- package/dist/web/primitives/calendar-popover.js +76 -0
- package/dist/web/primitives/combobox.d.ts +56 -0
- package/dist/web/primitives/combobox.js +127 -0
- package/dist/web/primitives/date-field.d.ts +18 -0
- package/dist/web/primitives/date-field.js +74 -0
- package/dist/web/primitives/date-input.d.ts +1 -0
- package/dist/web/primitives/date-input.js +5 -0
- package/dist/web/primitives/date-parse.d.ts +11 -0
- package/dist/web/primitives/date-parse.js +159 -0
- package/dist/web/primitives/dialog.d.ts +3 -0
- package/dist/web/primitives/dialog.js +42 -0
- package/dist/web/primitives/drawer.d.ts +3 -0
- package/dist/web/primitives/drawer.js +17 -0
- package/dist/web/primitives/dropdown-menu.d.ts +15 -0
- package/dist/web/primitives/dropdown-menu.js +56 -0
- package/dist/web/primitives/embedded-list-input.d.ts +9 -0
- package/dist/web/primitives/embedded-list-input.js +382 -0
- package/dist/web/primitives/file-thumbnail.d.ts +25 -0
- package/dist/web/primitives/file-thumbnail.js +90 -0
- package/dist/web/primitives/file-upload.d.ts +21 -0
- package/dist/web/primitives/file-upload.js +56 -0
- package/dist/web/primitives/index.d.ts +34 -0
- package/dist/web/primitives/index.js +2021 -0
- package/dist/web/primitives/json-view.d.ts +7 -0
- package/dist/web/primitives/json-view.js +84 -0
- package/dist/web/primitives/layout.d.ts +27 -0
- package/dist/web/primitives/layout.js +30 -0
- package/dist/web/primitives/lightbox.d.ts +3 -0
- package/dist/web/primitives/lightbox.js +36 -0
- package/dist/web/primitives/locale-number.d.ts +2 -0
- package/dist/web/primitives/locale-number.js +54 -0
- package/dist/web/primitives/located-timestamp-input.d.ts +22 -0
- package/dist/web/primitives/located-timestamp-input.js +22 -0
- package/dist/web/primitives/metric.d.ts +5 -0
- package/dist/web/primitives/metric.js +18 -0
- package/dist/web/primitives/modal-shell.d.ts +17 -0
- package/dist/web/primitives/modal-shell.js +9 -0
- package/dist/web/primitives/modal.d.ts +3 -0
- package/dist/web/primitives/modal.js +13 -0
- package/dist/web/primitives/money-input.d.ts +18 -0
- package/dist/web/primitives/money-input.js +122 -0
- package/dist/web/primitives/narrow-pinned-footer.d.ts +12 -0
- package/dist/web/primitives/narrow-pinned-footer.js +153 -0
- package/dist/web/primitives/number-input.d.ts +18 -0
- package/dist/web/primitives/number-input.js +53 -0
- package/dist/web/primitives/option-groups.d.ts +11 -0
- package/dist/web/primitives/option-groups.js +27 -0
- package/dist/web/primitives/page-header.d.ts +3 -0
- package/dist/web/primitives/page-header.js +52 -0
- package/dist/web/primitives/promo-panel.d.ts +3 -0
- package/dist/web/primitives/promo-panel.js +11 -0
- package/dist/web/primitives/segmented-select.d.ts +21 -0
- package/dist/web/primitives/segmented-select.js +62 -0
- package/dist/web/primitives/share-actions.d.ts +4 -0
- package/dist/web/primitives/share-actions.js +56 -0
- package/dist/web/primitives/status-badge.d.ts +3 -0
- package/dist/web/primitives/status-badge.js +5 -0
- package/dist/web/primitives/sticky-action-bar.d.ts +5 -0
- package/dist/web/primitives/sticky-action-bar.js +15 -0
- package/dist/web/primitives/tabs.d.ts +3 -0
- package/dist/web/primitives/tabs.js +107 -0
- package/dist/web/primitives/timestamp-input.d.ts +27 -0
- package/dist/web/primitives/timestamp-input.js +87 -0
- package/dist/web/primitives/toast.d.ts +19 -0
- package/dist/web/primitives/toast.js +63 -0
- package/dist/web/primitives/tz-input.d.ts +11 -0
- package/dist/web/primitives/tz-input.js +8 -0
- package/dist/web/primitives/tz-options.d.ts +4 -0
- package/dist/web/primitives/tz-options.js +17 -0
- package/dist/web/primitives/use-keyboard-inset.d.ts +1 -0
- package/dist/web/primitives/use-keyboard-inset.js +28 -0
- package/dist/web/primitives/use-narrow-viewport.d.ts +4 -0
- package/dist/web/primitives/use-narrow-viewport.js +46 -0
- package/dist/web/react-css-custom-properties.d.ts +6 -0
- package/dist/web/react-css-custom-properties.js +1 -0
- package/dist/web/sse/live-events.d.ts +15 -0
- package/dist/web/sse/live-events.js +148 -0
- package/dist/web/theme-plugin.d.ts +41 -0
- package/dist/web/theme-plugin.js +123 -0
- package/dist/web/tokens.d.ts +24 -0
- package/dist/web/tokens.js +203 -0
- package/dist/web/ui/avatar.d.ts +11 -0
- package/dist/web/ui/avatar.js +25 -0
- package/dist/web/ui/badge.d.ts +9 -0
- package/dist/web/ui/badge.js +26 -0
- package/dist/web/ui/breadcrumb.d.ts +11 -0
- package/dist/web/ui/breadcrumb.js +29 -0
- package/dist/web/ui/button.d.ts +10 -0
- package/dist/web/ui/button.js +37 -0
- package/dist/web/ui/checkbox.d.ts +4 -0
- package/dist/web/ui/checkbox.js +11 -0
- package/dist/web/ui/input.d.ts +3 -0
- package/dist/web/ui/input.js +8 -0
- package/dist/web/ui/label.d.ts +4 -0
- package/dist/web/ui/label.js +10 -0
- package/dist/web/ui/resizable.d.ts +7 -0
- package/dist/web/ui/resizable.js +16 -0
- package/dist/web/ui/separator.d.ts +4 -0
- package/dist/web/ui/separator.js +10 -0
- package/dist/web/ui/sheet.d.ts +14 -0
- package/dist/web/ui/sheet.js +42 -0
- package/dist/web/ui/sidebar.d.ts +73 -0
- package/dist/web/ui/sidebar.js +211 -0
- package/dist/web/ui/skeleton.d.ts +2 -0
- package/dist/web/ui/skeleton.js +7 -0
- package/dist/web/ui/switch.d.ts +6 -0
- package/dist/web/ui/switch.js +10 -0
- package/dist/web/ui/table.d.ts +10 -0
- package/dist/web/ui/table.js +30 -0
- package/dist/web/ui/tabs.d.ts +11 -0
- package/dist/web/ui/tabs.js +31 -0
- package/dist/web/ui/textarea.d.ts +3 -0
- package/dist/web/ui/textarea.js +8 -0
- package/dist/web/ui/tooltip.d.ts +7 -0
- package/dist/web/ui/tooltip.js +19 -0
- package/dist/web/ui/use-mobile.d.ts +1 -0
- package/dist/web/ui/use-mobile.js +16 -0
- package/dist/web/version/update-checker.d.ts +9 -0
- package/dist/web/version/update-checker.js +88 -0
- package/dist/web/widgets/ai-text-field.d.ts +36 -0
- package/dist/web/widgets/ai-text-field.js +137 -0
- package/dist/web/widgets/chart-window.d.ts +58 -0
- package/dist/web/widgets/chart-window.js +190 -0
- package/dist/web/widgets/charts.d.ts +208 -0
- package/dist/web/widgets/charts.js +685 -0
- package/dist/web/widgets/collapsible-section.d.ts +10 -0
- package/dist/web/widgets/collapsible-section.js +17 -0
- package/dist/web/widgets/dashboard-list.d.ts +21 -0
- package/dist/web/widgets/dashboard-list.js +45 -0
- package/dist/web/widgets/detail-list.d.ts +15 -0
- package/dist/web/widgets/detail-list.js +8 -0
- package/dist/web/widgets/drawer.d.ts +65 -0
- package/dist/web/widgets/drawer.js +142 -0
- package/dist/web/widgets/feed-list.d.ts +13 -0
- package/dist/web/widgets/feed-list.js +9 -0
- package/dist/web/widgets/floating-panel.d.ts +30 -0
- package/dist/web/widgets/floating-panel.js +242 -0
- package/dist/web/widgets/form-fields.d.ts +93 -0
- package/dist/web/widgets/form-fields.js +50 -0
- package/dist/web/widgets/index.d.ts +27 -0
- package/dist/web/widgets/index.js +30 -0
- package/dist/web/widgets/infinity-list.d.ts +46 -0
- package/dist/web/widgets/infinity-list.js +211 -0
- package/dist/web/widgets/mode-switch.d.ts +21 -0
- package/dist/web/widgets/mode-switch.js +25 -0
- package/dist/web/widgets/photo-slots.d.ts +29 -0
- package/dist/web/widgets/photo-slots.js +52 -0
- package/dist/web/widgets/plan-card.d.ts +36 -0
- package/dist/web/widgets/plan-card.js +13 -0
- package/dist/web/widgets/progress-bar.d.ts +19 -0
- package/dist/web/widgets/progress-bar.js +24 -0
- package/dist/web/widgets/progress-list.d.ts +19 -0
- package/dist/web/widgets/progress-list.js +11 -0
- package/dist/web/widgets/public-shell.d.ts +22 -0
- package/dist/web/widgets/public-shell.js +15 -0
- package/dist/web/widgets/query-table.d.ts +29 -0
- package/dist/web/widgets/query-table.js +30 -0
- package/dist/web/widgets/result-panel.d.ts +69 -0
- package/dist/web/widgets/result-panel.js +30 -0
- package/dist/web/widgets/section-card.d.ts +12 -0
- package/dist/web/widgets/section-card.js +9 -0
- package/dist/web/widgets/sheet-parts.d.ts +9 -0
- package/dist/web/widgets/sheet-parts.js +11 -0
- package/dist/web/widgets/side-by-side-table.d.ts +31 -0
- package/dist/web/widgets/side-by-side-table.js +11 -0
- package/dist/web/widgets/stat.d.ts +54 -0
- package/dist/web/widgets/stat.js +65 -0
- package/dist/web/widgets/states.d.ts +23 -0
- package/dist/web/widgets/states.js +20 -0
- package/dist/web/widgets/status-badge.d.ts +15 -0
- package/dist/web/widgets/status-badge.js +24 -0
- package/dist/web/widgets/step-bar.d.ts +35 -0
- package/dist/web/widgets/step-bar.js +60 -0
- package/dist/web/widgets/upload-zone.d.ts +24 -0
- package/dist/web/widgets/upload-zone.js +108 -0
- package/dist/web/widgets/use-draft.d.ts +20 -0
- package/dist/web/widgets/use-draft.js +21 -0
- package/dist/web/widgets/use-pointer-drag.d.ts +21 -0
- package/dist/web/widgets/use-pointer-drag.js +53 -0
- package/package.json +105 -7
- package/src/changes.json +53 -0
- package/src/web/fonts/OFL.txt +93 -0
- package/src/web/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-mono-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-500.woff2 +0 -0
- package/src/web/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
- package/src/web/styles.css +401 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { LocaleResolver } from "../contracts/index.ts";
|
|
2
|
+
export type LocaleRouterConfig<TPage extends string> = {
|
|
3
|
+
/** Canonical default, usually "de". No URL prefix. */
|
|
4
|
+
readonly defaultLocale: string;
|
|
5
|
+
/** Locales that get a URL prefix, e.g. ["en"] → /en/... */
|
|
6
|
+
readonly prefixedLocales: readonly string[];
|
|
7
|
+
/** Prefix segment per locale, default: locale code ("en" → "/en"). */
|
|
8
|
+
readonly prefixFor?: (locale: string) => string;
|
|
9
|
+
/** Logical page → path per locale. Every page must define defaultLocale path. */
|
|
10
|
+
readonly routes: Record<TPage, Record<string, string>>;
|
|
11
|
+
/** Legacy slug-only paths for detectLang/resolvePage, e.g. { en: ["/features"] }. */
|
|
12
|
+
readonly localeHints?: Readonly<Record<string, readonly string[]>>;
|
|
13
|
+
/** Fallback page when altLocalePath cannot resolve pathname. Default: "home". */
|
|
14
|
+
readonly homePage?: TPage;
|
|
15
|
+
};
|
|
16
|
+
export type LocaleRouter<TPage extends string> = {
|
|
17
|
+
detectLang(pathname: string): string;
|
|
18
|
+
publicPath(page: TPage, locale: string): string;
|
|
19
|
+
resolvePage(pathname: string): TPage | undefined;
|
|
20
|
+
altLocalePath(pathname: string, targetLocale?: string): string;
|
|
21
|
+
sectionAnchor(page: TPage, locale: string, fragment: string): string;
|
|
22
|
+
};
|
|
23
|
+
export declare function createLocaleRouter<TPage extends string>(config: LocaleRouterConfig<TPage>): LocaleRouter<TPage>;
|
|
24
|
+
export type WrapUrlLocaleResolverOptions = {
|
|
25
|
+
resolvePage: (pathname: string) => string | undefined;
|
|
26
|
+
detectLang: (pathname: string) => string;
|
|
27
|
+
pathname?: () => string | undefined;
|
|
28
|
+
/** Optional pathname-change subscription. Browser default listens to `popstate` only,
|
|
29
|
+
* which does not fire on `history.pushState`/`replaceState`: apps with a client-side
|
|
30
|
+
* router must supply this themselves. */
|
|
31
|
+
subscribePathname?: (listener: () => void) => () => void;
|
|
32
|
+
/** When set, translate against the URL-resolved locale instead of base.translate
|
|
33
|
+
* (needed for fixed-T / cloneInstance resolvers that are not locale-live). */
|
|
34
|
+
translateFor?: (locale: string, key: string, params?: Readonly<Record<string, unknown>>) => string;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Prefer URL-derived locale when `resolvePage` matches the current path;
|
|
38
|
+
* otherwise defer to `base.locale()`. Passes through setLocale and the rest of LocaleResolver.
|
|
39
|
+
* Without `translateFor`, `base.translate` must already be locale-live.
|
|
40
|
+
*/
|
|
41
|
+
export declare function wrapUrlLocaleResolver(base: LocaleResolver, options: WrapUrlLocaleResolverOptions): LocaleResolver;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
|
+
function normalizePath(pathname) {
|
|
3
|
+
if (pathname === "" || pathname === "/")
|
|
4
|
+
return "/";
|
|
5
|
+
return pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
6
|
+
}
|
|
7
|
+
function defaultPrefixFor(locale) {
|
|
8
|
+
return `/${locale}`;
|
|
9
|
+
}
|
|
10
|
+
function stripLocalePrefix(path, locale, prefixFor) {
|
|
11
|
+
const prefix = prefixFor(locale);
|
|
12
|
+
if (path === prefix)
|
|
13
|
+
return "/";
|
|
14
|
+
if (path.startsWith(`${prefix}/`))
|
|
15
|
+
return path.slice(prefix.length);
|
|
16
|
+
return path;
|
|
17
|
+
}
|
|
18
|
+
export function createLocaleRouter(config) {
|
|
19
|
+
const { defaultLocale, prefixedLocales, routes, localeHints = {}, prefixFor = defaultPrefixFor, homePage = "home", } = config;
|
|
20
|
+
if (routes[homePage] === undefined) {
|
|
21
|
+
throw new Error(`locale-routing: homePage "${String(homePage)}" has no entry in routes — altLocalePath's fallback would throw at request time`);
|
|
22
|
+
}
|
|
23
|
+
const pathIndex = new Map();
|
|
24
|
+
for (const [page, localePaths] of Object.entries(routes)) {
|
|
25
|
+
for (const [locale, routePath] of Object.entries(localePaths)) {
|
|
26
|
+
pathIndex.set(normalizePath(routePath), { page, locale });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
for (const [hintLocale, hints] of Object.entries(localeHints)) {
|
|
30
|
+
for (const hint of hints) {
|
|
31
|
+
const normalizedHint = normalizePath(hint);
|
|
32
|
+
if (pathIndex.has(normalizedHint))
|
|
33
|
+
continue;
|
|
34
|
+
for (const [page, localePaths] of Object.entries(routes)) {
|
|
35
|
+
const canonical = localePaths[hintLocale];
|
|
36
|
+
if (canonical === undefined)
|
|
37
|
+
continue;
|
|
38
|
+
const canonicalNorm = normalizePath(canonical);
|
|
39
|
+
const hintSlug = stripLocalePrefix(normalizedHint, hintLocale, prefixFor);
|
|
40
|
+
const canonicalSlug = stripLocalePrefix(canonicalNorm, hintLocale, prefixFor);
|
|
41
|
+
if (hintSlug === canonicalSlug) {
|
|
42
|
+
pathIndex.set(normalizedHint, { page, locale: hintLocale });
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function detectLang(pathname) {
|
|
49
|
+
const path = normalizePath(pathname);
|
|
50
|
+
for (const locale of prefixedLocales) {
|
|
51
|
+
const prefix = prefixFor(locale);
|
|
52
|
+
if (path === prefix || path.startsWith(`${prefix}/`))
|
|
53
|
+
return locale;
|
|
54
|
+
}
|
|
55
|
+
const resolved = pathIndex.get(path);
|
|
56
|
+
if (resolved !== undefined)
|
|
57
|
+
return resolved.locale;
|
|
58
|
+
for (const [locale, hints] of Object.entries(localeHints)) {
|
|
59
|
+
if (hints.some((hint) => normalizePath(hint) === path))
|
|
60
|
+
return locale;
|
|
61
|
+
}
|
|
62
|
+
return defaultLocale;
|
|
63
|
+
}
|
|
64
|
+
function resolvePage(pathname) {
|
|
65
|
+
return pathIndex.get(normalizePath(pathname))?.page;
|
|
66
|
+
}
|
|
67
|
+
function publicPath(page, locale) {
|
|
68
|
+
const localePaths = routes[page];
|
|
69
|
+
const routePath = localePaths?.[locale];
|
|
70
|
+
if (localePaths === undefined ||
|
|
71
|
+
!Object.hasOwn(localePaths, locale) ||
|
|
72
|
+
routePath === undefined) {
|
|
73
|
+
throw new Error(`locale-routing: no path for page "${String(page)}" locale "${locale}"`);
|
|
74
|
+
}
|
|
75
|
+
return routePath;
|
|
76
|
+
}
|
|
77
|
+
function otherLocale(currentLocale) {
|
|
78
|
+
if (currentLocale === defaultLocale) {
|
|
79
|
+
return prefixedLocales[0] ?? defaultLocale;
|
|
80
|
+
}
|
|
81
|
+
return defaultLocale;
|
|
82
|
+
}
|
|
83
|
+
function altLocalePath(pathname, targetLocale) {
|
|
84
|
+
const path = normalizePath(pathname);
|
|
85
|
+
const resolved = pathIndex.get(path);
|
|
86
|
+
const locale = targetLocale ?? otherLocale(detectLang(pathname));
|
|
87
|
+
if (resolved !== undefined) {
|
|
88
|
+
return publicPath(resolved.page, locale);
|
|
89
|
+
}
|
|
90
|
+
return publicPath(homePage, locale);
|
|
91
|
+
}
|
|
92
|
+
function sectionAnchor(page, locale, fragment) {
|
|
93
|
+
return `${publicPath(page, locale)}#${fragment}`;
|
|
94
|
+
}
|
|
95
|
+
return { detectLang, publicPath, resolvePage, altLocalePath, sectionAnchor };
|
|
96
|
+
}
|
|
97
|
+
function defaultBrowserPathname() {
|
|
98
|
+
const pathname = propertyOf(propertyOf(globalThis, "location"), "pathname");
|
|
99
|
+
return typeof pathname === "string" ? pathname : undefined;
|
|
100
|
+
}
|
|
101
|
+
function defaultSubscribePathname(listener) {
|
|
102
|
+
const add = propertyOf(globalThis, "addEventListener");
|
|
103
|
+
const remove = propertyOf(globalThis, "removeEventListener");
|
|
104
|
+
if (typeof add !== "function" || typeof remove !== "function") {
|
|
105
|
+
return () => { };
|
|
106
|
+
}
|
|
107
|
+
Reflect.apply(add, globalThis, ["popstate", listener]);
|
|
108
|
+
return () => {
|
|
109
|
+
Reflect.apply(remove, globalThis, ["popstate", listener]);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Prefer URL-derived locale when `resolvePage` matches the current path;
|
|
114
|
+
* otherwise defer to `base.locale()`. Passes through setLocale and the rest of LocaleResolver.
|
|
115
|
+
* Without `translateFor`, `base.translate` must already be locale-live.
|
|
116
|
+
*/
|
|
117
|
+
export function wrapUrlLocaleResolver(base, options) {
|
|
118
|
+
const getPathname = options.pathname ?? defaultBrowserPathname;
|
|
119
|
+
const subscribePathname = options.subscribePathname ?? defaultSubscribePathname;
|
|
120
|
+
const resolveLocale = () => {
|
|
121
|
+
const path = getPathname();
|
|
122
|
+
if (path === undefined)
|
|
123
|
+
return base.locale();
|
|
124
|
+
if (options.resolvePage(path) != null) {
|
|
125
|
+
return options.detectLang(path);
|
|
126
|
+
}
|
|
127
|
+
return base.locale();
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
translate: (key, params) => options.translateFor
|
|
131
|
+
? options.translateFor(resolveLocale(), key, params)
|
|
132
|
+
: base.translate(key, params),
|
|
133
|
+
timeZone: () => base.timeZone(),
|
|
134
|
+
subscribe: (listener) => {
|
|
135
|
+
const unsubBase = base.subscribe(listener);
|
|
136
|
+
const unsubPath = subscribePathname(listener);
|
|
137
|
+
return () => {
|
|
138
|
+
unsubBase();
|
|
139
|
+
unsubPath();
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
setLocale: base.setLocale !== undefined ? (locale) => base.setLocale?.(locale) : undefined,
|
|
143
|
+
locale: resolveLocale,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { resolveNavigation } from "./resolve.js";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { isUiAccessGranted } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
// Assembles the renderable nav tree from the registry's pre-grouped
|
|
3
|
+
// indexes (topLevel + byParent). Walks top-down: each node is
|
|
4
|
+
// access-checked; a hidden parent drops its entire subtree implicitly
|
|
5
|
+
// because we never recurse into it. Siblings sort by `order` (ascending,
|
|
6
|
+
// default 0), tie-broken by qualified name so renders stay deterministic
|
|
7
|
+
// across registry iteration orders. A pure group (no screen, target,
|
|
8
|
+
// provider or createAction) whose children are all hidden or absent is
|
|
9
|
+
// dropped too.
|
|
10
|
+
//
|
|
11
|
+
// Pure — same inputs produce the same tree. The renderer memoizes the
|
|
12
|
+
// result and only recomputes when the registry changes (rare — boot
|
|
13
|
+
// only) or the user's roles change (logout/login, tenant-switch).
|
|
14
|
+
export function resolveNavigation(options) {
|
|
15
|
+
const { source, user } = options;
|
|
16
|
+
function build(entry) {
|
|
17
|
+
// Shared default-visible UI predicate, not hasAccess from the engine:
|
|
18
|
+
// that module pulls server-side deps and would break bundle purity.
|
|
19
|
+
if (!isUiAccessGranted(entry.access, user?.roles))
|
|
20
|
+
return null;
|
|
21
|
+
// `entry.id` is already the qualified name — the registry stores
|
|
22
|
+
// it that way. No reverse-index lookup needed.
|
|
23
|
+
const children = [];
|
|
24
|
+
for (const child of source.byParent(entry.id)) {
|
|
25
|
+
const node = build(child);
|
|
26
|
+
if (node !== null)
|
|
27
|
+
children.push(node);
|
|
28
|
+
}
|
|
29
|
+
// A pure group (nothing to open itself) with nothing visible below it
|
|
30
|
+
// would render as an empty, unclickable heading.
|
|
31
|
+
if (children.length === 0 && isPureGroup(entry))
|
|
32
|
+
return null;
|
|
33
|
+
children.sort(bySortKey);
|
|
34
|
+
return {
|
|
35
|
+
qualifiedName: entry.id,
|
|
36
|
+
label: entry.label,
|
|
37
|
+
order: entry.order ?? 0,
|
|
38
|
+
children,
|
|
39
|
+
...(entry.icon !== undefined && { icon: entry.icon }),
|
|
40
|
+
...(entry.screen !== undefined && { screen: entry.screen }),
|
|
41
|
+
...(entry.target !== undefined && { target: entry.target }),
|
|
42
|
+
...(entry.actions !== undefined && { actions: entry.actions }),
|
|
43
|
+
...(entry.createAction !== undefined && { createAction: entry.createAction }),
|
|
44
|
+
...(entry.provider !== undefined && { provider: entry.provider }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const roots = [];
|
|
48
|
+
for (const entry of source.topLevel) {
|
|
49
|
+
const node = build(entry);
|
|
50
|
+
if (node !== null)
|
|
51
|
+
roots.push(node);
|
|
52
|
+
}
|
|
53
|
+
roots.sort(bySortKey);
|
|
54
|
+
return roots;
|
|
55
|
+
}
|
|
56
|
+
function isPureGroup(entry) {
|
|
57
|
+
return (entry.screen === undefined &&
|
|
58
|
+
entry.target === undefined &&
|
|
59
|
+
entry.provider === undefined &&
|
|
60
|
+
entry.actions === undefined &&
|
|
61
|
+
entry.createAction === undefined);
|
|
62
|
+
}
|
|
63
|
+
function bySortKey(a, b) {
|
|
64
|
+
// Primary key: `order` ascending. Secondary: qualifiedName alphabetic,
|
|
65
|
+
// which is a stable fallback — the registry-iteration order isn't
|
|
66
|
+
// guaranteed across boots, so tied-order entries would otherwise
|
|
67
|
+
// shuffle between renders.
|
|
68
|
+
if (a.order !== b.order)
|
|
69
|
+
return a.order - b.order;
|
|
70
|
+
return a.qualifiedName.localeCompare(b.qualifiedName);
|
|
71
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { NavDefinition, TargetRef, TreeAction } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
export type NavNode = {
|
|
3
|
+
readonly qualifiedName: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
readonly icon?: string;
|
|
6
|
+
readonly screen?: string;
|
|
7
|
+
readonly target?: TargetRef;
|
|
8
|
+
readonly actions?: readonly TreeAction[];
|
|
9
|
+
readonly createAction?: TreeAction;
|
|
10
|
+
readonly provider?: boolean;
|
|
11
|
+
readonly order: number;
|
|
12
|
+
readonly children: readonly NavNode[];
|
|
13
|
+
};
|
|
14
|
+
export type NavTree = readonly NavNode[];
|
|
15
|
+
export type NavRegistrySlice = {
|
|
16
|
+
readonly topLevel: readonly NavDefinition[];
|
|
17
|
+
readonly byParent: (parentQualifiedName: string) => readonly NavDefinition[];
|
|
18
|
+
};
|
|
19
|
+
export type ResolveNavigationOptions = {
|
|
20
|
+
readonly source: NavRegistrySlice;
|
|
21
|
+
readonly user?: {
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly roles: readonly string[];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
export type { NavDefinition };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Subscribe/Emit primitive matching React's useSyncExternalStore.
|
|
2
|
+
// Single canonical implementation — every stateful controller in
|
|
3
|
+
// ui-core/renderer land composes on top of this instead of rolling
|
|
4
|
+
// its own listener-set + notify-loop.
|
|
5
|
+
//
|
|
6
|
+
// Reentrancy semantics use the Set's documented iteration behavior:
|
|
7
|
+
// listeners deleted DURING the notify-loop but BEFORE their turn are
|
|
8
|
+
// skipped; listeners deleting themselves AFTER firing don't break the
|
|
9
|
+
// loop (Set iteration tolerates concurrent mutation of already-visited
|
|
10
|
+
// entries). MDN: "callbackFn is not invoked for values deleted before
|
|
11
|
+
// being visited." This is exactly the contract callers expect.
|
|
12
|
+
//
|
|
13
|
+
// Caveat — Function-valued stores: setState detects the reducer-form via
|
|
14
|
+
// `typeof next === "function"`. If T itself is a function type
|
|
15
|
+
// (`createStore<() => string>(...)`), there is no way to tell a "new
|
|
16
|
+
// value that happens to be a function" apart from a "reducer producing a
|
|
17
|
+
// new function". Same trap React's useState has. Workaround: wrap the
|
|
18
|
+
// new function in a reducer that ignores prev:
|
|
19
|
+
// store.setState(() => myNewFn);
|
|
20
|
+
// In practice, function-valued stores are rare — feature controllers
|
|
21
|
+
// hold values, not callbacks.
|
|
22
|
+
export function createStore(initial) {
|
|
23
|
+
let snapshot = initial;
|
|
24
|
+
const listeners = new Set();
|
|
25
|
+
return {
|
|
26
|
+
getSnapshot: () => snapshot,
|
|
27
|
+
subscribe: (listener) => {
|
|
28
|
+
listeners.add(listener);
|
|
29
|
+
return () => {
|
|
30
|
+
listeners.delete(listener);
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
setState: (next) => {
|
|
34
|
+
const nextValue = typeof next === "function" ? next(snapshot) : next;
|
|
35
|
+
// skip: next value identical to snapshot, avoid notifying listeners
|
|
36
|
+
if (Object.is(nextValue, snapshot))
|
|
37
|
+
return;
|
|
38
|
+
snapshot = nextValue;
|
|
39
|
+
for (const listener of listeners)
|
|
40
|
+
listener();
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function shallowEqual(a: unknown, b: unknown): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Shallow equality — Object.is on each own enumerable key. The
|
|
2
|
+
// recommended Equality-Arg for useStoreSelector when the selector
|
|
3
|
+
// returns a plain object/array literal (`s => ({ a: s.a, b: s.b })`),
|
|
4
|
+
// which would otherwise produce a fresh reference each render and
|
|
5
|
+
// trip useSyncExternalStore's identity check.
|
|
6
|
+
//
|
|
7
|
+
// Mirrors Zustand's `shallow` and react-redux's `shallowEqual` — same
|
|
8
|
+
//8-line shape, no recursion. Apps that need deep equality reach for
|
|
9
|
+
// their own helper.
|
|
10
|
+
// Signature is `(a: unknown, b: unknown)` not `<T>(a: T, b: T)` because the
|
|
11
|
+
// function legitimately compares cross-type values (primitive vs. object,
|
|
12
|
+
// null vs. {}, etc.) and returns false for mismatches. A generic `<T>`
|
|
13
|
+
// would force callers into type-gymnastics for those cases. Contra-variance
|
|
14
|
+
// ensures this still satisfies `(a: S, b: S) => boolean` slots like
|
|
15
|
+
// useStoreSelector's `equals` arg.
|
|
16
|
+
export function shallowEqual(a, b) {
|
|
17
|
+
if (Object.is(a, b))
|
|
18
|
+
return true;
|
|
19
|
+
if (typeof a !== "object" || a === null)
|
|
20
|
+
return false;
|
|
21
|
+
if (typeof b !== "object" || b === null)
|
|
22
|
+
return false;
|
|
23
|
+
const keysA = Object.keys(a);
|
|
24
|
+
const keysB = Object.keys(b);
|
|
25
|
+
if (keysA.length !== keysB.length)
|
|
26
|
+
return false;
|
|
27
|
+
for (const key of keysA) {
|
|
28
|
+
if (!Object.hasOwn(b, key))
|
|
29
|
+
return false;
|
|
30
|
+
if (!Object.is(Reflect.get(a, key), Reflect.get(b, key)))
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Store contract — Pull-Style Subscribe/Emit matching React's
|
|
2
|
+
// useSyncExternalStore signature. The single canonical shape for
|
|
3
|
+
// every stateful controller in ui-core/renderer land (form,
|
|
4
|
+
// dispatcher-status, locale, token, nav, lifecycle).
|
|
5
|
+
//
|
|
6
|
+
// Rationale in docs/plans/ui-store.md. Not a new state-management
|
|
7
|
+
// decision — ui-decisions.md already picked Subscribe/Emit; this
|
|
8
|
+
// module just materializes the pattern instead of rolling a new
|
|
9
|
+
// Set<() => void> per controller.
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EditRelatedListSection, EntityDefinition, EntityEditScreenDefinition } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
2
|
+
import type { EditRelatedListSectionViewModel, EditViewModel, Translate } from "./types.ts";
|
|
3
|
+
export type ComputeEditViewModelInput<TValues extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>> = {
|
|
4
|
+
readonly screen: EntityEditScreenDefinition;
|
|
5
|
+
readonly entity: EntityDefinition;
|
|
6
|
+
readonly values: TValues;
|
|
7
|
+
readonly translate: Translate;
|
|
8
|
+
readonly featureName: string;
|
|
9
|
+
/** Which write the form drives. Applies the screen's `writeExcludedFields`
|
|
10
|
+
* for that verb (create hides them, update shows them read-only); omitted
|
|
11
|
+
* means no exclusion applies. */
|
|
12
|
+
readonly mode?: EditFormMode;
|
|
13
|
+
/** The record being edited; omitted on create. */
|
|
14
|
+
readonly entityId?: string;
|
|
15
|
+
};
|
|
16
|
+
export type EditFormMode = "create" | "update";
|
|
17
|
+
export declare function computeRelatedListSectionViewModel(sectionSpec: EditRelatedListSection, translate: Translate): EditRelatedListSectionViewModel;
|
|
18
|
+
export declare function computeEditViewModel<TValues extends Readonly<Record<string, unknown>> = Readonly<Record<string, unknown>>>(input: ComputeEditViewModelInput<TValues>): EditViewModel;
|