@xemahq/ui-kernel 0.9.2 → 0.11.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/dist/lib/biome-host/agent-validation.d.ts.map +1 -1
- package/dist/lib/biome-host/agent-validation.js +26 -13
- package/dist/lib/biome-host/agent-validation.js.map +1 -1
- package/dist/lib/biome-host/biome-registry.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-registry.js +27 -10
- package/dist/lib/biome-host/biome-registry.js.map +1 -1
- package/dist/lib/biome-host/biome-scope-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scope-hooks.js +2 -1
- package/dist/lib/biome-host/biome-scope-hooks.js.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.js +5 -3
- package/dist/lib/biome-host/biome-scoped-query.js.map +1 -1
- package/dist/lib/biome-host/frontend-biome.d.ts +1 -1
- package/dist/lib/biome-host/frontend-biome.d.ts.map +1 -1
- package/dist/lib/biome-host/host-bridge.d.ts +1 -1
- package/dist/lib/biome-host/host-bridge.d.ts.map +1 -1
- package/dist/lib/biome-host/host-bridge.js.map +1 -1
- package/dist/lib/biome-host/i18n-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/i18n-hooks.js.map +1 -1
- package/dist/lib/biome-host/index.d.ts +0 -1
- package/dist/lib/biome-host/index.d.ts.map +1 -1
- package/dist/lib/biome-host/index.js +0 -1
- package/dist/lib/biome-host/index.js.map +1 -1
- package/dist/lib/biome-host/realtime-hooks.d.ts.map +1 -1
- package/dist/lib/biome-host/realtime-hooks.js.map +1 -1
- package/dist/lib/biome-host/session-contributions.d.ts +10 -5
- package/dist/lib/biome-host/session-contributions.d.ts.map +1 -1
- package/dist/lib/biome-host/use-mutation-with-error-toast.d.ts.map +1 -1
- package/dist/lib/biome-host/use-mutation-with-error-toast.js +3 -2
- package/dist/lib/biome-host/use-mutation-with-error-toast.js.map +1 -1
- package/dist/lib/biome-host/use-page-state.d.ts.map +1 -1
- package/dist/lib/biome-host/use-page-state.js +19 -10
- package/dist/lib/biome-host/use-page-state.js.map +1 -1
- package/dist/lib/capabilities/capability-provider.d.ts +1 -1
- package/dist/lib/capabilities/capability-provider.d.ts.map +1 -1
- package/dist/lib/capabilities/capability-provider.js +2 -2
- package/dist/lib/capabilities/capability-provider.js.map +1 -1
- package/dist/lib/capabilities/use-capability.d.ts +1 -1
- package/dist/lib/capabilities/use-capability.d.ts.map +1 -1
- package/dist/lib/capabilities/use-capability.js +2 -1
- package/dist/lib/capabilities/use-capability.js.map +1 -1
- package/dist/lib/contribution-registry/contribution-registry.d.ts.map +1 -1
- package/dist/lib/contribution-registry/contribution-registry.js +2 -1
- package/dist/lib/contribution-registry/contribution-registry.js.map +1 -1
- package/dist/lib/system-bus/deeplink.d.ts.map +1 -1
- package/dist/lib/system-bus/deeplink.js +4 -2
- package/dist/lib/system-bus/deeplink.js.map +1 -1
- package/dist/lib/system-bus/host-ports.d.ts +2 -2
- package/dist/lib/system-bus/host-ports.d.ts.map +1 -1
- package/dist/lib/system-bus/intent-registry.d.ts.map +1 -1
- package/dist/lib/system-bus/intent-registry.js +6 -3
- package/dist/lib/system-bus/intent-registry.js.map +1 -1
- package/dist/lib/system-bus/intents.d.ts +1 -1
- package/dist/lib/system-bus/intents.d.ts.map +1 -1
- package/dist/lib/system-bus/palette.d.ts +1 -1
- package/dist/lib/system-bus/palette.d.ts.map +1 -1
- package/dist/lib/system-bus/system-bus-builder.d.ts.map +1 -1
- package/dist/lib/system-bus/system-bus-builder.js +1 -1
- package/dist/lib/system-bus/system-bus-builder.js.map +1 -1
- package/dist/lib/system-bus/windows.d.ts +1 -1
- package/dist/lib/system-bus/windows.d.ts.map +1 -1
- package/dist/offline/outbox.d.ts +1 -0
- package/dist/offline/outbox.d.ts.map +1 -1
- package/dist/offline/outbox.js +4 -1
- package/dist/offline/outbox.js.map +1 -1
- package/dist/offline/react-hooks.d.ts +1 -1
- package/dist/offline/react-hooks.d.ts.map +1 -1
- package/dist/offline/react-hooks.js.map +1 -1
- package/dist/org-db/components/DbResultTable.d.ts.map +1 -1
- package/dist/org-db/components/DbResultTable.js +15 -6
- package/dist/org-db/components/DbResultTable.js.map +1 -1
- package/dist/registry/lib/agent-validation-host.d.ts.map +1 -1
- package/dist/registry/lib/agent-validation-host.js +1 -1
- package/dist/registry/lib/agent-validation-host.js.map +1 -1
- package/dist/registry/lib/biome-slot.d.ts.map +1 -1
- package/dist/registry/lib/biome-slot.js +5 -3
- package/dist/registry/lib/biome-slot.js.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.js +14 -2
- package/dist/registry/lib/primitives/SessionEventCard.js.map +1 -1
- package/dist/registry/lib/primitives/SessionEventTimeline.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionEventTimeline.js +6 -3
- package/dist/registry/lib/primitives/SessionEventTimeline.js.map +1 -1
- package/dist/registry/lib/primitives/SessionTabbedDrawer.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionTabbedDrawer.js +10 -5
- package/dist/registry/lib/primitives/SessionTabbedDrawer.js.map +1 -1
- package/dist/registry/lib/session-context-builder.d.ts +10 -2
- package/dist/registry/lib/session-context-builder.d.ts.map +1 -1
- package/dist/registry/lib/session-context-builder.js +14 -7
- package/dist/registry/lib/session-context-builder.js.map +1 -1
- package/dist/registry/lib/session-context-provider.d.ts +1 -1
- package/dist/registry/lib/session-context-provider.d.ts.map +1 -1
- package/dist/registry/lib/session-context-provider.js.map +1 -1
- package/dist/registry/lib/session-selectors.d.ts.map +1 -1
- package/dist/registry/lib/session-selectors.js +35 -20
- package/dist/registry/lib/session-selectors.js.map +1 -1
- package/dist/session/comments/CommentRail.d.ts.map +1 -1
- package/dist/session/comments/CommentRail.js.map +1 -1
- package/dist/session/shell/SessionWorkspaceShell.d.ts.map +1 -1
- package/dist/session/shell/SessionWorkspaceShell.js.map +1 -1
- package/dist/session-kit/approvals/ApprovalCard.d.ts.map +1 -1
- package/dist/session-kit/approvals/ApprovalCard.js +6 -2
- package/dist/session-kit/approvals/ApprovalCard.js.map +1 -1
- package/dist/session-kit/approvals/ApprovalsCenter.d.ts.map +1 -1
- package/dist/session-kit/approvals/ApprovalsCenter.js +6 -3
- package/dist/session-kit/approvals/ApprovalsCenter.js.map +1 -1
- package/dist/session-kit/combobox/Combobox.d.ts.map +1 -1
- package/dist/session-kit/combobox/Combobox.js +20 -6
- package/dist/session-kit/combobox/Combobox.js.map +1 -1
- package/dist/session-kit/display/MD.d.ts.map +1 -1
- package/dist/session-kit/display/MD.js +7 -4
- package/dist/session-kit/display/MD.js.map +1 -1
- package/dist/ui/branding/app-branding-provider.d.ts.map +1 -1
- package/dist/ui/branding/app-branding-provider.js.map +1 -1
- package/dist/ui/branding/sanitize.d.ts.map +1 -1
- package/dist/ui/branding/sanitize.js +12 -6
- package/dist/ui/branding/sanitize.js.map +1 -1
- package/dist/ui/capture/document-preview.d.ts +1 -1
- package/dist/ui/capture/document-preview.d.ts.map +1 -1
- package/dist/ui/capture/document-preview.js +8 -6
- package/dist/ui/capture/document-preview.js.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.d.ts.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.js +45 -16
- package/dist/ui/capture/field-spec-to-zod.js.map +1 -1
- package/dist/ui/capture/field-spec-validate.d.ts.map +1 -1
- package/dist/ui/capture/field-spec-validate.js +79 -38
- package/dist/ui/capture/field-spec-validate.js.map +1 -1
- package/dist/ui/capture/field-spec.d.ts.map +1 -1
- package/dist/ui/capture/field-spec.js +17 -6
- package/dist/ui/capture/field-spec.js.map +1 -1
- package/dist/ui/capture/schema-field-input.d.ts.map +1 -1
- package/dist/ui/capture/schema-field-input.js +23 -18
- package/dist/ui/capture/schema-field-input.js.map +1 -1
- package/dist/ui/capture/schema-form.d.ts +1 -1
- package/dist/ui/capture/schema-form.d.ts.map +1 -1
- package/dist/ui/capture/schema-form.js +7 -6
- package/dist/ui/capture/schema-form.js.map +1 -1
- package/dist/ui/capture/use-prefill.d.ts.map +1 -1
- package/dist/ui/capture/use-prefill.js +32 -14
- package/dist/ui/capture/use-prefill.js.map +1 -1
- package/dist/ui/capture/use-schema-validation.d.ts +1 -1
- package/dist/ui/capture/use-schema-validation.d.ts.map +1 -1
- package/dist/ui/capture/use-schema-validation.js +13 -8
- package/dist/ui/capture/use-schema-validation.js.map +1 -1
- package/dist/ui/capture/use-wizard.d.ts.map +1 -1
- package/dist/ui/capture/use-wizard.js +23 -8
- package/dist/ui/capture/use-wizard.js.map +1 -1
- package/dist/ui/capture/value-format.d.ts.map +1 -1
- package/dist/ui/capture/value-format.js +6 -3
- package/dist/ui/capture/value-format.js.map +1 -1
- package/dist/ui/capture/wizard.d.ts.map +1 -1
- package/dist/ui/capture/wizard.js +3 -3
- package/dist/ui/capture/wizard.js.map +1 -1
- package/dist/ui/charts/bar-chart.d.ts +1 -1
- package/dist/ui/charts/bar-chart.d.ts.map +1 -1
- package/dist/ui/charts/bar-chart.js +1 -1
- package/dist/ui/charts/bar-chart.js.map +1 -1
- package/dist/ui/charts/chart-frame.d.ts +2 -2
- package/dist/ui/charts/chart-frame.d.ts.map +1 -1
- package/dist/ui/charts/chart-frame.js +4 -3
- package/dist/ui/charts/chart-frame.js.map +1 -1
- package/dist/ui/charts/chart-utils.d.ts.map +1 -1
- package/dist/ui/charts/chart-utils.js +32 -14
- package/dist/ui/charts/chart-utils.js.map +1 -1
- package/dist/ui/charts/donut-chart.d.ts +1 -1
- package/dist/ui/charts/donut-chart.d.ts.map +1 -1
- package/dist/ui/charts/donut-chart.js +7 -3
- package/dist/ui/charts/donut-chart.js.map +1 -1
- package/dist/ui/charts/line-chart.d.ts +1 -1
- package/dist/ui/charts/line-chart.d.ts.map +1 -1
- package/dist/ui/charts/line-chart.js +7 -4
- package/dist/ui/charts/line-chart.js.map +1 -1
- package/dist/ui/charts/sparkline.d.ts +1 -1
- package/dist/ui/charts/sparkline.d.ts.map +1 -1
- package/dist/ui/charts/sparkline.js +10 -6
- package/dist/ui/charts/sparkline.js.map +1 -1
- package/dist/ui/chrome/AsyncBoundary.d.ts +2 -2
- package/dist/ui/chrome/AsyncBoundary.d.ts.map +1 -1
- package/dist/ui/chrome/AsyncBoundary.js +3 -3
- package/dist/ui/chrome/AsyncBoundary.js.map +1 -1
- package/dist/ui/chrome/EmptyState.d.ts +19 -8
- package/dist/ui/chrome/EmptyState.d.ts.map +1 -1
- package/dist/ui/chrome/EmptyState.js +6 -4
- package/dist/ui/chrome/EmptyState.js.map +1 -1
- package/dist/ui/chrome/RecordCardList.d.ts +19 -0
- package/dist/ui/chrome/RecordCardList.d.ts.map +1 -0
- package/dist/ui/chrome/RecordCardList.js +12 -0
- package/dist/ui/chrome/RecordCardList.js.map +1 -0
- package/dist/ui/chrome/page-shell.d.ts.map +1 -1
- package/dist/ui/chrome/page-shell.js +9 -3
- package/dist/ui/chrome/page-shell.js.map +1 -1
- package/dist/ui/chrome/status-badge.d.ts.map +1 -1
- package/dist/ui/chrome/status-badge.js +1 -1
- package/dist/ui/chrome/status-badge.js.map +1 -1
- package/dist/ui/design-tokens.d.ts +4 -6
- package/dist/ui/design-tokens.d.ts.map +1 -1
- package/dist/ui/design-tokens.js +17 -11
- package/dist/ui/design-tokens.js.map +1 -1
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/primitives/async-combobox.d.ts.map +1 -1
- package/dist/ui/primitives/async-combobox.js +4 -2
- package/dist/ui/primitives/async-combobox.js.map +1 -1
- package/dist/ui/primitives/badge.d.ts +2 -2
- package/dist/ui/primitives/badge.d.ts.map +1 -1
- package/dist/ui/primitives/badge.js +3 -3
- package/dist/ui/primitives/badge.js.map +1 -1
- package/dist/ui/primitives/button.d.ts +2 -2
- package/dist/ui/primitives/button.d.ts.map +1 -1
- package/dist/ui/primitives/button.js +5 -5
- package/dist/ui/primitives/button.js.map +1 -1
- package/dist/ui/primitives/overflow-tabs.d.ts.map +1 -1
- package/dist/ui/primitives/overflow-tabs.js +19 -12
- package/dist/ui/primitives/overflow-tabs.js.map +1 -1
- package/dist/ui/primitives/preview-device-frame.js +8 -4
- package/dist/ui/primitives/preview-device-frame.js.map +1 -1
- package/dist/ui/primitives/tag-multi-select.d.ts.map +1 -1
- package/dist/ui/primitives/tag-multi-select.js +10 -5
- package/dist/ui/primitives/tag-multi-select.js.map +1 -1
- package/dist/ui/primitives/url-preview-chrome.d.ts.map +1 -1
- package/dist/ui/primitives/url-preview-chrome.js.map +1 -1
- package/dist/vista/GenericCatalogueSurface.d.ts.map +1 -1
- package/dist/vista/GenericCatalogueSurface.js +5 -3
- package/dist/vista/GenericCatalogueSurface.js.map +1 -1
- package/dist/vista/VistaPanel.d.ts.map +1 -1
- package/dist/vista/VistaPanel.js +8 -4
- package/dist/vista/VistaPanel.js.map +1 -1
- package/dist/vista/html/CustomUiFrame.d.ts.map +1 -1
- package/dist/vista/html/CustomUiFrame.js +2 -1
- package/dist/vista/html/CustomUiFrame.js.map +1 -1
- package/dist/vista/html/custom-ui-frame-bridge.d.ts.map +1 -1
- package/dist/vista/html/custom-ui-frame-bridge.js +6 -3
- package/dist/vista/html/custom-ui-frame-bridge.js.map +1 -1
- package/dist/vista/html/custom-ui-intents.d.ts.map +1 -1
- package/dist/vista/html/custom-ui-intents.js +13 -15
- package/dist/vista/html/custom-ui-intents.js.map +1 -1
- package/dist/vista/surface-catalogue.d.ts.map +1 -1
- package/dist/vista/surface-catalogue.js +6 -3
- package/dist/vista/surface-catalogue.js.map +1 -1
- package/dist/vista/surfaces/FormSurface.d.ts.map +1 -1
- package/dist/vista/surfaces/FormSurface.js +20 -7
- package/dist/vista/surfaces/FormSurface.js.map +1 -1
- package/dist/vista/surfaces/TableSurface.d.ts.map +1 -1
- package/dist/vista/surfaces/TableSurface.js +2 -1
- package/dist/vista/surfaces/TableSurface.js.map +1 -1
- package/dist/vista/surfaces/blob-surfaces.d.ts.map +1 -1
- package/dist/vista/surfaces/blob-surfaces.js +7 -2
- package/dist/vista/surfaces/blob-surfaces.js.map +1 -1
- package/dist/vista/surfaces/elicitation-transport.d.ts.map +1 -1
- package/dist/vista/surfaces/elicitation-transport.js +14 -7
- package/dist/vista/surfaces/elicitation-transport.js.map +1 -1
- package/dist/vista/surfaces/file-surface-utils.d.ts.map +1 -1
- package/dist/vista/surfaces/file-surface-utils.js +8 -4
- package/dist/vista/surfaces/file-surface-utils.js.map +1 -1
- package/dist/vista/surfaces/register-surfaces.js +2 -1
- package/dist/vista/surfaces/register-surfaces.js.map +1 -1
- package/dist/vista/surfaces/text-surfaces.d.ts +1 -1
- package/dist/vista/surfaces/text-surfaces.d.ts.map +1 -1
- package/dist/vista/surfaces/text-surfaces.js +13 -7
- package/dist/vista/surfaces/text-surfaces.js.map +1 -1
- package/dist/vista/use-vista-tabs.d.ts.map +1 -1
- package/dist/vista/use-vista-tabs.js +8 -4
- package/dist/vista/use-vista-tabs.js.map +1 -1
- package/dist/vista/vista-code-renderer.d.ts.map +1 -1
- package/dist/vista/vista-code-renderer.js.map +1 -1
- package/dist/vista/vista-file-source.d.ts.map +1 -1
- package/dist/vista/vista-file-source.js +9 -5
- package/dist/vista/vista-file-source.js.map +1 -1
- package/dist/vista/vista-form-host.d.ts.map +1 -1
- package/dist/vista/vista-form-host.js +1 -1
- package/dist/vista/vista-form-host.js.map +1 -1
- package/dist/vista/vista-model.d.ts.map +1 -1
- package/dist/vista/vista-model.js +5 -3
- package/dist/vista/vista-model.js.map +1 -1
- package/dist/vista/vista-open-context.d.ts.map +1 -1
- package/dist/vista/vista-open-context.js +1 -1
- package/dist/vista/vista-open-context.js.map +1 -1
- package/dist/vista/vista-payloads.d.ts.map +1 -1
- package/dist/vista/vista-payloads.js +127 -63
- package/dist/vista/vista-payloads.js.map +1 -1
- package/dist/vista/vista-tabs-manifest.d.ts.map +1 -1
- package/dist/vista/vista-tabs-manifest.js +18 -9
- package/dist/vista/vista-tabs-manifest.js.map +1 -1
- package/dist/vista/vista-tools.d.ts.map +1 -1
- package/dist/vista/vista-tools.js +12 -6
- package/dist/vista/vista-tools.js.map +1 -1
- package/package.json +3 -3
- package/src/lib/biome-host/agent-validation.ts +37 -13
- package/src/lib/biome-host/biome-registry.ts +48 -13
- package/src/lib/biome-host/biome-scope-hooks.ts +3 -1
- package/src/lib/biome-host/biome-scoped-query.ts +7 -6
- package/src/lib/biome-host/frontend-biome.ts +1 -1
- package/src/lib/biome-host/host-bridge.ts +5 -4
- package/src/lib/biome-host/i18n-hooks.ts +1 -0
- package/src/lib/biome-host/index.ts +0 -1
- package/src/lib/biome-host/realtime-hooks.ts +1 -0
- package/src/lib/biome-host/session-contributions.ts +22 -19
- package/src/lib/biome-host/use-mutation-with-error-toast.ts +4 -2
- package/src/lib/biome-host/use-page-state.ts +27 -10
- package/src/lib/capabilities/capability-provider.tsx +12 -5
- package/src/lib/capabilities/use-capability.ts +8 -4
- package/src/lib/contribution-registry/contribution-registry.ts +3 -1
- package/src/lib/system-bus/deeplink.ts +14 -4
- package/src/lib/system-bus/host-ports.ts +3 -7
- package/src/lib/system-bus/intent-registry.ts +12 -8
- package/src/lib/system-bus/intents.ts +6 -2
- package/src/lib/system-bus/palette.ts +2 -1
- package/src/lib/system-bus/system-bus-builder.ts +4 -2
- package/src/lib/system-bus/windows.ts +1 -1
- package/src/offline/outbox.test.ts +12 -3
- package/src/offline/outbox.ts +5 -1
- package/src/offline/react-hooks.ts +5 -2
- package/src/org-db/components/DbResultTable.tsx +48 -15
- package/src/registry/lib/agent-validation-host.ts +1 -2
- package/src/registry/lib/biome-slot.tsx +7 -4
- package/src/registry/lib/primitives/SessionEventCard.tsx +29 -5
- package/src/registry/lib/primitives/SessionEventTimeline.tsx +9 -3
- package/src/registry/lib/primitives/SessionTabbedDrawer.tsx +15 -5
- package/src/registry/lib/session-context-builder.ts +33 -17
- package/src/registry/lib/session-context-provider.tsx +1 -1
- package/src/registry/lib/session-selectors.ts +66 -27
- package/src/session/comments/CommentRail.tsx +2 -2
- package/src/session/shell/SessionWorkspaceShell.tsx +2 -2
- package/src/session-kit/approvals/ApprovalCard.tsx +7 -2
- package/src/session-kit/approvals/ApprovalsCenter.tsx +13 -4
- package/src/session-kit/combobox/Combobox.tsx +42 -11
- package/src/session-kit/display/MD.tsx +14 -5
- package/src/ui/branding/app-branding-provider.tsx +2 -3
- package/src/ui/branding/sanitize.ts +18 -6
- package/src/ui/capture/document-preview.tsx +84 -19
- package/src/ui/capture/field-spec-to-zod.ts +62 -14
- package/src/ui/capture/field-spec-validate.ts +132 -43
- package/src/ui/capture/field-spec.test.ts +2 -2
- package/src/ui/capture/field-spec.ts +41 -10
- package/src/ui/capture/schema-field-input.tsx +218 -38
- package/src/ui/capture/schema-form.tsx +54 -13
- package/src/ui/capture/use-prefill.ts +50 -17
- package/src/ui/capture/use-schema-validation.ts +45 -13
- package/src/ui/capture/use-wizard.ts +57 -11
- package/src/ui/capture/value-format.ts +14 -4
- package/src/ui/capture/wizard.tsx +9 -5
- package/src/ui/charts/bar-chart.tsx +8 -4
- package/src/ui/charts/chart-frame.tsx +18 -5
- package/src/ui/charts/chart-utils.ts +47 -15
- package/src/ui/charts/donut-chart.tsx +24 -6
- package/src/ui/charts/line-chart.tsx +34 -12
- package/src/ui/charts/sparkline.tsx +17 -9
- package/src/ui/chrome/AsyncBoundary.tsx +14 -6
- package/src/ui/chrome/EmptyState.tsx +116 -43
- package/src/ui/chrome/RecordCardList.tsx +98 -0
- package/src/ui/chrome/page-shell.tsx +32 -8
- package/src/ui/chrome/status-badge.tsx +8 -4
- package/src/ui/design-tokens.ts +39 -13
- package/src/ui/index.ts +5 -0
- package/src/ui/primitives/async-combobox.tsx +7 -3
- package/src/ui/primitives/badge.tsx +14 -5
- package/src/ui/primitives/button.tsx +13 -6
- package/src/ui/primitives/overflow-tabs.tsx +46 -16
- package/src/ui/primitives/preview-device-frame.tsx +12 -4
- package/src/ui/primitives/tag-multi-select.tsx +30 -9
- package/src/ui/primitives/url-preview-chrome.tsx +1 -0
- package/src/vista/GenericCatalogueSurface.tsx +7 -5
- package/src/vista/VistaPanel.tsx +12 -4
- package/src/vista/html/CustomUiFrame.spec.tsx +3 -1
- package/src/vista/html/CustomUiFrame.tsx +3 -1
- package/src/vista/html/custom-ui-frame-bridge.ts +9 -3
- package/src/vista/html/custom-ui-intents.spec.ts +3 -1
- package/src/vista/html/custom-ui-intents.ts +19 -15
- package/src/vista/surface-catalogue.ts +9 -3
- package/src/vista/surfaces/FormSurface.tsx +27 -10
- package/src/vista/surfaces/TableSurface.tsx +4 -3
- package/src/vista/surfaces/blob-surfaces.tsx +13 -3
- package/src/vista/surfaces/elicitation-transport.ts +21 -7
- package/src/vista/surfaces/file-surface-utils.ts +11 -4
- package/src/vista/surfaces/register-surfaces.tsx +3 -1
- package/src/vista/surfaces/text-surfaces.tsx +21 -8
- package/src/vista/use-vista-tabs.ts +12 -4
- package/src/vista/vista-code-renderer.tsx +6 -5
- package/src/vista/vista-file-source.tsx +15 -14
- package/src/vista/vista-form-host.tsx +3 -8
- package/src/vista/vista-model.ts +10 -3
- package/src/vista/vista-open-context.tsx +3 -8
- package/src/vista/vista-payloads.ts +186 -63
- package/src/vista/vista-tabs-manifest.ts +28 -13
- package/src/vista/vista-tools.ts +18 -6
- package/dist/lib/biome-host/session-profiles.d.ts +0 -18
- package/dist/lib/biome-host/session-profiles.d.ts.map +0 -1
- package/dist/lib/biome-host/session-profiles.js +0 -38
- package/dist/lib/biome-host/session-profiles.js.map +0 -1
- package/src/lib/biome-host/session-profiles.ts +0 -105
|
@@ -8,35 +8,66 @@
|
|
|
8
8
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
CaptureFieldType,
|
|
13
|
+
type CaptureFieldSpec,
|
|
14
|
+
type CaptureSchema,
|
|
15
|
+
type CaptureSection,
|
|
16
|
+
toFieldList,
|
|
17
|
+
} from './field-spec';
|
|
12
18
|
|
|
13
19
|
/** `''`, `null`, `undefined` all mean "absent" at the capture boundary. */
|
|
14
20
|
export function isEmptyValue(value: unknown): boolean {
|
|
15
|
-
return
|
|
21
|
+
return (
|
|
22
|
+
value === undefined ||
|
|
23
|
+
value === null ||
|
|
24
|
+
value === '' ||
|
|
25
|
+
(Array.isArray(value) && value.length === 0)
|
|
26
|
+
);
|
|
16
27
|
}
|
|
17
28
|
|
|
18
29
|
function scalarSchema(field: CaptureFieldSpec): z.ZodTypeAny {
|
|
19
30
|
switch (field.type) {
|
|
20
31
|
case CaptureFieldType.Number: {
|
|
21
32
|
let s = z.number({ message: `${field.label} must be a number` });
|
|
22
|
-
if (typeof field.min === 'number')
|
|
23
|
-
|
|
33
|
+
if (typeof field.min === 'number') {
|
|
34
|
+
s = s.min(field.min, {
|
|
35
|
+
message: `${field.label} must be ≥ ${field.min}`,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (typeof field.max === 'number') {
|
|
39
|
+
s = s.max(field.max, {
|
|
40
|
+
message: `${field.label} must be ≤ ${field.max}`,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
24
43
|
return s;
|
|
25
44
|
}
|
|
26
45
|
case CaptureFieldType.Boolean:
|
|
27
46
|
return z.boolean({ message: `${field.label} must be true or false` });
|
|
28
47
|
case CaptureFieldType.Decimal:
|
|
29
48
|
// NUMERIC carried as a string to avoid float precision loss.
|
|
30
|
-
return z
|
|
49
|
+
return z
|
|
50
|
+
.string()
|
|
51
|
+
.regex(/^-?\d+(\.\d+)?$/, {
|
|
52
|
+
message: `${field.label} must be a decimal number`,
|
|
53
|
+
});
|
|
31
54
|
case CaptureFieldType.Enum: {
|
|
32
55
|
const values = [...(field.enumValues ?? [])];
|
|
33
|
-
if (values.length === 0)
|
|
56
|
+
if (values.length === 0) {
|
|
57
|
+
return z.string();
|
|
58
|
+
}
|
|
34
59
|
return z.enum(values as [string, ...string[]]);
|
|
35
60
|
}
|
|
36
61
|
case CaptureFieldType.Date:
|
|
37
|
-
return z
|
|
62
|
+
return z
|
|
63
|
+
.string()
|
|
64
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, {
|
|
65
|
+
message: `${field.label} must be a date`,
|
|
66
|
+
});
|
|
38
67
|
case CaptureFieldType.Datetime:
|
|
39
|
-
return z
|
|
68
|
+
return z
|
|
69
|
+
.string()
|
|
70
|
+
.min(1, { message: `${field.label} must be a date/time` });
|
|
40
71
|
// string / text / user / reference — plain text.
|
|
41
72
|
default:
|
|
42
73
|
return z.string();
|
|
@@ -69,8 +100,16 @@ function fieldSchema(field: CaptureFieldSpec): z.ZodTypeAny {
|
|
|
69
100
|
});
|
|
70
101
|
} else if (field.type === CaptureFieldType.List) {
|
|
71
102
|
let arr = z.array(objectSchema(field.fields ?? []));
|
|
72
|
-
if (typeof field.min === 'number')
|
|
73
|
-
|
|
103
|
+
if (typeof field.min === 'number') {
|
|
104
|
+
arr = arr.min(field.min, {
|
|
105
|
+
message: `${field.label} needs at least ${field.min} item(s)`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (typeof field.max === 'number') {
|
|
109
|
+
arr = arr.max(field.max, {
|
|
110
|
+
message: `${field.label} allows at most ${field.max} item(s)`,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
74
113
|
base = arr;
|
|
75
114
|
} else {
|
|
76
115
|
base = scalarSchema(field);
|
|
@@ -88,7 +127,9 @@ function fieldSchema(field: CaptureFieldSpec): z.ZodTypeAny {
|
|
|
88
127
|
field.type === CaptureFieldType.File ||
|
|
89
128
|
field.type === CaptureFieldType.Audio)
|
|
90
129
|
) {
|
|
91
|
-
base = (base as z.ZodString).min(1, {
|
|
130
|
+
base = (base as z.ZodString).min(1, {
|
|
131
|
+
message: `${field.label} is required`,
|
|
132
|
+
});
|
|
92
133
|
}
|
|
93
134
|
}
|
|
94
135
|
|
|
@@ -101,9 +142,13 @@ function fieldSchema(field: CaptureFieldSpec): z.ZodTypeAny {
|
|
|
101
142
|
return base;
|
|
102
143
|
}
|
|
103
144
|
|
|
104
|
-
function objectSchema(
|
|
145
|
+
function objectSchema(
|
|
146
|
+
fields: readonly CaptureFieldSpec[],
|
|
147
|
+
): z.ZodObject<z.ZodRawShape> {
|
|
105
148
|
const shape: Record<string, z.ZodTypeAny> = {};
|
|
106
|
-
for (const f of fields)
|
|
149
|
+
for (const f of fields) {
|
|
150
|
+
shape[f.key] = fieldSchema(f);
|
|
151
|
+
}
|
|
107
152
|
// Non-strict: unknown keys are ignored (the server is the strict fence).
|
|
108
153
|
return z.object(shape);
|
|
109
154
|
}
|
|
@@ -120,7 +165,10 @@ function objectSchema(fields: readonly CaptureFieldSpec[]): z.ZodObject<z.ZodRaw
|
|
|
120
165
|
* schema.safeParse({ title: 'Hi', tags: [{ name: 'a' }] }); // { success: true }
|
|
121
166
|
*/
|
|
122
167
|
export function fieldSpecToZod(
|
|
123
|
-
schema:
|
|
168
|
+
schema:
|
|
169
|
+
| CaptureSchema
|
|
170
|
+
| readonly CaptureFieldSpec[]
|
|
171
|
+
| readonly CaptureSection[],
|
|
124
172
|
): z.ZodObject<z.ZodRawShape> {
|
|
125
173
|
return objectSchema(toFieldList(schema));
|
|
126
174
|
}
|
|
@@ -10,10 +10,18 @@
|
|
|
10
10
|
// exactly like the Vista payload validators, so a malformed schema degrades to
|
|
11
11
|
// a visible typed fallback instead of a half-rendered form.
|
|
12
12
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
import {
|
|
14
|
+
CaptureFieldTransform,
|
|
15
|
+
CaptureFieldType,
|
|
16
|
+
type CaptureFieldSpec,
|
|
17
|
+
} from './field-spec';
|
|
18
|
+
|
|
19
|
+
const FIELD_TYPES: ReadonlySet<string> = new Set(
|
|
20
|
+
Object.values(CaptureFieldType),
|
|
21
|
+
);
|
|
22
|
+
const TRANSFORMS: ReadonlySet<string> = new Set(
|
|
23
|
+
Object.values(CaptureFieldTransform),
|
|
24
|
+
);
|
|
17
25
|
|
|
18
26
|
type UnknownRecord = Readonly<Record<string, unknown>>;
|
|
19
27
|
|
|
@@ -25,72 +33,117 @@ function asRecord(value: unknown): UnknownRecord | null {
|
|
|
25
33
|
|
|
26
34
|
/** `undefined` passes through; a present non-string is a rejection (`null`). */
|
|
27
35
|
function optionalString(value: unknown): string | undefined | null {
|
|
28
|
-
if (value === undefined)
|
|
36
|
+
if (value === undefined) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
29
39
|
return typeof value === 'string' ? value : null;
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
/** `undefined` passes through; a present non-boolean is a rejection (`null`). */
|
|
33
43
|
function optionalBoolean(value: unknown): boolean | undefined | null {
|
|
34
|
-
if (value === undefined)
|
|
44
|
+
if (value === undefined) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
35
47
|
return typeof value === 'boolean' ? value : null;
|
|
36
48
|
}
|
|
37
49
|
|
|
38
50
|
/** `undefined` passes through; a present non-number is a rejection (`null`). */
|
|
39
51
|
function optionalNumber(value: unknown): number | undefined | null {
|
|
40
|
-
if (value === undefined)
|
|
52
|
+
if (value === undefined) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
41
55
|
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
42
56
|
}
|
|
43
57
|
|
|
44
58
|
/** Narrow ONE field spec. Returns `null` for anything malformed. */
|
|
45
59
|
export function validateCaptureField(raw: unknown): CaptureFieldSpec | null {
|
|
46
60
|
const record = asRecord(raw);
|
|
47
|
-
if (record === null)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (typeof record.
|
|
61
|
+
if (record === null) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
if (typeof record.key !== 'string' || record.key.length === 0) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
if (typeof record.label !== 'string' || record.label.length === 0) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
if (typeof record.type !== 'string' || !FIELD_TYPES.has(record.type)) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
51
73
|
|
|
52
74
|
const required = optionalBoolean(record.required);
|
|
53
|
-
if (required === null)
|
|
75
|
+
if (required === null) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
54
78
|
const isSecret = optionalBoolean(record.isSecret);
|
|
55
|
-
if (isSecret === null)
|
|
79
|
+
if (isSecret === null) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
56
82
|
const description = optionalString(record.description);
|
|
57
|
-
if (description === null)
|
|
83
|
+
if (description === null) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
58
86
|
const placeholder = optionalString(record.placeholder);
|
|
59
|
-
if (placeholder === null)
|
|
87
|
+
if (placeholder === null) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
60
90
|
const section = optionalString(record.section);
|
|
61
|
-
if (section === null)
|
|
91
|
+
if (section === null) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
62
94
|
const referenceEntity = optionalString(record.referenceEntity);
|
|
63
|
-
if (referenceEntity === null)
|
|
95
|
+
if (referenceEntity === null) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
64
98
|
const accept = optionalString(record.accept);
|
|
65
|
-
if (accept === null)
|
|
99
|
+
if (accept === null) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
66
102
|
const min = optionalNumber(record.min);
|
|
67
|
-
if (min === null)
|
|
103
|
+
if (min === null) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
68
106
|
const max = optionalNumber(record.max);
|
|
69
|
-
if (max === null)
|
|
107
|
+
if (max === null) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
70
110
|
|
|
71
111
|
let transform: CaptureFieldTransform | undefined;
|
|
72
112
|
if (record.transform !== undefined) {
|
|
73
|
-
if (
|
|
113
|
+
if (
|
|
114
|
+
typeof record.transform !== 'string' ||
|
|
115
|
+
!TRANSFORMS.has(record.transform)
|
|
116
|
+
) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
74
119
|
transform = record.transform as CaptureFieldTransform;
|
|
75
120
|
}
|
|
76
121
|
|
|
77
122
|
let enumValues: readonly string[] | undefined;
|
|
78
123
|
if (record.enumValues !== undefined) {
|
|
79
|
-
if (!Array.isArray(record.enumValues))
|
|
80
|
-
|
|
124
|
+
if (!Array.isArray(record.enumValues)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (!record.enumValues.every((v) => typeof v === 'string')) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
81
130
|
enumValues = record.enumValues;
|
|
82
131
|
}
|
|
83
132
|
|
|
84
133
|
let capture: 'user' | 'environment' | undefined;
|
|
85
134
|
if (record.capture !== undefined) {
|
|
86
|
-
if (record.capture !== 'user' && record.capture !== 'environment')
|
|
135
|
+
if (record.capture !== 'user' && record.capture !== 'environment') {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
87
138
|
capture = record.capture;
|
|
88
139
|
}
|
|
89
140
|
|
|
90
141
|
let fields: readonly CaptureFieldSpec[] | undefined;
|
|
91
142
|
if (record.fields !== undefined) {
|
|
92
143
|
const nested = validateCaptureFields(record.fields);
|
|
93
|
-
if (nested === null)
|
|
144
|
+
if (nested === null) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
94
147
|
fields = nested;
|
|
95
148
|
}
|
|
96
149
|
|
|
@@ -111,21 +164,51 @@ export function validateCaptureField(raw: unknown): CaptureFieldSpec | null {
|
|
|
111
164
|
fields?: readonly CaptureFieldSpec[];
|
|
112
165
|
min?: number;
|
|
113
166
|
max?: number;
|
|
114
|
-
} = {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
167
|
+
} = {
|
|
168
|
+
key: record.key,
|
|
169
|
+
label: record.label,
|
|
170
|
+
type: record.type as CaptureFieldType,
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
if (required !== undefined) {
|
|
174
|
+
spec.required = required;
|
|
175
|
+
}
|
|
176
|
+
if (isSecret !== undefined) {
|
|
177
|
+
spec.isSecret = isSecret;
|
|
178
|
+
}
|
|
179
|
+
if (transform !== undefined) {
|
|
180
|
+
spec.transform = transform;
|
|
181
|
+
}
|
|
182
|
+
if (description !== undefined) {
|
|
183
|
+
spec.description = description;
|
|
184
|
+
}
|
|
185
|
+
if (placeholder !== undefined) {
|
|
186
|
+
spec.placeholder = placeholder;
|
|
187
|
+
}
|
|
188
|
+
if (section !== undefined) {
|
|
189
|
+
spec.section = section;
|
|
190
|
+
}
|
|
191
|
+
if (referenceEntity !== undefined) {
|
|
192
|
+
spec.referenceEntity = referenceEntity;
|
|
193
|
+
}
|
|
194
|
+
if (accept !== undefined) {
|
|
195
|
+
spec.accept = accept;
|
|
196
|
+
}
|
|
197
|
+
if (capture !== undefined) {
|
|
198
|
+
spec.capture = capture;
|
|
199
|
+
}
|
|
200
|
+
if (enumValues !== undefined) {
|
|
201
|
+
spec.enumValues = enumValues;
|
|
202
|
+
}
|
|
203
|
+
if (fields !== undefined) {
|
|
204
|
+
spec.fields = fields;
|
|
205
|
+
}
|
|
206
|
+
if (min !== undefined) {
|
|
207
|
+
spec.min = min;
|
|
208
|
+
}
|
|
209
|
+
if (max !== undefined) {
|
|
210
|
+
spec.max = max;
|
|
211
|
+
}
|
|
129
212
|
|
|
130
213
|
return spec;
|
|
131
214
|
}
|
|
@@ -135,12 +218,18 @@ export function validateCaptureField(raw: unknown): CaptureFieldSpec | null {
|
|
|
135
218
|
* empty schema is a real, meaningful state (the server is the authority on
|
|
136
219
|
* whether a form with no fields may be submitted), not a validation failure.
|
|
137
220
|
*/
|
|
138
|
-
export function validateCaptureFields(
|
|
139
|
-
|
|
221
|
+
export function validateCaptureFields(
|
|
222
|
+
raw: unknown,
|
|
223
|
+
): readonly CaptureFieldSpec[] | null {
|
|
224
|
+
if (!Array.isArray(raw)) {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
140
227
|
const out: CaptureFieldSpec[] = [];
|
|
141
228
|
for (const entry of raw) {
|
|
142
229
|
const spec = validateCaptureField(entry);
|
|
143
|
-
if (spec === null)
|
|
230
|
+
if (spec === null) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
144
233
|
out.push(spec);
|
|
145
234
|
}
|
|
146
235
|
return out;
|
|
@@ -34,8 +34,8 @@ describe('groupFieldsBySection', () => {
|
|
|
34
34
|
it('splits a flat list by each field section key, preserving order', () => {
|
|
35
35
|
const grouped = groupFieldsBySection(fields);
|
|
36
36
|
expect(grouped.map((s) => s.key)).toEqual(['one', 'two']);
|
|
37
|
-
expect(grouped[0]
|
|
38
|
-
expect(grouped[1]
|
|
37
|
+
expect(grouped[0]?.fields.map((f) => f.key)).toEqual(['a', 'b']);
|
|
38
|
+
expect(grouped[1]?.fields.map((f) => f.key)).toEqual(['c']);
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -174,8 +174,14 @@ export interface CaptureSection {
|
|
|
174
174
|
* either face.
|
|
175
175
|
*/
|
|
176
176
|
export type CaptureSchema =
|
|
177
|
-
| {
|
|
178
|
-
|
|
177
|
+
| {
|
|
178
|
+
readonly fields: readonly CaptureFieldSpec[];
|
|
179
|
+
readonly sections?: undefined;
|
|
180
|
+
}
|
|
181
|
+
| {
|
|
182
|
+
readonly sections: readonly CaptureSection[];
|
|
183
|
+
readonly fields?: undefined;
|
|
184
|
+
};
|
|
179
185
|
|
|
180
186
|
/** Structured record value the capture kit reads/writes. */
|
|
181
187
|
export type CaptureValues = Record<string, unknown>;
|
|
@@ -184,7 +190,11 @@ export type CaptureValues = Record<string, unknown>;
|
|
|
184
190
|
export function isSectioned(
|
|
185
191
|
x: CaptureSchema | readonly CaptureFieldSpec[] | readonly CaptureSection[],
|
|
186
192
|
): x is { readonly sections: readonly CaptureSection[] } {
|
|
187
|
-
return
|
|
193
|
+
return (
|
|
194
|
+
!Array.isArray(x) &&
|
|
195
|
+
'sections' in (x as object) &&
|
|
196
|
+
Array.isArray((x as { sections?: unknown }).sections)
|
|
197
|
+
);
|
|
188
198
|
}
|
|
189
199
|
|
|
190
200
|
/**
|
|
@@ -194,17 +204,25 @@ export function isSectioned(
|
|
|
194
204
|
* `CaptureSchema`.
|
|
195
205
|
*/
|
|
196
206
|
export function toFieldList(
|
|
197
|
-
schema:
|
|
207
|
+
schema:
|
|
208
|
+
| CaptureSchema
|
|
209
|
+
| readonly CaptureFieldSpec[]
|
|
210
|
+
| readonly CaptureSection[],
|
|
198
211
|
): readonly CaptureFieldSpec[] {
|
|
199
212
|
if (Array.isArray(schema)) {
|
|
200
213
|
const arr = schema as readonly (CaptureFieldSpec | CaptureSection)[];
|
|
201
214
|
// A CaptureSection has `title`+`fields`; a CaptureFieldSpec has `type`.
|
|
202
|
-
if (
|
|
215
|
+
if (
|
|
216
|
+
arr.length > 0 &&
|
|
217
|
+
arr.every((e) => 'title' in e && 'fields' in e && !('type' in e))
|
|
218
|
+
) {
|
|
203
219
|
return (arr as readonly CaptureSection[]).flatMap((s) => s.fields);
|
|
204
220
|
}
|
|
205
221
|
return arr as readonly CaptureFieldSpec[];
|
|
206
222
|
}
|
|
207
|
-
if (isSectioned(schema))
|
|
223
|
+
if (isSectioned(schema)) {
|
|
224
|
+
return schema.sections.flatMap((s) => s.fields);
|
|
225
|
+
}
|
|
208
226
|
return (schema as { fields: readonly CaptureFieldSpec[] }).fields;
|
|
209
227
|
}
|
|
210
228
|
|
|
@@ -214,13 +232,22 @@ export function toFieldList(
|
|
|
214
232
|
* `section` key when present).
|
|
215
233
|
*/
|
|
216
234
|
export function toSections(
|
|
217
|
-
schema:
|
|
235
|
+
schema:
|
|
236
|
+
| CaptureSchema
|
|
237
|
+
| readonly CaptureFieldSpec[]
|
|
238
|
+
| readonly CaptureSection[],
|
|
218
239
|
fallbackTitle = '',
|
|
219
240
|
): readonly CaptureSection[] {
|
|
220
|
-
if (
|
|
241
|
+
if (
|
|
242
|
+
Array.isArray(schema) &&
|
|
243
|
+
schema.length > 0 &&
|
|
244
|
+
(schema as readonly object[]).every((e) => 'title' in e && 'fields' in e)
|
|
245
|
+
) {
|
|
221
246
|
return schema as readonly CaptureSection[];
|
|
222
247
|
}
|
|
223
|
-
if (!Array.isArray(schema) && isSectioned(schema))
|
|
248
|
+
if (!Array.isArray(schema) && isSectioned(schema)) {
|
|
249
|
+
return schema.sections;
|
|
250
|
+
}
|
|
224
251
|
return groupFieldsBySection(toFieldList(schema), fallbackTitle);
|
|
225
252
|
}
|
|
226
253
|
|
|
@@ -239,5 +266,9 @@ export function groupFieldsBySection(
|
|
|
239
266
|
}
|
|
240
267
|
byKey.get(key)!.push(f);
|
|
241
268
|
}
|
|
242
|
-
return order.map((key) => ({
|
|
269
|
+
return order.map((key) => ({
|
|
270
|
+
key: key || '_',
|
|
271
|
+
title: key || fallbackTitle,
|
|
272
|
+
fields: byKey.get(key)!,
|
|
273
|
+
}));
|
|
243
274
|
}
|