@cosmicdrift/kumiko-renderer 0.374.0 → 0.378.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 +10 -7
- 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/form-derivation-patch.d.ts +8 -0
- package/dist/components/form-derivation-patch.js +24 -0
- package/dist/components/form-screen-layout.d.ts +13 -0
- package/dist/components/form-screen-layout.js +13 -0
- 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 +6 -3
- package/dist/components/render-edit.d.ts +1 -1
- package/dist/components/render-edit.js +18 -3
- package/dist/components/render-field.d.ts +1 -1
- package/dist/components/render-field.js +12 -2
- 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/file-ids-of.d.ts +1 -0
- package/dist/file-ids-of.js +7 -0
- package/dist/flow-diagram/icons.d.ts +3 -0
- package/dist/flow-diagram/icons.js +14 -0
- package/dist/flow-diagram/index.d.ts +2 -0
- package/dist/flow-diagram/index.js +1 -0
- package/dist/flow-diagram/render.d.ts +3 -0
- package/dist/flow-diagram/render.js +234 -0
- package/dist/flow-diagram/types.d.ts +18 -0
- package/dist/flow-diagram/types.js +1 -0
- 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 +21 -0
- package/dist/headless/view-model/edit.js +512 -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 +6 -0
- package/dist/i18n.d.ts +1 -1
- package/dist/i18n.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +5 -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 +45 -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 +31 -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/file-value-list.d.ts +3 -0
- package/dist/web/primitives/file-value-list.js +22 -0
- package/dist/web/primitives/index.d.ts +34 -0
- package/dist/web/primitives/index.js +2023 -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/bounded-load-cache.d.ts +1 -0
- package/dist/web/widgets/bounded-load-cache.js +25 -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 +177 -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 +28 -0
- package/dist/web/widgets/index.js +31 -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/pdf-preview.d.ts +10 -0
- package/dist/web/widgets/pdf-preview.js +140 -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 +114 -7
- package/src/changes.json +92 -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 +405 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
type PublicShellCommonProps = {
|
|
3
|
+
readonly brand: ReactNode;
|
|
4
|
+
readonly headerActions?: ReactNode;
|
|
5
|
+
readonly footer?: ReactNode;
|
|
6
|
+
readonly children: ReactNode;
|
|
7
|
+
readonly testId?: string;
|
|
8
|
+
};
|
|
9
|
+
export type PublicShellVariant = "marketing" | "focus" | "card";
|
|
10
|
+
export type PublicShellProps = PublicShellCommonProps & ({
|
|
11
|
+
readonly variant: "marketing";
|
|
12
|
+
readonly notice?: ReactNode;
|
|
13
|
+
} | {
|
|
14
|
+
readonly variant: "focus";
|
|
15
|
+
readonly progress?: ReactNode;
|
|
16
|
+
} | {
|
|
17
|
+
readonly variant: "card";
|
|
18
|
+
});
|
|
19
|
+
/** One header and footer for anonymous pages; `focus` narrows to a task column,
|
|
20
|
+
* `card` centers a single card (sign-in). */
|
|
21
|
+
export declare function PublicShell(props: PublicShellProps): ReactNode;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const CONTENT_WIDTH_CLASS = "mx-auto w-full max-w-6xl px-4 sm:px-6";
|
|
3
|
+
const MAIN_CLASS = {
|
|
4
|
+
marketing: "w-full flex-1",
|
|
5
|
+
focus: "mx-auto w-full max-w-3xl flex-1 px-4 py-6 sm:px-6",
|
|
6
|
+
card: "flex w-full flex-1 items-center justify-center bg-muted px-4 py-10",
|
|
7
|
+
};
|
|
8
|
+
/** One header and footer for anonymous pages; `focus` narrows to a task column,
|
|
9
|
+
* `card` centers a single card (sign-in). */
|
|
10
|
+
export function PublicShell(props) {
|
|
11
|
+
const { variant, brand, headerActions, footer, children, testId = "public-shell" } = props;
|
|
12
|
+
const notice = props.variant === "marketing" ? props.notice : undefined;
|
|
13
|
+
const progress = props.variant === "focus" ? props.progress : undefined;
|
|
14
|
+
return (_jsxs("div", { "data-testid": testId, "data-variant": variant, className: "flex min-h-dvh flex-col bg-background text-foreground", children: [notice !== undefined && (_jsx("div", { "data-testid": `${testId}-notice`, className: "bg-promo px-4 py-2 text-center text-promo-foreground text-sm", children: notice })), _jsxs("header", { className: "border-border border-b", children: [_jsxs("div", { className: `${CONTENT_WIDTH_CLASS} flex min-h-16 items-center justify-between gap-4`, children: [_jsx("div", { className: "min-w-0", children: brand }), headerActions !== undefined && (_jsx("div", { className: "flex shrink-0 items-center gap-2", children: headerActions }))] }), progress !== undefined && (_jsx("div", { "data-testid": `${testId}-progress`, className: "mx-auto w-full max-w-3xl px-4 pb-3 sm:px-6", children: progress }))] }), _jsx("main", { className: MAIN_CLASS[variant], children: variant === "card" ? (_jsx("div", { "data-testid": `${testId}-card`, className: "w-full max-w-md rounded-(--card-radius) border border-border bg-card p-6 text-card-foreground shadow-sm sm:p-8", children: children })) : (children) }), footer !== undefined && (_jsx("footer", { className: "border-border border-t", children: _jsx("div", { className: `${CONTENT_WIDTH_CLASS} py-6 text-muted-foreground text-sm`, children: footer }) }))] }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type DataTableProps } from "../../index.ts";
|
|
3
|
+
export type QueryTableColumn = {
|
|
4
|
+
readonly field: string;
|
|
5
|
+
/** Translated Header-Label (i18n-Key auflösen liegt beim Caller). */
|
|
6
|
+
readonly label: string;
|
|
7
|
+
/** Field-Type für die Zell-Formatierung. Default "text". */
|
|
8
|
+
readonly type?: string;
|
|
9
|
+
};
|
|
10
|
+
export type QueryTableProps<TData = unknown> = {
|
|
11
|
+
/** Dispatcher-Query-Type (`<feature>:query:<entity>:<verb>`). */
|
|
12
|
+
readonly query: string;
|
|
13
|
+
readonly payload?: unknown;
|
|
14
|
+
/** SSE-Invalidierung — refetcht bei Entity-Events (useQuery live-mode). */
|
|
15
|
+
readonly live?: boolean;
|
|
16
|
+
readonly columns: readonly QueryTableColumn[];
|
|
17
|
+
/** Rows aus dem Query-Result ziehen. Default: Result selbst als Array. */
|
|
18
|
+
readonly rows?: (data: TData) => readonly Readonly<Record<string, unknown>>[];
|
|
19
|
+
/** Row-Id für Keys/Row-Click. Default: `row.id`, sonst der Index. */
|
|
20
|
+
readonly rowId?: (row: Readonly<Record<string, unknown>>, index: number) => string;
|
|
21
|
+
readonly onRowClick?: DataTableProps["onRowClick"];
|
|
22
|
+
readonly rowActions?: DataTableProps["rowActions"];
|
|
23
|
+
/** Empty-Inhalt — Default ist der Standard-Empty-State der Listen. */
|
|
24
|
+
readonly emptyState?: ReactNode;
|
|
25
|
+
readonly toolbarTitle?: ReactNode;
|
|
26
|
+
readonly toolbarEnd?: ReactNode;
|
|
27
|
+
readonly testId?: string;
|
|
28
|
+
};
|
|
29
|
+
export declare function QueryTable<TData = unknown>({ query, payload, live, columns, rows, rowId, onRowClick, rowActions, emptyState, toolbarTitle, toolbarEnd, testId, }: QueryTableProps<TData>): ReactNode;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { usePrimitives, useQuery, useTranslation } from "../../index.js";
|
|
3
|
+
import { EmptyState, ErrorState, LoadingState } from "./states.js";
|
|
4
|
+
function defaultRows(data) {
|
|
5
|
+
return Array.isArray(data) ? data : [];
|
|
6
|
+
}
|
|
7
|
+
export function QueryTable({ query, payload, live = false, columns, rows, rowId, onRowClick, rowActions, emptyState, toolbarTitle, toolbarEnd, testId, }) {
|
|
8
|
+
const { DataTable } = usePrimitives();
|
|
9
|
+
const t = useTranslation();
|
|
10
|
+
const { data, error, loading, refetch } = useQuery(query, payload ?? {}, { live });
|
|
11
|
+
if (loading && data === null)
|
|
12
|
+
return _jsx(LoadingState, { rows: 4, testId: testId });
|
|
13
|
+
if (error !== null)
|
|
14
|
+
return _jsx(ErrorState, { error: error, onRetry: () => void refetch(), testId: testId });
|
|
15
|
+
const rawRows = rows !== undefined ? rows(data) : defaultRows(data);
|
|
16
|
+
const vmRows = rawRows.map((row, index) => ({
|
|
17
|
+
id: rowId !== undefined
|
|
18
|
+
? rowId(row, index)
|
|
19
|
+
: typeof row["id"] === "string"
|
|
20
|
+
? row["id"]
|
|
21
|
+
: String(index),
|
|
22
|
+
values: row,
|
|
23
|
+
}));
|
|
24
|
+
return (_jsx(DataTable, { columns: columns.map((c) => ({
|
|
25
|
+
field: c.field,
|
|
26
|
+
label: c.label,
|
|
27
|
+
type: c.type ?? "text",
|
|
28
|
+
sortable: false,
|
|
29
|
+
})), rows: vmRows, onRowClick: onRowClick, rowActions: rowActions, emptyState: emptyState ?? _jsx(EmptyState, { title: t("kumiko.list.no-entries") }), toolbarTitle: toolbarTitle, toolbarEnd: toolbarEnd, testId: testId }));
|
|
30
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Ergebnis-Sektion eines Rechners: SectionCard mit Empty-Zustand (Banner)
|
|
3
|
+
* oder Kennzahl-Liste (DetailList) + optionalen Extras (Tabelle, Hinweise).
|
|
4
|
+
* Ersetzt die handgebauten `<dl>`/Banner-Blöcke in Custom-Screens. */
|
|
5
|
+
export declare function ResultPanel({ title, subtitle, empty, emptyText, rows, footer, children, testId, }: {
|
|
6
|
+
readonly title: string;
|
|
7
|
+
readonly subtitle?: string;
|
|
8
|
+
readonly empty?: boolean;
|
|
9
|
+
readonly emptyText?: ReactNode;
|
|
10
|
+
readonly rows?: readonly {
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly value: ReactNode;
|
|
13
|
+
readonly emphasize?: boolean;
|
|
14
|
+
}[];
|
|
15
|
+
/** Action-Slot am Karten-Fuß (z.B. „In Finanzierung übernehmen"). */
|
|
16
|
+
readonly footer?: ReactNode;
|
|
17
|
+
readonly children?: ReactNode;
|
|
18
|
+
readonly testId?: string;
|
|
19
|
+
}): ReactNode;
|
|
20
|
+
export interface ResultColumn<Row> {
|
|
21
|
+
readonly header: string;
|
|
22
|
+
readonly align?: "left" | "right";
|
|
23
|
+
readonly cell: (row: Row) => ReactNode;
|
|
24
|
+
}
|
|
25
|
+
export interface ResultTableFooterRow {
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly value: ReactNode;
|
|
28
|
+
readonly emphasize?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Statische, prop-getriebene Ergebnistabelle für berechnete Zeilen (Tranchen,
|
|
31
|
+
* Szenarien). Nimmt dem Screen die `<table>`+tabular-nums-Ketten ab.
|
|
32
|
+
* ponytail: bewusst die minimale Read-only-Tabelle — für Sort/Pager/Facets
|
|
33
|
+
* stattdessen usePrimitives().DataTable bzw. QueryTable nutzen. */
|
|
34
|
+
export declare function ResultTable<Row>({ columns, rows, rowKey, testId, className, card, footer, }: {
|
|
35
|
+
readonly columns: readonly ResultColumn<Row>[];
|
|
36
|
+
readonly rows: readonly Row[];
|
|
37
|
+
readonly rowKey: (row: Row, index: number) => string;
|
|
38
|
+
readonly testId?: string;
|
|
39
|
+
readonly className?: string;
|
|
40
|
+
/** Rahmen-Look wie die CRUD-Liste (DataTable): gerundeter Border-Container +
|
|
41
|
+
* bg-muted-Header-Band. Default = bare (nur die Tabelle, ohne Container). */
|
|
42
|
+
readonly card?: boolean;
|
|
43
|
+
/** Summary rows (Subtotal/Tax/Total) rendered as real `<tr>`s in the same
|
|
44
|
+
* `<table>` instead of a separate flex-div next to it — guarantees
|
|
45
|
+
* column-alignment to the last (typically "Amount") column instead of
|
|
46
|
+
* approximating it with an independent layout. */
|
|
47
|
+
readonly footer?: readonly ResultTableFooterRow[];
|
|
48
|
+
}): ReactNode;
|
|
49
|
+
export interface ComparisonMetric<Col> {
|
|
50
|
+
readonly label: string;
|
|
51
|
+
readonly value: (col: Col, index: number) => ReactNode;
|
|
52
|
+
/** Index der besten Spalte für diese Zeile (hervorgehoben); -1 = keine. */
|
|
53
|
+
readonly bestIndex?: (cols: readonly Col[]) => number;
|
|
54
|
+
}
|
|
55
|
+
/** Transponierte Vergleichstabelle: Zeile = Kennzahl, Spalte = Variante, je
|
|
56
|
+
* Kennzahl optional die beste Spalte hervorgehoben. Für Szenario-/Angebots-
|
|
57
|
+
* Vergleiche, wo ResultTable (Zeile=Datensatz) nicht passt. */
|
|
58
|
+
export declare function ComparisonTable<Col>({ columns, columnHeader, columnKey, metrics, metricLabel, testId, className, card, }: {
|
|
59
|
+
readonly columns: readonly Col[];
|
|
60
|
+
readonly columnHeader: (col: Col, index: number) => string;
|
|
61
|
+
readonly columnKey: (col: Col, index: number) => string;
|
|
62
|
+
readonly metrics: readonly ComparisonMetric<Col>[];
|
|
63
|
+
readonly metricLabel: string;
|
|
64
|
+
readonly testId?: string;
|
|
65
|
+
readonly className?: string;
|
|
66
|
+
/** Rahmen-Look wie die CRUD-Liste (DataTable): gerundeter Border-Container +
|
|
67
|
+
* bg-muted-Header-Band. Default = bare. */
|
|
68
|
+
readonly card?: boolean;
|
|
69
|
+
}): ReactNode;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { usePrimitives } from "../../index.js";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { DetailList } from "./detail-list.js";
|
|
5
|
+
import { SectionCard } from "./section-card.js";
|
|
6
|
+
/** Ergebnis-Sektion eines Rechners: SectionCard mit Empty-Zustand (Banner)
|
|
7
|
+
* oder Kennzahl-Liste (DetailList) + optionalen Extras (Tabelle, Hinweise).
|
|
8
|
+
* Ersetzt die handgebauten `<dl>`/Banner-Blöcke in Custom-Screens. */
|
|
9
|
+
export function ResultPanel({ title, subtitle, empty, emptyText, rows, footer, children, testId, }) {
|
|
10
|
+
const { Banner } = usePrimitives();
|
|
11
|
+
return (_jsx(SectionCard, { title: title, subtitle: subtitle, footer: footer, testId: testId, children: empty === true ? (_jsx(Banner, { variant: "info", padded: true, children: emptyText })) : (_jsxs("div", { className: "flex flex-col gap-4", children: [rows !== undefined && rows.length > 0 && _jsx(DetailList, { rows: rows }), children] })) }));
|
|
12
|
+
}
|
|
13
|
+
/** Statische, prop-getriebene Ergebnistabelle für berechnete Zeilen (Tranchen,
|
|
14
|
+
* Szenarien). Nimmt dem Screen die `<table>`+tabular-nums-Ketten ab.
|
|
15
|
+
* ponytail: bewusst die minimale Read-only-Tabelle — für Sort/Pager/Facets
|
|
16
|
+
* stattdessen usePrimitives().DataTable bzw. QueryTable nutzen. */
|
|
17
|
+
export function ResultTable({ columns, rows, rowKey, testId, className, card, footer, }) {
|
|
18
|
+
const table = (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { "data-testid": testId, className: cn("w-full text-sm", className), children: [_jsx("thead", { className: cn(card === true && "bg-muted"), children: _jsx("tr", { className: "border-b text-left text-muted-foreground", children: columns.map((col) => (_jsx("th", { className: cn("py-1.5 font-medium", card === true && "px-3", col.align === "right" && "text-right"), children: col.header }, col.header))) }) }), _jsxs("tbody", { children: [rows.map((row, i) => (_jsx("tr", { className: "border-b last:border-0", children: columns.map((col) => (_jsx("td", { className: cn("py-1.5", card === true && "px-3", col.align === "right" && "text-right tabular-nums"), children: col.cell(row) }, col.header))) }, rowKey(row, i)))), footer?.map((row, i) => (_jsxs("tr", { className: cn(i === 0 && "border-t", row.emphasize === true && "font-semibold"), children: [_jsxs("td", { colSpan: columns.length > 1 ? Math.max(columns.length - 1, 1) : undefined, className: cn("py-1.5 text-muted-foreground", card === true && "px-3", row.emphasize === true && "text-foreground", columns.length === 1 && "flex items-center justify-between gap-4"), children: [row.label, columns.length === 1 && (_jsx("span", { className: cn("text-right tabular-nums", row.emphasize === true && "text-foreground"), children: row.value }))] }), columns.length > 1 && (_jsx("td", { className: cn("py-1.5 text-right tabular-nums", card === true && "px-3"), children: row.value }))] }, row.label)))] })] }) }));
|
|
19
|
+
return card === true ? (_jsx("div", { className: "overflow-hidden rounded-lg border bg-card", children: table })) : (table);
|
|
20
|
+
}
|
|
21
|
+
/** Transponierte Vergleichstabelle: Zeile = Kennzahl, Spalte = Variante, je
|
|
22
|
+
* Kennzahl optional die beste Spalte hervorgehoben. Für Szenario-/Angebots-
|
|
23
|
+
* Vergleiche, wo ResultTable (Zeile=Datensatz) nicht passt. */
|
|
24
|
+
export function ComparisonTable({ columns, columnHeader, columnKey, metrics, metricLabel, testId, className, card, }) {
|
|
25
|
+
const table = (_jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { "data-testid": testId, className: cn("w-full min-w-[24rem] text-sm", className), children: [_jsx("thead", { className: cn(card === true && "bg-muted"), children: _jsxs("tr", { className: "border-b text-left text-muted-foreground", children: [_jsx("th", { className: cn("py-1.5 font-medium", card === true && "px-3"), children: metricLabel }), columns.map((col, i) => (_jsx("th", { className: cn("py-1.5 text-right font-medium", card === true && "px-3"), children: columnHeader(col, i) }, columnKey(col, i))))] }) }), _jsx("tbody", { children: metrics.map((metric) => {
|
|
26
|
+
const best = metric.bestIndex !== undefined ? metric.bestIndex(columns) : -1;
|
|
27
|
+
return (_jsxs("tr", { className: "border-b last:border-0", children: [_jsx("td", { className: cn("py-1.5 text-muted-foreground", card === true && "px-3"), children: metric.label }), columns.map((col, i) => (_jsx("td", { className: cn("py-1.5 text-right tabular-nums", card === true && "px-3"), children: i === best ? (_jsx("span", { className: "inline-block rounded bg-primary/10 px-2 py-0.5 font-semibold text-primary", children: metric.value(col, i) })) : (metric.value(col, i)) }, columnKey(col, i))))] }, metric.label));
|
|
28
|
+
}) })] }) }));
|
|
29
|
+
return card === true ? (_jsx("div", { className: "overflow-hidden rounded-lg border bg-card", children: table })) : (table);
|
|
30
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Sektion mit Titel + optionalem Action-Slot (Range-Umschalter, Filter) —
|
|
3
|
+
* ersetzt die wiederholten `<section className={CARD}>…<h2>`-Blöcke in
|
|
4
|
+
* Custom-Screens. Dünner Wrapper über das Card-Primitive. */
|
|
5
|
+
export declare function SectionCard({ title, subtitle, action, footer, children, testId, }: {
|
|
6
|
+
readonly title: string;
|
|
7
|
+
readonly subtitle?: string;
|
|
8
|
+
readonly action?: ReactNode;
|
|
9
|
+
readonly footer?: ReactNode;
|
|
10
|
+
readonly children: ReactNode;
|
|
11
|
+
readonly testId?: string;
|
|
12
|
+
}): ReactNode;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { usePrimitives } from "../../index.js";
|
|
3
|
+
/** Sektion mit Titel + optionalem Action-Slot (Range-Umschalter, Filter) —
|
|
4
|
+
* ersetzt die wiederholten `<section className={CARD}>…<h2>`-Blöcke in
|
|
5
|
+
* Custom-Screens. Dünner Wrapper über das Card-Primitive. */
|
|
6
|
+
export function SectionCard({ title, subtitle, action, footer, children, testId, }) {
|
|
7
|
+
const { Card } = usePrimitives();
|
|
8
|
+
return (_jsx(Card, { slots: { title, subtitle, headerActions: action, footer }, testId: testId, children: _jsx("div", { className: "flex h-full flex-col gap-4", children: children }) }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
2
|
+
import type { ComponentProps, CSSProperties, ReactNode } from "react";
|
|
3
|
+
export type DrawerSheetContentProps = ComponentProps<typeof SheetPrimitive.Content> & {
|
|
4
|
+
readonly side?: "top" | "right" | "bottom" | "left";
|
|
5
|
+
readonly showCloseButton?: boolean;
|
|
6
|
+
readonly overlayStyle?: CSSProperties;
|
|
7
|
+
readonly closeLabel: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function DrawerSheetContent({ className, overlayStyle, children, side, showCloseButton, closeLabel, ...props }: DrawerSheetContentProps): ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { XIcon } from "lucide-react";
|
|
3
|
+
import { Dialog as SheetPrimitive } from "radix-ui";
|
|
4
|
+
import { cn } from "../lib/cn.js";
|
|
5
|
+
export function DrawerSheetContent({ className, overlayStyle, children, side = "right", showCloseButton = true, closeLabel, ...props }) {
|
|
6
|
+
return (_jsxs(SheetPrimitive.Portal, { "data-slot": "sheet-portal", children: [_jsx(SheetPrimitive.Overlay, { "data-slot": "sheet-overlay", style: overlayStyle, className: "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0" }), _jsxs(SheetPrimitive.Content, { "data-slot": "sheet-content", className: cn("fixed z-50 flex flex-col gap-4 bg-background shadow-lg transition ease-in-out data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:animate-in data-[state=open]:duration-500", side === "right" &&
|
|
7
|
+
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm", side === "left" &&
|
|
8
|
+
"inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm", side === "top" &&
|
|
9
|
+
"inset-x-0 top-0 h-auto border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top", side === "bottom" &&
|
|
10
|
+
"inset-x-0 bottom-0 h-auto border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom", className), ...props, children: [children, showCloseButton && (_jsxs(SheetPrimitive.Close, { className: "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none data-[state=open]:bg-secondary", children: [_jsx(XIcon, { className: "size-4" }), _jsx("span", { className: "sr-only", children: closeLabel })] }))] })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type SideBySideTableColumn = {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
};
|
|
6
|
+
export type SideBySideTableCell = {
|
|
7
|
+
readonly content: ReactNode;
|
|
8
|
+
/** Spans this cell over following columns (a value that is identical on
|
|
9
|
+
* both sides shown once). */
|
|
10
|
+
readonly colSpan?: number;
|
|
11
|
+
};
|
|
12
|
+
export type SideBySideTableRow = {
|
|
13
|
+
readonly id: string;
|
|
14
|
+
readonly header: ReactNode;
|
|
15
|
+
readonly cells: readonly SideBySideTableCell[];
|
|
16
|
+
/** Highlights a row that needs attention (e.g. differing values). */
|
|
17
|
+
readonly tone?: "warn";
|
|
18
|
+
};
|
|
19
|
+
/** Small read-only grid with real table semantics (`th scope`) whose cells
|
|
20
|
+
* are arbitrary React nodes — for side-by-side comparisons like "from the
|
|
21
|
+
* document" vs. "in stock". Not a `DataTable`: no sorting, paging, or
|
|
22
|
+
* view-model columns. */
|
|
23
|
+
export declare function SideBySideTable({ caption, rowHeaderLabel, columns, rows, rowHeaderWidth, testId, }: {
|
|
24
|
+
/** Accessible name of the table, not rendered visibly. */
|
|
25
|
+
readonly caption: string;
|
|
26
|
+
readonly rowHeaderLabel: string;
|
|
27
|
+
readonly columns: readonly SideBySideTableColumn[];
|
|
28
|
+
readonly rows: readonly SideBySideTableRow[];
|
|
29
|
+
readonly rowHeaderWidth?: number;
|
|
30
|
+
readonly testId?: string;
|
|
31
|
+
}): ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
/** Small read-only grid with real table semantics (`th scope`) whose cells
|
|
4
|
+
* are arbitrary React nodes — for side-by-side comparisons like "from the
|
|
5
|
+
* document" vs. "in stock". Not a `DataTable`: no sorting, paging, or
|
|
6
|
+
* view-model columns. */
|
|
7
|
+
export function SideBySideTable({ caption, rowHeaderLabel, columns, rows, rowHeaderWidth = 120, testId, }) {
|
|
8
|
+
return (_jsxs("table", { "data-testid": testId, className: "w-full table-fixed border-collapse border border-border text-sm", children: [_jsx("caption", { className: "sr-only", children: caption }), _jsx("thead", { children: _jsxs("tr", { className: "bg-muted text-[13px] text-muted-foreground", children: [_jsx("th", { scope: "col", style: { width: rowHeaderWidth }, className: "border-b border-border px-3 py-2 text-left font-medium", children: rowHeaderLabel }), columns.map((column) => (_jsx("th", { scope: "col", className: "border-b border-border px-3 py-2 text-left font-medium", children: column.label }, column.id)))] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { className: cn(row.tone === "warn" && "bg-status-warn-surface"), children: [_jsx("th", { scope: "row", className: cn("border-b border-border-row px-3 py-2 text-left align-top", row.tone === "warn"
|
|
9
|
+
? "font-semibold text-status-warn"
|
|
10
|
+
: "font-normal text-muted-foreground"), children: row.header }), row.cells.map((cell, index) => (_jsx("td", { colSpan: cell.colSpan, className: "border-b border-border-row px-3 py-2 align-top", children: cell.content }, index)))] }, row.id))) })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { DashboardStatTone } from "@cosmicdrift/kumiko-types/screen";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export type StatTone = DashboardStatTone;
|
|
4
|
+
export type StatDelta = {
|
|
5
|
+
readonly value: string;
|
|
6
|
+
readonly direction: "up" | "down";
|
|
7
|
+
readonly tone?: StatTone;
|
|
8
|
+
};
|
|
9
|
+
export declare function Sparkline({ points, className, }: {
|
|
10
|
+
readonly points: readonly number[];
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
}): ReactNode;
|
|
13
|
+
/** Icon-tragende Kennzahl-Kachel mit optionalem Delta-Chip, Trend-Zeile
|
|
14
|
+
* und Sparkline. `icon` ist ein fertiger Knoten (App liefert ihr SVG). */
|
|
15
|
+
export declare function StatCard({ icon, label, value, sub, tone, accentColor, delta, trend, spark, testId, children, }: {
|
|
16
|
+
readonly icon?: ReactNode;
|
|
17
|
+
readonly label: string;
|
|
18
|
+
readonly value: string;
|
|
19
|
+
readonly sub?: string;
|
|
20
|
+
readonly tone?: StatTone;
|
|
21
|
+
readonly accentColor?: string;
|
|
22
|
+
readonly delta?: StatDelta;
|
|
23
|
+
readonly trend?: string;
|
|
24
|
+
readonly spark?: readonly number[];
|
|
25
|
+
readonly testId?: string;
|
|
26
|
+
/** Extra content below the built-in fields (e.g. a usage meter) — kept
|
|
27
|
+
* inside the same card chrome instead of stacking a second bordered box. */
|
|
28
|
+
readonly children?: ReactNode;
|
|
29
|
+
}): ReactNode;
|
|
30
|
+
/** Flat KPI cell for a strip (divider instead of card): label, value with
|
|
31
|
+
* sparkline beside it, sub line. */
|
|
32
|
+
export declare function StatStripCell({ icon, label, value, sub, tone, accentColor, delta, spark, testId, }: {
|
|
33
|
+
/** Chip before the label, colored like StatCard's (`accentColor` or the tone). */
|
|
34
|
+
readonly icon?: ReactNode;
|
|
35
|
+
readonly label: string;
|
|
36
|
+
readonly value: string;
|
|
37
|
+
readonly sub?: string;
|
|
38
|
+
readonly tone?: StatTone;
|
|
39
|
+
readonly accentColor?: string;
|
|
40
|
+
readonly delta?: StatDelta;
|
|
41
|
+
readonly spark?: readonly number[];
|
|
42
|
+
readonly testId?: string;
|
|
43
|
+
}): ReactNode;
|
|
44
|
+
/** Kompakte Kennzahl-Kachel (ohne Icon) — für dichte KPI-Raster.
|
|
45
|
+
* StatCard ist die icon-tragende Variante. */
|
|
46
|
+
export declare function MiniStat({ label, value, tone, emphasize, testId, labelTestId, valueTestId, }: {
|
|
47
|
+
readonly label: string;
|
|
48
|
+
readonly value: string;
|
|
49
|
+
readonly tone?: StatTone;
|
|
50
|
+
readonly emphasize?: boolean;
|
|
51
|
+
readonly testId?: string;
|
|
52
|
+
readonly labelTestId?: string;
|
|
53
|
+
readonly valueTestId?: string;
|
|
54
|
+
}): ReactNode;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { usePrimitives } from "../../index.js";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
const TONE_CHIP = {
|
|
5
|
+
default: "bg-muted text-foreground",
|
|
6
|
+
positive: "bg-primary/10 text-primary",
|
|
7
|
+
ok: "bg-status-ok-surface text-status-ok",
|
|
8
|
+
warn: "bg-destructive/10 text-destructive",
|
|
9
|
+
negative: "bg-status-bad-surface text-status-bad",
|
|
10
|
+
};
|
|
11
|
+
const TONE_VALUE = {
|
|
12
|
+
default: "text-foreground",
|
|
13
|
+
positive: "text-primary",
|
|
14
|
+
ok: "text-status-ok",
|
|
15
|
+
warn: "text-destructive",
|
|
16
|
+
negative: "text-status-bad",
|
|
17
|
+
};
|
|
18
|
+
// Inline-SVG-Sparkline (kein Chart-Dep für eine 28px-Kurve): Linie +
|
|
19
|
+
// schwacher Flächen-Verlauf, Farbe via currentColor (Caller setzt text-tone).
|
|
20
|
+
export function Sparkline({ points, className, }) {
|
|
21
|
+
if (points.length < 2)
|
|
22
|
+
return null;
|
|
23
|
+
const w = 100;
|
|
24
|
+
const h = 28;
|
|
25
|
+
const min = Math.min(...points);
|
|
26
|
+
const max = Math.max(...points);
|
|
27
|
+
const span = max - min || 1;
|
|
28
|
+
const line = points
|
|
29
|
+
.map((p, i) => {
|
|
30
|
+
const x = (i / (points.length - 1)) * w;
|
|
31
|
+
const y = h - ((p - min) / span) * h;
|
|
32
|
+
return `${i === 0 ? "M" : "L"}${x.toFixed(1)},${y.toFixed(1)}`;
|
|
33
|
+
})
|
|
34
|
+
.join(" ");
|
|
35
|
+
return (_jsxs("svg", { viewBox: `0 0 ${w} ${h}`, preserveAspectRatio: "none", className: className ?? "h-7 w-full", "aria-hidden": "true", children: [_jsx("path", { d: `${line} L${w},${h} L0,${h} Z`, fill: "currentColor", fillOpacity: 0.12 }), _jsx("path", { d: line, fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", vectorEffect: "non-scaling-stroke" })] }));
|
|
36
|
+
}
|
|
37
|
+
function StatIconChip({ icon, tone, accentColor, }) {
|
|
38
|
+
return (_jsx("span", { className: cn("flex size-7 shrink-0 items-center justify-center rounded-lg", accentColor === undefined && TONE_CHIP[tone]), style: accentColor === undefined
|
|
39
|
+
? undefined
|
|
40
|
+
: {
|
|
41
|
+
color: accentColor,
|
|
42
|
+
backgroundColor: `color-mix(in srgb, ${accentColor} 12%, transparent)`,
|
|
43
|
+
}, children: icon }));
|
|
44
|
+
}
|
|
45
|
+
/** Icon-tragende Kennzahl-Kachel mit optionalem Delta-Chip, Trend-Zeile
|
|
46
|
+
* und Sparkline. `icon` ist ein fertiger Knoten (App liefert ihr SVG). */
|
|
47
|
+
export function StatCard({ icon, label, value, sub, tone = "default", accentColor, delta, trend, spark, testId, children, }) {
|
|
48
|
+
const { Card } = usePrimitives();
|
|
49
|
+
// StatCard is a reusable small-tile widget (a metrics dashboard grid, not
|
|
50
|
+
// a whole-section frame) — an extension section mounting several of
|
|
51
|
+
// these renders a grid of tiles inside its own host Card, not a
|
|
52
|
+
// duplicate outer frame around the section's full content.
|
|
53
|
+
return (_jsxs(Card, { options: { padded: false }, className: "p-4", testId: testId, children: [_jsxs("div", { className: "flex flex-wrap items-start justify-between gap-x-2 gap-y-1", children: [_jsxs("div", { className: "flex min-w-0 flex-1 basis-[7rem] items-center gap-2 text-muted-foreground", children: [icon !== undefined && _jsx(StatIconChip, { icon: icon, tone: tone, accentColor: accentColor }), _jsx("span", { title: label, className: "min-w-0 line-clamp-2 text-xs font-medium", children: label })] }), delta !== undefined && (_jsxs("span", { className: cn("inline-flex shrink-0 items-center gap-0.5 whitespace-nowrap rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums", TONE_CHIP[delta.tone ?? tone]), children: [delta.direction === "up" ? "↑" : "↓", delta.value] }))] }), _jsx("div", { className: "mt-2 text-xl font-semibold tabular-nums text-foreground", children: value }), sub !== undefined && _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: sub }), trend !== undefined && (_jsx("div", { className: "mt-0.5 text-xs font-medium text-foreground/80", children: trend })), spark !== undefined && (_jsx(Sparkline, { points: spark, className: cn("mt-2 h-7 w-full", TONE_VALUE[tone]) })), children !== undefined && _jsx("div", { className: "mt-3", children: children })] }));
|
|
54
|
+
}
|
|
55
|
+
/** Flat KPI cell for a strip (divider instead of card): label, value with
|
|
56
|
+
* sparkline beside it, sub line. */
|
|
57
|
+
export function StatStripCell({ icon, label, value, sub, tone = "default", accentColor, delta, spark, testId, }) {
|
|
58
|
+
return (_jsxs("div", { "data-testid": testId, className: "flex min-w-0 flex-col gap-1 px-4 py-3", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-1", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2 text-xs font-medium text-muted-foreground", children: [icon !== undefined && _jsx(StatIconChip, { icon: icon, tone: tone, accentColor: accentColor }), _jsx("span", { children: label })] }), delta !== undefined && (_jsxs("span", { className: cn("inline-flex shrink-0 items-center gap-0.5 whitespace-nowrap rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums", TONE_CHIP[delta.tone ?? tone]), children: [delta.direction === "up" ? "↑" : "↓", delta.value] }))] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: cn("text-xl font-semibold tabular-nums", TONE_VALUE[tone]), children: value }), spark !== undefined && (_jsx(Sparkline, { points: spark, className: cn("h-7 w-20 shrink-0", TONE_VALUE[tone]) }))] }), sub !== undefined && _jsx("div", { className: "text-xs text-muted-foreground", children: sub })] }));
|
|
59
|
+
}
|
|
60
|
+
/** Kompakte Kennzahl-Kachel (ohne Icon) — für dichte KPI-Raster.
|
|
61
|
+
* StatCard ist die icon-tragende Variante. */
|
|
62
|
+
export function MiniStat({ label, value, tone = "default", emphasize = false, testId, labelTestId, valueTestId, }) {
|
|
63
|
+
const { Card } = usePrimitives();
|
|
64
|
+
return (_jsxs(Card, { options: { padded: false }, className: cn("p-3", emphasize && "ring-1 ring-primary/30"), testId: testId, children: [_jsx("div", { className: "text-xs text-muted-foreground", "data-testid": labelTestId, children: label }), _jsx("div", { className: cn("mt-0.5 font-semibold tabular-nums", TONE_VALUE[tone], emphasize ? "text-lg" : "text-sm"), "data-testid": valueTestId, children: value })] }));
|
|
65
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { DispatcherError } from "../../headless/index.ts";
|
|
3
|
+
/** Leerer-Zustand mit optionalem Icon + CTA — die dashed-Box-Optik der
|
|
4
|
+
* entityList-Empty-States, als Standalone-Widget für Custom-Screens. */
|
|
5
|
+
export declare function EmptyState({ icon, title, description, action, testId, }: {
|
|
6
|
+
readonly icon?: ReactNode;
|
|
7
|
+
readonly title: string;
|
|
8
|
+
readonly description?: string;
|
|
9
|
+
readonly action?: ReactNode;
|
|
10
|
+
readonly testId?: string;
|
|
11
|
+
}): ReactNode;
|
|
12
|
+
/** Lade-Zustand: Skeleton-Zeilen in Card-Optik. `rows` steuert die Höhe. */
|
|
13
|
+
export declare function LoadingState({ rows, className, testId, }: {
|
|
14
|
+
readonly rows?: number;
|
|
15
|
+
readonly className?: string;
|
|
16
|
+
readonly testId?: string;
|
|
17
|
+
}): ReactNode;
|
|
18
|
+
/** Fehler-Zustand auf Basis des Banner-Primitives, mit Retry-Button. */
|
|
19
|
+
export declare function ErrorState({ error, onRetry, testId, }: {
|
|
20
|
+
readonly error: DispatcherError;
|
|
21
|
+
readonly onRetry?: () => void;
|
|
22
|
+
readonly testId?: string;
|
|
23
|
+
}): ReactNode;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { dispatcherErrorText, usePrimitives, useTranslation } from "../../index.js";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { Skeleton } from "../ui/skeleton.js";
|
|
5
|
+
/** Leerer-Zustand mit optionalem Icon + CTA — die dashed-Box-Optik der
|
|
6
|
+
* entityList-Empty-States, als Standalone-Widget für Custom-Screens. */
|
|
7
|
+
export function EmptyState({ icon, title, description, action, testId, }) {
|
|
8
|
+
return (_jsxs("div", { "data-testid": testId, className: "flex flex-col items-center justify-center gap-2 rounded-lg border border-dashed px-6 py-10 text-center", children: [icon !== undefined && _jsx("div", { className: "text-muted-foreground", children: icon }), _jsx("div", { className: "text-sm font-medium", children: title }), description !== undefined && (_jsx("div", { className: "text-sm text-muted-foreground", children: description })), action !== undefined && _jsx("div", { className: "mt-2", children: action })] }));
|
|
9
|
+
}
|
|
10
|
+
/** Lade-Zustand: Skeleton-Zeilen in Card-Optik. `rows` steuert die Höhe. */
|
|
11
|
+
export function LoadingState({ rows = 3, className, testId, }) {
|
|
12
|
+
const t = useTranslation();
|
|
13
|
+
return (_jsx("output", { "data-testid": testId, "aria-label": t("kumiko.widget.loading"), className: cn("flex w-full flex-col gap-2", className), children: Array.from({ length: rows }, (_, i) => (_jsx(Skeleton, { className: "h-9 w-full" }, i))) }));
|
|
14
|
+
}
|
|
15
|
+
/** Fehler-Zustand auf Basis des Banner-Primitives, mit Retry-Button. */
|
|
16
|
+
export function ErrorState({ error, onRetry, testId, }) {
|
|
17
|
+
const { Banner, Button } = usePrimitives();
|
|
18
|
+
const t = useTranslation();
|
|
19
|
+
return (_jsxs(Banner, { variant: "error", testId: testId, actions: onRetry !== undefined ? (_jsx(Button, { variant: "secondary", onClick: onRetry, children: t("kumiko.actions.reload") })) : undefined, children: [t("kumiko.widget.error.title"), " ", dispatcherErrorText(error, t)] }));
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type StatusTone = "ok" | "warn" | "bad" | "critical" | "muted";
|
|
3
|
+
export declare const STATUS_TONE_TEXT: Record<StatusTone, string>;
|
|
4
|
+
/** `accent` is a brand-colored call-out (e.g. "3 suggestions"), not a status —
|
|
5
|
+
* hence not part of `StatusTone`, which toasts and select options share. */
|
|
6
|
+
export type StatusBadgeTone = StatusTone | "accent";
|
|
7
|
+
/** Pill badge with a status dot. Caller maps domain values to a tone
|
|
8
|
+
* (e.g. operational→ok, investigating→warn) and passes the translated
|
|
9
|
+
* label as children. */
|
|
10
|
+
export declare function StatusBadge({ tone, children, className, testId, }: {
|
|
11
|
+
readonly tone: StatusBadgeTone;
|
|
12
|
+
readonly children: ReactNode;
|
|
13
|
+
readonly className?: string;
|
|
14
|
+
readonly testId?: string;
|
|
15
|
+
}): ReactNode;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../lib/cn.js";
|
|
3
|
+
export const STATUS_TONE_TEXT = {
|
|
4
|
+
ok: "text-status-ok",
|
|
5
|
+
warn: "text-status-warn",
|
|
6
|
+
bad: "text-status-bad",
|
|
7
|
+
critical: "text-status-critical",
|
|
8
|
+
muted: "text-muted-foreground",
|
|
9
|
+
};
|
|
10
|
+
// `muted` maps to the neutral tokens, not a status-* palette.
|
|
11
|
+
const TONE_PILL = {
|
|
12
|
+
accent: "bg-primary/10 text-primary",
|
|
13
|
+
ok: "bg-status-ok-surface text-status-ok",
|
|
14
|
+
warn: "bg-status-warn-surface text-status-warn",
|
|
15
|
+
bad: "bg-status-bad-surface text-status-bad",
|
|
16
|
+
critical: "bg-status-critical-surface text-status-critical",
|
|
17
|
+
muted: "bg-status-neutral-surface text-status-neutral",
|
|
18
|
+
};
|
|
19
|
+
/** Pill badge with a status dot. Caller maps domain values to a tone
|
|
20
|
+
* (e.g. operational→ok, investigating→warn) and passes the translated
|
|
21
|
+
* label as children. */
|
|
22
|
+
export function StatusBadge({ tone, children, className, testId, }) {
|
|
23
|
+
return (_jsxs("span", { "data-testid": testId, className: cn("inline-flex h-[22px] items-center gap-1.5 whitespace-nowrap rounded-full px-2 text-xs font-medium", TONE_PILL[tone], className), children: [_jsx("span", { "aria-hidden": "true", "data-status-dot": true, className: "size-1.5 rounded-full bg-current" }), children] }));
|
|
24
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
/** Wizard step overview — numbered chips with a connector line between
|
|
3
|
+
* them. With `onStepSelect`, done chips render as buttons for jumping back
|
|
4
|
+
* (every non-current chip with `selectableSteps="all"`); the current chip
|
|
5
|
+
* never does. `doneSteps` overrides the position-based done state. With
|
|
6
|
+
* `onStepSelect` and `selectableSteps="all"` the narrow-viewport label becomes
|
|
7
|
+
* a dropdown listing every step (same rows as the rail), so phones can jump
|
|
8
|
+
* too. Three visual states, none conveyed by color alone:
|
|
9
|
+
* done (checkmark replaces the number, `aria-current` absent, a sr-only
|
|
10
|
+
* label says so since the number itself is gone), current (`aria-current
|
|
11
|
+
* ="step"`, own background), upcoming (dimmed, number visible). Below
|
|
12
|
+
* `sm` the chip row hides in favor of `compactLabel` (seven step names
|
|
13
|
+
* don't fit on a phone) — both live in the DOM, Tailwind's
|
|
14
|
+
* `hidden`/`sm:hidden` pair picks the visible one per viewport (same
|
|
15
|
+
* pattern as embedded-list-input.tsx's desktop/mobile split). */
|
|
16
|
+
export declare function StepBar({ steps, currentIndex, compactLabel, onStepSelect, doneSteps, selectableSteps, narrowLayout, orientation, heading, description, subtitles, upNext, testId, compactTestId, }: {
|
|
17
|
+
readonly steps: readonly string[];
|
|
18
|
+
readonly currentIndex: number;
|
|
19
|
+
readonly compactLabel: string;
|
|
20
|
+
readonly onStepSelect?: (index: number) => void;
|
|
21
|
+
readonly doneSteps?: readonly boolean[];
|
|
22
|
+
readonly selectableSteps?: "done" | "all";
|
|
23
|
+
readonly narrowLayout?: "label" | "steps";
|
|
24
|
+
readonly orientation?: "horizontal" | "vertical";
|
|
25
|
+
readonly heading?: string;
|
|
26
|
+
readonly description?: string;
|
|
27
|
+
readonly subtitles?: readonly (string | undefined)[];
|
|
28
|
+
readonly upNext?: {
|
|
29
|
+
readonly heading: string;
|
|
30
|
+
readonly title: string;
|
|
31
|
+
readonly subtitle?: string;
|
|
32
|
+
};
|
|
33
|
+
readonly testId?: string;
|
|
34
|
+
readonly compactTestId?: string;
|
|
35
|
+
}): ReactNode;
|