@cosmicdrift/kumiko-renderer 0.373.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 +58 -0
- package/dist/app/action-form-support.js +96 -0
- package/dist/app/client-actions.d.ts +46 -0
- package/dist/app/client-actions.js +60 -0
- 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/entity-list-expanded-row.js +4 -0
- package/dist/app/form-schema.d.ts +1 -1
- package/dist/app/form-schema.js +2 -2
- package/dist/app/header-actions-bar.d.ts +19 -0
- package/dist/app/header-actions-bar.js +30 -0
- package/dist/app/kumiko-screen.d.ts +1 -1
- package/dist/app/kumiko-screen.js +134 -66
- package/dist/app/list-empty-content.d.ts +2 -2
- package/dist/app/list-empty-content.js +3 -2
- 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 +10 -2
- package/dist/app/row-actions.js +85 -6
- 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 +12 -0
- package/dist/app/use-record-actions.js +30 -0
- 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 +4 -2
- package/dist/components/grid-cell-for-field.js +2 -2
- 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/related-list-section.js +16 -3
- 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 +5 -3
- package/dist/components/render-field.d.ts +5 -2
- package/dist/components/render-field.js +103 -9
- 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-defaults.js +7 -0
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +7 -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 +53 -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 +77 -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,35 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
// Wire envelopes of /api/{write,query,batch,stream}. Only the envelope is
|
|
3
|
+
// validated; `data` payloads stay unknown and are typed by the caller.
|
|
4
|
+
export const serverErrorSchema = z.object({
|
|
5
|
+
code: z.string(),
|
|
6
|
+
httpStatus: z.number().optional(),
|
|
7
|
+
// Some gates (bad-request helper in server.ts, pii-leak-guard) send no
|
|
8
|
+
// i18nKey; keeping their `code` beats collapsing them into network_error.
|
|
9
|
+
i18nKey: z.string().default("errors.unknown"),
|
|
10
|
+
message: z.string(),
|
|
11
|
+
details: z.unknown().optional(),
|
|
12
|
+
i18nParams: z.record(z.string(), z.unknown()).optional(),
|
|
13
|
+
docsUrl: z.string().optional(),
|
|
14
|
+
requestId: z.string().optional(),
|
|
15
|
+
});
|
|
16
|
+
const writeItemSchema = z.discriminatedUnion("isSuccess", [
|
|
17
|
+
z.object({ isSuccess: z.literal(true), data: z.unknown().optional() }),
|
|
18
|
+
z.object({ isSuccess: z.literal(false), error: serverErrorSchema }),
|
|
19
|
+
]);
|
|
20
|
+
export const writeEnvelopeSchema = writeItemSchema;
|
|
21
|
+
export const batchEnvelopeSchema = z.discriminatedUnion("isSuccess", [
|
|
22
|
+
z.object({ isSuccess: z.literal(true), results: z.array(writeItemSchema) }),
|
|
23
|
+
z.object({
|
|
24
|
+
isSuccess: z.literal(false),
|
|
25
|
+
error: serverErrorSchema,
|
|
26
|
+
failedIndex: z.number(),
|
|
27
|
+
results: z.array(writeItemSchema),
|
|
28
|
+
}),
|
|
29
|
+
]);
|
|
30
|
+
// `error` is nullish: a null/absent error means success, as before.
|
|
31
|
+
export const queryEnvelopeSchema = z.object({
|
|
32
|
+
data: z.unknown().optional(),
|
|
33
|
+
error: serverErrorSchema.nullish(),
|
|
34
|
+
});
|
|
35
|
+
export const errorOnlyEnvelopeSchema = z.object({ error: serverErrorSchema });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DispatcherError } from "../headless/index.ts";
|
|
2
|
+
type ServerErrorInfo = {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly httpStatus: number;
|
|
5
|
+
readonly i18nKey: string;
|
|
6
|
+
readonly i18nParams?: Readonly<Record<string, unknown>>;
|
|
7
|
+
readonly message: string;
|
|
8
|
+
readonly details?: unknown;
|
|
9
|
+
readonly docsUrl?: string;
|
|
10
|
+
readonly requestId?: string;
|
|
11
|
+
readonly timestamp?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function mapServerError(serverError: ServerErrorInfo): DispatcherError;
|
|
14
|
+
export declare function buildNetworkError(cause: unknown): DispatcherError;
|
|
15
|
+
export declare function buildAbortError(): DispatcherError;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
|
+
// Narrow cast into the DispatcherError shape. Pass-through for everything
|
|
3
|
+
// except `details.fields`, which we normalize: the server uses
|
|
4
|
+
// ValidationFieldIssue (path/code/i18nKey/params), which is structurally
|
|
5
|
+
// identical to FieldIssue — but we re-build it so a future field-addition
|
|
6
|
+
// on either side forces a compile error here, the right place to update.
|
|
7
|
+
export function mapServerError(serverError) {
|
|
8
|
+
const normalizedDetails = normalizeDetails(serverError.details);
|
|
9
|
+
return {
|
|
10
|
+
code: serverError.code,
|
|
11
|
+
httpStatus: serverError.httpStatus,
|
|
12
|
+
i18nKey: serverError.i18nKey,
|
|
13
|
+
message: serverError.message,
|
|
14
|
+
...(serverError.i18nParams && { i18nParams: serverError.i18nParams }),
|
|
15
|
+
...(normalizedDetails && { details: normalizedDetails }),
|
|
16
|
+
...(serverError.docsUrl && { docsUrl: serverError.docsUrl }),
|
|
17
|
+
...(serverError.requestId && { requestId: serverError.requestId }),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function normalizeDetails(details) {
|
|
21
|
+
if (!isPlainObject(details))
|
|
22
|
+
return undefined;
|
|
23
|
+
const { fields, ...otherDetails } = details;
|
|
24
|
+
if (!Array.isArray(fields)) {
|
|
25
|
+
// Details without fields still pass through — non-validation errors
|
|
26
|
+
// (rate-limit, version-conflict, ...) carry their own structured
|
|
27
|
+
// payload here.
|
|
28
|
+
return otherDetails;
|
|
29
|
+
}
|
|
30
|
+
const mappedFields = [];
|
|
31
|
+
for (const r of fields) {
|
|
32
|
+
if (!isPlainObject(r)) {
|
|
33
|
+
// Server sent a non-object entry in details.fields — contract
|
|
34
|
+
// breach (ValidationFieldIssue shape is required). Warn so the
|
|
35
|
+
// skip doesn't hide a broken server build.
|
|
36
|
+
// biome-ignore lint/suspicious/noConsole: ops-visible warning when the server breaks the validation-error contract
|
|
37
|
+
console.warn("[dispatcher-live] dropping malformed field issue (not an object):", r);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (typeof r["path"] !== "string" ||
|
|
41
|
+
typeof r["code"] !== "string" ||
|
|
42
|
+
typeof r["i18nKey"] !== "string") {
|
|
43
|
+
// Entry is an object but missing required keys — same reasoning.
|
|
44
|
+
// biome-ignore lint/suspicious/noConsole: ops-visible warning when the server breaks the validation-error contract
|
|
45
|
+
console.warn("[dispatcher-live] dropping malformed field issue (missing keys):", r);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
mappedFields.push({
|
|
49
|
+
path: r["path"],
|
|
50
|
+
code: r["code"],
|
|
51
|
+
i18nKey: r["i18nKey"],
|
|
52
|
+
...(isPlainObject(r["params"]) && { params: r["params"] }),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return { ...otherDetails, fields: mappedFields };
|
|
56
|
+
}
|
|
57
|
+
// Builds a DispatcherError for a failure that never reached the server —
|
|
58
|
+
// network dropped, DNS error, CORS block, fetch() threw. The UI should
|
|
59
|
+
// surface this differently (offline indicator, retry button) from a
|
|
60
|
+
// typed server-rejection; callers key off `code === "network_error"`.
|
|
61
|
+
export function buildNetworkError(cause) {
|
|
62
|
+
const message = cause instanceof Error ? cause.message : String(cause ?? "network error");
|
|
63
|
+
return {
|
|
64
|
+
code: "network_error",
|
|
65
|
+
// 0 is the JS fetch-failure convention (xhr.status is 0 on abort/fail
|
|
66
|
+
// too). Distinguishes network from typed 5xx server errors.
|
|
67
|
+
httpStatus: 0,
|
|
68
|
+
i18nKey: "dispatcher.errors.network",
|
|
69
|
+
message,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Abort-specific error — used when the caller canceled via AbortSignal.
|
|
73
|
+
// Distinct code so a form submit that was cancelled because the user
|
|
74
|
+
// closed the modal doesn't toast "network error" (confusing).
|
|
75
|
+
export function buildAbortError() {
|
|
76
|
+
return {
|
|
77
|
+
code: "aborted",
|
|
78
|
+
httpStatus: 0,
|
|
79
|
+
i18nKey: "dispatcher.errors.aborted",
|
|
80
|
+
message: "request was aborted",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CSRF_HEADER_NAME, readCsrfToken } from "./csrf.ts";
|
|
2
|
+
export type { LiveDispatcherOptions } from "./dispatcher-live.ts";
|
|
3
|
+
export { createLiveDispatcher } from "./dispatcher-live.ts";
|
|
4
|
+
export { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping.ts";
|
|
5
|
+
export { LOCALE_HEADER_NAME, readActiveLocale } from "./locale.ts";
|
|
6
|
+
export type { SseFrame } from "./sse-stream.ts";
|
|
7
|
+
export { iterateSseChunks, parseSseBlock, parseSseFrames } from "./sse-stream.ts";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { CSRF_HEADER_NAME, readCsrfToken } from "./csrf.js";
|
|
2
|
+
export { createLiveDispatcher } from "./dispatcher-live.js";
|
|
3
|
+
export { buildAbortError, buildNetworkError, mapServerError } from "./error-mapping.js";
|
|
4
|
+
export { LOCALE_HEADER_NAME, readActiveLocale } from "./locale.js";
|
|
5
|
+
export { iterateSseChunks, parseSseBlock, parseSseFrames } from "./sse-stream.js";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Active-locale header transport for the live dispatcher.
|
|
2
|
+
//
|
|
3
|
+
// @cosmicdrift/kumiko-renderer/web's DocumentLangSync (mounted by
|
|
4
|
+
// createKumikoApp/createPublicSurface) sets dataset.kumikoLocale from the
|
|
5
|
+
// LocaleResolver. This module reads that marker back so every outgoing
|
|
6
|
+
// request carries the language the user is ACTUALLY using — not a static
|
|
7
|
+
// <html lang> — with zero app-side wiring.
|
|
8
|
+
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
9
|
+
// Kept in sync with LOCALE_HEADER_NAME in api-constants.ts by hand rather
|
|
10
|
+
// than imported from @cosmicdrift/kumiko-framework — this package must
|
|
11
|
+
// remain server-dep-free (runs in browsers and React Native).
|
|
12
|
+
export const LOCALE_HEADER_NAME = "X-Locale";
|
|
13
|
+
// Loose BCP-47 tag check — reject newlines/junk that would break fetch headers.
|
|
14
|
+
const LOCALE_TAG = /^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
15
|
+
// Reads dataset.kumikoLocale. Returns undefined for non-browser environments
|
|
16
|
+
// (SSR, Web Worker, React Native), before DocumentLangSync has run, or when
|
|
17
|
+
// the value is not a safe language tag — callers skip the header and the
|
|
18
|
+
// server falls back to Accept-Language, then its boot default.
|
|
19
|
+
export function readActiveLocale() {
|
|
20
|
+
const dataset = propertyOf(propertyOf(propertyOf(globalThis, "document"), "documentElement"), "dataset");
|
|
21
|
+
const lang = propertyOf(dataset, "kumikoLocale");
|
|
22
|
+
if (typeof lang !== "string" || lang.length === 0)
|
|
23
|
+
return undefined;
|
|
24
|
+
return LOCALE_TAG.test(lang) ? lang : undefined;
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type SseFrame = {
|
|
2
|
+
readonly event: string;
|
|
3
|
+
readonly data: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function parseSseBlock(block: string): SseFrame | null;
|
|
6
|
+
/** Split a complete SSE body (tests / non-streaming buffers) into frames. */
|
|
7
|
+
export declare function parseSseFrames(text: string): SseFrame[];
|
|
8
|
+
/**
|
|
9
|
+
* Incremental SSE reader over a fetch body. Yields `chunk` payloads as
|
|
10
|
+
* parsed JSON; swallows `ping`; returns on `done`; throws DispatcherError
|
|
11
|
+
* on `error` frames. Caller is responsible for aborting the underlying
|
|
12
|
+
* fetch via AbortSignal.
|
|
13
|
+
*/
|
|
14
|
+
export declare function iterateSseChunks<TChunk>(body: ReadableStream<Uint8Array>): AsyncGenerator<TChunk, void, undefined>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { StreamFrame } from "../headless/index.js";
|
|
2
|
+
import { serverErrorSchema } from "./envelopes.js";
|
|
3
|
+
import { mapServerError } from "./error-mapping.js";
|
|
4
|
+
export function parseSseBlock(block) {
|
|
5
|
+
const trimmed = block.trim();
|
|
6
|
+
if (trimmed.length === 0)
|
|
7
|
+
return null;
|
|
8
|
+
const event = /^event: (.*)$/m.exec(trimmed)?.[1] ?? "";
|
|
9
|
+
const data = /^data: (.*)$/m.exec(trimmed)?.[1] ?? "";
|
|
10
|
+
return { event, data };
|
|
11
|
+
}
|
|
12
|
+
/** Split a complete SSE body (tests / non-streaming buffers) into frames. */
|
|
13
|
+
export function parseSseFrames(text) {
|
|
14
|
+
return text
|
|
15
|
+
.split("\n\n")
|
|
16
|
+
.map(parseSseBlock)
|
|
17
|
+
.filter((f) => f !== null);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Incremental SSE reader over a fetch body. Yields `chunk` payloads as
|
|
21
|
+
* parsed JSON; swallows `ping`; returns on `done`; throws DispatcherError
|
|
22
|
+
* on `error` frames. Caller is responsible for aborting the underlying
|
|
23
|
+
* fetch via AbortSignal.
|
|
24
|
+
*/
|
|
25
|
+
export async function* iterateSseChunks(body) {
|
|
26
|
+
const reader = body.getReader();
|
|
27
|
+
const decoder = new TextDecoder();
|
|
28
|
+
let buffer = "";
|
|
29
|
+
let sawDone = false;
|
|
30
|
+
try {
|
|
31
|
+
while (true) {
|
|
32
|
+
const { done, value } = await reader.read();
|
|
33
|
+
if (done)
|
|
34
|
+
break;
|
|
35
|
+
buffer += decoder.decode(value, { stream: true });
|
|
36
|
+
const parts = buffer.split("\n\n");
|
|
37
|
+
buffer = parts.pop() ?? "";
|
|
38
|
+
for (const part of parts) {
|
|
39
|
+
const frame = parseSseBlock(part);
|
|
40
|
+
if (frame === null)
|
|
41
|
+
continue;
|
|
42
|
+
if (frame.event === StreamFrame.ping)
|
|
43
|
+
continue;
|
|
44
|
+
// skip: terminal SSE done frame — end the generator cleanly
|
|
45
|
+
if (frame.event === StreamFrame.done) {
|
|
46
|
+
sawDone = true;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (frame.event === StreamFrame.error) {
|
|
50
|
+
throw frameDataToDispatcherError(frame.data);
|
|
51
|
+
}
|
|
52
|
+
if (frame.event === StreamFrame.chunk) {
|
|
53
|
+
yield parseChunkData(frame.data);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Trailing buffer without final blank line (some runtimes).
|
|
58
|
+
const frame = parseSseBlock(buffer);
|
|
59
|
+
if (frame?.event === StreamFrame.chunk) {
|
|
60
|
+
yield parseChunkData(frame.data);
|
|
61
|
+
}
|
|
62
|
+
else if (frame?.event === StreamFrame.error) {
|
|
63
|
+
throw frameDataToDispatcherError(frame.data);
|
|
64
|
+
}
|
|
65
|
+
else if (frame?.event === StreamFrame.done) {
|
|
66
|
+
sawDone = true;
|
|
67
|
+
}
|
|
68
|
+
if (!sawDone) {
|
|
69
|
+
throw buildTruncatedStreamError();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
// cancel() releases the reader's lock too (safe on an already-drained
|
|
74
|
+
// stream) and, unlike releaseLock() alone, tells the underlying HTTP
|
|
75
|
+
// response to close instead of leaving the connection open until the
|
|
76
|
+
// server finishes writing a body no one is reading anymore.
|
|
77
|
+
await reader.cancel().catch(() => { });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function parseChunkData(data) {
|
|
81
|
+
try {
|
|
82
|
+
return JSON.parse(data);
|
|
83
|
+
}
|
|
84
|
+
catch (e) {
|
|
85
|
+
const cause = e instanceof Error ? e.message : String(e);
|
|
86
|
+
throw {
|
|
87
|
+
code: "stream_error",
|
|
88
|
+
httpStatus: 200,
|
|
89
|
+
i18nKey: "errors.unknown",
|
|
90
|
+
message: `malformed chunk frame: ${cause}`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function buildTruncatedStreamError() {
|
|
95
|
+
return {
|
|
96
|
+
code: "stream_error",
|
|
97
|
+
httpStatus: 200,
|
|
98
|
+
i18nKey: "errors.unknown",
|
|
99
|
+
message: "stream ended without a done frame",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function frameDataToDispatcherError(data) {
|
|
103
|
+
let parsed;
|
|
104
|
+
try {
|
|
105
|
+
parsed = JSON.parse(data);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return unparsableErrorFrame(data);
|
|
109
|
+
}
|
|
110
|
+
// Server serializeError shape — mapServerError expects the same fields
|
|
111
|
+
// as /api/query failures (httpStatus may be absent; reinject 200 for
|
|
112
|
+
// mid-stream gates that flush SSE headers first).
|
|
113
|
+
const envelope = serverErrorSchema.safeParse(parsed);
|
|
114
|
+
if (!envelope.success)
|
|
115
|
+
return unparsableErrorFrame(data);
|
|
116
|
+
return mapServerError({
|
|
117
|
+
...envelope.data,
|
|
118
|
+
httpStatus: envelope.data.httpStatus ?? 200,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function unparsableErrorFrame(data) {
|
|
122
|
+
return {
|
|
123
|
+
code: "stream_error",
|
|
124
|
+
httpStatus: 200,
|
|
125
|
+
i18nKey: "errors.unknown",
|
|
126
|
+
message: data.length > 0 ? data : "stream error frame",
|
|
127
|
+
};
|
|
128
|
+
}
|
package/dist/primitives.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ConfigCascade, ConfigScope, ConfigValueSource } from "@cosmicdrift/kumiko-framework/engine";
|
|
2
2
|
import type { FieldIconKey, FormWidth, IconKey, NavIconKey, RowActionDisplay, SelectOptionTone } from "@cosmicdrift/kumiko-framework/ui-types";
|
|
3
|
-
import type { FieldIssue, ListColumnViewModel, ListRowViewModel, RuntimeRenderer } from "@cosmicdrift/kumiko-headless";
|
|
4
3
|
import { type ComponentType, type FormEvent, type KeyboardEvent, type ReactNode, type Ref } from "react";
|
|
4
|
+
import type { FieldIssue, ListColumnViewModel, ListRowViewModel, RuntimeRenderer } from "./headless/index.ts";
|
|
5
5
|
export type { RuntimeRenderer };
|
|
6
6
|
/** Escape hatch for `data-*` test hooks (e.g. an E2E selector) that don't
|
|
7
7
|
* warrant a dedicated typed prop. Web merges these onto the rendered
|
|
8
|
-
* element
|
|
8
|
+
* element. */
|
|
9
9
|
export type DataAttributes = Readonly<Record<`data-${string}`, string>>;
|
|
10
10
|
/** Structural marker a top-level `actions` node can carry so DefaultForm's
|
|
11
11
|
* sticky-footer split (fw#1918) treats it as the pinned primary action even
|
|
@@ -56,7 +56,7 @@ type ButtonBaseProps = {
|
|
|
56
56
|
/** Barrierefreies Label — Pflicht bei icon-only-Buttons (children ist nur
|
|
57
57
|
* ein Icon/Zeichen), sonst hat der Button keinen zugänglichen Namen. */
|
|
58
58
|
readonly ariaLabel?: string;
|
|
59
|
-
/** Tooltip —
|
|
59
|
+
/** Tooltip — rendered as the `title` attribute. */
|
|
60
60
|
readonly title?: string;
|
|
61
61
|
/** Toggle state for toggle buttons — web sets `aria-pressed`; leave unset for plain buttons. */
|
|
62
62
|
readonly pressed?: boolean;
|
|
@@ -67,12 +67,10 @@ type ButtonBaseProps = {
|
|
|
67
67
|
* des Containers, kein Button-Prop (Kit hält arbiträres Sizing draußen). */
|
|
68
68
|
readonly width?: "full" | "auto";
|
|
69
69
|
readonly testId?: string;
|
|
70
|
-
/** Layout extras
|
|
71
|
-
* (precedent: LinkProps.className). */
|
|
70
|
+
/** Layout extras, merged via cn(). */
|
|
72
71
|
readonly className?: string;
|
|
73
72
|
/** DOM ref on the button — escape hatch for cases that need more than
|
|
74
|
-
* a click (e.g. binding a drop-target handler).
|
|
75
|
-
* impls ignore it (no native equivalent). */
|
|
73
|
+
* a click (e.g. binding a drop-target handler). Forwarded to the element. */
|
|
76
74
|
readonly ref?: Ref<HTMLButtonElement>;
|
|
77
75
|
/** Icon before the label. */
|
|
78
76
|
readonly icon?: NavIconKey;
|
|
@@ -94,8 +92,7 @@ export type LinkProps = {
|
|
|
94
92
|
/** Plain left-click handler (SPA navigation); `href` stays set for
|
|
95
93
|
* modifier/middle clicks, which the browser handles itself. */
|
|
96
94
|
readonly onPress?: () => void;
|
|
97
|
-
/** Layout
|
|
98
|
-
* Native-Impls ignorieren es (Präzedenz: CardProps.className). */
|
|
95
|
+
/** Layout extras (self-center, text-xs), merged via cn(). */
|
|
99
96
|
readonly className?: string;
|
|
100
97
|
readonly children: ReactNode;
|
|
101
98
|
readonly testId?: string;
|
|
@@ -174,6 +171,17 @@ export type FieldProps = {
|
|
|
174
171
|
/** Discriminated union — jede Input-Sorte hat ihre eigene value/onChange
|
|
175
172
|
* Signatur. Custom-Impls dispatchen intern, rendern anders (Toggle
|
|
176
173
|
* statt Checkbox), oder nur einzelne kinds unterschiedlich. */
|
|
174
|
+
/** Button beside a single-line text/number input that fills it with a
|
|
175
|
+
* suggestion. Stays usable on a `disabled` input (the readOnly+fill case). */
|
|
176
|
+
export type InputFillAction = {
|
|
177
|
+
readonly label: string;
|
|
178
|
+
readonly onPress: () => void;
|
|
179
|
+
/** A suggestion is being fetched: the button shows a spinner and is inert. */
|
|
180
|
+
readonly busy?: boolean;
|
|
181
|
+
/** The surrounding form is locked as a whole. */
|
|
182
|
+
readonly disabled?: boolean;
|
|
183
|
+
readonly testId?: string;
|
|
184
|
+
};
|
|
177
185
|
export type TrailingInputAction = {
|
|
178
186
|
readonly icon: "clear" | "undo";
|
|
179
187
|
readonly label: string;
|
|
@@ -209,12 +217,15 @@ export type InputProps = {
|
|
|
209
217
|
/** Read-only Input (z.B. gewürfelter Free-Tier-Slug). Nicht `disabled`
|
|
210
218
|
* — bleibt fokussier-/kopierbar. */
|
|
211
219
|
readonly readOnly?: boolean;
|
|
212
|
-
/** Closed FieldIconKey vocabulary (FIELD_ICONS registry, renderer
|
|
220
|
+
/** Closed FieldIconKey vocabulary (FIELD_ICONS registry, renderer/web). */
|
|
213
221
|
readonly icon?: FieldIconKey;
|
|
222
|
+
/** Resolved inline text before/after the input (EditFieldSpec.prefix/suffix). */
|
|
223
|
+
readonly prefix?: string;
|
|
224
|
+
readonly suffix?: string;
|
|
225
|
+
readonly fill?: InputFillAction;
|
|
214
226
|
readonly dataAttributes?: DataAttributes;
|
|
215
227
|
/** Raw keydown access (e.g. Enter-to-submit at the field instead of
|
|
216
|
-
* the surrounding Form).
|
|
217
|
-
* (precedent: `ButtonProps.ref`). */
|
|
228
|
+
* the surrounding Form). Forwarded to the element. */
|
|
218
229
|
readonly onKeyDown?: (event: KeyboardEvent<HTMLInputElement>) => void;
|
|
219
230
|
} | {
|
|
220
231
|
readonly kind: "email";
|
|
@@ -230,6 +241,17 @@ export type InputProps = {
|
|
|
230
241
|
* Username-or-Email) reichen das durch. */
|
|
231
242
|
readonly autoComplete?: string;
|
|
232
243
|
readonly testId?: string;
|
|
244
|
+
} | {
|
|
245
|
+
/** Month picker; the value is `YYYY-MM` (empty string when unset). */
|
|
246
|
+
readonly kind: "month";
|
|
247
|
+
readonly id: string;
|
|
248
|
+
readonly name: string;
|
|
249
|
+
readonly value: string;
|
|
250
|
+
readonly onChange: (v: string) => void;
|
|
251
|
+
readonly disabled?: boolean;
|
|
252
|
+
readonly required?: boolean;
|
|
253
|
+
readonly hasError?: boolean;
|
|
254
|
+
readonly testId?: string;
|
|
233
255
|
} | {
|
|
234
256
|
readonly kind: "password";
|
|
235
257
|
readonly id: string;
|
|
@@ -261,7 +283,7 @@ export type InputProps = {
|
|
|
261
283
|
/** Hint text shown when the field is empty (analog to kind:"text"). */
|
|
262
284
|
readonly placeholder?: string;
|
|
263
285
|
readonly testId?: string;
|
|
264
|
-
/** Closed FieldIconKey vocabulary (FIELD_ICONS registry, renderer
|
|
286
|
+
/** Closed FieldIconKey vocabulary (FIELD_ICONS registry, renderer/web). */
|
|
265
287
|
readonly icon?: FieldIconKey;
|
|
266
288
|
/** `<input step>`. "any" disables the native stepMismatch constraint
|
|
267
289
|
* (needed for decimal fields — integer fields leave this unset).
|
|
@@ -276,6 +298,9 @@ export type InputProps = {
|
|
|
276
298
|
/** Resolved display suffix (static or from a sibling field) — never
|
|
277
299
|
* part of the numeric value. */
|
|
278
300
|
readonly unit?: string;
|
|
301
|
+
readonly prefix?: string;
|
|
302
|
+
readonly suffix?: string;
|
|
303
|
+
readonly fill?: InputFillAction;
|
|
279
304
|
} | {
|
|
280
305
|
readonly kind: "range";
|
|
281
306
|
readonly id: string;
|
|
@@ -327,7 +352,7 @@ export type InputProps = {
|
|
|
327
352
|
* attribute so a phone opens the camera instead of the file picker. */
|
|
328
353
|
readonly capture?: "environment" | "user";
|
|
329
354
|
/** Web-only folder picker: the picked files (with `webkitRelativePath`)
|
|
330
|
-
* go to `onFilesPicked` and nothing is uploaded.
|
|
355
|
+
* go to `onFilesPicked` and nothing is uploaded. */
|
|
331
356
|
readonly directory?: boolean;
|
|
332
357
|
readonly onFilesPicked?: (files: readonly PickedFile[]) => void;
|
|
333
358
|
/** Translated label of the pick button; absent → the upload/change default. */
|
|
@@ -523,8 +548,8 @@ export type InputProps = {
|
|
|
523
548
|
readonly dataAttributes?: DataAttributes;
|
|
524
549
|
/** Raw keydown access (e.g. plain-Enter-submits/Shift+Enter-newline at
|
|
525
550
|
* the field instead of the surrounding Form). Composes with
|
|
526
|
-
* `onSubmitShortcut` — both fire on the same keystroke when set.
|
|
527
|
-
*
|
|
551
|
+
* `onSubmitShortcut` — both fire on the same keystroke when set. Forwarded
|
|
552
|
+
* to the element. */
|
|
528
553
|
readonly onKeyDown?: (event: KeyboardEvent<HTMLTextAreaElement>) => void;
|
|
529
554
|
};
|
|
530
555
|
export type DataTableSortDir = "asc" | "desc";
|
|
@@ -765,7 +790,7 @@ export type DataTableProps = {
|
|
|
765
790
|
readonly renderExpandedRow?: (row: ListRowViewModel) => ReactNode;
|
|
766
791
|
};
|
|
767
792
|
/** Cell type for one column of an embedded-list field. Mirrors
|
|
768
|
-
* EmbeddedListCellViewModel["type"] from `@cosmicdrift/kumiko-headless`. */
|
|
793
|
+
* EmbeddedListCellViewModel["type"] from `@cosmicdrift/kumiko-renderer/headless`. */
|
|
769
794
|
export type EmbeddedListCellType = "text" | "number" | "boolean" | "date" | "money" | "decimal" | "select" | "reference" | "timestamp";
|
|
770
795
|
/** One column of an embedded-list table (one entry per key of the source
|
|
771
796
|
* EmbeddedFieldDef's `schema`). */
|
|
@@ -862,8 +887,7 @@ export type FormSectionNavItem = {
|
|
|
862
887
|
*
|
|
863
888
|
* `title`: slot in the card header. `actions`: optional slot for the
|
|
864
889
|
* primary form actions (Save, Cancel) — renders as a footer row at the
|
|
865
|
-
* end of the card (normal document flow).
|
|
866
|
-
* same slot as a bottom bar instead. */
|
|
890
|
+
* end of the card (normal document flow). */
|
|
867
891
|
export type FormProps = {
|
|
868
892
|
readonly onSubmit: (e?: FormEvent) => void;
|
|
869
893
|
readonly children: ReactNode;
|
|
@@ -877,24 +901,20 @@ export type FormProps = {
|
|
|
877
901
|
readonly secondaryActions?: ReactNode;
|
|
878
902
|
readonly testId?: string;
|
|
879
903
|
/** Max width of the form container. Default "full" — see FormWidth
|
|
880
|
-
* (`packages/types/src/screen.ts`, EditLayout.width).
|
|
881
|
-
* ignore this prop (no width constraint there). */
|
|
904
|
+
* (`packages/types/src/screen.ts`, EditLayout.width). */
|
|
882
905
|
readonly width?: FormWidth;
|
|
883
906
|
/** Pins `actions` to the viewport bottom on narrow screens (`<640px`)
|
|
884
907
|
* instead of normal document flow, so it stays reachable when a virtual
|
|
885
908
|
* keyboard shrinks the visible viewport (fw#1918). Desktop/tablet
|
|
886
|
-
* unaffected.
|
|
887
|
-
* convention there). */
|
|
909
|
+
* unaffected. */
|
|
888
910
|
readonly stickyActions?: boolean;
|
|
889
911
|
/** Extra content rendered above the card, inside the same page padding
|
|
890
912
|
* the card itself sits in — for a host that needs its own header region
|
|
891
913
|
* (title/metrics/tabs) to share the form's left padding and width
|
|
892
|
-
* instead of rendering as unpadded siblings before it.
|
|
893
|
-
* ignore this prop. */
|
|
914
|
+
* instead of rendering as unpadded siblings before it. */
|
|
894
915
|
readonly headerRegion?: ReactNode;
|
|
895
916
|
/** Compact content on the right of the form title, same row — status
|
|
896
|
-
* chips or allowance badges that belong to the screen, not to a field.
|
|
897
|
-
* Native impls may ignore this prop. */
|
|
917
|
+
* chips or allowance badges that belong to the screen, not to a field. */
|
|
898
918
|
readonly titleAction?: ReactNode;
|
|
899
919
|
/** Sizes the form to fill its container's height (instead of the page's
|
|
900
920
|
* natural content height) so a single scrolling child — a lone
|
|
@@ -903,8 +923,7 @@ export type FormProps = {
|
|
|
903
923
|
* section and for screens that fill the shell height (together with
|
|
904
924
|
* `stickyActions`: sections scroll, footer stays pinned without
|
|
905
925
|
* `position: fixed`); every other caller leaves it unset and keeps normal
|
|
906
|
-
* document-flow height.
|
|
907
|
-
* bounded viewport there). */
|
|
926
|
+
* document-flow height. */
|
|
908
927
|
readonly fillHeight?: boolean;
|
|
909
928
|
/** Drops the surrounding card (bg/border/rounded, title/subtitle block,
|
|
910
929
|
* footer border) so sections+footer render as siblings of `headerRegion`
|
|
@@ -912,14 +931,12 @@ export type FormProps = {
|
|
|
912
931
|
* projectionDetail's tab content is a sibling of the head card, not its
|
|
913
932
|
* child (bedienkonzept A1), so it must look like a standalone screen
|
|
914
933
|
* instead of a form embedded in another card. Default false: unchanged
|
|
915
|
-
* card chrome.
|
|
916
|
-
* to begin with). */
|
|
934
|
+
* card chrome. */
|
|
917
935
|
readonly chromeless?: boolean;
|
|
918
936
|
/** Set by RenderEdit for entityEdit/actionForm screens that fill the shell
|
|
919
937
|
* height: the form renders without a surrounding card, in a padded scroll
|
|
920
938
|
* surface with a fixed-width form column. Requires `fillHeight`; projection
|
|
921
|
-
* detail screens (which also fill the height) do not set it.
|
|
922
|
-
* may ignore this prop. */
|
|
939
|
+
* detail screens (which also fill the height) do not set it. */
|
|
923
940
|
readonly screenForm?: boolean;
|
|
924
941
|
/** Number of unsaved changes, shown in the pinned footer; 0 shows the quiet
|
|
925
942
|
* "No unsaved changes" status. Omitted (create mode) — no status at all. */
|
|
@@ -933,7 +950,7 @@ export type FormProps = {
|
|
|
933
950
|
* `screenForm`. The web impl shows it only with three or more entries. */
|
|
934
951
|
readonly sectionNav?: readonly FormSectionNavItem[];
|
|
935
952
|
/** Leading column next to the scroll surface of a `screenForm` (wizard step
|
|
936
|
-
* navigation).
|
|
953
|
+
* navigation). */
|
|
937
954
|
readonly sideRail?: ReactNode;
|
|
938
955
|
};
|
|
939
956
|
/** Titled Gruppe von Feldern. Web: `<fieldset>` + `<legend>`, Native:
|
|
@@ -1414,7 +1431,7 @@ export type CopyButtonProps = {
|
|
|
1414
1431
|
readonly label: string;
|
|
1415
1432
|
readonly copiedLabel: string;
|
|
1416
1433
|
readonly variant?: "primary" | "secondary";
|
|
1417
|
-
/** Layout extras
|
|
1434
|
+
/** Layout extras, merged via cn(). */
|
|
1418
1435
|
readonly className?: string;
|
|
1419
1436
|
readonly testId?: string;
|
|
1420
1437
|
};
|
|
@@ -1426,7 +1443,7 @@ export type ShareButtonProps = {
|
|
|
1426
1443
|
readonly text: string;
|
|
1427
1444
|
readonly label: string;
|
|
1428
1445
|
readonly variant?: "primary" | "secondary";
|
|
1429
|
-
/** Layout extras
|
|
1446
|
+
/** Layout extras, merged via cn(). */
|
|
1430
1447
|
readonly className?: string;
|
|
1431
1448
|
readonly testId?: string;
|
|
1432
1449
|
} & ({
|
package/dist/primitives.js
CHANGED
|
@@ -79,7 +79,7 @@ export function useOptionalPrimitives() {
|
|
|
79
79
|
export function usePrimitives() {
|
|
80
80
|
const registry = useContext(PrimitivesContext);
|
|
81
81
|
if (registry === undefined) {
|
|
82
|
-
throw new Error("usePrimitives: no <PrimitivesProvider> mounted. Wrap your app in one (createKumikoApp does this for you with defaultPrimitives from @cosmicdrift/kumiko-renderer
|
|
82
|
+
throw new Error("usePrimitives: no <PrimitivesProvider> mounted. Wrap your app in one (createKumikoApp does this for you with defaultPrimitives from @cosmicdrift/kumiko-renderer/web).");
|
|
83
83
|
}
|
|
84
84
|
return registry;
|
|
85
85
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Dispatcher, DispatcherError } from "@cosmicdrift/kumiko-headless";
|
|
2
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import type { Dispatcher, DispatcherError } from "../headless/index.ts";
|
|
3
3
|
export declare const SESSION_ENDED_ERROR_CODES: readonly ["session_invalid", "invalid_token", "missing_token", "unauthenticated"];
|
|
4
4
|
export declare function isSessionEndedError(error: Pick<DispatcherError, "code" | "httpStatus">): boolean;
|
|
5
5
|
export type SessionEndedSignal = {
|
package/dist/tokens.d.ts
CHANGED
|
@@ -85,8 +85,7 @@ export declare function TokensProvider({ children, value }: TokensProviderProps)
|
|
|
85
85
|
export declare function useTokens(): Tokens;
|
|
86
86
|
/** Volle API inkl. Theme-Toggle. Für den Dark/Light-Switch-Button. */
|
|
87
87
|
export declare function useTokenController(): TokensApi;
|
|
88
|
-
/** Tokens
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* -native) importieren das in ihre TokensApi-Impl. */
|
|
88
|
+
/** Tokens with var-string values. Constant: the "values" are references,
|
|
89
|
+
* the real colors change via CSS without mutating the object. Platform
|
|
90
|
+
* bindings (renderer/web) import it into their TokensApi impl. */
|
|
92
91
|
export declare const cssVarTokens: Tokens;
|
package/dist/tokens.js
CHANGED
|
@@ -30,14 +30,13 @@ export function useTokens() {
|
|
|
30
30
|
export function useTokenController() {
|
|
31
31
|
const api = useContext(TokensContext);
|
|
32
32
|
if (api === undefined) {
|
|
33
|
-
throw new Error("useTokens/useTokenController: no <TokensProvider> mounted. createKumikoApp verdrahtet den Provider automatisch mit @cosmicdrift/kumiko-renderer
|
|
33
|
+
throw new Error("useTokens/useTokenController: no <TokensProvider> mounted. createKumikoApp verdrahtet den Provider automatisch mit @cosmicdrift/kumiko-renderer/web defaults.");
|
|
34
34
|
}
|
|
35
35
|
return api;
|
|
36
36
|
}
|
|
37
|
-
/** Tokens
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* -native) importieren das in ihre TokensApi-Impl. */
|
|
37
|
+
/** Tokens with var-string values. Constant: the "values" are references,
|
|
38
|
+
* the real colors change via CSS without mutating the object. Platform
|
|
39
|
+
* bindings (renderer/web) import it into their TokensApi impl. */
|
|
41
40
|
export const cssVarTokens = {
|
|
42
41
|
color: {
|
|
43
42
|
background: "var(--color-background)",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { AppSchema } from "../../index.ts";
|
|
3
|
+
export declare const APP_SCHEMA_API_PATH = "/api/schema";
|
|
4
|
+
export declare function isAppSchemaPayload(value: unknown): value is AppSchema;
|
|
5
|
+
export type AppSchemaFetchResult = {
|
|
6
|
+
readonly kind: "loaded";
|
|
7
|
+
readonly app: AppSchema;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: "session-ended";
|
|
10
|
+
} | {
|
|
11
|
+
readonly kind: "unauthorized";
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: "failed";
|
|
14
|
+
};
|
|
15
|
+
export declare function fetchAppSchema(signal: AbortSignal, schemaUrl?: string): Promise<AppSchemaFetchResult>;
|
|
16
|
+
export declare function AppSchemaFetchBoot({ onLoaded, schemaUrl, }: {
|
|
17
|
+
readonly onLoaded: (app: AppSchema) => void;
|
|
18
|
+
readonly schemaUrl?: string;
|
|
19
|
+
}): ReactNode;
|