@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,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Select` — a design-system wrapper over Radix Select (an accessible listbox with
|
|
3
|
+
* a `combobox` trigger). Options are passed declaratively — either a flat
|
|
4
|
+
* `options` run or labelled `groups`, never both — and the trigger auto-wires to
|
|
5
|
+
* an enclosing `Field`.
|
|
6
|
+
*
|
|
7
|
+
* Every surface is a class — `tai-select-trigger` for the control, and
|
|
8
|
+
* `tai-select-content` / `tai-select-item` for the popup, which is where the
|
|
9
|
+
* shared keyboard-highlight rule lives. The disclosure mark is the design
|
|
10
|
+
* system's `ChevronDownIcon`, decorative behind the trigger's own name.
|
|
11
|
+
*/
|
|
12
|
+
import * as RadixSelect from '@radix-ui/react-select';
|
|
13
|
+
|
|
14
|
+
import { SELECT_TRIGGER_CLASS } from './control-styles';
|
|
15
|
+
import { useFieldControl } from './field';
|
|
16
|
+
import { CheckIcon, ChevronDownIcon } from './icons';
|
|
17
|
+
|
|
18
|
+
export interface SelectOption {
|
|
19
|
+
readonly value: string;
|
|
20
|
+
readonly label: string;
|
|
21
|
+
readonly disabled?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** A labelled cluster of options (e.g. tools grouped by tag). */
|
|
25
|
+
export interface SelectGroup {
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly options: readonly SelectOption[];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Everything the two listbox shapes have in common. */
|
|
31
|
+
interface SelectSharedProps {
|
|
32
|
+
readonly value?: string;
|
|
33
|
+
readonly defaultValue?: string;
|
|
34
|
+
readonly onValueChange?: (value: string) => void;
|
|
35
|
+
readonly placeholder?: string;
|
|
36
|
+
readonly disabled?: boolean;
|
|
37
|
+
readonly name?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Accessible name for the trigger when it is not wired to an enclosing
|
|
40
|
+
* `Field`. A `Field` wins where both are given — it names the trigger from
|
|
41
|
+
* visible text, and `aria-label` would override that native label and leave
|
|
42
|
+
* the visible text out of the accessible name (WCAG 2.5.3).
|
|
43
|
+
*/
|
|
44
|
+
readonly 'aria-label'?: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** The FLAT listbox: one ungrouped run of options. */
|
|
48
|
+
export interface SelectProps extends SelectSharedProps {
|
|
49
|
+
readonly options: readonly SelectOption[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The GROUPED listbox: labelled clusters, each carrying its own options. */
|
|
53
|
+
export interface SelectGroupsProps extends SelectSharedProps {
|
|
54
|
+
readonly groups: readonly SelectGroup[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* What `Select` ACCEPTS: exactly one of the two shapes, never both. Only one
|
|
59
|
+
* list can be rendered, so accepting `options` alongside `groups` means
|
|
60
|
+
* discarding every entry of the other without a word.
|
|
61
|
+
*
|
|
62
|
+
* The exclusion lives HERE and not on the two interfaces because both are
|
|
63
|
+
* published plugin API and must stay extendable: `groups?: undefined` written
|
|
64
|
+
* onto `SelectProps` makes `interface MyPicker extends SelectProps { groups:
|
|
65
|
+
* readonly SelectGroup[] }` a TS2430, and a union cannot be `extends`-ed at all
|
|
66
|
+
* (TS2312).
|
|
67
|
+
*/
|
|
68
|
+
type SelectArgs =
|
|
69
|
+
| (SelectProps & { readonly groups?: undefined })
|
|
70
|
+
| (SelectGroupsProps & { readonly options?: undefined });
|
|
71
|
+
|
|
72
|
+
function OptionItem({ option }: { option: SelectOption }) {
|
|
73
|
+
return (
|
|
74
|
+
<RadixSelect.Item className="tai-select-item" value={option.value} disabled={option.disabled}>
|
|
75
|
+
<RadixSelect.ItemText>{option.label}</RadixSelect.ItemText>
|
|
76
|
+
{/* The highlight follows the reader through the list, so it cannot also
|
|
77
|
+
stand for the chosen value. The check is what marks that, and Radix
|
|
78
|
+
renders it for the selected option only. It is decorative: Radix already
|
|
79
|
+
puts `aria-selected` on the item. */}
|
|
80
|
+
<RadixSelect.ItemIndicator className="tai-select-item-indicator">
|
|
81
|
+
<CheckIcon />
|
|
82
|
+
</RadixSelect.ItemIndicator>
|
|
83
|
+
</RadixSelect.Item>
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function Select(props: SelectArgs) {
|
|
88
|
+
const {
|
|
89
|
+
value,
|
|
90
|
+
defaultValue,
|
|
91
|
+
onValueChange,
|
|
92
|
+
placeholder = 'Select…',
|
|
93
|
+
disabled,
|
|
94
|
+
name,
|
|
95
|
+
'aria-label': ariaLabel,
|
|
96
|
+
} = props;
|
|
97
|
+
const field = useFieldControl();
|
|
98
|
+
// Untyped JavaScript is the only caller that reaches this. Rendering one list
|
|
99
|
+
// and dropping the other would lose every entry in the discarded one silently,
|
|
100
|
+
// and an empty listbox reads as "there is nothing to choose".
|
|
101
|
+
if ((props.options === undefined) === (props.groups === undefined)) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
'Select renders exactly one of `options` or `groups`; it was given both, or neither.',
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
return (
|
|
107
|
+
<RadixSelect.Root
|
|
108
|
+
value={value}
|
|
109
|
+
defaultValue={defaultValue}
|
|
110
|
+
onValueChange={onValueChange}
|
|
111
|
+
disabled={disabled}
|
|
112
|
+
name={name}
|
|
113
|
+
>
|
|
114
|
+
<RadixSelect.Trigger
|
|
115
|
+
id={field.id}
|
|
116
|
+
className={SELECT_TRIGGER_CLASS}
|
|
117
|
+
// A trigger claiming the field's id is named by that field's `<label
|
|
118
|
+
// for>`, and `aria-label` outranks a native label — emitting both would
|
|
119
|
+
// discard the visible text the field renders.
|
|
120
|
+
aria-label={field.id === undefined ? ariaLabel : undefined}
|
|
121
|
+
aria-describedby={field['aria-describedby']}
|
|
122
|
+
aria-invalid={field['aria-invalid']}
|
|
123
|
+
>
|
|
124
|
+
<RadixSelect.Value placeholder={placeholder} />
|
|
125
|
+
<RadixSelect.Icon aria-hidden="true">
|
|
126
|
+
<ChevronDownIcon />
|
|
127
|
+
</RadixSelect.Icon>
|
|
128
|
+
</RadixSelect.Trigger>
|
|
129
|
+
<RadixSelect.Portal>
|
|
130
|
+
<RadixSelect.Content className="tai-select-content" position="popper" sideOffset={4}>
|
|
131
|
+
<RadixSelect.Viewport className="tai-select-viewport">
|
|
132
|
+
{props.groups !== undefined
|
|
133
|
+
? props.groups.map((group) => (
|
|
134
|
+
<RadixSelect.Group key={group.label}>
|
|
135
|
+
<RadixSelect.Label className="tai-select-group-label tai-label">
|
|
136
|
+
{group.label}
|
|
137
|
+
</RadixSelect.Label>
|
|
138
|
+
{group.options.map((option) => (
|
|
139
|
+
<OptionItem key={option.value} option={option} />
|
|
140
|
+
))}
|
|
141
|
+
</RadixSelect.Group>
|
|
142
|
+
))
|
|
143
|
+
: props.options.map((option) => <OptionItem key={option.value} option={option} />)}
|
|
144
|
+
</RadixSelect.Viewport>
|
|
145
|
+
</RadixSelect.Content>
|
|
146
|
+
</RadixSelect.Portal>
|
|
147
|
+
</RadixSelect.Root>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Semantic table primitives — thin wrappers over the native table elements.
|
|
3
|
+
* They keep the real `table`/`row`/`columnheader`/`cell` roles so assistive
|
|
4
|
+
* tech and tests read a proper table. Only the root carries a class: the header
|
|
5
|
+
* and cell rules in the stylesheet are descendants of `.tai-table`, so a cell
|
|
6
|
+
* cannot drift out of the system by forgetting one.
|
|
7
|
+
*
|
|
8
|
+
* A numeric column opts in with `numeric`, which stamps `data-numeric="true"` —
|
|
9
|
+
* the hook the stylesheet right-aligns on tabular figures so digits line up.
|
|
10
|
+
*
|
|
11
|
+
* Each wrapper FORWARDS a consumer `ref` to the native element it renders — the
|
|
12
|
+
* attribute spread carries it, the same way it carries every other native prop —
|
|
13
|
+
* so a caller that has to measure or scroll a cell is not forced back to a raw
|
|
14
|
+
* `<td>` and out of the system.
|
|
15
|
+
*/
|
|
16
|
+
import type { HTMLAttributes, Ref, ReactNode, TdHTMLAttributes, ThHTMLAttributes } from 'react';
|
|
17
|
+
|
|
18
|
+
export interface TableProps extends HTMLAttributes<HTMLTableElement> {
|
|
19
|
+
readonly children?: ReactNode;
|
|
20
|
+
/** A consumer ref for the `<table>` itself. */
|
|
21
|
+
readonly ref?: Ref<HTMLTableElement>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function Table({ children, className, ...props }: TableProps) {
|
|
25
|
+
return (
|
|
26
|
+
<table {...props} className={className === undefined ? 'tai-table' : `tai-table ${className}`}>
|
|
27
|
+
{children}
|
|
28
|
+
</table>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** `<thead>` and `<tbody>` take the same surface: the native one. */
|
|
33
|
+
export interface TableSectionProps extends HTMLAttributes<HTMLTableSectionElement> {
|
|
34
|
+
readonly children?: ReactNode;
|
|
35
|
+
/** A consumer ref for the section element itself. */
|
|
36
|
+
readonly ref?: Ref<HTMLTableSectionElement>;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function THead({ children, ...props }: TableSectionProps) {
|
|
40
|
+
return <thead {...props}>{children}</thead>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function TBody({ children, ...props }: TableSectionProps) {
|
|
44
|
+
return <tbody {...props}>{children}</tbody>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface TableRowProps extends HTMLAttributes<HTMLTableRowElement> {
|
|
48
|
+
readonly children?: ReactNode;
|
|
49
|
+
/** A consumer ref for the `<tr>` itself. */
|
|
50
|
+
readonly ref?: Ref<HTMLTableRowElement>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function TR({ children, ...props }: TableRowProps) {
|
|
54
|
+
return <tr {...props}>{children}</tr>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Right-align a column of digits on tabular figures. */
|
|
58
|
+
export interface NumericColumnProps {
|
|
59
|
+
readonly numeric?: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* A header cell. `scope` defaults to `col` because that is what a `<th>` in the
|
|
64
|
+
* header row IS, and without it nothing associates the cell with the column
|
|
65
|
+
* below it: a screen reader announcing a data cell has no header to name it.
|
|
66
|
+
* A row header — the leading cell of a body row — passes `scope="row"`.
|
|
67
|
+
*/
|
|
68
|
+
export interface THProps extends ThHTMLAttributes<HTMLTableCellElement>, NumericColumnProps {
|
|
69
|
+
readonly children?: ReactNode;
|
|
70
|
+
/** A consumer ref for the `<th>` itself. */
|
|
71
|
+
readonly ref?: Ref<HTMLTableCellElement>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function TH({ children, numeric = false, scope = 'col', ...props }: THProps) {
|
|
75
|
+
return (
|
|
76
|
+
<th {...props} scope={scope} data-numeric={numeric ? 'true' : undefined}>
|
|
77
|
+
{children}
|
|
78
|
+
</th>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface TDProps extends TdHTMLAttributes<HTMLTableCellElement>, NumericColumnProps {
|
|
83
|
+
readonly children?: ReactNode;
|
|
84
|
+
/** A consumer ref for the `<td>` itself. */
|
|
85
|
+
readonly ref?: Ref<HTMLTableCellElement>;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function TD({ children, numeric = false, ...props }: TDProps) {
|
|
89
|
+
return (
|
|
90
|
+
<td {...props} data-numeric={numeric ? 'true' : undefined}>
|
|
91
|
+
{children}
|
|
92
|
+
</td>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Tabs` — a wrapper over Radix Tabs (roles `tablist` / `tab` / `tabpanel`,
|
|
3
|
+
* arrow-key roving focus). Panels are declared inline per item. The selected
|
|
4
|
+
* tab's accent rail and heavier label come from `.tai-tab[data-state='active']`
|
|
5
|
+
* in the stylesheet, keyed off the `data-state` Radix stamps on each trigger.
|
|
6
|
+
*/
|
|
7
|
+
import * as RadixTabs from '@radix-ui/react-tabs';
|
|
8
|
+
import type { ReactNode } from 'react';
|
|
9
|
+
|
|
10
|
+
export interface TabItem {
|
|
11
|
+
readonly value: string;
|
|
12
|
+
readonly label: string;
|
|
13
|
+
readonly content: ReactNode;
|
|
14
|
+
readonly disabled?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TabsProps {
|
|
18
|
+
readonly items: readonly TabItem[];
|
|
19
|
+
readonly value?: string;
|
|
20
|
+
readonly defaultValue?: string;
|
|
21
|
+
readonly onValueChange?: (value: string) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function Tabs({ items, value, defaultValue, onValueChange }: TabsProps) {
|
|
25
|
+
const firstValue = items[0]?.value;
|
|
26
|
+
return (
|
|
27
|
+
<RadixTabs.Root
|
|
28
|
+
value={value}
|
|
29
|
+
defaultValue={defaultValue ?? firstValue}
|
|
30
|
+
onValueChange={onValueChange}
|
|
31
|
+
>
|
|
32
|
+
<RadixTabs.List className="tai-tablist">
|
|
33
|
+
{items.map((item) => (
|
|
34
|
+
<RadixTabs.Trigger
|
|
35
|
+
key={item.value}
|
|
36
|
+
value={item.value}
|
|
37
|
+
disabled={item.disabled}
|
|
38
|
+
className="tai-tab"
|
|
39
|
+
>
|
|
40
|
+
{item.label}
|
|
41
|
+
</RadixTabs.Trigger>
|
|
42
|
+
))}
|
|
43
|
+
</RadixTabs.List>
|
|
44
|
+
{items.map((item) => (
|
|
45
|
+
<RadixTabs.Content key={item.value} value={item.value} className="tai-tabpanel">
|
|
46
|
+
{item.content}
|
|
47
|
+
</RadixTabs.Content>
|
|
48
|
+
))}
|
|
49
|
+
</RadixTabs.Root>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tag rendering + authoring, shared across features. `TagChips` displays a list of
|
|
3
|
+
* labels as escaped chips (server strings are arbitrary — React escapes every one,
|
|
4
|
+
* never an HTML sink). `TagsInput` is the controlled add/remove editor.
|
|
5
|
+
*
|
|
6
|
+
* A tag is a `tai-chip tai-chip-static`: it reads, it is not a control. The
|
|
7
|
+
* control beside it is the `tai-icon-btn` that removes it, which carries the
|
|
8
|
+
* accessible name ("Remove tag <tag>") because its `CloseIcon` is decorative.
|
|
9
|
+
*
|
|
10
|
+
* These live in the SDK because more than one feature (presets, agents, and the
|
|
11
|
+
* version-history panel's per-version tag editor) needs the same control; a single
|
|
12
|
+
* canonical copy keeps the affordance identical everywhere.
|
|
13
|
+
*/
|
|
14
|
+
import { useState, type CSSProperties, type ReactNode } from 'react';
|
|
15
|
+
|
|
16
|
+
import { CloseIcon } from './icons';
|
|
17
|
+
import { Button } from './primitives';
|
|
18
|
+
import { TextInput } from './inputs';
|
|
19
|
+
|
|
20
|
+
/** A tag and its remove control read as one unit, tighter than the row default. */
|
|
21
|
+
const tagGroupStyle: CSSProperties = { gap: 'var(--tai-space-1)' };
|
|
22
|
+
|
|
23
|
+
export interface TagChipsProps {
|
|
24
|
+
readonly tags: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Read-only chips for a list of tags. Renders nothing when there are none. */
|
|
28
|
+
export function TagChips({ tags }: TagChipsProps): ReactNode {
|
|
29
|
+
if (tags.length === 0) return null;
|
|
30
|
+
return (
|
|
31
|
+
<span className="tai-row" style={tagGroupStyle}>
|
|
32
|
+
{tags.map((tag) => (
|
|
33
|
+
<span key={tag} className="tai-chip tai-chip-static">
|
|
34
|
+
{tag}
|
|
35
|
+
</span>
|
|
36
|
+
))}
|
|
37
|
+
</span>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TagsInputProps {
|
|
42
|
+
readonly value: readonly string[];
|
|
43
|
+
readonly onChange: (next: string[]) => void;
|
|
44
|
+
readonly disabled?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The draft input's accessible name when no enclosing `Field` supplies one.
|
|
47
|
+
* Forwarded to the input as a native attribute — see the docblock below.
|
|
48
|
+
*/
|
|
49
|
+
readonly 'aria-label'?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Controlled tag editor. The caller owns the `value` list; `onChange` receives the
|
|
54
|
+
* next list on every add/remove. A blank or duplicate entry is ignored (never a
|
|
55
|
+
* silent duplicate chip). Enter or comma commits the draft chip.
|
|
56
|
+
*
|
|
57
|
+
* The draft input is a NATIVE-ATTRIBUTE PASS-THROUGH (the family `inputs.tsx`
|
|
58
|
+
* documents): inside a `Field` it renders the SDK's `TextInput`, which spreads
|
|
59
|
+
* `useFieldControl()` and so claims the Field's control id, taking the Field's
|
|
60
|
+
* visible label as its name; mounted OUTSIDE a `Field` it is named by a caller
|
|
61
|
+
* `aria-label`, which the editor forwards to that same input. Without one a bare
|
|
62
|
+
* editor is unnamed — the published component owns the naming route rather than
|
|
63
|
+
* assuming a `Field` is always present. When a `Field` DOES name it, a caller
|
|
64
|
+
* `aria-label` still has to CONTAIN that visible label (WCAG 2.5.3, Label in
|
|
65
|
+
* Name); `components/field-group.test.ts` enforces that at every call site.
|
|
66
|
+
*/
|
|
67
|
+
export function TagsInput({
|
|
68
|
+
value,
|
|
69
|
+
onChange,
|
|
70
|
+
disabled,
|
|
71
|
+
'aria-label': ariaLabel,
|
|
72
|
+
}: TagsInputProps): ReactNode {
|
|
73
|
+
const [draft, setDraft] = useState('');
|
|
74
|
+
|
|
75
|
+
const add = (): void => {
|
|
76
|
+
const tag = draft.trim();
|
|
77
|
+
if (tag === '' || value.includes(tag)) {
|
|
78
|
+
setDraft('');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
onChange([...value, tag]);
|
|
82
|
+
setDraft('');
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const remove = (tag: string): void => {
|
|
86
|
+
onChange(value.filter((existing) => existing !== tag));
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<div className="tai-stack tai-stack-2">
|
|
91
|
+
<div className="tai-row">
|
|
92
|
+
{/* The input takes the row; the button keeps its intrinsic width. */}
|
|
93
|
+
<div style={{ flex: 1 }}>
|
|
94
|
+
<TextInput
|
|
95
|
+
value={draft}
|
|
96
|
+
onChange={(event) => {
|
|
97
|
+
setDraft(event.target.value);
|
|
98
|
+
}}
|
|
99
|
+
onKeyDown={(event) => {
|
|
100
|
+
// Enter or comma commits the draft chip.
|
|
101
|
+
if (event.key === 'Enter' || event.key === ',') {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
add();
|
|
104
|
+
}
|
|
105
|
+
}}
|
|
106
|
+
placeholder="Add a tag…"
|
|
107
|
+
aria-label={ariaLabel}
|
|
108
|
+
disabled={disabled}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
<Button type="button" onClick={add} disabled={disabled}>
|
|
112
|
+
Add tag
|
|
113
|
+
</Button>
|
|
114
|
+
</div>
|
|
115
|
+
{value.length > 0 ? (
|
|
116
|
+
<div className="tai-row">
|
|
117
|
+
{value.map((tag) => (
|
|
118
|
+
<span key={tag} className="tai-row" style={tagGroupStyle}>
|
|
119
|
+
<span className="tai-chip tai-chip-static">{tag}</span>
|
|
120
|
+
<button
|
|
121
|
+
type="button"
|
|
122
|
+
className="tai-icon-btn"
|
|
123
|
+
aria-label={`Remove tag ${tag}`}
|
|
124
|
+
onClick={() => {
|
|
125
|
+
remove(tag);
|
|
126
|
+
}}
|
|
127
|
+
disabled={disabled}
|
|
128
|
+
>
|
|
129
|
+
<CloseIcon />
|
|
130
|
+
</button>
|
|
131
|
+
</span>
|
|
132
|
+
))}
|
|
133
|
+
</div>
|
|
134
|
+
) : null}
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|