@tai42/studio-sdk 0.2.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/LICENSE +202 -0
- package/NOTICE +15 -0
- package/README.md +318 -0
- package/SECURITY.md +51 -0
- package/dist/components/badge.d.ts +13 -0
- package/dist/components/badge.d.ts.map +1 -0
- package/dist/components/badge.js +14 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/checkbox.d.ts +24 -0
- package/dist/components/checkbox.d.ts.map +1 -0
- package/dist/components/checkbox.js +31 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/code-block.d.ts +7 -0
- package/dist/components/code-block.d.ts.map +1 -0
- package/dist/components/code-block.js +23 -0
- package/dist/components/code-block.js.map +1 -0
- package/dist/components/completion-input.d.ts +31 -0
- package/dist/components/completion-input.d.ts.map +1 -0
- package/dist/components/completion-input.js +61 -0
- package/dist/components/completion-input.js.map +1 -0
- package/dist/components/components.css +2212 -0
- package/dist/components/confirm-dialog.d.ts +40 -0
- package/dist/components/confirm-dialog.d.ts.map +1 -0
- package/dist/components/confirm-dialog.js +11 -0
- package/dist/components/confirm-dialog.js.map +1 -0
- package/dist/components/control-styles.d.ts +12 -0
- package/dist/components/control-styles.d.ts.map +1 -0
- package/dist/components/control-styles.js +14 -0
- package/dist/components/control-styles.js.map +1 -0
- package/dist/components/copy-field.d.ts +8 -0
- package/dist/components/copy-field.d.ts.map +1 -0
- package/dist/components/copy-field.js +106 -0
- package/dist/components/copy-field.js.map +1 -0
- package/dist/components/dialog.d.ts +21 -0
- package/dist/components/dialog.d.ts.map +1 -0
- package/dist/components/dialog.js +25 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/drawer.d.ts +22 -0
- package/dist/components/drawer.d.ts.map +1 -0
- package/dist/components/drawer.js +32 -0
- package/dist/components/drawer.js.map +1 -0
- package/dist/components/error-boundary.d.ts +33 -0
- package/dist/components/error-boundary.d.ts.map +1 -0
- package/dist/components/error-boundary.js +36 -0
- package/dist/components/error-boundary.js.map +1 -0
- package/dist/components/extension-combo-builder.d.ts +70 -0
- package/dist/components/extension-combo-builder.d.ts.map +1 -0
- package/dist/components/extension-combo-builder.js +154 -0
- package/dist/components/extension-combo-builder.js.map +1 -0
- package/dist/components/extension-grouping.d.ts +65 -0
- package/dist/components/extension-grouping.d.ts.map +1 -0
- package/dist/components/extension-grouping.js +78 -0
- package/dist/components/extension-grouping.js.map +1 -0
- package/dist/components/extension-picker.d.ts +35 -0
- package/dist/components/extension-picker.d.ts.map +1 -0
- package/dist/components/extension-picker.js +31 -0
- package/dist/components/extension-picker.js.map +1 -0
- package/dist/components/external-link.d.ts +19 -0
- package/dist/components/external-link.d.ts.map +1 -0
- package/dist/components/external-link.js +12 -0
- package/dist/components/external-link.js.map +1 -0
- package/dist/components/field.d.ts +64 -0
- package/dist/components/field.d.ts.map +1 -0
- package/dist/components/field.js +56 -0
- package/dist/components/field.js.map +1 -0
- package/dist/components/fleet-report.d.ts +39 -0
- package/dist/components/fleet-report.d.ts.map +1 -0
- package/dist/components/fleet-report.js +50 -0
- package/dist/components/fleet-report.js.map +1 -0
- package/dist/components/fonts.css +22 -0
- package/dist/components/icons.d.ts +142 -0
- package/dist/components/icons.d.ts.map +1 -0
- package/dist/components/icons.js +139 -0
- package/dist/components/icons.js.map +1 -0
- package/dist/components/inputs.d.ts +52 -0
- package/dist/components/inputs.d.ts.map +1 -0
- package/dist/components/inputs.js +35 -0
- package/dist/components/inputs.js.map +1 -0
- package/dist/components/json-diff.d.ts +40 -0
- package/dist/components/json-diff.d.ts.map +1 -0
- package/dist/components/json-diff.js +119 -0
- package/dist/components/json-diff.js.map +1 -0
- package/dist/components/json-tree.d.ts +8 -0
- package/dist/components/json-tree.d.ts.map +1 -0
- package/dist/components/json-tree.js +70 -0
- package/dist/components/json-tree.js.map +1 -0
- package/dist/components/modal-focus.d.ts +15 -0
- package/dist/components/modal-focus.d.ts.map +1 -0
- package/dist/components/modal-focus.js +136 -0
- package/dist/components/modal-focus.js.map +1 -0
- package/dist/components/page-header.d.ts +56 -0
- package/dist/components/page-header.d.ts.map +1 -0
- package/dist/components/page-header.js +24 -0
- package/dist/components/page-header.js.map +1 -0
- package/dist/components/primitives.d.ts +186 -0
- package/dist/components/primitives.d.ts.map +1 -0
- package/dist/components/primitives.js +204 -0
- package/dist/components/primitives.js.map +1 -0
- package/dist/components/progress-bar.d.ts +29 -0
- package/dist/components/progress-bar.d.ts.map +1 -0
- package/dist/components/progress-bar.js +48 -0
- package/dist/components/progress-bar.js.map +1 -0
- package/dist/components/radio-group.d.ts +37 -0
- package/dist/components/radio-group.d.ts.map +1 -0
- package/dist/components/radio-group.js +56 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/reveal-input.d.ts +13 -0
- package/dist/components/reveal-input.d.ts.map +1 -0
- package/dist/components/reveal-input.js +31 -0
- package/dist/components/reveal-input.js.map +1 -0
- package/dist/components/scroll-region.d.ts +85 -0
- package/dist/components/scroll-region.d.ts.map +1 -0
- package/dist/components/scroll-region.js +574 -0
- package/dist/components/scroll-region.js.map +1 -0
- package/dist/components/select.d.ts +53 -0
- package/dist/components/select.d.ts.map +1 -0
- package/dist/components/select.js +33 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/table.d.ts +59 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.js +20 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.d.ts +15 -0
- package/dist/components/tabs.d.ts.map +1 -0
- package/dist/components/tabs.js +13 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/tags.d.ts +46 -0
- package/dist/components/tags.d.ts.map +1 -0
- package/dist/components/tags.js +68 -0
- package/dist/components/tags.js.map +1 -0
- package/dist/components/tokens.css +392 -0
- package/dist/components/tokens.d.ts +15 -0
- package/dist/components/tokens.d.ts.map +1 -0
- package/dist/components/tokens.js +101 -0
- package/dist/components/tokens.js.map +1 -0
- package/dist/components/tool-picker.d.ts +24 -0
- package/dist/components/tool-picker.d.ts.map +1 -0
- package/dist/components/tool-picker.js +97 -0
- package/dist/components/tool-picker.js.map +1 -0
- package/dist/components/tooltip.d.ts +17 -0
- package/dist/components/tooltip.d.ts.map +1 -0
- package/dist/components/tooltip.js +18 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/components/version-history-panel.d.ts +71 -0
- package/dist/components/version-history-panel.d.ts.map +1 -0
- package/dist/components/version-history-panel.js +148 -0
- package/dist/components/version-history-panel.js.map +1 -0
- package/dist/download.d.ts +7 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +18 -0
- package/dist/download.js.map +1 -0
- package/dist/element-slot.d.ts +4 -0
- package/dist/element-slot.d.ts.map +1 -0
- package/dist/element-slot.js +20 -0
- package/dist/element-slot.js.map +1 -0
- package/dist/elicitation/ElicitationForm.d.ts +34 -0
- package/dist/elicitation/ElicitationForm.d.ts.map +1 -0
- package/dist/elicitation/ElicitationForm.js +24 -0
- package/dist/elicitation/ElicitationForm.js.map +1 -0
- package/dist/errors.d.ts +9 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +15 -0
- package/dist/errors.js.map +1 -0
- package/dist/extension-combos.d.ts +13 -0
- package/dist/extension-combos.d.ts.map +1 -0
- package/dist/extension-combos.js +9 -0
- package/dist/extension-combos.js.map +1 -0
- package/dist/hooks/useApi.d.ts +1222 -0
- package/dist/hooks/useApi.d.ts.map +1 -0
- package/dist/hooks/useApi.js +22 -0
- package/dist/hooks/useApi.js.map +1 -0
- package/dist/hooks/useAuth.d.ts +13 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useAuth.js +53 -0
- package/dist/hooks/useAuth.js.map +1 -0
- package/dist/hooks/useBreakpoint.d.ts +10 -0
- package/dist/hooks/useBreakpoint.d.ts.map +1 -0
- package/dist/hooks/useBreakpoint.js +66 -0
- package/dist/hooks/useBreakpoint.js.map +1 -0
- package/dist/hooks/useCapabilities.d.ts +88 -0
- package/dist/hooks/useCapabilities.d.ts.map +1 -0
- package/dist/hooks/useCapabilities.js +203 -0
- package/dist/hooks/useCapabilities.js.map +1 -0
- package/dist/hooks/useSse.d.ts +13 -0
- package/dist/hooks/useSse.d.ts.map +1 -0
- package/dist/hooks/useSse.js +298 -0
- package/dist/hooks/useSse.js.map +1 -0
- package/dist/hooks/useTheme.d.ts +20 -0
- package/dist/hooks/useTheme.d.ts.map +1 -0
- package/dist/hooks/useTheme.js +97 -0
- package/dist/hooks/useTheme.js.map +1 -0
- package/dist/hooks/useUnauthorized.d.ts +3 -0
- package/dist/hooks/useUnauthorized.d.ts.map +1 -0
- package/dist/hooks/useUnauthorized.js +18 -0
- package/dist/hooks/useUnauthorized.js.map +1 -0
- package/dist/host.d.ts +11 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +10 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/context.d.ts +25 -0
- package/dist/navigation/context.d.ts.map +1 -0
- package/dist/navigation/context.js +45 -0
- package/dist/navigation/context.js.map +1 -0
- package/dist/navigation/index.d.ts +4 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +2 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/types.d.ts +97 -0
- package/dist/navigation/types.d.ts.map +1 -0
- package/dist/navigation/types.js +16 -0
- package/dist/navigation/types.js.map +1 -0
- package/dist/plugin/host-state.d.ts +45 -0
- package/dist/plugin/host-state.d.ts.map +1 -0
- package/dist/plugin/host-state.js +62 -0
- package/dist/plugin/host-state.js.map +1 -0
- package/dist/plugin/registry.d.ts +35 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/registry.js +129 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/types.d.ts +165 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +2 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/plugin/version.d.ts +34 -0
- package/dist/plugin/version.d.ts.map +1 -0
- package/dist/plugin/version.js +37 -0
- package/dist/plugin/version.js.map +1 -0
- package/dist/query-keys.d.ts +31 -0
- package/dist/query-keys.d.ts.map +1 -0
- package/dist/query-keys.js +31 -0
- package/dist/query-keys.js.map +1 -0
- package/dist/schema-editor/SchemaEditor.d.ts +43 -0
- package/dist/schema-editor/SchemaEditor.d.ts.map +1 -0
- package/dist/schema-editor/SchemaEditor.js +106 -0
- package/dist/schema-editor/SchemaEditor.js.map +1 -0
- package/dist/schema-editor/index.d.ts +10 -0
- package/dist/schema-editor/index.d.ts.map +1 -0
- package/dist/schema-editor/index.js +8 -0
- package/dist/schema-editor/index.js.map +1 -0
- package/dist/schema-editor/lint.d.ts +37 -0
- package/dist/schema-editor/lint.d.ts.map +1 -0
- package/dist/schema-editor/lint.js +49 -0
- package/dist/schema-editor/lint.js.map +1 -0
- package/dist/schema-form/SchemaForm.d.ts +70 -0
- package/dist/schema-form/SchemaForm.d.ts.map +1 -0
- package/dist/schema-form/SchemaForm.js +13 -0
- package/dist/schema-form/SchemaForm.js.map +1 -0
- package/dist/schema-form/array-field.d.ts +20 -0
- package/dist/schema-form/array-field.d.ts.map +1 -0
- package/dist/schema-form/array-field.js +39 -0
- package/dist/schema-form/array-field.js.map +1 -0
- package/dist/schema-form/classify.d.ts +87 -0
- package/dist/schema-form/classify.d.ts.map +1 -0
- package/dist/schema-form/classify.js +199 -0
- package/dist/schema-form/classify.js.map +1 -0
- package/dist/schema-form/context.d.ts +4 -0
- package/dist/schema-form/context.d.ts.map +1 -0
- package/dist/schema-form/context.js +14 -0
- package/dist/schema-form/context.js.map +1 -0
- package/dist/schema-form/default-value.d.ts +8 -0
- package/dist/schema-form/default-value.d.ts.map +1 -0
- package/dist/schema-form/default-value.js +64 -0
- package/dist/schema-form/default-value.js.map +1 -0
- package/dist/schema-form/enum-field.d.ts +19 -0
- package/dist/schema-form/enum-field.d.ts.map +1 -0
- package/dist/schema-form/enum-field.js +26 -0
- package/dist/schema-form/enum-field.js.map +1 -0
- package/dist/schema-form/field-group.d.ts +9 -0
- package/dist/schema-form/field-group.d.ts.map +1 -0
- package/dist/schema-form/field-group.js +32 -0
- package/dist/schema-form/field-group.js.map +1 -0
- package/dist/schema-form/field-node.d.ts +24 -0
- package/dist/schema-form/field-node.d.ts.map +1 -0
- package/dist/schema-form/field-node.js +51 -0
- package/dist/schema-form/field-node.js.map +1 -0
- package/dist/schema-form/index.d.ts +13 -0
- package/dist/schema-form/index.d.ts.map +1 -0
- package/dist/schema-form/index.js +11 -0
- package/dist/schema-form/index.js.map +1 -0
- package/dist/schema-form/media-field.d.ts +24 -0
- package/dist/schema-form/media-field.d.ts.map +1 -0
- package/dist/schema-form/media-field.js +169 -0
- package/dist/schema-form/media-field.js.map +1 -0
- package/dist/schema-form/media.d.ts +40 -0
- package/dist/schema-form/media.d.ts.map +1 -0
- package/dist/schema-form/media.js +65 -0
- package/dist/schema-form/media.js.map +1 -0
- package/dist/schema-form/object-fields.d.ts +20 -0
- package/dist/schema-form/object-fields.d.ts.map +1 -0
- package/dist/schema-form/object-fields.js +24 -0
- package/dist/schema-form/object-fields.js.map +1 -0
- package/dist/schema-form/resolve.d.ts +41 -0
- package/dist/schema-form/resolve.d.ts.map +1 -0
- package/dist/schema-form/resolve.js +102 -0
- package/dist/schema-form/resolve.js.map +1 -0
- package/dist/schema-form/string-field.d.ts +20 -0
- package/dist/schema-form/string-field.d.ts.map +1 -0
- package/dist/schema-form/string-field.js +68 -0
- package/dist/schema-form/string-field.js.map +1 -0
- package/dist/schema-form/styles.d.ts +18 -0
- package/dist/schema-form/styles.d.ts.map +1 -0
- package/dist/schema-form/styles.js +18 -0
- package/dist/schema-form/styles.js.map +1 -0
- package/dist/schema-form/types.d.ts +67 -0
- package/dist/schema-form/types.d.ts.map +1 -0
- package/dist/schema-form/types.js +10 -0
- package/dist/schema-form/types.js.map +1 -0
- package/dist/schema-form/union-field.d.ts +24 -0
- package/dist/schema-form/union-field.d.ts.map +1 -0
- package/dist/schema-form/union-field.js +55 -0
- package/dist/schema-form/union-field.js.map +1 -0
- package/dist/schema-form/union.d.ts +4 -0
- package/dist/schema-form/union.d.ts.map +1 -0
- package/dist/schema-form/union.js +68 -0
- package/dist/schema-form/union.js.map +1 -0
- package/dist/schema-form/unsupported-notice.d.ts +18 -0
- package/dist/schema-form/unsupported-notice.d.ts.map +1 -0
- package/dist/schema-form/unsupported-notice.js +8 -0
- package/dist/schema-form/unsupported-notice.js.map +1 -0
- package/dist/schema-form/validate.d.ts +18 -0
- package/dist/schema-form/validate.d.ts.map +1 -0
- package/dist/schema-form/validate.js +162 -0
- package/dist/schema-form/validate.js.map +1 -0
- package/dist/structured-output/StructuredOutput.d.ts +27 -0
- package/dist/structured-output/StructuredOutput.d.ts.map +1 -0
- package/dist/structured-output/StructuredOutput.js +41 -0
- package/dist/structured-output/StructuredOutput.js.map +1 -0
- package/dist/testing.d.ts +80 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +207 -0
- package/dist/testing.js.map +1 -0
- package/package.json +101 -0
- package/src/components/badge.tsx +31 -0
- package/src/components/checkbox.tsx +93 -0
- package/src/components/code-block.tsx +37 -0
- package/src/components/completion-input.tsx +137 -0
- package/src/components/components.css +2212 -0
- package/src/components/confirm-dialog.tsx +77 -0
- package/src/components/control-styles.ts +14 -0
- package/src/components/copy-field.tsx +178 -0
- package/src/components/dialog.tsx +76 -0
- package/src/components/drawer.tsx +83 -0
- package/src/components/error-boundary.tsx +56 -0
- package/src/components/extension-combo-builder.tsx +305 -0
- package/src/components/extension-grouping.ts +116 -0
- package/src/components/extension-picker.tsx +97 -0
- package/src/components/external-link.tsx +40 -0
- package/src/components/field.tsx +169 -0
- package/src/components/fleet-report.tsx +136 -0
- package/src/components/fonts.css +22 -0
- package/src/components/icons.tsx +504 -0
- package/src/components/inputs.tsx +125 -0
- package/src/components/json-diff.tsx +192 -0
- package/src/components/json-tree.tsx +129 -0
- package/src/components/modal-focus.ts +150 -0
- package/src/components/page-header.tsx +107 -0
- package/src/components/primitives.tsx +489 -0
- package/src/components/progress-bar.tsx +100 -0
- package/src/components/radio-group.tsx +160 -0
- package/src/components/reveal-input.tsx +87 -0
- package/src/components/scroll-region.tsx +703 -0
- package/src/components/select.tsx +149 -0
- package/src/components/table.tsx +94 -0
- package/src/components/tabs.tsx +51 -0
- package/src/components/tags.tsx +137 -0
- package/src/components/tokens.css +392 -0
- package/src/components/tokens.ts +102 -0
- package/src/components/tool-picker.tsx +175 -0
- package/src/components/tooltip.tsx +46 -0
- package/src/components/version-history-panel.tsx +407 -0
- package/src/css.d.ts +2 -0
- package/src/download.ts +17 -0
- package/src/element-slot.ts +22 -0
- package/src/elicitation/ElicitationForm.tsx +87 -0
- package/src/errors.ts +12 -0
- package/src/extension-combos.ts +18 -0
- package/src/hooks/useApi.ts +27 -0
- package/src/hooks/useAuth.ts +67 -0
- package/src/hooks/useBreakpoint.ts +78 -0
- package/src/hooks/useCapabilities.ts +242 -0
- package/src/hooks/useSse.ts +314 -0
- package/src/hooks/useTheme.ts +133 -0
- package/src/hooks/useUnauthorized.ts +20 -0
- package/src/host.ts +15 -0
- package/src/index.ts +267 -0
- package/src/navigation/context.tsx +90 -0
- package/src/navigation/index.ts +9 -0
- package/src/navigation/types.ts +90 -0
- package/src/plugin/host-state.ts +93 -0
- package/src/plugin/registry.ts +174 -0
- package/src/plugin/types.ts +178 -0
- package/src/plugin/version.ts +44 -0
- package/src/query-keys.ts +34 -0
- package/src/schema-editor/SchemaEditor.tsx +186 -0
- package/src/schema-editor/index.ts +9 -0
- package/src/schema-editor/lint.ts +70 -0
- package/src/schema-form/SchemaForm.tsx +107 -0
- package/src/schema-form/array-field.tsx +110 -0
- package/src/schema-form/classify.ts +302 -0
- package/src/schema-form/context.ts +17 -0
- package/src/schema-form/default-value.ts +65 -0
- package/src/schema-form/enum-field.tsx +65 -0
- package/src/schema-form/field-group.tsx +71 -0
- package/src/schema-form/field-node.tsx +161 -0
- package/src/schema-form/index.ts +12 -0
- package/src/schema-form/media-field.tsx +281 -0
- package/src/schema-form/media.ts +69 -0
- package/src/schema-form/object-fields.tsx +74 -0
- package/src/schema-form/resolve.ts +114 -0
- package/src/schema-form/string-field.tsx +161 -0
- package/src/schema-form/styles.ts +20 -0
- package/src/schema-form/types.ts +71 -0
- package/src/schema-form/union-field.tsx +122 -0
- package/src/schema-form/union.ts +78 -0
- package/src/schema-form/unsupported-notice.tsx +39 -0
- package/src/schema-form/validate.ts +183 -0
- package/src/structured-output/StructuredOutput.tsx +81 -0
- package/src/testing.ts +235 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ConfirmDialog` — a modal that asks the operator to confirm an action and then
|
|
3
|
+
* runs it. It owns the scaffolding every confirm shares: a Cancel button, the
|
|
4
|
+
* confirm button (showing a pending Spinner while the action runs and disabled
|
|
5
|
+
* meanwhile), and a loud `ErrorState` when the action fails. The caller supplies
|
|
6
|
+
* the prompt as `children` and drives the action through `onConfirm` /
|
|
7
|
+
* `isPending` / `error`.
|
|
8
|
+
*
|
|
9
|
+
* Mount it only while the confirmation is active; any close gesture — Cancel,
|
|
10
|
+
* Escape, the overlay — calls `onClose`. The confirm button is destructive
|
|
11
|
+
* (`danger`) by default; pass `confirmVariant` for a non-destructive confirm.
|
|
12
|
+
*
|
|
13
|
+
* The footer is the design system's `tai-dialog-actions` row, so every confirm
|
|
14
|
+
* across Studio lands its buttons in the same place.
|
|
15
|
+
*/
|
|
16
|
+
import type { ReactNode } from 'react';
|
|
17
|
+
export interface ConfirmDialogProps {
|
|
18
|
+
readonly title: string;
|
|
19
|
+
/** The confirm button's resting label (e.g. `Delete scope`). */
|
|
20
|
+
readonly confirmLabel: string;
|
|
21
|
+
/** The Spinner's accessible label while the action runs (e.g. `Deleting`). */
|
|
22
|
+
readonly pendingLabel: string;
|
|
23
|
+
readonly onConfirm: () => void;
|
|
24
|
+
readonly onClose: () => void;
|
|
25
|
+
readonly isPending: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The failed action's error, rendered loudly; omit/`null` while there is none.
|
|
28
|
+
*
|
|
29
|
+
* A thrown `Error` or the message on its own — `Field`'s `error` is a plain
|
|
30
|
+
* string, and the two props sit side by side on a form, so this one accepts
|
|
31
|
+
* that spelling too rather than making one surface's `error` unassignable to
|
|
32
|
+
* the other's.
|
|
33
|
+
*/
|
|
34
|
+
readonly error?: Error | string | null;
|
|
35
|
+
readonly confirmVariant?: 'primary' | 'danger';
|
|
36
|
+
/** The prompt body — what the operator is confirming. */
|
|
37
|
+
readonly children: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
export declare function ConfirmDialog({ title, confirmLabel, pendingLabel, onConfirm, onClose, isPending, error, confirmVariant, children, }: ConfirmDialogProps): ReactNode;
|
|
40
|
+
//# sourceMappingURL=confirm-dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-dialog.d.ts","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/C,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,OAAO,EACP,SAAS,EACT,KAAK,EACL,cAAyB,EACzB,QAAQ,GACT,EAAE,kBAAkB,GAAG,SAAS,CAsBhC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Dialog } from './dialog';
|
|
3
|
+
import { Button, ErrorState, Spinner } from './primitives';
|
|
4
|
+
import { errorMessage } from '../errors';
|
|
5
|
+
export function ConfirmDialog({ title, confirmLabel, pendingLabel, onConfirm, onClose, isPending, error, confirmVariant = 'danger', children, }) {
|
|
6
|
+
return (_jsxs(Dialog, { title: title, open: true, onOpenChange: (next) => {
|
|
7
|
+
if (!next)
|
|
8
|
+
onClose();
|
|
9
|
+
}, children: [children, error != null ? _jsx(ErrorState, { message: errorMessage(error) }) : null, _jsxs("div", { className: "tai-dialog-actions", children: [_jsx(Button, { type: "button", onClick: onClose, children: "Cancel" }), _jsxs(Button, { type: "button", variant: confirmVariant, disabled: isPending, onClick: onConfirm, children: [isPending ? _jsx(Spinner, { label: pendingLabel }) : null, confirmLabel] })] })] }));
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=confirm-dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"confirm-dialog.js","sourceRoot":"","sources":["../../src/components/confirm-dialog.tsx"],"names":[],"mappings":";AAiBA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAyBzC,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,OAAO,EACP,SAAS,EACT,KAAK,EACL,cAAc,GAAG,QAAQ,EACzB,QAAQ,GACW;IACnB,OAAO,CACL,MAAC,MAAM,IACL,KAAK,EAAE,KAAK,EACZ,IAAI,QACJ,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE;YACrB,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC;QACvB,CAAC,aAEA,QAAQ,EACR,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAC,UAAU,IAAC,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,GAAI,CAAC,CAAC,CAAC,IAAI,EACpE,eAAK,SAAS,EAAC,oBAAoB,aACjC,KAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,OAAO,uBAE7B,EACT,MAAC,MAAM,IAAC,IAAI,EAAC,QAAQ,EAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,aACnF,SAAS,CAAC,CAAC,CAAC,KAAC,OAAO,IAAC,KAAK,EAAE,YAAY,GAAI,CAAC,CAAC,CAAC,IAAI,EACnD,YAAY,IACN,IACL,IACC,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The design-system class each form control wears. The 36 px geometry, the
|
|
3
|
+
* boundary, the placeholder, and the hover/disabled/invalid states all live in
|
|
4
|
+
* `components.css` under these names — this module is the single place a
|
|
5
|
+
* control names the class, so no control re-derives that geometry inline.
|
|
6
|
+
*/
|
|
7
|
+
export declare const INPUT_CLASS = "tai-input";
|
|
8
|
+
export declare const TEXTAREA_CLASS = "tai-textarea";
|
|
9
|
+
export declare const SELECT_TRIGGER_CLASS = "tai-select-trigger";
|
|
10
|
+
/** A control's class plus the caller's, which sorts last so it can override. */
|
|
11
|
+
export declare function controlClassName(base: string, className: string | undefined): string;
|
|
12
|
+
//# sourceMappingURL=control-styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-styles.d.ts","sourceRoot":"","sources":["../../src/components/control-styles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,cAAc,iBAAiB,CAAC;AAC7C,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAEzD,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEpF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The design-system class each form control wears. The 36 px geometry, the
|
|
3
|
+
* boundary, the placeholder, and the hover/disabled/invalid states all live in
|
|
4
|
+
* `components.css` under these names — this module is the single place a
|
|
5
|
+
* control names the class, so no control re-derives that geometry inline.
|
|
6
|
+
*/
|
|
7
|
+
export const INPUT_CLASS = 'tai-input';
|
|
8
|
+
export const TEXTAREA_CLASS = 'tai-textarea';
|
|
9
|
+
export const SELECT_TRIGGER_CLASS = 'tai-select-trigger';
|
|
10
|
+
/** A control's class plus the caller's, which sorts last so it can override. */
|
|
11
|
+
export function controlClassName(base, className) {
|
|
12
|
+
return className === undefined ? base : `${base} ${className}`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=control-styles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-styles.js","sourceRoot":"","sources":["../../src/components/control-styles.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,cAAc,CAAC;AAC7C,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAEzD,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAA6B;IAC1E,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,SAAS,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface CopyFieldProps {
|
|
2
|
+
readonly value: string;
|
|
3
|
+
readonly caption?: string;
|
|
4
|
+
readonly idPrefix?: string;
|
|
5
|
+
readonly label?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function CopyField({ value, caption, idPrefix, label }: CopyFieldProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=copy-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-field.d.ts","sourceRoot":"","sources":["../../src/components/copy-field.tsx"],"names":[],"mappings":"AA8BA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAyDD,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAuB,EAAE,KAAK,EAAE,EAAE,cAAc,+BAqF3F"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `CopyField` — a show-once box for a freshly-minted secret (an API key or a
|
|
4
|
+
* minted backup key). It renders the value in a monospace, break-all,
|
|
5
|
+
* select-all box beside a copy button that writes the value to the clipboard and
|
|
6
|
+
* shows a transient "Copied" affordance. It is PRESENTATIONAL: the caller owns
|
|
7
|
+
* the value; this component fetches nothing and never re-reads the secret.
|
|
8
|
+
*
|
|
9
|
+
* The button holds BOTH states stacked in one grid cell, so the widest of them
|
|
10
|
+
* sets the width once and the flip never reflows the row. Only the active state
|
|
11
|
+
* is exposed to assistive tech, and that state's own words are the button's
|
|
12
|
+
* accessible name: a constant `aria-label` would leave a button reading "Copied"
|
|
13
|
+
* named "Copy", which fails WCAG 2.5.3 (Label in Name) and leaves a voice-control
|
|
14
|
+
* user naming a control they cannot see. The polite live region beside the button
|
|
15
|
+
* is what actually announces the flip.
|
|
16
|
+
*
|
|
17
|
+
* A clipboard write can FAIL — a permissions policy blocks it, or the page is
|
|
18
|
+
* not in a secure context, where `navigator.clipboard` does not exist at all.
|
|
19
|
+
* Either way the value is a secret shown once, so the failure is rendered as a
|
|
20
|
+
* visible `role="alert"` telling the reader to copy it by hand: throwing it at
|
|
21
|
+
* the console would leave the button looking inert and the secret unrecoverable.
|
|
22
|
+
*
|
|
23
|
+
* SAFETY: the value and caption render as TEXT (React escapes them) — never an
|
|
24
|
+
* HTML sink. The value is never logged, and neither is a failure — the alert
|
|
25
|
+
* names the reason, never the value. Pinned by a test.
|
|
26
|
+
*/
|
|
27
|
+
import { useEffect, useRef, useState } from 'react';
|
|
28
|
+
import { CheckIcon, CopyIcon, XCircleIcon } from './icons';
|
|
29
|
+
const COPIED_RESET_MS = 2000;
|
|
30
|
+
/** The button's two faces. Whichever is exposed is also its accessible name. */
|
|
31
|
+
const COPY_LABEL = 'Copy';
|
|
32
|
+
const COPIED_LABEL = 'Copied';
|
|
33
|
+
/** Announced once, and worded so it is never mistaken for the visible label. */
|
|
34
|
+
const COPIED_ANNOUNCEMENT = 'Copied to clipboard';
|
|
35
|
+
/** The clipboard this browser actually offers, or `undefined` when it offers none. */
|
|
36
|
+
function clipboardOf(host) {
|
|
37
|
+
return host.clipboard;
|
|
38
|
+
}
|
|
39
|
+
/** Shown when the browser offers no clipboard at all (any non-secure context). */
|
|
40
|
+
const NO_CLIPBOARD = 'This browser will not write to the clipboard here. Select the value above and copy it.';
|
|
41
|
+
/** Shown when the write is offered and refused. */
|
|
42
|
+
function writeFailed(reason) {
|
|
43
|
+
const detail = reason instanceof Error ? reason.message : String(reason);
|
|
44
|
+
return `Copy failed: ${detail}. Select the value above and copy it.`;
|
|
45
|
+
}
|
|
46
|
+
const valueStyle = {
|
|
47
|
+
flex: 1,
|
|
48
|
+
padding: 'var(--tai-space-2) var(--tai-space-3)',
|
|
49
|
+
wordBreak: 'break-all',
|
|
50
|
+
userSelect: 'all',
|
|
51
|
+
};
|
|
52
|
+
/** Both states share one grid cell, so the button is as wide as the wider one. */
|
|
53
|
+
const statesStyle = {
|
|
54
|
+
display: 'grid',
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
justifyItems: 'center',
|
|
57
|
+
};
|
|
58
|
+
const stateStyle = {
|
|
59
|
+
gridArea: '1 / 1',
|
|
60
|
+
display: 'inline-flex',
|
|
61
|
+
alignItems: 'center',
|
|
62
|
+
gap: 'var(--tai-space-2)',
|
|
63
|
+
};
|
|
64
|
+
export function CopyField({ value, caption, idPrefix = 'copy-field', label }) {
|
|
65
|
+
const [copied, setCopied] = useState(false);
|
|
66
|
+
const [copyError, setCopyError] = useState(undefined);
|
|
67
|
+
const resetTimer = useRef(null);
|
|
68
|
+
// The clipboard write is async, so a copy can still be in flight when the
|
|
69
|
+
// component goes away — the caller's dialog closes on the same click. Clearing
|
|
70
|
+
// the timer alone would not cover that: at unmount there is no timer yet, and
|
|
71
|
+
// the resolution that follows would start one nothing is left to clear. This
|
|
72
|
+
// flag is what the resolution checks before it touches state at all.
|
|
73
|
+
const mounted = useRef(true);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
mounted.current = true;
|
|
76
|
+
return () => {
|
|
77
|
+
mounted.current = false;
|
|
78
|
+
if (resetTimer.current !== null)
|
|
79
|
+
clearTimeout(resetTimer.current);
|
|
80
|
+
};
|
|
81
|
+
}, []);
|
|
82
|
+
const handleCopy = () => {
|
|
83
|
+
const clipboard = clipboardOf(navigator);
|
|
84
|
+
if (clipboard === undefined) {
|
|
85
|
+
setCopyError(NO_CLIPBOARD);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
setCopyError(undefined);
|
|
89
|
+
void clipboard.writeText(value).then(() => {
|
|
90
|
+
if (!mounted.current)
|
|
91
|
+
return;
|
|
92
|
+
setCopied(true);
|
|
93
|
+
if (resetTimer.current !== null)
|
|
94
|
+
clearTimeout(resetTimer.current);
|
|
95
|
+
resetTimer.current = setTimeout(() => {
|
|
96
|
+
setCopied(false);
|
|
97
|
+
}, COPIED_RESET_MS);
|
|
98
|
+
}, (error) => {
|
|
99
|
+
if (!mounted.current)
|
|
100
|
+
return;
|
|
101
|
+
setCopyError(writeFailed(error));
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
return (_jsxs("div", { "data-testid": idPrefix, className: "tai-stack tai-stack-2", children: [label !== undefined ? _jsx("span", { className: "tai-field-label", children: label }) : null, _jsxs("div", { className: "tai-row", children: [_jsx("code", { className: "tai-code", style: valueStyle, children: value }), _jsx("button", { type: "button", className: "tai-btn tai-btn-secondary", "data-testid": `${idPrefix}-copy`, onClick: handleCopy, children: _jsxs("span", { style: statesStyle, children: [_jsxs("span", { "aria-hidden": copied, style: { ...stateStyle, visibility: copied ? 'hidden' : 'visible' }, children: [_jsx(CopyIcon, {}), COPY_LABEL] }), _jsxs("span", { "aria-hidden": !copied, style: { ...stateStyle, visibility: copied ? 'visible' : 'hidden' }, children: [_jsx(CheckIcon, {}), COPIED_LABEL] })] }) }), _jsx("span", { "aria-live": "polite", className: "tai-visually-hidden", children: copied ? COPIED_ANNOUNCEMENT : '' })] }), copyError !== undefined ? (_jsxs("span", { role: "alert", className: "tai-field-error", children: [_jsx(XCircleIcon, {}), copyError] })) : null, caption !== undefined ? _jsx("span", { className: "tai-field-hint", children: caption }) : null] }));
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=copy-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copy-field.js","sourceRoot":"","sources":["../../src/components/copy-field.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface DialogProps {
|
|
3
|
+
readonly title: string;
|
|
4
|
+
readonly description?: string;
|
|
5
|
+
readonly children?: ReactNode;
|
|
6
|
+
/**
|
|
7
|
+
* A trigger element; when omitted, control the dialog via `open`/`onOpenChange`.
|
|
8
|
+
*
|
|
9
|
+
* It is a single ELEMENT, not any node: Radix clones its props onto it, so a
|
|
10
|
+
* string throws. The type admits a FRAGMENT — `<></>` is a `ReactElement` —
|
|
11
|
+
* which would render openers carrying neither the
|
|
12
|
+
* `aria-haspopup`/`aria-expanded`/`aria-controls` wiring nor a click handler,
|
|
13
|
+
* so {@link assertSlotElement} rejects that one at runtime.
|
|
14
|
+
*/
|
|
15
|
+
readonly trigger?: ReactElement;
|
|
16
|
+
readonly open?: boolean;
|
|
17
|
+
readonly defaultOpen?: boolean;
|
|
18
|
+
readonly onOpenChange?: (open: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare function Dialog({ title, description, children, trigger, open, defaultOpen, onOpenChange, }: DialogProps): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=dialog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,WAAW,EACX,YAAY,GACb,EAAE,WAAW,+BA4Bb"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `Dialog` — a design-system wrapper over Radix Dialog: an accessible modal (role
|
|
4
|
+
* `dialog`, focus trap, Escape to close) labelled by its title. Modality is
|
|
5
|
+
* enforced by the focus trap and by Radix marking the rest of the page inert, not
|
|
6
|
+
* by an `aria-modal` attribute — the panel ships none.
|
|
7
|
+
*
|
|
8
|
+
* Radix owns every modal behaviour — the focus trap, the background scroll lock,
|
|
9
|
+
* Escape, and focus return to the trigger — so this component adds no second
|
|
10
|
+
* mechanism. It contributes only the design-system surface: `tai-overlay` paints
|
|
11
|
+
* the scrim from `--tai-color-scrim`, and `tai-dialog` sizes the panel with a
|
|
12
|
+
* `min()` so it still fits a 320 px viewport. The one gap Radix leaves — focus
|
|
13
|
+
* return for a dialog that renders no trigger — is filled by
|
|
14
|
+
* `useModalFocusReturn`, which stands down whenever a trigger IS rendered.
|
|
15
|
+
*/
|
|
16
|
+
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
17
|
+
import { assertSlotElement } from '../element-slot';
|
|
18
|
+
import { useModalFocusReturn } from './modal-focus';
|
|
19
|
+
export function Dialog({ title, description, children, trigger, open, defaultOpen, onOpenChange, }) {
|
|
20
|
+
const focusReturn = useModalFocusReturn(trigger !== undefined);
|
|
21
|
+
if (trigger !== undefined)
|
|
22
|
+
assertSlotElement(trigger, 'Dialog `trigger`');
|
|
23
|
+
return (_jsxs(RadixDialog.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, children: [trigger !== undefined ? _jsx(RadixDialog.Trigger, { asChild: true, children: trigger }) : null, _jsxs(RadixDialog.Portal, { children: [_jsx(RadixDialog.Overlay, { className: "tai-overlay" }), _jsxs(RadixDialog.Content, { className: "tai-dialog", ...focusReturn, ...(description === undefined ? { 'aria-describedby': undefined } : {}), children: [_jsx(RadixDialog.Title, { className: "tai-dialog-title", children: title }), _jsxs("div", { className: "tai-stack", children: [description !== undefined ? (_jsx(RadixDialog.Description, { className: "tai-muted", children: description })) : null, children] })] })] })] }));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/components/dialog.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAqBpD,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,WAAW,EACX,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,WAAW,EACX,YAAY,GACA;IACZ,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;IAC/D,IAAI,OAAO,KAAK,SAAS;QAAE,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAC1E,OAAO,CACL,MAAC,WAAW,CAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,aAC/E,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAC,WAAW,CAAC,OAAO,IAAC,OAAO,kBAAE,OAAO,GAAuB,CAAC,CAAC,CAAC,IAAI,EAC5F,MAAC,WAAW,CAAC,MAAM,eACjB,KAAC,WAAW,CAAC,OAAO,IAAC,SAAS,EAAC,aAAa,GAAG,EAK/C,MAAC,WAAW,CAAC,OAAO,IAClB,SAAS,EAAC,YAAY,KAClB,WAAW,KACX,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAExE,KAAC,WAAW,CAAC,KAAK,IAAC,SAAS,EAAC,kBAAkB,YAAE,KAAK,GAAqB,EAC3E,eAAK,SAAS,EAAC,WAAW,aACvB,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,KAAC,WAAW,CAAC,WAAW,IAAC,SAAS,EAAC,WAAW,YAAE,WAAW,GAA2B,CACvF,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,IACL,IACc,IACH,IACJ,CACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface DrawerProps {
|
|
3
|
+
/** The dialog's accessible name. */
|
|
4
|
+
readonly title: string;
|
|
5
|
+
readonly children: ReactNode;
|
|
6
|
+
readonly side?: 'left' | 'right';
|
|
7
|
+
/**
|
|
8
|
+
* The opener. Radix labels it and returns focus to it when the drawer closes.
|
|
9
|
+
*
|
|
10
|
+
* It is a single ELEMENT, not any node: Radix clones its props onto it, so a
|
|
11
|
+
* string throws. The type admits a FRAGMENT — `<></>` is a `ReactElement` —
|
|
12
|
+
* which would render openers carrying neither the
|
|
13
|
+
* `aria-haspopup`/`aria-expanded`/`aria-controls` wiring nor a click handler,
|
|
14
|
+
* so {@link assertSlotElement} rejects that one at runtime.
|
|
15
|
+
*/
|
|
16
|
+
readonly trigger?: ReactElement;
|
|
17
|
+
readonly open?: boolean;
|
|
18
|
+
readonly defaultOpen?: boolean;
|
|
19
|
+
readonly onOpenChange?: (open: boolean) => void;
|
|
20
|
+
}
|
|
21
|
+
export declare function Drawer({ title, children, side, trigger, open, defaultOpen, onOpenChange, }: DrawerProps): import("react").JSX.Element;
|
|
22
|
+
//# sourceMappingURL=drawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer.d.ts","sourceRoot":"","sources":["../../src/components/drawer.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMrD,MAAM,WAAW,WAAW;IAC1B,oCAAoC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,QAAQ,EACR,IAAa,EACb,OAAO,EACP,IAAI,EACJ,WAAW,EACX,YAAY,GACb,EAAE,WAAW,+BA2Bb"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `Drawer` — a side-anchored, full-height modal panel, published for a screen
|
|
4
|
+
* that wants a modal it can anchor to an edge rather than centre. Nothing in
|
|
5
|
+
* Studio renders one today; it is SDK surface a plugin can reach for. It is the
|
|
6
|
+
* same Radix Dialog machinery `Dialog` uses, so
|
|
7
|
+
* the focus trap, the scroll lock, Escape and overlay dismissal, the inert
|
|
8
|
+
* background, and focus return to the opener all come from the primitive; only
|
|
9
|
+
* the anchoring differs, and that lives entirely in `.tai-drawer`.
|
|
10
|
+
*
|
|
11
|
+
* Pass the opener as `trigger` where there is one (as `Dialog` does): Radix's own
|
|
12
|
+
* trigger is what carries `aria-haspopup`/`aria-expanded`/`aria-controls` and
|
|
13
|
+
* what its close sequence hands focus back to. A drawer opened purely by flipping
|
|
14
|
+
* `open` renders no trigger, so `useModalFocusReturn` returns focus to the opener
|
|
15
|
+
* in that case alone — with a trigger present it stands down and Radix's own
|
|
16
|
+
* restore is the only mechanism.
|
|
17
|
+
*
|
|
18
|
+
* Open state takes either form, the same three props `Dialog` publishes:
|
|
19
|
+
* `open`/`onOpenChange` to drive it from the caller's state, `defaultOpen` (or
|
|
20
|
+
* nothing at all) to let Radix own it behind a `trigger`.
|
|
21
|
+
*/
|
|
22
|
+
import * as RadixDialog from '@radix-ui/react-dialog';
|
|
23
|
+
import { assertSlotElement } from '../element-slot';
|
|
24
|
+
import { CloseIcon } from './icons';
|
|
25
|
+
import { useModalFocusReturn } from './modal-focus';
|
|
26
|
+
export function Drawer({ title, children, side = 'left', trigger, open, defaultOpen, onOpenChange, }) {
|
|
27
|
+
const focusReturn = useModalFocusReturn(trigger !== undefined);
|
|
28
|
+
if (trigger !== undefined)
|
|
29
|
+
assertSlotElement(trigger, 'Drawer `trigger`');
|
|
30
|
+
return (_jsxs(RadixDialog.Root, { open: open, defaultOpen: defaultOpen, onOpenChange: onOpenChange, children: [trigger === undefined ? null : _jsx(RadixDialog.Trigger, { asChild: true, children: trigger }), _jsxs(RadixDialog.Portal, { children: [_jsx(RadixDialog.Overlay, { className: "tai-overlay" }), _jsxs(RadixDialog.Content, { className: "tai-drawer", "data-side": side, "aria-describedby": undefined, ...focusReturn, children: [_jsxs("div", { className: "tai-drawer-header", children: [_jsx(RadixDialog.Title, { className: "tai-section-title", children: title }), _jsx(RadixDialog.Close, { className: "tai-icon-btn", "aria-label": "Close", children: _jsx(CloseIcon, {}) })] }), children] })] })] }));
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=drawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawer.js","sourceRoot":"","sources":["../../src/components/drawer.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAsBpD,MAAM,UAAU,MAAM,CAAC,EACrB,KAAK,EACL,QAAQ,EACR,IAAI,GAAG,MAAM,EACb,OAAO,EACP,IAAI,EACJ,WAAW,EACX,YAAY,GACA;IACZ,MAAM,WAAW,GAAG,mBAAmB,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC;IAC/D,IAAI,OAAO,KAAK,SAAS;QAAE,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;IAC1E,OAAO,CACL,MAAC,WAAW,CAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,aAC/E,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,WAAW,CAAC,OAAO,IAAC,OAAO,kBAAE,OAAO,GAAuB,EAC5F,MAAC,WAAW,CAAC,MAAM,eACjB,KAAC,WAAW,CAAC,OAAO,IAAC,SAAS,EAAC,aAAa,GAAG,EAG/C,MAAC,WAAW,CAAC,OAAO,IAClB,SAAS,EAAC,YAAY,eACX,IAAI,sBACG,SAAS,KACvB,WAAW,aAEf,eAAK,SAAS,EAAC,mBAAmB,aAChC,KAAC,WAAW,CAAC,KAAK,IAAC,SAAS,EAAC,mBAAmB,YAAE,KAAK,GAAqB,EAC5E,KAAC,WAAW,CAAC,KAAK,IAAC,SAAS,EAAC,cAAc,gBAAY,OAAO,YAC5D,KAAC,SAAS,KAAG,GACK,IAChB,EACL,QAAQ,IACW,IACH,IACJ,CACpB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A generic render-error boundary: it contains a throw from its subtree and shows
|
|
3
|
+
* a loud `role="alert"` panel in its place, so one failing region never blanks the
|
|
4
|
+
* page around it. `label` prefixes the caught message to name the contained region
|
|
5
|
+
* (e.g. the plugin whose content threw); `onError` observes the error for logging.
|
|
6
|
+
* There is no in-place retry — the boundary resets by remounting, so callers that
|
|
7
|
+
* want a reset give it a fresh `key`.
|
|
8
|
+
*
|
|
9
|
+
* The fallback is the design system's `ErrorState`, so a contained render error
|
|
10
|
+
* looks exactly like a failed fetch: one `role="alert"` surface headed by a mark
|
|
11
|
+
* and words, never color alone. It is rendered without a retry, since the
|
|
12
|
+
* boundary resets by remounting.
|
|
13
|
+
*/
|
|
14
|
+
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
15
|
+
export interface ErrorBoundaryProps {
|
|
16
|
+
readonly children: ReactNode;
|
|
17
|
+
/** Prefixed to the caught error message, naming the contained region. */
|
|
18
|
+
readonly label?: string;
|
|
19
|
+
/** Called with the caught error and React's component stack, for logging. */
|
|
20
|
+
readonly onError?: (error: unknown, info: ErrorInfo) => void;
|
|
21
|
+
}
|
|
22
|
+
interface ErrorBoundaryState {
|
|
23
|
+
readonly hasError: boolean;
|
|
24
|
+
readonly error: unknown;
|
|
25
|
+
}
|
|
26
|
+
export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
27
|
+
state: ErrorBoundaryState;
|
|
28
|
+
static getDerivedStateFromError(error: unknown): ErrorBoundaryState;
|
|
29
|
+
componentDidCatch(error: unknown, info: ErrorInfo): void;
|
|
30
|
+
render(): ReactNode;
|
|
31
|
+
}
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=error-boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-boundary.d.ts","sourceRoot":"","sources":["../../src/components/error-boundary.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAKlE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC9D;AAMD,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,qBAAa,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;IACzE,KAAK,EAAE,kBAAkB,CAAoC;IAEtE,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB;IAI1D,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAIxD,MAAM,IAAI,SAAS;CAS7B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A generic render-error boundary: it contains a throw from its subtree and shows
|
|
4
|
+
* a loud `role="alert"` panel in its place, so one failing region never blanks the
|
|
5
|
+
* page around it. `label` prefixes the caught message to name the contained region
|
|
6
|
+
* (e.g. the plugin whose content threw); `onError` observes the error for logging.
|
|
7
|
+
* There is no in-place retry — the boundary resets by remounting, so callers that
|
|
8
|
+
* want a reset give it a fresh `key`.
|
|
9
|
+
*
|
|
10
|
+
* The fallback is the design system's `ErrorState`, so a contained render error
|
|
11
|
+
* looks exactly like a failed fetch: one `role="alert"` surface headed by a mark
|
|
12
|
+
* and words, never color alone. It is rendered without a retry, since the
|
|
13
|
+
* boundary resets by remounting.
|
|
14
|
+
*/
|
|
15
|
+
import { Component } from 'react';
|
|
16
|
+
import { errorMessage } from '../errors';
|
|
17
|
+
import { ErrorState } from './primitives';
|
|
18
|
+
export class ErrorBoundary extends Component {
|
|
19
|
+
state = { hasError: false, error: null };
|
|
20
|
+
static getDerivedStateFromError(error) {
|
|
21
|
+
return { hasError: true, error };
|
|
22
|
+
}
|
|
23
|
+
componentDidCatch(error, info) {
|
|
24
|
+
this.props.onError?.(error, info);
|
|
25
|
+
}
|
|
26
|
+
render() {
|
|
27
|
+
if (this.state.hasError) {
|
|
28
|
+
const { label } = this.props;
|
|
29
|
+
const text = errorMessage(this.state.error);
|
|
30
|
+
const message = label !== undefined ? `${label}: ${text}` : text;
|
|
31
|
+
return _jsx(ErrorState, { message: message });
|
|
32
|
+
}
|
|
33
|
+
return this.props.children;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=error-boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-boundary.js","sourceRoot":"","sources":["../../src/components/error-boundary.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,SAAS,EAAkC,MAAM,OAAO,CAAC;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAmB1C,MAAM,OAAO,aAAc,SAAQ,SAAiD;IACzE,KAAK,GAAuB,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAEtE,MAAM,CAAC,wBAAwB,CAAC,KAAc;QAC5C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACnC,CAAC;IAEQ,iBAAiB,CAAC,KAAc,EAAE,IAAe;QACxD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAEQ,MAAM;QACb,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;YAC7B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACjE,OAAO,KAAC,UAAU,IAAC,OAAO,EAAE,OAAO,GAAI,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ExtensionComboBuilder` — a controlled editor for a preset/tool's LIST OF
|
|
3
|
+
* extension combos. A combo is an ordered list of extension ELEMENTS, each a bare
|
|
4
|
+
* extension NAME or a `{ name, config }` mapping carrying author config; the value
|
|
5
|
+
* is the list of combos (`PresetExtensionElement[][]`), the SAME shape the
|
|
6
|
+
* preset/tool extensions wire carries. It is PRESENTATIONAL: the caller fetches the
|
|
7
|
+
* extension catalog (`available`) and owns the `value`; this component fetches nothing.
|
|
8
|
+
*
|
|
9
|
+
* The surface has two parts:
|
|
10
|
+
* - the current combos, each an ordered row of name `Badge`s with a per-combo Edit
|
|
11
|
+
* (pull it back into the draft) and Remove;
|
|
12
|
+
* - a combo UNDER CONSTRUCTION, authored with the shared `ExtensionPicker` (grouped
|
|
13
|
+
* by kind, single-select for the non-stackable `backend` kind). When the draft
|
|
14
|
+
* includes the `output_schema` extension, its config is authored inline with a
|
|
15
|
+
* `SchemaEditor` (no title required); an "Add combo" / "Update combo" action
|
|
16
|
+
* composes the elements — `output_schema` as `{ name, config: { schema } }`, every
|
|
17
|
+
* other extension as a bare name — and writes it into the value.
|
|
18
|
+
*
|
|
19
|
+
* The builder only blocks the client-trivial invalids: an EMPTY combo (Add is
|
|
20
|
+
* disabled until the draft has ≥1 member), a DUPLICATE of a combo already in the
|
|
21
|
+
* value (by name sequence; flagged inline, Add blocked), an INVALID `output_schema`
|
|
22
|
+
* config (the `SchemaEditor` shows the parse/lint error and Add is blocked), and an
|
|
23
|
+
* UNKNOWN extension name in an existing combo (a name absent from `available`, which
|
|
24
|
+
* happens when a plugin is removed after a preset was authored) — flagged inline on
|
|
25
|
+
* that combo row and reported through `onValidityChange` so the caller can block
|
|
26
|
+
* submit. Every deeper rule — the registry's one-per-non-stackable-kind constraint,
|
|
27
|
+
* meta-schema validity, kind/ordering — is SERVER-AUTHORITATIVE: the write route
|
|
28
|
+
* validates each combo and its 400 message is surfaced verbatim by the caller.
|
|
29
|
+
*
|
|
30
|
+
* Loading is signaled by `availableReady`: while the catalog is still loading the
|
|
31
|
+
* builder reports VALID and suppresses the unknown-name notes (no danger-note flash
|
|
32
|
+
* while submit stays enabled — the server backstops), so a stale-seeded combo does
|
|
33
|
+
* not flicker invalid before the catalog resolves.
|
|
34
|
+
*
|
|
35
|
+
* SAFETY: an extension name is server-supplied, so every name renders as TEXT through
|
|
36
|
+
* the DS `Badge`/`Checkbox` (React escapes it) — never an HTML sink.
|
|
37
|
+
*
|
|
38
|
+
* Geometry and ink come from the design-system classes: each committed combo is a
|
|
39
|
+
* `tai-card` row, the invalid notes are `tai-field-error` (icon + message, never
|
|
40
|
+
* color alone), and Remove is a labelled `Button` carrying `CloseIcon` beside the
|
|
41
|
+
* word, under an accessible name that names the combo it removes.
|
|
42
|
+
*/
|
|
43
|
+
import { type ReactNode } from 'react';
|
|
44
|
+
import type { Extension, PresetExtensionElement } from '@tai42/api-client';
|
|
45
|
+
export interface ExtensionComboBuilderProps {
|
|
46
|
+
/** The extension catalog the combos are drawn from (caller-fetched). */
|
|
47
|
+
readonly available: readonly Extension[];
|
|
48
|
+
/** The current list of combos, each an ordered list of extension elements. */
|
|
49
|
+
readonly value: readonly PresetExtensionElement[][];
|
|
50
|
+
/** Fired with the next list of combos on every add/update/remove. */
|
|
51
|
+
readonly onChange: (next: PresetExtensionElement[][]) => void;
|
|
52
|
+
readonly disabled?: boolean;
|
|
53
|
+
readonly idPrefix?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Fired (effect-driven) on mount and whenever `value`, `available`, or
|
|
56
|
+
* `availableReady` changes with whether every combo's names are known. A caller
|
|
57
|
+
* blocks submit while this is `false`. The `onChange` payload shape is unchanged;
|
|
58
|
+
* this is a SECOND callback so the prop surface stays backward-compatible.
|
|
59
|
+
*/
|
|
60
|
+
readonly onValidityChange?: (valid: boolean) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Whether the `available` catalog has finished loading. Default `true` (existing
|
|
63
|
+
* consumers keep today's behavior). While `false` the builder reports VALID and
|
|
64
|
+
* suppresses the unknown-name notes, so a stale-seeded combo does not flash invalid
|
|
65
|
+
* before the catalog resolves.
|
|
66
|
+
*/
|
|
67
|
+
readonly availableReady?: boolean;
|
|
68
|
+
}
|
|
69
|
+
export declare function ExtensionComboBuilder({ available, value, onChange, disabled, idPrefix, onValidityChange, availableReady, }: ExtensionComboBuilderProps): ReactNode;
|
|
70
|
+
//# sourceMappingURL=extension-combo-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-combo-builder.d.ts","sourceRoot":"","sources":["../../src/components/extension-combo-builder.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtE,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAY3E,MAAM,WAAW,0BAA0B;IACzC,wEAAwE;IACxE,QAAQ,CAAC,SAAS,EAAE,SAAS,SAAS,EAAE,CAAC;IACzC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,SAAS,sBAAsB,EAAE,EAAE,CAAC;IACpD,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,sBAAsB,EAAE,EAAE,KAAK,IAAI,CAAC;IAC9D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CACnC;AA8BD,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAoC,EACpC,gBAAgB,EAChB,cAAqB,GACtB,EAAE,0BAA0B,GAAG,SAAS,CA2LxC"}
|