@xemahq/ui-kernel 0.9.0 → 0.9.2
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/biome-host/biome-builders.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-builders.js +3 -1
- package/dist/lib/biome-host/biome-builders.js.map +1 -1
- package/dist/lib/biome-host/biome-registry.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-registry.js +14 -9
- package/dist/lib/biome-host/biome-registry.js.map +1 -1
- package/dist/lib/biome-host/biome-scope-hooks.d.ts +11 -0
- package/dist/lib/biome-host/biome-scope-hooks.d.ts.map +1 -0
- package/dist/lib/biome-host/biome-scope-hooks.js +25 -0
- package/dist/lib/biome-host/biome-scope-hooks.js.map +1 -0
- package/dist/lib/biome-host/biome-scope.d.ts +1 -10
- package/dist/lib/biome-host/biome-scope.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scope.js +1 -24
- package/dist/lib/biome-host/biome-scope.js.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.d.ts +1 -1
- package/dist/lib/biome-host/biome-scoped-query.d.ts.map +1 -1
- package/dist/lib/biome-host/biome-scoped-query.js +1 -1
- package/dist/lib/biome-host/biome-scoped-query.js.map +1 -1
- package/dist/lib/biome-host/create-biome-orval-config.js +2 -2
- package/dist/lib/biome-host/create-biome-orval-config.js.map +1 -1
- package/dist/lib/biome-host/errors.js.map +1 -1
- package/dist/lib/biome-host/index.d.ts +1 -1
- package/dist/lib/biome-host/index.d.ts.map +1 -1
- package/dist/lib/biome-host/index.js +1 -1
- package/dist/lib/biome-host/index.js.map +1 -1
- package/dist/lib/biome-host/session-profiles.d.ts.map +1 -1
- package/dist/lib/biome-host/session-profiles.js +4 -1
- package/dist/lib/biome-host/session-profiles.js.map +1 -1
- package/dist/lib/capabilities/capability-context.d.ts +9 -0
- package/dist/lib/capabilities/capability-context.d.ts.map +1 -0
- package/dist/lib/capabilities/capability-context.js +13 -0
- package/dist/lib/capabilities/capability-context.js.map +1 -0
- package/dist/lib/capabilities/capability-provider.d.ts +2 -8
- package/dist/lib/capabilities/capability-provider.d.ts.map +1 -1
- package/dist/lib/capabilities/capability-provider.js +1 -12
- package/dist/lib/capabilities/capability-provider.js.map +1 -1
- package/dist/lib/capabilities/index.d.ts +1 -0
- package/dist/lib/capabilities/index.d.ts.map +1 -1
- package/dist/lib/capabilities/index.js +1 -0
- package/dist/lib/capabilities/index.js.map +1 -1
- package/dist/lib/capabilities/use-capability.d.ts.map +1 -1
- package/dist/lib/capabilities/use-capability.js +1 -1
- package/dist/lib/capabilities/use-capability.js.map +1 -1
- package/dist/lib/contribution-registry/contribution-registry.d.ts +24 -0
- package/dist/lib/contribution-registry/contribution-registry.d.ts.map +1 -0
- package/dist/lib/contribution-registry/contribution-registry.js +67 -0
- package/dist/lib/contribution-registry/contribution-registry.js.map +1 -0
- package/dist/lib/contribution-registry/index.d.ts +3 -0
- package/dist/lib/contribution-registry/index.d.ts.map +1 -0
- package/dist/lib/contribution-registry/index.js +3 -0
- package/dist/lib/contribution-registry/index.js.map +1 -0
- package/dist/lib/contribution-registry/renderable-registry.d.ts +33 -0
- package/dist/lib/contribution-registry/renderable-registry.d.ts.map +1 -0
- package/dist/lib/contribution-registry/renderable-registry.js +51 -0
- package/dist/lib/contribution-registry/renderable-registry.js.map +1 -0
- package/dist/lib/system-bus/deeplink.js.map +1 -1
- package/dist/lib/system-bus/host-ports.d.ts +2 -1
- 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.map +1 -1
- package/dist/offline/index.d.ts +2 -1
- package/dist/offline/index.d.ts.map +1 -1
- package/dist/offline/index.js +2 -1
- package/dist/offline/index.js.map +1 -1
- package/dist/offline/offline-status-badge.js +1 -1
- package/dist/offline/offline-status-badge.js.map +1 -1
- package/dist/offline/outbox.js.map +1 -1
- package/dist/offline/react-hooks.d.ts +7 -0
- package/dist/offline/react-hooks.d.ts.map +1 -0
- package/dist/offline/react-hooks.js +25 -0
- package/dist/offline/react-hooks.js.map +1 -0
- package/dist/offline/react.d.ts +0 -4
- package/dist/offline/react.d.ts.map +1 -1
- package/dist/offline/react.js +2 -24
- package/dist/offline/react.js.map +1 -1
- package/dist/offline/storage.d.ts.map +1 -1
- package/dist/offline/storage.js +8 -5
- package/dist/offline/storage.js.map +1 -1
- package/dist/registry/index.d.ts +1 -0
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +1 -0
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.d.ts.map +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.js +1 -1
- package/dist/registry/lib/primitives/SessionEventCard.js.map +1 -1
- package/dist/registry/lib/session-context-provider.d.ts +1 -3
- package/dist/registry/lib/session-context-provider.d.ts.map +1 -1
- package/dist/registry/lib/session-context-provider.js +2 -15
- package/dist/registry/lib/session-context-provider.js.map +1 -1
- package/dist/registry/lib/session-context.d.ts +5 -0
- package/dist/registry/lib/session-context.d.ts.map +1 -0
- package/dist/registry/lib/session-context.js +15 -0
- package/dist/registry/lib/session-context.js.map +1 -0
- package/dist/registry/lib/session-selectors.d.ts.map +1 -1
- package/dist/registry/lib/session-selectors.js +3 -1
- package/dist/registry/lib/session-selectors.js.map +1 -1
- package/dist/ui/branding/app-branding-context.d.ts +9 -0
- package/dist/ui/branding/app-branding-context.d.ts.map +1 -0
- package/dist/ui/branding/app-branding-context.js +10 -0
- package/dist/ui/branding/app-branding-context.js.map +1 -0
- package/dist/ui/branding/app-branding-provider.d.ts +0 -6
- package/dist/ui/branding/app-branding-provider.d.ts.map +1 -1
- package/dist/ui/branding/app-branding-provider.js +1 -8
- package/dist/ui/branding/app-branding-provider.js.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.d.ts +1 -0
- package/dist/ui/capture/field-spec-to-zod.d.ts.map +1 -1
- package/dist/ui/capture/field-spec-to-zod.js +19 -0
- package/dist/ui/capture/field-spec-to-zod.js.map +1 -1
- package/dist/ui/capture/field-spec-validate.d.ts +4 -0
- package/dist/ui/capture/field-spec-validate.d.ts.map +1 -0
- package/dist/ui/capture/field-spec-validate.js +129 -0
- package/dist/ui/capture/field-spec-validate.js.map +1 -0
- package/dist/ui/capture/field-spec.d.ts +13 -1
- package/dist/ui/capture/field-spec.d.ts.map +1 -1
- package/dist/ui/capture/field-spec.js +25 -0
- package/dist/ui/capture/field-spec.js.map +1 -1
- package/dist/ui/capture/index.d.ts +4 -2
- package/dist/ui/capture/index.d.ts.map +1 -1
- package/dist/ui/capture/index.js +4 -2
- package/dist/ui/capture/index.js.map +1 -1
- package/dist/ui/capture/schema-field-input.d.ts.map +1 -1
- package/dist/ui/capture/schema-field-input.js +40 -13
- package/dist/ui/capture/schema-field-input.js.map +1 -1
- package/dist/ui/capture/submit-values.d.ts +6 -0
- package/dist/ui/capture/submit-values.d.ts.map +1 -0
- package/dist/ui/capture/submit-values.js +28 -0
- package/dist/ui/capture/submit-values.js.map +1 -0
- package/dist/ui/capture/use-prefill.d.ts.map +1 -1
- package/dist/ui/capture/use-prefill.js +3 -1
- package/dist/ui/capture/use-prefill.js.map +1 -1
- package/dist/ui/capture/use-wizard.d.ts +1 -1
- package/dist/ui/capture/use-wizard.d.ts.map +1 -1
- package/dist/ui/capture/use-wizard.js +1 -1
- package/dist/ui/capture/use-wizard.js.map +1 -1
- package/dist/ui/capture/wizard.d.ts.map +1 -1
- package/dist/ui/capture/wizard.js.map +1 -1
- package/dist/ui/index.d.ts +6 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +6 -1
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/primitives/alert-dialog.js +1 -1
- package/dist/ui/primitives/alert-dialog.js.map +1 -1
- package/dist/ui/primitives/badge-variants.d.ts +4 -0
- package/dist/ui/primitives/badge-variants.d.ts.map +1 -0
- package/dist/ui/primitives/badge-variants.js +15 -0
- package/dist/ui/primitives/badge-variants.js.map +1 -0
- package/dist/ui/primitives/badge.d.ts +3 -5
- package/dist/ui/primitives/badge.d.ts.map +1 -1
- package/dist/ui/primitives/badge.js +2 -15
- package/dist/ui/primitives/badge.js.map +1 -1
- package/dist/ui/primitives/button-variants.d.ts +5 -0
- package/dist/ui/primitives/button-variants.d.ts.map +1 -0
- package/dist/ui/primitives/button-variants.js +24 -0
- package/dist/ui/primitives/button-variants.js.map +1 -0
- package/dist/ui/primitives/button.d.ts +3 -6
- package/dist/ui/primitives/button.d.ts.map +1 -1
- package/dist/ui/primitives/button.js +2 -24
- package/dist/ui/primitives/button.js.map +1 -1
- package/dist/ui/primitives/form-stepper.d.ts +1 -13
- package/dist/ui/primitives/form-stepper.d.ts.map +1 -1
- package/dist/ui/primitives/form-stepper.js +1 -6
- package/dist/ui/primitives/form-stepper.js.map +1 -1
- package/dist/ui/primitives/form-stepper.types.d.ts +14 -0
- package/dist/ui/primitives/form-stepper.types.d.ts.map +1 -0
- package/dist/ui/primitives/form-stepper.types.js +7 -0
- package/dist/ui/primitives/form-stepper.types.js.map +1 -0
- package/dist/ui/primitives/overflow-tabs.d.ts +5 -0
- package/dist/ui/primitives/overflow-tabs.d.ts.map +1 -1
- package/dist/ui/primitives/overflow-tabs.js +4 -4
- package/dist/ui/primitives/overflow-tabs.js.map +1 -1
- package/dist/ui/primitives/preview-device-frame.js +1 -1
- 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 +1 -1
- package/dist/ui/primitives/tag-multi-select.js.map +1 -1
- package/dist/ui/primitives/url-preview-chrome.d.ts +8 -0
- package/dist/ui/primitives/url-preview-chrome.d.ts.map +1 -0
- package/dist/ui/primitives/url-preview-chrome.js +40 -0
- package/dist/ui/primitives/url-preview-chrome.js.map +1 -0
- package/dist/vista/GenericCatalogueSurface.d.ts +10 -0
- package/dist/vista/GenericCatalogueSurface.d.ts.map +1 -0
- package/dist/vista/GenericCatalogueSurface.js +80 -0
- package/dist/vista/GenericCatalogueSurface.js.map +1 -0
- package/dist/vista/SurfaceFallbackCard.d.ts +9 -0
- package/dist/vista/SurfaceFallbackCard.d.ts.map +1 -0
- package/dist/vista/SurfaceFallbackCard.js +44 -0
- package/dist/vista/SurfaceFallbackCard.js.map +1 -0
- package/dist/vista/VistaPanel.d.ts +21 -0
- package/dist/vista/VistaPanel.d.ts.map +1 -0
- package/dist/vista/VistaPanel.js +31 -0
- package/dist/vista/VistaPanel.js.map +1 -0
- package/dist/vista/html/CustomUiFrame.d.ts +20 -0
- package/dist/vista/html/CustomUiFrame.d.ts.map +1 -0
- package/dist/vista/html/CustomUiFrame.js +69 -0
- package/dist/vista/html/CustomUiFrame.js.map +1 -0
- package/dist/vista/html/custom-ui-frame-bridge.d.ts +13 -0
- package/dist/vista/html/custom-ui-frame-bridge.d.ts.map +1 -0
- package/dist/vista/html/custom-ui-frame-bridge.js +30 -0
- package/dist/vista/html/custom-ui-frame-bridge.js.map +1 -0
- package/dist/vista/html/custom-ui-frame-contract.d.ts +29 -0
- package/dist/vista/html/custom-ui-frame-contract.d.ts.map +1 -0
- package/dist/vista/html/custom-ui-frame-contract.js +16 -0
- package/dist/vista/html/custom-ui-frame-contract.js.map +1 -0
- package/dist/vista/html/custom-ui-intents.d.ts +20 -0
- package/dist/vista/html/custom-ui-intents.d.ts.map +1 -0
- package/dist/vista/html/custom-ui-intents.js +57 -0
- package/dist/vista/html/custom-ui-intents.js.map +1 -0
- package/dist/vista/html/custom-ui-srcdoc.d.ts +17 -0
- package/dist/vista/html/custom-ui-srcdoc.d.ts.map +1 -0
- package/dist/vista/html/custom-ui-srcdoc.js +70 -0
- package/dist/vista/html/custom-ui-srcdoc.js.map +1 -0
- package/dist/vista/html/index.d.ts +6 -0
- package/dist/vista/html/index.d.ts.map +1 -0
- package/dist/vista/html/index.js +6 -0
- package/dist/vista/html/index.js.map +1 -0
- package/dist/vista/index.d.ts +22 -0
- package/dist/vista/index.d.ts.map +1 -0
- package/dist/vista/index.js +22 -0
- package/dist/vista/index.js.map +1 -0
- package/dist/vista/surface-catalogue.d.ts +5 -0
- package/dist/vista/surface-catalogue.d.ts.map +1 -0
- package/dist/vista/surface-catalogue.js +30 -0
- package/dist/vista/surface-catalogue.js.map +1 -0
- package/dist/vista/surface-icons.d.ts +7 -0
- package/dist/vista/surface-icons.d.ts.map +1 -0
- package/dist/vista/surface-icons.js +26 -0
- package/dist/vista/surface-icons.js.map +1 -0
- package/dist/vista/surface-registry.d.ts +7 -0
- package/dist/vista/surface-registry.d.ts.map +1 -0
- package/dist/vista/surface-registry.js +7 -0
- package/dist/vista/surface-registry.js.map +1 -0
- package/dist/vista/surfaces/ChartSurface.d.ts +4 -0
- package/dist/vista/surfaces/ChartSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/ChartSurface.js +17 -0
- package/dist/vista/surfaces/ChartSurface.js.map +1 -0
- package/dist/vista/surfaces/FilesSurface.d.ts +4 -0
- package/dist/vista/surfaces/FilesSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/FilesSurface.js +77 -0
- package/dist/vista/surfaces/FilesSurface.js.map +1 -0
- package/dist/vista/surfaces/FormSurface.d.ts +4 -0
- package/dist/vista/surfaces/FormSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/FormSurface.js +124 -0
- package/dist/vista/surfaces/FormSurface.js.map +1 -0
- package/dist/vista/surfaces/HtmlSurface.d.ts +4 -0
- package/dist/vista/surfaces/HtmlSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/HtmlSurface.js +11 -0
- package/dist/vista/surfaces/HtmlSurface.js.map +1 -0
- package/dist/vista/surfaces/TableSurface.d.ts +4 -0
- package/dist/vista/surfaces/TableSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/TableSurface.js +42 -0
- package/dist/vista/surfaces/TableSurface.js.map +1 -0
- package/dist/vista/surfaces/UrlSurface.d.ts +4 -0
- package/dist/vista/surfaces/UrlSurface.d.ts.map +1 -0
- package/dist/vista/surfaces/UrlSurface.js +7 -0
- package/dist/vista/surfaces/UrlSurface.js.map +1 -0
- package/dist/vista/surfaces/blob-surfaces.d.ts +6 -0
- package/dist/vista/surfaces/blob-surfaces.d.ts.map +1 -0
- package/dist/vista/surfaces/blob-surfaces.js +38 -0
- package/dist/vista/surfaces/blob-surfaces.js.map +1 -0
- package/dist/vista/surfaces/elicitation-transport.d.ts +27 -0
- package/dist/vista/surfaces/elicitation-transport.d.ts.map +1 -0
- package/dist/vista/surfaces/elicitation-transport.js +193 -0
- package/dist/vista/surfaces/elicitation-transport.js.map +1 -0
- package/dist/vista/surfaces/file-surface-utils.d.ts +13 -0
- package/dist/vista/surfaces/file-surface-utils.d.ts.map +1 -0
- package/dist/vista/surfaces/file-surface-utils.js +46 -0
- package/dist/vista/surfaces/file-surface-utils.js.map +1 -0
- package/dist/vista/surfaces/index.d.ts +12 -0
- package/dist/vista/surfaces/index.d.ts.map +1 -0
- package/dist/vista/surfaces/index.js +12 -0
- package/dist/vista/surfaces/index.js.map +1 -0
- package/dist/vista/surfaces/register-surfaces.d.ts +2 -0
- package/dist/vista/surfaces/register-surfaces.d.ts.map +1 -0
- package/dist/vista/surfaces/register-surfaces.js +80 -0
- package/dist/vista/surfaces/register-surfaces.js.map +1 -0
- package/dist/vista/surfaces/text-surfaces.d.ts +8 -0
- package/dist/vista/surfaces/text-surfaces.d.ts.map +1 -0
- package/dist/vista/surfaces/text-surfaces.js +54 -0
- package/dist/vista/surfaces/text-surfaces.js.map +1 -0
- package/dist/vista/use-vista-tabs.d.ts +30 -0
- package/dist/vista/use-vista-tabs.d.ts.map +1 -0
- package/dist/vista/use-vista-tabs.js +77 -0
- package/dist/vista/use-vista-tabs.js.map +1 -0
- package/dist/vista/vista-code-renderer-context.d.ts +9 -0
- package/dist/vista/vista-code-renderer-context.d.ts.map +1 -0
- package/dist/vista/vista-code-renderer-context.js +6 -0
- package/dist/vista/vista-code-renderer-context.js.map +1 -0
- package/dist/vista/vista-code-renderer.d.ts +7 -0
- package/dist/vista/vista-code-renderer.d.ts.map +1 -0
- package/dist/vista/vista-code-renderer.js +6 -0
- package/dist/vista/vista-code-renderer.js.map +1 -0
- package/dist/vista/vista-file-context.d.ts +8 -0
- package/dist/vista/vista-file-context.d.ts.map +1 -0
- package/dist/vista/vista-file-context.js +6 -0
- package/dist/vista/vista-file-context.js.map +1 -0
- package/dist/vista/vista-file-source.d.ts +15 -0
- package/dist/vista/vista-file-source.d.ts.map +1 -0
- package/dist/vista/vista-file-source.js +66 -0
- package/dist/vista/vista-file-source.js.map +1 -0
- package/dist/vista/vista-form-context.d.ts +13 -0
- package/dist/vista/vista-form-context.d.ts.map +1 -0
- package/dist/vista/vista-form-context.js +6 -0
- package/dist/vista/vista-form-context.js.map +1 -0
- package/dist/vista/vista-form-host.d.ts +7 -0
- package/dist/vista/vista-form-host.d.ts.map +1 -0
- package/dist/vista/vista-form-host.js +6 -0
- package/dist/vista/vista-form-host.js.map +1 -0
- package/dist/vista/vista-model.d.ts +12 -0
- package/dist/vista/vista-model.d.ts.map +1 -0
- package/dist/vista/vista-model.js +72 -0
- package/dist/vista/vista-model.js.map +1 -0
- package/dist/vista/vista-open-context.d.ts +7 -0
- package/dist/vista/vista-open-context.d.ts.map +1 -0
- package/dist/vista/vista-open-context.js +6 -0
- package/dist/vista/vista-open-context.js.map +1 -0
- package/dist/vista/vista-open-state.d.ts +5 -0
- package/dist/vista/vista-open-state.d.ts.map +1 -0
- package/dist/vista/vista-open-state.js +6 -0
- package/dist/vista/vista-open-state.js.map +1 -0
- package/dist/vista/vista-payloads.d.ts +106 -0
- package/dist/vista/vista-payloads.d.ts.map +1 -0
- package/dist/vista/vista-payloads.js +302 -0
- package/dist/vista/vista-payloads.js.map +1 -0
- package/dist/vista/vista-tabs-manifest.d.ts +17 -0
- package/dist/vista/vista-tabs-manifest.d.ts.map +1 -0
- package/dist/vista/vista-tabs-manifest.js +60 -0
- package/dist/vista/vista-tabs-manifest.js.map +1 -0
- package/dist/vista/vista-tools.d.ts +41 -0
- package/dist/vista/vista-tools.d.ts.map +1 -0
- package/dist/vista/vista-tools.js +113 -0
- package/dist/vista/vista-tools.js.map +1 -0
- package/package.json +4 -4
- package/src/index.ts +5 -0
- package/src/lib/biome-host/biome-builders.ts +4 -1
- package/src/lib/biome-host/biome-registry.ts +31 -12
- package/src/lib/biome-host/biome-scope-hooks.ts +39 -0
- package/src/lib/biome-host/biome-scope.tsx +1 -68
- package/src/lib/biome-host/biome-scoped-query.ts +4 -1
- package/src/lib/biome-host/create-biome-orval-config.ts +2 -2
- package/src/lib/biome-host/errors.ts +1 -1
- package/src/lib/biome-host/index.ts +1 -1
- package/src/lib/biome-host/session-profiles.ts +7 -1
- package/src/lib/capabilities/capability-context.ts +25 -0
- package/src/lib/capabilities/capability-provider.tsx +5 -34
- package/src/lib/capabilities/index.ts +1 -0
- package/src/lib/capabilities/use-capability.ts +4 -1
- package/src/lib/contribution-registry/contribution-registry.spec.ts +141 -0
- package/src/lib/contribution-registry/contribution-registry.ts +202 -0
- package/src/lib/contribution-registry/index.ts +9 -0
- package/src/lib/contribution-registry/renderable-registry.ts +142 -0
- package/src/lib/system-bus/deeplink.ts +1 -1
- package/src/lib/system-bus/host-ports.ts +2 -1
- package/src/lib/system-bus/intent-registry.ts +1 -2
- package/src/offline/index.ts +4 -2
- package/src/offline/offline-status-badge.tsx +1 -1
- package/src/offline/outbox.test.ts +23 -16
- package/src/offline/outbox.ts +1 -1
- package/src/offline/react-hooks.ts +37 -0
- package/src/offline/react.tsx +1 -40
- package/src/offline/storage.ts +11 -6
- package/src/registry/index.ts +1 -0
- package/src/registry/lib/primitives/SessionEventCard.tsx +4 -2
- package/src/registry/lib/session-context-provider.tsx +8 -25
- package/src/registry/lib/session-context.ts +21 -0
- package/src/registry/lib/session-selectors.ts +3 -1
- package/src/ui/branding/app-branding-context.ts +20 -0
- package/src/ui/branding/app-branding-provider.tsx +5 -27
- package/src/ui/capture/field-spec-to-zod.ts +22 -0
- package/src/ui/capture/field-spec-validate.ts +147 -0
- package/src/ui/capture/field-spec.ts +62 -0
- package/src/ui/capture/index.ts +9 -1
- package/src/ui/capture/schema-field-input.tsx +141 -15
- package/src/ui/capture/submit-values.test.ts +70 -0
- package/src/ui/capture/submit-values.ts +63 -0
- package/src/ui/capture/use-prefill.ts +4 -1
- package/src/ui/capture/use-wizard.ts +2 -2
- package/src/ui/capture/wizard.tsx +2 -1
- package/src/ui/index.ts +11 -2
- package/src/ui/primitives/alert-dialog.tsx +1 -1
- package/src/ui/primitives/badge-variants.ts +21 -0
- package/src/ui/primitives/badge.tsx +3 -19
- package/src/ui/primitives/button-variants.ts +31 -0
- package/src/ui/primitives/button.tsx +3 -28
- package/src/ui/primitives/form-stepper.tsx +1 -16
- package/src/ui/primitives/form-stepper.types.ts +15 -0
- package/src/ui/primitives/overflow-tabs.tsx +24 -4
- package/src/ui/primitives/preview-device-frame.tsx +1 -1
- package/src/ui/primitives/tag-multi-select.tsx +3 -4
- package/src/ui/primitives/url-preview-chrome.tsx +102 -0
- package/src/vista/GenericCatalogueSurface.tsx +177 -0
- package/src/vista/SurfaceFallbackCard.tsx +109 -0
- package/src/vista/VistaPanel.tsx +155 -0
- package/src/vista/form-payload.spec.ts +139 -0
- package/src/vista/html/CustomUiFrame.spec.tsx +125 -0
- package/src/vista/html/CustomUiFrame.tsx +204 -0
- package/src/vista/html/custom-ui-frame-bridge.spec.ts +191 -0
- package/src/vista/html/custom-ui-frame-bridge.ts +92 -0
- package/src/vista/html/custom-ui-frame-contract.ts +88 -0
- package/src/vista/html/custom-ui-intents.spec.ts +133 -0
- package/src/vista/html/custom-ui-intents.ts +151 -0
- package/src/vista/html/custom-ui-srcdoc.spec.ts +151 -0
- package/src/vista/html/custom-ui-srcdoc.ts +193 -0
- package/src/vista/html/index.ts +13 -0
- package/src/vista/index.ts +52 -0
- package/src/vista/surface-catalogue.spec.ts +140 -0
- package/src/vista/surface-catalogue.ts +84 -0
- package/src/vista/surface-icons.ts +57 -0
- package/src/vista/surface-registry.ts +56 -0
- package/src/vista/surfaces/ChartSurface.tsx +34 -0
- package/src/vista/surfaces/FilesSurface.tsx +202 -0
- package/src/vista/surfaces/FormSurface.tsx +363 -0
- package/src/vista/surfaces/HtmlSurface.tsx +43 -0
- package/src/vista/surfaces/TableSurface.tsx +99 -0
- package/src/vista/surfaces/UrlSurface.tsx +40 -0
- package/src/vista/surfaces/blob-surfaces.tsx +129 -0
- package/src/vista/surfaces/elicitation-transport.spec.ts +369 -0
- package/src/vista/surfaces/elicitation-transport.ts +353 -0
- package/src/vista/surfaces/file-surface-utils.ts +62 -0
- package/src/vista/surfaces/index.ts +24 -0
- package/src/vista/surfaces/register-surfaces.tsx +137 -0
- package/src/vista/surfaces/text-surfaces.tsx +119 -0
- package/src/vista/use-vista-tabs.ts +188 -0
- package/src/vista/vista-code-renderer-context.ts +16 -0
- package/src/vista/vista-code-renderer.tsx +34 -0
- package/src/vista/vista-file-context.ts +14 -0
- package/src/vista/vista-file-source.tsx +140 -0
- package/src/vista/vista-form-context.ts +20 -0
- package/src/vista/vista-form-host.tsx +53 -0
- package/src/vista/vista-model.ts +130 -0
- package/src/vista/vista-open-context.tsx +32 -0
- package/src/vista/vista-open-state.ts +11 -0
- package/src/vista/vista-payloads.ts +512 -0
- package/src/vista/vista-tabs-manifest.ts +123 -0
- package/src/vista/vista-tools.ts +220 -0
- package/dist/lib/biome-host/response-envelope.d.ts +0 -3
- package/dist/lib/biome-host/response-envelope.d.ts.map +0 -1
- package/dist/lib/biome-host/response-envelope.js +0 -21
- package/dist/lib/biome-host/response-envelope.js.map +0 -1
- package/src/lib/biome-host/response-envelope.ts +0 -69
|
@@ -6,8 +6,14 @@
|
|
|
6
6
|
// items) composites. `reference` is source-agnostic here: it defaults to a text
|
|
7
7
|
// input, but a caller can inject a picker via `renderReference` (that is the
|
|
8
8
|
// seam app-forge uses to plug its record-backed `ReferenceSelect`).
|
|
9
|
+
//
|
|
10
|
+
// This is the ONE schema→input renderer in the tree. The connector-specific
|
|
11
|
+
// `CredentialFormRenderer` was folded in here: a DECLARED-secret field
|
|
12
|
+
// (`spec.isSecret`) renders the write-only masked input, and `email`/`url`/
|
|
13
|
+
// `json` are ordinary capture field types. Secrecy is never inferred from the
|
|
14
|
+
// field type.
|
|
9
15
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
10
|
-
import { Plus, Trash2 } from 'lucide-react';
|
|
16
|
+
import { Eye, EyeOff, Plus, Trash2 } from 'lucide-react';
|
|
11
17
|
import { useCallback, useRef, useState, type ReactNode } from 'react';
|
|
12
18
|
|
|
13
19
|
import { cn } from '../cn';
|
|
@@ -17,7 +23,7 @@ import { Input } from '../primitives/input';
|
|
|
17
23
|
import { Label } from '../primitives/label';
|
|
18
24
|
import { Textarea } from '../primitives/textarea';
|
|
19
25
|
|
|
20
|
-
import { CaptureFieldType, type CaptureFieldSpec, type CaptureValues } from './field-spec';
|
|
26
|
+
import { applyCaptureTransform, CaptureFieldType, type CaptureFieldSpec, type CaptureValues } from './field-spec';
|
|
21
27
|
import { asString } from './value-format';
|
|
22
28
|
|
|
23
29
|
const SELECT_CLASS =
|
|
@@ -44,42 +50,78 @@ export interface SchemaFieldInputProps {
|
|
|
44
50
|
readonly renderReference?: RenderReference;
|
|
45
51
|
}
|
|
46
52
|
|
|
53
|
+
/** Native `type` for the single-line text-ish capture types. */
|
|
54
|
+
function nativeInputType(type: CaptureFieldSpec['type']): 'text' | 'email' | 'url' {
|
|
55
|
+
switch (type) {
|
|
56
|
+
case CaptureFieldType.Email:
|
|
57
|
+
return 'email';
|
|
58
|
+
case CaptureFieldType.Url:
|
|
59
|
+
return 'url';
|
|
60
|
+
default:
|
|
61
|
+
return 'text';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
47
65
|
export function SchemaFieldInput(props: SchemaFieldInputProps) {
|
|
48
66
|
const { field, value, onChange, disabled, path, renderReference } = props;
|
|
49
67
|
const inputId = `field-${path}`;
|
|
50
68
|
|
|
69
|
+
// The ONE place a captured string is normalized. Composites (object/list)
|
|
70
|
+
// emit records/arrays and pass through untouched.
|
|
71
|
+
const emit = (next: unknown): void =>
|
|
72
|
+
onChange(typeof next === 'string' ? applyCaptureTransform(next, field.transform) : next);
|
|
73
|
+
|
|
74
|
+
// DECLARED secrecy wins over the field type: a secret is always write-only
|
|
75
|
+
// and masked, whatever shape it has. Never inferred from `type`.
|
|
76
|
+
if (field.isSecret === true) {
|
|
77
|
+
return <SecretFieldInput field={field} value={value} onChange={emit} disabled={disabled} inputId={inputId} />;
|
|
78
|
+
}
|
|
79
|
+
|
|
51
80
|
switch (field.type) {
|
|
52
81
|
case CaptureFieldType.Text:
|
|
53
|
-
return <Textarea id={inputId} value={asString(value)} onChange={(e) =>
|
|
82
|
+
return <Textarea id={inputId} value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} rows={4} placeholder={field.placeholder} />;
|
|
83
|
+
case CaptureFieldType.Json:
|
|
84
|
+
return (
|
|
85
|
+
<Textarea
|
|
86
|
+
id={inputId}
|
|
87
|
+
value={asString(value)}
|
|
88
|
+
onChange={(e) => emit(e.target.value)}
|
|
89
|
+
disabled={disabled}
|
|
90
|
+
rows={6}
|
|
91
|
+
spellCheck={false}
|
|
92
|
+
className="min-h-[120px] font-mono"
|
|
93
|
+
placeholder={field.placeholder}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
54
96
|
case CaptureFieldType.Number:
|
|
55
97
|
return (
|
|
56
98
|
<Input
|
|
57
99
|
id={inputId}
|
|
58
100
|
type="number"
|
|
59
101
|
value={asString(value)}
|
|
60
|
-
onChange={(e) =>
|
|
102
|
+
onChange={(e) => emit(e.target.value === '' ? '' : Number(e.target.value))}
|
|
61
103
|
disabled={disabled}
|
|
62
104
|
placeholder={field.placeholder}
|
|
63
105
|
/>
|
|
64
106
|
);
|
|
65
107
|
case CaptureFieldType.Decimal:
|
|
66
108
|
// NUMERIC carried verbatim as text — never Number()-coerced (precision).
|
|
67
|
-
return <Input id={inputId} type="text" inputMode="decimal" value={asString(value)} onChange={(e) =>
|
|
109
|
+
return <Input id={inputId} type="text" inputMode="decimal" value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} placeholder={field.placeholder ?? '0.00'} />;
|
|
68
110
|
case CaptureFieldType.User:
|
|
69
|
-
return <Input id={inputId} value={asString(value)} onChange={(e) =>
|
|
111
|
+
return <Input id={inputId} value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} placeholder={field.placeholder ?? 'subject id'} />;
|
|
70
112
|
case CaptureFieldType.Boolean:
|
|
71
113
|
return (
|
|
72
114
|
<div className="mt-1">
|
|
73
|
-
<Checkbox id={inputId} checked={value === true} onCheckedChange={(checked) =>
|
|
115
|
+
<Checkbox id={inputId} checked={value === true} onCheckedChange={(checked) => emit(checked === true)} disabled={disabled} />
|
|
74
116
|
</div>
|
|
75
117
|
);
|
|
76
118
|
case CaptureFieldType.Date:
|
|
77
|
-
return <Input id={inputId} type="date" value={asString(value)} onChange={(e) =>
|
|
119
|
+
return <Input id={inputId} type="date" value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} />;
|
|
78
120
|
case CaptureFieldType.Datetime:
|
|
79
|
-
return <Input id={inputId} type="datetime-local" value={asString(value)} onChange={(e) =>
|
|
121
|
+
return <Input id={inputId} type="datetime-local" value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} />;
|
|
80
122
|
case CaptureFieldType.Enum:
|
|
81
123
|
return (
|
|
82
|
-
<select id={inputId} className={SELECT_CLASS} value={asString(value)} onChange={(e) =>
|
|
124
|
+
<select id={inputId} className={SELECT_CLASS} value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled}>
|
|
83
125
|
<option value="">— select —</option>
|
|
84
126
|
{(field.enumValues ?? []).map((v) => (
|
|
85
127
|
<option key={v} value={v}>
|
|
@@ -90,9 +132,9 @@ export function SchemaFieldInput(props: SchemaFieldInputProps) {
|
|
|
90
132
|
);
|
|
91
133
|
case CaptureFieldType.Reference:
|
|
92
134
|
return renderReference ? (
|
|
93
|
-
<>{renderReference({ field, value, onChange, disabled, inputId })}</>
|
|
135
|
+
<>{renderReference({ field, value, onChange: emit, disabled, inputId })}</>
|
|
94
136
|
) : (
|
|
95
|
-
<Input id={inputId} value={asString(value)} onChange={(e) =>
|
|
137
|
+
<Input id={inputId} value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} placeholder={field.placeholder ?? 'reference id'} />
|
|
96
138
|
);
|
|
97
139
|
case CaptureFieldType.Object:
|
|
98
140
|
return <ObjectInput {...props} />;
|
|
@@ -103,12 +145,90 @@ export function SchemaFieldInput(props: SchemaFieldInputProps) {
|
|
|
103
145
|
return <MediaFieldInput {...props} />;
|
|
104
146
|
case CaptureFieldType.Audio:
|
|
105
147
|
return <AudioFieldInput {...props} />;
|
|
106
|
-
// string (and any unknown) —
|
|
148
|
+
// string / email / url (and any unknown) — single-line input.
|
|
107
149
|
default:
|
|
108
|
-
return <Input id={inputId} value={asString(value)} onChange={(e) =>
|
|
150
|
+
return <Input id={inputId} type={nativeInputType(field.type)} value={asString(value)} onChange={(e) => emit(e.target.value)} disabled={disabled} placeholder={field.placeholder} />;
|
|
109
151
|
}
|
|
110
152
|
}
|
|
111
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Write-only input for a DECLARED-secret field.
|
|
156
|
+
*
|
|
157
|
+
* `autoComplete="off"` + `data-lpignore` keep password managers and the browser
|
|
158
|
+
* credential store from persisting the value; the reveal toggle is local and
|
|
159
|
+
* transient. The component holds no cache: it renders exactly the value the
|
|
160
|
+
* caller passes and nothing else, so a read path that returns no secret
|
|
161
|
+
* material (the only kind this kit is used with) can never repopulate it.
|
|
162
|
+
*/
|
|
163
|
+
function SecretFieldInput({
|
|
164
|
+
field,
|
|
165
|
+
value,
|
|
166
|
+
onChange,
|
|
167
|
+
disabled,
|
|
168
|
+
inputId,
|
|
169
|
+
}: Readonly<{
|
|
170
|
+
field: CaptureFieldSpec;
|
|
171
|
+
value: unknown;
|
|
172
|
+
onChange: (next: unknown) => void;
|
|
173
|
+
disabled?: boolean;
|
|
174
|
+
inputId: string;
|
|
175
|
+
}>) {
|
|
176
|
+
const [reveal, setReveal] = useState(false);
|
|
177
|
+
const multiline = field.type === CaptureFieldType.Json || field.type === CaptureFieldType.Text;
|
|
178
|
+
|
|
179
|
+
if (multiline && reveal) {
|
|
180
|
+
return (
|
|
181
|
+
<div className="relative">
|
|
182
|
+
<Textarea
|
|
183
|
+
id={inputId}
|
|
184
|
+
value={asString(value)}
|
|
185
|
+
onChange={(e) => onChange(e.target.value)}
|
|
186
|
+
disabled={disabled}
|
|
187
|
+
rows={6}
|
|
188
|
+
spellCheck={false}
|
|
189
|
+
autoComplete="off"
|
|
190
|
+
className="min-h-[120px] pr-9 font-mono"
|
|
191
|
+
placeholder={field.placeholder}
|
|
192
|
+
/>
|
|
193
|
+
<RevealToggle reveal={reveal} onToggle={() => setReveal((v) => !v)} />
|
|
194
|
+
</div>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return (
|
|
199
|
+
<div className="relative">
|
|
200
|
+
<Input
|
|
201
|
+
id={inputId}
|
|
202
|
+
type={reveal ? 'text' : 'password'}
|
|
203
|
+
value={asString(value)}
|
|
204
|
+
onChange={(e) => onChange(e.target.value)}
|
|
205
|
+
disabled={disabled}
|
|
206
|
+
autoComplete="off"
|
|
207
|
+
spellCheck={false}
|
|
208
|
+
data-lpignore="true"
|
|
209
|
+
className="pr-9 font-mono"
|
|
210
|
+
placeholder={field.placeholder}
|
|
211
|
+
/>
|
|
212
|
+
<RevealToggle reveal={reveal} onToggle={() => setReveal((v) => !v)} />
|
|
213
|
+
</div>
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function RevealToggle({ reveal, onToggle }: Readonly<{ reveal: boolean; onToggle: () => void }>) {
|
|
218
|
+
return (
|
|
219
|
+
<Button
|
|
220
|
+
type="button"
|
|
221
|
+
size="sm"
|
|
222
|
+
variant="ghost"
|
|
223
|
+
className="absolute right-0 top-0 h-9 w-9 p-0"
|
|
224
|
+
onClick={onToggle}
|
|
225
|
+
aria-label={reveal ? 'Hide value' : 'Show value'}
|
|
226
|
+
>
|
|
227
|
+
{reveal ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
|
|
228
|
+
</Button>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
112
232
|
const FILE_INPUT_CLASS =
|
|
113
233
|
'block w-full text-body-2 text-foreground file:mr-3 file:rounded-md file:border-0 file:bg-secondary file:px-3 file:py-1.5 file:text-body-2 file:text-secondary-foreground hover:file:bg-secondary/80 disabled:cursor-not-allowed disabled:opacity-50';
|
|
114
234
|
|
|
@@ -227,7 +347,13 @@ function AudioFieldInput({ value, onChange, disabled, path }: SchemaFieldInputPr
|
|
|
227
347
|
) : null}
|
|
228
348
|
</div>
|
|
229
349
|
{error ? <p className="text-body-2 text-destructive">{error}</p> : null}
|
|
230
|
-
{current && !recording ?
|
|
350
|
+
{current && !recording ? (
|
|
351
|
+
<Button asChild variant="outline" size="sm">
|
|
352
|
+
<a id={inputId} href={current} target="_blank" rel="noreferrer">
|
|
353
|
+
Open recorded audio
|
|
354
|
+
</a>
|
|
355
|
+
</Button>
|
|
356
|
+
) : null}
|
|
231
357
|
</div>
|
|
232
358
|
);
|
|
233
359
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// Pure-logic proofs for the ONE values→wire projection and the declared
|
|
2
|
+
// transform. Runs under the host-web vitest runner (this package carries no
|
|
3
|
+
// vitest dep — see tsconfig exclude).
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
import { applyCaptureTransform, CaptureFieldTransform, CaptureFieldType, type CaptureFieldSpec } from './field-spec';
|
|
7
|
+
import { fieldSpecToZod } from './field-spec-to-zod';
|
|
8
|
+
import { captureValuesToStringMap, captureValuesToSubmitPayload } from './submit-values';
|
|
9
|
+
|
|
10
|
+
const fields: CaptureFieldSpec[] = [
|
|
11
|
+
{ key: 'apiKey', label: 'API key', type: CaptureFieldType.String, required: true, isSecret: true },
|
|
12
|
+
{ key: 'baseUrl', label: 'Base URL', type: CaptureFieldType.Url, required: true },
|
|
13
|
+
{ key: 'serviceAccount', label: 'Service account', type: CaptureFieldType.Json, required: false },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
describe('applyCaptureTransform', () => {
|
|
17
|
+
it('applies only the DECLARED transform', () => {
|
|
18
|
+
expect(applyCaptureTransform(' a ', CaptureFieldTransform.Trim)).toBe('a');
|
|
19
|
+
expect(applyCaptureTransform('a', CaptureFieldTransform.Uppercase)).toBe('A');
|
|
20
|
+
expect(applyCaptureTransform('A', CaptureFieldTransform.Lowercase)).toBe('a');
|
|
21
|
+
expect(applyCaptureTransform(' a ', CaptureFieldTransform.None)).toBe(' a ');
|
|
22
|
+
// Absent = no normalization. There is no implicit blanket trim.
|
|
23
|
+
expect(applyCaptureTransform(' a ', undefined)).toBe(' a ');
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('captureValuesToStringMap', () => {
|
|
28
|
+
it('projects ONLY declared keys, as strings', () => {
|
|
29
|
+
expect(
|
|
30
|
+
captureValuesToStringMap(fields, {
|
|
31
|
+
apiKey: 'sk-1',
|
|
32
|
+
baseUrl: 'https://acme.test',
|
|
33
|
+
rogue: 'should not travel',
|
|
34
|
+
}),
|
|
35
|
+
).toEqual({ apiKey: 'sk-1', baseUrl: 'https://acme.test', serviceAccount: '' });
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('captureValuesToSubmitPayload', () => {
|
|
40
|
+
it('parses a json field and leaves the rest untouched', () => {
|
|
41
|
+
expect(
|
|
42
|
+
captureValuesToSubmitPayload(fields, {
|
|
43
|
+
apiKey: 'sk-1',
|
|
44
|
+
baseUrl: 'https://acme.test',
|
|
45
|
+
serviceAccount: '{"a":1}',
|
|
46
|
+
}),
|
|
47
|
+
).toEqual({ apiKey: 'sk-1', baseUrl: 'https://acme.test', serviceAccount: { a: 1 } });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('does not drop an unparseable json value — validation is the gate', () => {
|
|
51
|
+
expect(captureValuesToSubmitPayload(fields, { serviceAccount: '{' }).serviceAccount).toBe('{');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('json field validation', () => {
|
|
56
|
+
const schema = fieldSpecToZod(fields);
|
|
57
|
+
|
|
58
|
+
it('rejects an unparseable json blob', () => {
|
|
59
|
+
expect(schema.safeParse({ apiKey: 'k', baseUrl: 'u', serviceAccount: '{' }).success).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('accepts a parseable json blob and an omitted optional one', () => {
|
|
63
|
+
expect(schema.safeParse({ apiKey: 'k', baseUrl: 'u', serviceAccount: '{"a":1}' }).success).toBe(true);
|
|
64
|
+
expect(schema.safeParse({ apiKey: 'k', baseUrl: 'u' }).success).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('requires a non-empty url/email field when required', () => {
|
|
68
|
+
expect(schema.safeParse({ apiKey: 'k', baseUrl: '' }).success).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
// Capture values → submit payload
|
|
3
|
+
//
|
|
4
|
+
// The ONE projection from the form's in-memory `CaptureValues` to what goes on
|
|
5
|
+
// the wire. Two faces, because two wire contracts exist and neither should grow
|
|
6
|
+
// its own inline projection:
|
|
7
|
+
//
|
|
8
|
+
// • `captureValuesToStringMap` — every field as a STRING (the shape a
|
|
9
|
+
// credential submit takes: `fields: Record<string, string>`).
|
|
10
|
+
// • `captureValuesToSubmitPayload` — same, except a `json` field is PARSED
|
|
11
|
+
// into its structured value (the shape the connection credential write
|
|
12
|
+
// takes: `credentials: Record<string, unknown>`).
|
|
13
|
+
//
|
|
14
|
+
// Both are field-driven: only DECLARED keys are projected, so a stray key in
|
|
15
|
+
// the values record can never reach the wire. Neither performs an undeclared
|
|
16
|
+
// normalization — trimming/casing is `CaptureFieldTransform`, applied once at
|
|
17
|
+
// the input boundary. A blanket trim here would silently override a field that
|
|
18
|
+
// declared `transform: none`.
|
|
19
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
20
|
+
import { CaptureFieldType, toFieldList, type CaptureFieldSpec, type CaptureSchema, type CaptureSection, type CaptureValues } from './field-spec';
|
|
21
|
+
import { asString } from './value-format';
|
|
22
|
+
|
|
23
|
+
type Schema = CaptureSchema | readonly CaptureFieldSpec[] | readonly CaptureSection[];
|
|
24
|
+
|
|
25
|
+
/** Project the declared fields to a flat `string` map (fields-only wire). */
|
|
26
|
+
export function captureValuesToStringMap(
|
|
27
|
+
schema: Schema,
|
|
28
|
+
values: CaptureValues,
|
|
29
|
+
): Record<string, string> {
|
|
30
|
+
const payload: Record<string, string> = {};
|
|
31
|
+
for (const field of toFieldList(schema)) {
|
|
32
|
+
payload[field.key] = asString(values[field.key]);
|
|
33
|
+
}
|
|
34
|
+
return payload;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Project the declared fields, parsing `json` fields into structured values.
|
|
39
|
+
*
|
|
40
|
+
* A `json` field that does not parse is left as its raw string — validation is
|
|
41
|
+
* `useSchemaValidation`'s job and it must run first; this projection does not
|
|
42
|
+
* silently drop a value it cannot parse.
|
|
43
|
+
*/
|
|
44
|
+
export function captureValuesToSubmitPayload(
|
|
45
|
+
schema: Schema,
|
|
46
|
+
values: CaptureValues,
|
|
47
|
+
): CaptureValues {
|
|
48
|
+
const payload: CaptureValues = {};
|
|
49
|
+
for (const field of toFieldList(schema)) {
|
|
50
|
+
const raw = values[field.key];
|
|
51
|
+
if (field.type !== CaptureFieldType.Json) {
|
|
52
|
+
payload[field.key] = raw;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
const text = asString(raw);
|
|
56
|
+
try {
|
|
57
|
+
payload[field.key] = JSON.parse(text);
|
|
58
|
+
} catch {
|
|
59
|
+
payload[field.key] = text;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return payload;
|
|
63
|
+
}
|
|
@@ -81,7 +81,10 @@ export function usePrefill<T extends CaptureValues = CaptureValues>(
|
|
|
81
81
|
|
|
82
82
|
const setValues = useCallback((updater: Partial<T> | ((prev: T) => T)) => {
|
|
83
83
|
setValuesState((prev) => {
|
|
84
|
-
const next =
|
|
84
|
+
const next =
|
|
85
|
+
typeof updater === 'function'
|
|
86
|
+
? updater(prev)
|
|
87
|
+
: { ...prev, ...updater };
|
|
85
88
|
const changed = new Set<string>();
|
|
86
89
|
for (const k of Object.keys(next)) {
|
|
87
90
|
if (next[k] !== prev[k]) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
9
|
import { useCallback, useMemo, useState } from 'react';
|
|
10
10
|
|
|
11
|
-
import { FormStepStatus } from '../primitives/form-stepper';
|
|
11
|
+
import { FormStepStatus } from '../primitives/form-stepper.types';
|
|
12
12
|
|
|
13
13
|
export interface WizardStepDef {
|
|
14
14
|
readonly key: string;
|
|
@@ -68,7 +68,7 @@ export function useWizard(options: UseWizardOptions): WizardApi {
|
|
|
68
68
|
|
|
69
69
|
const isControlled = step !== undefined;
|
|
70
70
|
const [internal, setInternal] = useState(() => clamp(initialStep));
|
|
71
|
-
const activeIndex = clamp(isControlled ?
|
|
71
|
+
const activeIndex = clamp(isControlled ? step : internal);
|
|
72
72
|
|
|
73
73
|
const gate = useCallback((i: number) => (canAdvance ? canAdvance(i) : true), [canAdvance]);
|
|
74
74
|
|
|
@@ -10,7 +10,8 @@ import { Children, isValidElement, type ReactElement, type ReactNode } from 'rea
|
|
|
10
10
|
|
|
11
11
|
import { cn } from '../cn';
|
|
12
12
|
import { Button } from '../primitives/button';
|
|
13
|
-
import { FormStepper
|
|
13
|
+
import { FormStepper } from '../primitives/form-stepper';
|
|
14
|
+
import type { FormStep } from '../primitives/form-stepper.types';
|
|
14
15
|
|
|
15
16
|
import type { WizardApi } from './use-wizard';
|
|
16
17
|
|
package/src/ui/index.ts
CHANGED
|
@@ -24,7 +24,9 @@ export { useIsMobile } from './hooks/use-is-mobile';
|
|
|
24
24
|
|
|
25
25
|
// ── shadcn primitives ──
|
|
26
26
|
export * from './primitives/button';
|
|
27
|
+
export * from './primitives/button-variants';
|
|
27
28
|
export * from './primitives/badge';
|
|
29
|
+
export * from './primitives/badge-variants';
|
|
28
30
|
export * from './primitives/input';
|
|
29
31
|
export * from './primitives/label';
|
|
30
32
|
export * from './primitives/select';
|
|
@@ -49,11 +51,16 @@ export * from './primitives/overflow-tabs';
|
|
|
49
51
|
export * from './primitives/tag-multi-select';
|
|
50
52
|
export * from './primitives/sheet';
|
|
51
53
|
export * from './primitives/form-stepper';
|
|
54
|
+
export * from './primitives/form-stepper.types';
|
|
52
55
|
export * from './primitives/async-combobox';
|
|
53
56
|
export {
|
|
54
57
|
PreviewDeviceFrame,
|
|
55
58
|
type PreviewDevice,
|
|
56
59
|
} from './primitives/preview-device-frame';
|
|
60
|
+
export {
|
|
61
|
+
UrlPreviewChrome,
|
|
62
|
+
type UrlPreviewChromeProps,
|
|
63
|
+
} from './primitives/url-preview-chrome';
|
|
57
64
|
|
|
58
65
|
// ── chart primitives (Wave 9.2 — pure SVG, no external chart lib) ──
|
|
59
66
|
export * from './charts';
|
|
@@ -61,11 +68,13 @@ export * from './charts';
|
|
|
61
68
|
// ── runtime branding applier (Wave 8.4) ──
|
|
62
69
|
export {
|
|
63
70
|
AppBrandingProvider,
|
|
64
|
-
useAppBranding,
|
|
65
71
|
APP_PRIMARY_COLOR_VAR,
|
|
66
72
|
type AppBrandingProviderProps,
|
|
67
|
-
type AppBrandingContextValue,
|
|
68
73
|
} from './branding/app-branding-provider';
|
|
74
|
+
export {
|
|
75
|
+
useAppBranding,
|
|
76
|
+
type AppBrandingContextValue,
|
|
77
|
+
} from './branding/app-branding-context';
|
|
69
78
|
|
|
70
79
|
// ── Xema chrome ──
|
|
71
80
|
export { default as ErrorCard, type ErrorMessageFormatter } from './chrome/ErrorCard';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
-
import { buttonVariants } from './button';
|
|
4
|
+
import { buttonVariants } from './button-variants';
|
|
5
5
|
import { cn } from '../cn';
|
|
6
6
|
|
|
7
7
|
const AlertDialog = AlertDialogPrimitive.Root;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
export const badgeVariants = cva(
|
|
4
|
+
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-body-1 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
default:
|
|
9
|
+
'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
|
|
10
|
+
secondary:
|
|
11
|
+
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
12
|
+
destructive:
|
|
13
|
+
'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
|
|
14
|
+
outline: 'border-rule bg-paper text-ink',
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: 'default',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
@@ -1,24 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { VariantProps } from "class-variance-authority";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
4
|
import { cn } from '../cn';
|
|
5
|
-
|
|
6
|
-
const badgeVariants = cva(
|
|
7
|
-
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-body-1 font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
8
|
-
{
|
|
9
|
-
variants: {
|
|
10
|
-
variant: {
|
|
11
|
-
default: "border-transparent bg-primary text-primary-foreground hover:bg-primary/80",
|
|
12
|
-
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
13
|
-
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
14
|
-
outline: "border-rule bg-paper text-ink",
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
defaultVariants: {
|
|
18
|
-
variant: "default",
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
);
|
|
5
|
+
import { badgeVariants } from './badge-variants';
|
|
22
6
|
|
|
23
7
|
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof badgeVariants> {}
|
|
24
8
|
|
|
@@ -29,4 +13,4 @@ const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
|
|
29
13
|
);
|
|
30
14
|
Badge.displayName = "Badge";
|
|
31
15
|
|
|
32
|
-
export { Badge
|
|
16
|
+
export { Badge };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
|
|
3
|
+
export const buttonVariants = cva(
|
|
4
|
+
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-body-1 font-medium ring-offset-background transition-[background-color,color,border-color,box-shadow] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
|
5
|
+
{
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
default:
|
|
9
|
+
'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
10
|
+
destructive:
|
|
11
|
+
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
|
12
|
+
outline:
|
|
13
|
+
'border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground',
|
|
14
|
+
secondary:
|
|
15
|
+
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
16
|
+
ghost: 'text-ink-2 hover:bg-paper-elev hover:text-ink',
|
|
17
|
+
link: 'text-primary underline-offset-4 hover:underline',
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
default: 'h-10 px-4 py-2',
|
|
21
|
+
sm: 'h-9 rounded-md px-3',
|
|
22
|
+
lg: 'h-11 rounded-md px-8',
|
|
23
|
+
icon: 'h-10 w-10',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: 'default',
|
|
28
|
+
size: 'default',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
);
|
|
@@ -1,34 +1,9 @@
|
|
|
1
1
|
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
-
import {
|
|
2
|
+
import type { VariantProps } from "class-variance-authority";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
import { cn } from '../cn';
|
|
6
|
-
|
|
7
|
-
const buttonVariants = cva(
|
|
8
|
-
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-body-1 font-medium ring-offset-background transition-[background-color,color,border-color,box-shadow] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
9
|
-
{
|
|
10
|
-
variants: {
|
|
11
|
-
variant: {
|
|
12
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
13
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
14
|
-
outline: "border border-input bg-background text-foreground hover:bg-accent hover:text-accent-foreground",
|
|
15
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
16
|
-
ghost: "text-ink-2 hover:bg-paper-elev hover:text-ink",
|
|
17
|
-
link: "text-primary underline-offset-4 hover:underline",
|
|
18
|
-
},
|
|
19
|
-
size: {
|
|
20
|
-
default: "h-10 px-4 py-2",
|
|
21
|
-
sm: "h-9 rounded-md px-3",
|
|
22
|
-
lg: "h-11 rounded-md px-8",
|
|
23
|
-
icon: "h-10 w-10",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
defaultVariants: {
|
|
27
|
-
variant: "default",
|
|
28
|
-
size: "default",
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
);
|
|
6
|
+
import { buttonVariants } from './button-variants';
|
|
32
7
|
|
|
33
8
|
export interface ButtonProps
|
|
34
9
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
@@ -44,4 +19,4 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
|
44
19
|
);
|
|
45
20
|
Button.displayName = "Button";
|
|
46
21
|
|
|
47
|
-
export { Button
|
|
22
|
+
export { Button };
|
|
@@ -1,22 +1,7 @@
|
|
|
1
1
|
import { Check } from 'lucide-react';
|
|
2
2
|
|
|
3
|
-
import type { ReactNode } from 'react';
|
|
4
|
-
|
|
5
3
|
import { cn } from '../cn';
|
|
6
|
-
|
|
7
|
-
export enum FormStepStatus {
|
|
8
|
-
PENDING = 'pending',
|
|
9
|
-
ACTIVE = 'active',
|
|
10
|
-
DONE = 'done',
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface FormStep {
|
|
14
|
-
readonly key: string;
|
|
15
|
-
readonly label: string;
|
|
16
|
-
readonly hint?: string;
|
|
17
|
-
readonly status: FormStepStatus;
|
|
18
|
-
readonly children: ReactNode;
|
|
19
|
-
}
|
|
4
|
+
import { FormStepStatus, type FormStep } from './form-stepper.types';
|
|
20
5
|
|
|
21
6
|
interface FormStepperProps {
|
|
22
7
|
readonly steps: readonly FormStep[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export enum FormStepStatus {
|
|
4
|
+
PENDING = 'pending',
|
|
5
|
+
ACTIVE = 'active',
|
|
6
|
+
DONE = 'done',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface FormStep {
|
|
10
|
+
readonly key: string;
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly hint?: string;
|
|
13
|
+
readonly status: FormStepStatus;
|
|
14
|
+
readonly children: ReactNode;
|
|
15
|
+
}
|