@jini-ai/ui 0.3.13 → 0.4.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/CHANGELOG.md +139 -0
- package/README.md +120 -26
- package/dist/browser/index.js +1 -1
- package/dist/browser/useDismissOnOutsideOrEscape.d.ts +10 -1
- package/dist/browser/useDismissOnOutsideOrEscape.js +7 -4
- package/dist/browser/useGlobalKeydown.d.ts +14 -2
- package/dist/browser/useGlobalKeydown.js +8 -17
- package/dist/features/a2ui/catalog-from-registry.d.ts +6 -3
- package/dist/features/a2ui/catalog-from-registry.js +1 -1
- package/dist/features/a2ui/index.d.ts +1 -1
- package/dist/features/a2ui/protocol.d.ts +1 -1
- package/dist/features/a2ui/renderer.js +23 -10
- package/dist/features/a2ui/use-a2ui-surface.d.ts +11 -6
- package/dist/features/a2ui/use-a2ui-surface.js +40 -10
- package/dist/features/admin-widgets/components/ComingSoonNotice.d.ts +11 -0
- package/dist/features/admin-widgets/components/ComingSoonNotice.js +7 -0
- package/dist/features/admin-widgets/components/ComingSoonPanel.d.ts +10 -0
- package/dist/features/admin-widgets/components/ComingSoonPanel.js +10 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.d.ts +16 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.d.ts +13 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.hooks.js +46 -0
- package/dist/features/admin-widgets/components/ImagePreviewModal.js +13 -0
- package/dist/features/admin-widgets/components/InfoTip.d.ts +18 -0
- package/dist/features/admin-widgets/components/InfoTip.hooks.d.ts +16 -0
- package/dist/features/admin-widgets/components/InfoTip.hooks.js +45 -0
- package/dist/features/admin-widgets/components/InfoTip.js +12 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.d.ts +41 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.hooks.d.ts +14 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.hooks.js +57 -0
- package/dist/features/admin-widgets/components/SeeMore/SeeMore.js +24 -0
- package/dist/features/admin-widgets/components/Select/Select.d.ts +39 -0
- package/dist/features/admin-widgets/components/Select/Select.hooks.d.ts +105 -0
- package/dist/features/admin-widgets/components/Select/Select.hooks.js +359 -0
- package/dist/features/admin-widgets/components/Select/Select.js +46 -0
- package/dist/features/admin-widgets/index.d.ts +20 -0
- package/dist/features/admin-widgets/index.js +11 -0
- package/dist/features/admin-widgets/styles/admin-widgets.css +2 -0
- package/dist/features/appearance/constants.d.ts +2 -2
- package/dist/features/appearance/constants.js +2 -1
- package/dist/features/appearance/react/components/AppearanceTab.js +5 -5
- package/dist/features/appearance/rules.d.ts +10 -4
- package/dist/features/appearance/rules.js +5 -5
- package/dist/features/appearance/types.d.ts +1 -1
- package/dist/features/appearance/types.js +1 -1
- package/dist/features/asset-grid/react/components/AssetGrid.js +1 -1
- package/dist/features/asset-grid/react/components/DeleteConfirmDialog.js +1 -1
- package/dist/features/asset-grid/react/hooks/useAssetGridKeyboardShortcuts.js +23 -21
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.d.ts +1 -1
- package/dist/features/asset-grid/react/hooks/useAssetGridLiveUpdates.js +1 -1
- package/dist/features/asset-tree-browser/ports.d.ts +3 -1
- package/dist/features/asset-tree-browser/react/hooks/useAssetTreeCopyLocalPath.js +1 -1
- package/dist/features/browser-chrome/react/components/BrowserViewportControls.js +1 -1
- package/dist/features/browser-chrome/types.js +1 -1
- package/dist/features/command-palette/ports.js +1 -1
- package/dist/features/connectors/ConnectorsBrowser.js +2 -2
- package/dist/features/connectors/components/ConnectorCard.js +3 -3
- package/dist/features/connectors/components/ConnectorDetailDrawer.js +1 -1
- package/dist/features/connectors/components/ConnectorGrid.js +2 -2
- package/dist/features/connectors/components/ConnectorSearchBar.js +2 -2
- package/dist/features/connectors/components/ProviderTabBar.js +2 -2
- package/dist/features/connectors/constants.d.ts +1 -1
- package/dist/features/connectors/constants.js +1 -1
- package/dist/features/connectors/hooks/useConnectorAuthorization.js +1 -1
- package/dist/features/connectors/rules.d.ts +2 -2
- package/dist/features/connectors/rules.js +1 -1
- package/dist/features/connectors/types.d.ts +2 -2
- package/dist/features/connectors/types.js +1 -1
- package/dist/features/execution/react/components/ByokProviderForm.js +3 -3
- package/dist/features/execution/react/components/ExecutionTab.js +2 -2
- package/dist/features/execution/react/components/LocalCliAgentCard.js +3 -3
- package/dist/features/execution/react/components/LocalCliAgentList.js +2 -2
- package/dist/features/execution/react/components/ProviderChipGroup.js +2 -2
- package/dist/features/execution/react/components/SearchableModelSelect.js +1 -1
- package/dist/features/execution/rules.js +1 -1
- package/dist/features/file-dropzone/react/components/FileDropzone.js +5 -3
- package/dist/features/file-dropzone/react/hooks/useFileDropzone.d.ts +1 -1
- package/dist/features/file-dropzone/react/hooks/useFileDropzone.js +1 -1
- package/dist/features/file-dropzone/types.d.ts +1 -1
- package/dist/features/file-dropzone/types.js +1 -1
- package/dist/features/folder-path-drop/react/hooks/useFolderPathDropCapture.js +6 -4
- package/dist/features/html-editor/canvas-content-wrapper.js +1 -1
- package/dist/features/html-editor/canvas-embed-placeholders.js +7 -7
- package/dist/features/html-editor/canvas-style.d.ts +4 -0
- package/dist/features/html-editor/canvas-style.js +6 -21
- package/dist/features/html-viewer/constants.d.ts +1 -1
- package/dist/features/html-viewer/constants.js +1 -1
- package/dist/features/html-viewer/react/components/PresentMenu.js +1 -1
- package/dist/features/html-viewer/react/components/ZoomMenu.js +1 -1
- package/dist/features/html-viewer/types.d.ts +1 -1
- package/dist/features/html-viewer/types.js +1 -1
- package/dist/features/i18n/dictionaries/index.d.ts +2 -3
- package/dist/features/i18n/dictionaries/settings-dialog.en.d.ts +1 -1
- package/dist/features/i18n/dictionary-translator.d.ts +16 -0
- package/dist/features/i18n/dictionary-translator.js +14 -0
- package/dist/features/i18n/index.d.ts +3 -0
- package/dist/features/i18n/index.js +2 -0
- package/dist/features/i18n/locale.d.ts +1 -1
- package/dist/features/i18n/template-i18n.d.ts +26 -0
- package/dist/features/i18n/template-i18n.js +36 -0
- package/dist/features/iframe-pool/react/components/IframeKeepAliveProvider.d.ts +1 -1
- package/dist/features/iframe-pool/react/components/IframeKeepAliveProvider.js +1 -1
- package/dist/features/instructions/react/components/InstructionsTab.js +1 -1
- package/dist/features/integrations/react/components/ClientPicker.js +4 -4
- package/dist/features/integrations/react/components/CodexInstallToggleButton.js +1 -1
- package/dist/features/integrations/react/components/IntegrationsTab.js +2 -2
- package/dist/features/integrations/react/components/SnippetBlock.js +1 -1
- package/dist/features/integrations/types.d.ts +1 -1
- package/dist/features/integrations/types.js +1 -1
- package/dist/features/interactive-ui/index.js +13 -13
- package/dist/features/interactive-ui/interactive-ui.css +1 -1
- package/dist/features/interactive-ui/providers/recharts/bar-chart.js +1 -1
- package/dist/features/interactive-ui/providers/recharts/line-chart.js +1 -1
- package/dist/features/interactive-ui/providers/recharts/pie-chart.js +2 -2
- package/dist/features/interactive-ui/providers/shadcn/lib/utils.d.ts +1 -1
- package/dist/features/interactive-ui/providers/shadcn/lib/utils.js +1 -1
- package/dist/features/interactive-ui/registry.d.ts +15 -4
- package/dist/features/interactive-ui/registry.js +5 -5
- package/dist/features/language/react/components/LanguageTab.js +2 -2
- package/dist/features/list-detail-panel/types.d.ts +1 -1
- package/dist/features/list-detail-panel/types.js +1 -1
- package/dist/features/mcp-ui/confirmation-store.js +2 -1
- package/dist/features/mcp-ui/surfaces/bridge.d.ts +2 -1
- package/dist/features/mcp-ui/surfaces/bridge.js +17 -7
- package/dist/features/mcp-ui/surfaces/confirmation.d.ts +20 -0
- package/dist/features/mcp-ui/surfaces/confirmation.js +38 -6
- package/dist/features/mcp-ui/surfaces/document.d.ts +7 -1
- package/dist/features/mcp-ui/surfaces/document.js +19 -1
- package/dist/features/mcp-ui/surfaces/text-input.js +4 -4
- package/dist/features/mcp-ui/surfaces/tokens.d.ts +17 -20
- package/dist/features/mcp-ui/surfaces/tokens.js +33 -35
- package/dist/features/media-providers/index.d.ts +1 -1
- package/dist/features/media-providers/index.js +1 -1
- package/dist/features/media-providers/react/components/MediaProvidersTab.js +4 -4
- package/dist/features/media-providers/rules.js +1 -1
- package/dist/features/memory/async-commit-guard.d.ts +1 -1
- package/dist/features/memory/constants.d.ts +1 -1
- package/dist/features/memory/constants.js +1 -1
- package/dist/features/memory/dependencies.d.ts +11 -23
- package/dist/features/memory/dependencies.js +116 -106
- package/dist/features/memory/index.d.ts +1 -1
- package/dist/features/memory/index.js +1 -1
- package/dist/features/memory/react/components/MemoryAdvancedModal.js +2 -2
- package/dist/features/memory/react/components/MemoryEntryCard.js +1 -1
- package/dist/features/memory/react/components/MemoryExtractionCard.js +1 -1
- package/dist/features/memory/react/components/MemoryHooksPanel.js +1 -1
- package/dist/features/memory/react/components/MemoryList.js +5 -5
- package/dist/features/memory/react/components/MemoryManualEditor.js +5 -5
- package/dist/features/memory/react/components/MemorySettingsPanel.js +1 -1
- package/dist/features/memory/react/hooks/useMemoryEntries.hooks.js +1 -1
- package/dist/features/memory/react/hooks/useMemoryNavigation.hooks.js +1 -1
- package/dist/features/memory/react/styles.js +1 -1
- package/dist/features/memory/rules.js +1 -1
- package/dist/features/memory/types.d.ts +1 -1
- package/dist/features/mention-autocomplete/react/hooks/useMentionAutocomplete.js +1 -1
- package/dist/features/notifications/react/components/NotificationsTab.js +7 -7
- package/dist/features/notifications/types.d.ts +1 -1
- package/dist/features/observability/boot-timing.js +2 -2
- package/dist/features/observability/stuck-run.js +1 -1
- package/dist/features/observability/white-screen.js +4 -4
- package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +35 -0
- package/dist/features/panel-kit/fetch-query/adapter.react.js +122 -0
- package/dist/features/panel-kit/fetch-query/cache.d.ts +123 -0
- package/dist/features/panel-kit/fetch-query/cache.js +231 -0
- package/dist/features/panel-kit/fetch-query/environment.browser.d.ts +4 -0
- package/dist/features/panel-kit/fetch-query/environment.browser.js +25 -0
- package/dist/features/panel-kit/fetch-query/index.d.ts +4 -0
- package/dist/features/panel-kit/fetch-query/index.js +2 -0
- package/dist/features/panel-kit/fetch-query/types.d.ts +91 -0
- package/dist/features/panel-kit/fetch-query/types.js +2 -0
- package/dist/features/panel-kit/helpers/format-timestamp.d.ts +18 -0
- package/dist/features/panel-kit/helpers/format-timestamp.js +20 -0
- package/dist/features/panel-kit/helpers/permissions.d.ts +11 -0
- package/dist/features/panel-kit/helpers/permissions.js +10 -0
- package/dist/features/panel-kit/helpers/resolve-active-tab-id.d.ts +13 -0
- package/dist/features/panel-kit/helpers/resolve-active-tab-id.js +13 -0
- package/dist/features/panel-kit/helpers/retry-unreachable.d.ts +20 -0
- package/dist/features/panel-kit/helpers/retry-unreachable.js +39 -0
- package/dist/features/panel-kit/hooks/use-async-action.hooks.d.ts +13 -0
- package/dist/features/panel-kit/hooks/use-async-action.hooks.js +27 -0
- package/dist/features/panel-kit/hooks/use-dirty-guard.hooks.d.ts +18 -0
- package/dist/features/panel-kit/hooks/use-dirty-guard.hooks.js +33 -0
- package/dist/features/panel-kit/hooks/use-focus-trap.hooks.d.ts +8 -0
- package/dist/features/panel-kit/hooks/use-focus-trap.hooks.js +66 -0
- package/dist/features/panel-kit/hooks/use-serial-writes.hooks.d.ts +26 -0
- package/dist/features/panel-kit/hooks/use-serial-writes.hooks.js +41 -0
- package/dist/features/panel-kit/hooks/use-settlement-generation.hooks.d.ts +9 -0
- package/dist/features/panel-kit/hooks/use-settlement-generation.hooks.js +25 -0
- package/dist/features/panel-kit/index.d.ts +19 -0
- package/dist/features/panel-kit/index.js +13 -0
- package/dist/features/privacy/react/components/PrivacyTab.js +2 -2
- package/dist/features/privacy/types.d.ts +1 -1
- package/dist/features/privacy/types.js +1 -1
- package/dist/features/progress-card/reference-adapters.d.ts +1 -1
- package/dist/features/progress-card/rules.d.ts +1 -1
- package/dist/features/progress-card/rules.js +1 -1
- package/dist/features/progress-card/types.d.ts +1 -1
- package/dist/features/progress-card/types.js +1 -1
- package/dist/features/resource-dashboard/dependencies.d.ts +1 -1
- package/dist/features/resource-dashboard/ports.d.ts +1 -1
- package/dist/features/resource-dashboard/react/hooks/useResourceBoard.d.ts +1 -1
- package/dist/features/resource-dashboard/react/hooks/useResourceBoard.js +1 -1
- package/dist/features/resource-dashboard/rules.d.ts +1 -1
- package/dist/features/resource-dashboard/rules.js +2 -2
- package/dist/features/resource-dashboard/types.d.ts +4 -4
- package/dist/features/resource-dashboard/types.js +1 -1
- package/dist/features/schedule-picker/react/hooks/useRecurringSchedulePicker.js +1 -1
- package/dist/features/settings/dialog/styles/settings-dialog.css +62 -60
- package/dist/features/sketch-editor/constants.d.ts +1 -1
- package/dist/features/sketch-editor/constants.js +1 -1
- package/dist/features/sketch-editor/dom.d.ts +1 -1
- package/dist/features/sketch-editor/dom.js +1 -1
- package/dist/features/sketch-editor/react/hooks/useSketchDomEnhancements.d.ts +1 -1
- package/dist/features/sketch-editor/react/hooks/useSketchDomEnhancements.js +11 -9
- package/dist/features/sketch-editor/types.d.ts +1 -1
- package/dist/features/sketch-editor/types.js +1 -1
- package/dist/features/skills/react/components/SkillDraftForm.js +1 -1
- package/dist/features/skills/react/components/SkillRow.js +1 -1
- package/dist/features/skills/react/components/SkillsTab.js +2 -2
- package/dist/features/source-config-list/agent-handles.js +2 -2
- package/dist/features/source-config-list/react/hooks/useSourceConfigAddForm.d.ts +1 -1
- package/dist/features/source-config-list/react/hooks/useSourceConfigAddForm.js +1 -1
- package/dist/features/source-config-list/rules.d.ts +1 -1
- package/dist/features/source-config-list/rules.js +3 -3
- package/dist/features/source-config-list/types.d.ts +1 -1
- package/dist/features/source-config-list/types.js +1 -1
- package/dist/features/tab-launcher-menu/react/hooks/useTabLauncherMenu.js +1 -1
- package/dist/features/tab-strip/index.d.ts +4 -0
- package/dist/features/tab-strip/index.js +2 -0
- package/dist/features/tab-strip/react/components/TabBar.d.ts +23 -0
- package/dist/features/tab-strip/react/components/TabBar.hooks.d.ts +25 -0
- package/dist/features/tab-strip/react/components/TabBar.hooks.js +57 -0
- package/dist/features/tab-strip/react/components/TabBar.js +18 -0
- package/dist/features/tab-strip/react/components/TabStrip.js +2 -1
- package/dist/features/tab-strip/react/components/TabStripFrame.d.ts +3 -0
- package/dist/features/tab-strip/react/components/TabStripFrame.js +7 -0
- package/dist/features/tabbed-dialog/react/hooks/useTabbedDialog.js +1 -1
- package/dist/features/tabbed-dialog/styles/tabbed-dialog.css +8 -141
- package/dist/features/tabbed-dialog/types.d.ts +1 -1
- package/dist/features/tabbed-dialog/types.js +1 -1
- package/dist/features/version-manager/ports.d.ts +1 -1
- package/dist/features/version-manager/react/components/VersionPromptPopover.js +5 -3
- package/dist/features/version-manager/react/components/VersionRestoreControl.js +1 -1
- package/dist/features/version-manager/types.d.ts +1 -1
- package/dist/features/version-manager/types.js +1 -1
- package/dist/features/viewer-shell/dependencies.js +1 -1
- package/dist/features/viewer-shell/ports.d.ts +1 -1
- package/dist/features/viewer-shell/react/components/ViewportSwitcher.js +1 -1
- package/dist/features/viewer-shell/react/hooks/useMarkdownScrollSync.d.ts +1 -1
- package/dist/features/viewer-shell/react/hooks/useMarkdownScrollSync.js +1 -1
- package/dist/features/viewer-shell/types.d.ts +1 -1
- package/dist/features/viewer-shell/types.js +1 -1
- package/dist/index.d.ts +420 -0
- package/dist/index.js +421 -1
- package/dist/react/components/ComponentKitPreview.js +1 -1
- package/dist/react/components/EditorIcon.d.ts +1 -1
- package/dist/react/components/EditorIcon.js +22 -22
- package/dist/react/components/ExportDiagnosticsButton.d.ts +8 -1
- package/dist/react/components/ExportDiagnosticsButton.js +6 -6
- package/dist/react/components/PaletteTweaks.js +5 -5
- package/dist/react/hooks/useBrandFonts.d.ts +19 -4
- package/dist/react/hooks/useBrandFonts.js +11 -7
- package/dist/react/hooks/useDebouncedValue.d.ts +12 -1
- package/dist/react/hooks/useDebouncedValue.js +9 -4
- package/dist/react/hooks/useStableHandler.d.ts +3 -1
- package/dist/react/hooks/useStableHandler.js +1 -1
- package/dist/renderers/annotation-canvas/drawing.d.ts +4 -4
- package/dist/renderers/annotation-canvas/drawing.js +28 -15
- package/dist/renderers/annotation-canvas/react/components/AnnotationCanvas.js +2 -2
- package/dist/renderers/annotation-canvas/react/hooks/useAnnotationCanvas.js +4 -3
- package/dist/renderers/annotation-canvas/rules.d.ts +1 -1
- package/dist/renderers/annotation-canvas/theme.d.ts +13 -0
- package/dist/renderers/annotation-canvas/theme.js +16 -0
- package/dist/renderers/annotation-canvas/types.d.ts +1 -1
- package/dist/renderers/index.d.ts +1 -1
- package/dist/renderers/new-tab-preview.d.ts +3 -0
- package/dist/renderers/new-tab-preview.js +3 -1
- package/dist/renderers/preview-modal-shell/react/hooks/usePreviewModalShell.d.ts +1 -1
- package/dist/renderers/preview-modal-shell/react/hooks/usePreviewModalShell.js +1 -1
- package/dist/renderers/preview-modal-shell/rules.d.ts +1 -1
- package/dist/renderers/preview-modal-shell/types.d.ts +3 -3
- package/dist/renderers/preview-modal-shell/types.js +2 -2
- package/dist/renderers/react/components/ArtifactView.d.ts +1 -1
- package/dist/renderers/react/components/ArtifactView.js +1 -1
- package/dist/renderers/registry.d.ts +12 -6
- package/dist/renderers/registry.js +7 -9
- package/dist/renderers/renderers/html.js +2 -2
- package/dist/renderers/renderers/index.js +1 -1
- package/dist/renderers/renderers/markdown.js +2 -2
- package/dist/renderers/renderers/react-component.js +1 -1
- package/dist/renderers/renderers/svg.js +1 -1
- package/dist/renderers/shiki.js +1 -1
- package/dist/renderers/srcdoc/build.d.ts +1 -1
- package/dist/renderers/srcdoc/build.js +1 -1
- package/dist/renderers/url-load-decision.d.ts +1 -1
- package/dist/renderers/url-load-decision.js +1 -1
- package/dist/styles/admin.css +273 -0
- package/dist/styles/variables.css +117 -0
- package/dist/theme/apply.d.ts +9 -0
- package/dist/theme/apply.js +77 -0
- package/dist/theme/color-scheme.d.ts +8 -0
- package/dist/theme/color-scheme.js +9 -0
- package/dist/theme/default.d.ts +4 -0
- package/dist/theme/default.js +11 -0
- package/dist/theme/index.d.ts +6 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/stylesheet.d.ts +8 -0
- package/dist/theme/stylesheet.js +14 -0
- package/dist/theme/types.d.ts +39 -0
- package/dist/theme/types.js +2 -0
- package/dist/theme/validation.d.ts +15 -0
- package/dist/theme/validation.js +55 -0
- package/dist/utils/appearance.js +1 -1
- package/dist/utils/browser-request.d.ts +12 -0
- package/dist/utils/browser-request.js +10 -0
- package/dist/utils/color-math.d.ts +20 -6
- package/dist/utils/color-math.js +12 -12
- package/dist/utils/copy-to-clipboard.d.ts +19 -8
- package/dist/utils/copy-to-clipboard.js +15 -11
- package/dist/utils/dom-subscriptions.js +1 -1
- package/dist/utils/endpoint-policy.d.ts +9 -3
- package/dist/utils/endpoint-policy.js +5 -5
- package/dist/utils/markdown-scroll-sync.js +3 -3
- package/dist/utils/notifications.d.ts +1 -1
- package/dist/utils/notifications.js +1 -1
- package/dist/utils/polygon-selection.d.ts +1 -1
- package/dist/utils/polygon-selection.js +1 -1
- package/dist/utils/scroll-tabs-with-wheel.d.ts +4 -1
- package/dist/utils/scroll-tabs-with-wheel.js +1 -1
- package/dist/utils/smooth-scroll-to-top.js +1 -1
- package/dist/utils/sse.d.ts +3 -1
- package/dist/utils/sse.js +1 -1
- package/package.json +105 -16
- package/dist/features/lexical-rich-text-editor/react/test-support/lexical-harness.d.ts +0 -11
- package/dist/features/lexical-rich-text-editor/react/test-support/lexical-harness.js +0 -35
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* it. `agentic/core` owns the catalog/interpreter/protocol types (framework-free); this feature
|
|
4
4
|
* folder is the React-facing wiring on top.
|
|
5
5
|
*/
|
|
6
|
-
export { createA2uiInterpreter, createLabCatalog, type A2uiInterpreter, type ApplyMessageResult, type BuildActionResult, type ComponentInstance, type SurfaceSnapshot, type Catalog, type ComponentSpec, type ComponentKind, } from '@jini-ai/agentic/a2ui';
|
|
6
|
+
export { createA2uiInterpreter, createLabCatalog, type A2uiInterpreter, type A2uiIdsPort, type ApplyMessageResult, type BuildActionResult, type ComponentInstance, type SurfaceSnapshot, type Catalog, type ComponentSpec, type ComponentKind, } from '@jini-ai/agentic/a2ui';
|
|
7
7
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useA2uiSurfaceRoot } from './use-a2ui-surface.js';
|
|
3
|
+
// Explicit provider contracts, not a guessed common callback. Display-only cards/charts
|
|
4
|
+
// have no action callback; custom interactive entries can declare their own `actionProp`.
|
|
5
|
+
const PROVIDER_ACTION_PROPS = new Map([
|
|
6
|
+
['native.data-table', 'onRowClick'],
|
|
7
|
+
['shadcn.data-table', 'onRowClick'],
|
|
8
|
+
['shadcn.button', 'onPress'],
|
|
9
|
+
['shadcn.checkbox', 'onCheckedChange'],
|
|
10
|
+
['shadcn.radio-group', 'onValueChange'],
|
|
11
|
+
['shadcn.text-input', 'onValueChange'],
|
|
12
|
+
['shadcn.select', 'onValueChange'],
|
|
13
|
+
]);
|
|
3
14
|
/**
|
|
4
15
|
* Recursively walks a surface's component map from `componentId` — same shape as
|
|
5
16
|
* `@jini-ai/chat/react`'s `A2uiSurfaceCard`'s `RenderComponent` (cycle guard via `ancestors`,
|
|
@@ -17,7 +28,7 @@ function RenderNode({ interpreter, surfaceId, registry, componentId, ancestors,
|
|
|
17
28
|
if (ancestors.has(componentId)) {
|
|
18
29
|
return (_jsxs("span", { className: "a2ui-placeholder a2ui-placeholder-cycle", "data-a2ui-status": "cycle", "data-a2ui-component-id": componentId, children: ["\u27F2 circular reference at \"", componentId, "\""] }));
|
|
19
30
|
}
|
|
20
|
-
const surface = interpreter.getSurface(surfaceId);
|
|
31
|
+
const surface = interpreter.getSurface({ surfaceId });
|
|
21
32
|
const component = surface?.components.get(componentId);
|
|
22
33
|
if (!component) {
|
|
23
34
|
return (_jsxs("span", { className: "a2ui-placeholder a2ui-placeholder-missing", "data-a2ui-status": "missing", "data-a2ui-component-id": componentId, children: ["\u26A0 missing component \"", componentId, "\""] }));
|
|
@@ -26,7 +37,7 @@ function RenderNode({ interpreter, surfaceId, registry, componentId, ancestors,
|
|
|
26
37
|
nextAncestors.add(componentId);
|
|
27
38
|
const childProps = { interpreter, surfaceId, registry, ancestors: nextAncestors, onAction };
|
|
28
39
|
function resolveText(value) {
|
|
29
|
-
const result = interpreter.resolve(surfaceId, value);
|
|
40
|
+
const result = interpreter.resolve({ surfaceId, value: value });
|
|
30
41
|
if (!result.ok)
|
|
31
42
|
return `⚠ unresolved (${result.reason})`;
|
|
32
43
|
return typeof result.value === 'string' ? result.value : JSON.stringify(result.value);
|
|
@@ -49,15 +60,17 @@ function RenderNode({ interpreter, surfaceId, registry, componentId, ancestors,
|
|
|
49
60
|
case 'Button':
|
|
50
61
|
return (_jsx("button", { type: "button", className: `a2ui-button a2ui-button-${String(component.props.variant)}`, "data-a2ui-component-id": componentId, onClick: () => onAction(componentId), children: _jsx(RenderNode, { ...childProps, componentId: String(component.props.child) }) }));
|
|
51
62
|
default: {
|
|
52
|
-
const entry = registry.resolveById(component.component);
|
|
63
|
+
const entry = registry.resolveById({ id: component.component });
|
|
53
64
|
if (!entry) {
|
|
54
65
|
return (_jsxs("span", { className: "a2ui-placeholder", "data-a2ui-status": "unrenderable-type", "data-a2ui-component-id": componentId, children: ["\u26A0 no renderer yet for component type \"", component.component, "\""] }));
|
|
55
66
|
}
|
|
56
67
|
const RegistryComponent = entry.Component;
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
68
|
+
// `onRowClick` belongs to `native.data-table`/`shadcn.data-table`, not a generic
|
|
69
|
+
// per-component-type feedback convention — each non-table provider needs an explicit
|
|
70
|
+
// callback contract, supplied by the built-in map or its registry entry, not a guess.
|
|
71
|
+
// Unannotated custom entries retain the old table callback for compatibility.
|
|
72
|
+
const actionProp = entry.actionProp ?? PROVIDER_ACTION_PROPS.get(entry.id) ?? 'onRowClick';
|
|
73
|
+
return _jsx(RegistryComponent, { ...component.props, [actionProp]: () => onAction(componentId) });
|
|
61
74
|
}
|
|
62
75
|
}
|
|
63
76
|
}
|
|
@@ -67,13 +80,13 @@ function RenderNode({ interpreter, surfaceId, registry, componentId, ancestors,
|
|
|
67
80
|
* for coverage and the fallback resolution order.
|
|
68
81
|
*/
|
|
69
82
|
export function A2uiSurfaceRenderer({ interpreter, surfaceId, registry, fallback }) {
|
|
70
|
-
const root = useA2uiSurfaceRoot(interpreter, surfaceId);
|
|
83
|
+
const root = useA2uiSurfaceRoot({ interpreter: interpreter, surfaceId: surfaceId });
|
|
71
84
|
if (!root)
|
|
72
85
|
return fallback ?? null;
|
|
73
86
|
const onAction = (componentId) => {
|
|
74
|
-
const component = interpreter.getSurface(surfaceId)?.components.get(componentId);
|
|
87
|
+
const component = interpreter.getSurface({ surfaceId })?.components.get(componentId);
|
|
75
88
|
if (component?.props.action !== undefined)
|
|
76
|
-
interpreter.buildAction(surfaceId, componentId);
|
|
89
|
+
interpreter.buildAction({ surfaceId, componentId });
|
|
77
90
|
};
|
|
78
91
|
return (_jsx(RenderNode, { interpreter: interpreter, surfaceId: surfaceId, registry: registry, componentId: root.id, ancestors: new Set(), onAction: onAction }));
|
|
79
92
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import type { A2uiInterpreter, ComponentInstance } from './protocol.js';
|
|
2
2
|
/**
|
|
3
|
-
* Subscribes a component to one A2UI surface's root, re-rendering
|
|
4
|
-
*
|
|
5
|
-
* interpreter has no per-surface subscription granularity, so this hook re-reads
|
|
6
|
-
* every notification and lets `useSyncExternalStore`'s reference-equality check skip
|
|
7
|
-
* if this particular surface's
|
|
3
|
+
* Subscribes a component to one A2UI surface's root, re-rendering when its components or data
|
|
4
|
+
* change (a message applied via `interpreter.applyAgentMessage` notifies for any surface — the
|
|
5
|
+
* interpreter has no per-surface subscription granularity, so this hook re-reads the whole
|
|
6
|
+
* surface on every notification and lets `useSyncExternalStore`'s reference-equality check skip
|
|
7
|
+
* the render if this particular surface's components and data model are unchanged). Descendant
|
|
8
|
+
* and binding updates must render even when the root object itself is unchanged.
|
|
8
9
|
*
|
|
9
10
|
* Returns `undefined` when the surface doesn't exist yet, or exists but has no `'root'`
|
|
10
11
|
* component yet (a legal, "still streaming in" state per the interpreter's own `getRoot` doc).
|
|
12
|
+
* @complexity O(n) time per snapshot read and O(n) retained space for n surface components.
|
|
11
13
|
*/
|
|
12
|
-
export declare function useA2uiSurfaceRoot(interpreter
|
|
14
|
+
export declare function useA2uiSurfaceRoot({ interpreter, surfaceId }: {
|
|
15
|
+
interpreter: A2uiInterpreter;
|
|
16
|
+
surfaceId: string;
|
|
17
|
+
}): ComponentInstance | undefined;
|
|
13
18
|
//# sourceMappingURL=use-a2ui-surface.d.ts.map
|
|
@@ -1,17 +1,47 @@
|
|
|
1
|
-
import { useCallback, useSyncExternalStore } from 'react';
|
|
1
|
+
import { useCallback, useMemo, useSyncExternalStore } from 'react';
|
|
2
2
|
/**
|
|
3
|
-
* Subscribes a component to one A2UI surface's root, re-rendering
|
|
4
|
-
*
|
|
5
|
-
* interpreter has no per-surface subscription granularity, so this hook re-reads
|
|
6
|
-
* every notification and lets `useSyncExternalStore`'s reference-equality check skip
|
|
7
|
-
* if this particular surface's
|
|
3
|
+
* Subscribes a component to one A2UI surface's root, re-rendering when its components or data
|
|
4
|
+
* change (a message applied via `interpreter.applyAgentMessage` notifies for any surface — the
|
|
5
|
+
* interpreter has no per-surface subscription granularity, so this hook re-reads the whole
|
|
6
|
+
* surface on every notification and lets `useSyncExternalStore`'s reference-equality check skip
|
|
7
|
+
* the render if this particular surface's components and data model are unchanged). Descendant
|
|
8
|
+
* and binding updates must render even when the root object itself is unchanged.
|
|
8
9
|
*
|
|
9
10
|
* Returns `undefined` when the surface doesn't exist yet, or exists but has no `'root'`
|
|
10
11
|
* component yet (a legal, "still streaming in" state per the interpreter's own `getRoot` doc).
|
|
12
|
+
* @complexity O(n) time per snapshot read and O(n) retained space for n surface components.
|
|
11
13
|
*/
|
|
12
|
-
export function useA2uiSurfaceRoot(interpreter, surfaceId) {
|
|
13
|
-
const subscribe = useCallback((onStoreChange) =>
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
export function useA2uiSurfaceRoot({ interpreter, surfaceId }) {
|
|
15
|
+
const subscribe = useCallback((onStoreChange) => {
|
|
16
|
+
const unsubscribe = interpreter.subscribe({ listener: () => onStoreChange() });
|
|
17
|
+
return () => unsubscribe({});
|
|
18
|
+
}, [interpreter]);
|
|
19
|
+
const getSnapshot = useMemo(() => {
|
|
20
|
+
let snapshot;
|
|
21
|
+
return () => {
|
|
22
|
+
const current = interpreter.getSurface({ surfaceId });
|
|
23
|
+
if (!current) {
|
|
24
|
+
snapshot = undefined;
|
|
25
|
+
return snapshot;
|
|
26
|
+
}
|
|
27
|
+
// getSurface returns a new wrapper around a mutable component map. Cache a copy,
|
|
28
|
+
// comparing component identities and immutable data-model identity so repeated reads
|
|
29
|
+
// stay stable and changes before subscription are still visible to React's recheck.
|
|
30
|
+
let unchanged = snapshot !== undefined && snapshot.catalogId === current.catalogId
|
|
31
|
+
&& Object.is(snapshot.dataModel, current.dataModel) && snapshot.components.size === current.components.size;
|
|
32
|
+
if (unchanged) {
|
|
33
|
+
for (const [id, component] of current.components) {
|
|
34
|
+
if (snapshot.components.get(id) !== component) {
|
|
35
|
+
unchanged = false;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (!unchanged)
|
|
41
|
+
snapshot = { ...current, components: new Map(current.components) };
|
|
42
|
+
return snapshot;
|
|
43
|
+
};
|
|
44
|
+
}, [interpreter, surfaceId]);
|
|
45
|
+
return useSyncExternalStore(subscribe, getSnapshot)?.components.get('root');
|
|
16
46
|
}
|
|
17
47
|
//# sourceMappingURL=use-a2ui-surface.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface ComingSoonNoticeProps {
|
|
2
|
+
kicker: string;
|
|
3
|
+
label: string;
|
|
4
|
+
/** Fully translated description supplied by the host. */
|
|
5
|
+
description: string;
|
|
6
|
+
note?: string | undefined;
|
|
7
|
+
agentHandle?: string | undefined;
|
|
8
|
+
}
|
|
9
|
+
/** A notice without navigation lookup, route knowledge, or locale state. */
|
|
10
|
+
export declare function ComingSoonNotice({ kicker, label, description, note, agentHandle }: ComingSoonNoticeProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=ComingSoonNotice.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle as handleProps } from '@jini-ai/agentic';
|
|
3
|
+
/** A notice without navigation lookup, route knowledge, or locale state. */
|
|
4
|
+
export function ComingSoonNotice({ kicker, label, description, note, agentHandle }) {
|
|
5
|
+
return (_jsx("div", { className: "coming-soon-notice", ...(agentHandle ? handleProps({ handle: agentHandle }, { role: 'status', label }) : {}), children: _jsxs("div", { className: "coming-soon-notice-header", children: [_jsx("p", { className: "coming-soon-notice-kicker", children: kicker }), _jsx("h1", { children: label }), _jsx("p", { children: description }), note ? _jsx("p", { children: note }) : null] }) }));
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=ComingSoonNotice.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export interface ComingSoonPanelProps {
|
|
3
|
+
/** Terse status without promised dates; label plus optional note should occupy at most two lines. */
|
|
4
|
+
label: string;
|
|
5
|
+
note?: string | undefined;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/** Keeps preview content mounted inside an inert subtree, with caller-supplied status copy. */
|
|
9
|
+
export declare function ComingSoonPanel({ label, note, children }: ComingSoonPanelProps): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=ComingSoonPanel.d.ts.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Keep the real content visible so operators can see what is coming; an empty placeholder
|
|
3
|
+
// would hide that context. Native inert removes the subtree from tab order, click handling and
|
|
4
|
+
// the accessibility tree: opacity or pointer-events alone leaves apparently disabled controls usable.
|
|
5
|
+
// The existing inert-control style uses 0.55 opacity to signal inactivity while retaining legibility.
|
|
6
|
+
/** Keeps preview content mounted inside an inert subtree, with caller-supplied status copy. */
|
|
7
|
+
export function ComingSoonPanel({ label, note, children }) {
|
|
8
|
+
return (_jsxs("div", { className: "coming-soon-panel", children: [_jsxs("p", { className: "settings-ui-inert-note", role: "note", children: [_jsx("strong", { children: label }), note ? _jsxs(_Fragment, { children: [" ", note] }) : null] }), _jsx("div", { className: "settings-ui-inert-control", inert: true, children: children })] }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=ComingSoonPanel.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useImagePreviewModal } from "./ImagePreviewModal.hooks.js";
|
|
2
|
+
export interface ImagePreviewModalProps {
|
|
3
|
+
open: boolean;
|
|
4
|
+
src: string;
|
|
5
|
+
alt: string;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
/** A fake controller can exercise rendering without a real native-dialog lifecycle. */
|
|
8
|
+
useModal?: typeof useImagePreviewModal | undefined;
|
|
9
|
+
/** Optional tagging preserves existing untagged renders when no agent handle is supplied. */
|
|
10
|
+
agentHandle?: string | undefined;
|
|
11
|
+
/** No locale is owned here; a translated caller must pass its own accessible close label. */
|
|
12
|
+
closeLabel?: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
/** Controlled native-dialog lightbox. The host supplies image copy and a translated close label. */
|
|
15
|
+
export declare function ImagePreviewModal({ open, src, alt, onClose, useModal, agentHandle: handle, closeLabel, }: ImagePreviewModalProps): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=ImagePreviewModal.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type MouseEvent, type SyntheticEvent } from "react";
|
|
2
|
+
export interface ImagePreviewModalController {
|
|
3
|
+
dialogRef: React.RefObject<HTMLDialogElement | null>;
|
|
4
|
+
/** Prevent native Escape-close and route through onClose; the open prop/effect owns lifecycle. */
|
|
5
|
+
handleNativeCancel: (e: SyntheticEvent<HTMLDialogElement>) => void;
|
|
6
|
+
/** The dialog box is content-sized: a target on the dialog itself, rather than a child, is backdrop. */
|
|
7
|
+
handleBackdropClick: (e: MouseEvent<HTMLDialogElement>) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function useImagePreviewModal({ open, onClose }: {
|
|
10
|
+
open: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}): ImagePreviewModalController;
|
|
13
|
+
//# sourceMappingURL=ImagePreviewModal.hooks.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Isolate native dialog lifecycle in an injectable hook so rendering can use a fake controller.
|
|
4
|
+
* showModal/close are synchronous browser APIs: no async port or disposed-after-unmount guard
|
|
5
|
+
* is needed. Separate helpers keep each fallback branch shallow rather than nesting in the effect.
|
|
6
|
+
*/
|
|
7
|
+
/** Idempotent native open; the attribute fallback supports DOM environments without showModal. */
|
|
8
|
+
function openDialog(dialog) {
|
|
9
|
+
if (typeof dialog.showModal === "function") {
|
|
10
|
+
if (!dialog.open)
|
|
11
|
+
dialog.showModal();
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
dialog.setAttribute("open", "");
|
|
15
|
+
}
|
|
16
|
+
/** Mirror the attribute fallback where a DOM environment has no native close method. */
|
|
17
|
+
function closeDialog(dialog) {
|
|
18
|
+
if (typeof dialog.close === "function") {
|
|
19
|
+
if (dialog.open)
|
|
20
|
+
dialog.close();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
dialog.removeAttribute("open");
|
|
24
|
+
}
|
|
25
|
+
export function useImagePreviewModal({ open, onClose }) {
|
|
26
|
+
const dialogRef = useRef(null);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const dialog = dialogRef.current;
|
|
29
|
+
if (!dialog)
|
|
30
|
+
return;
|
|
31
|
+
if (open)
|
|
32
|
+
openDialog(dialog);
|
|
33
|
+
else
|
|
34
|
+
closeDialog(dialog);
|
|
35
|
+
}, [open]);
|
|
36
|
+
function handleNativeCancel(e) {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
onClose();
|
|
39
|
+
}
|
|
40
|
+
function handleBackdropClick(e) {
|
|
41
|
+
if (e.target === dialogRef.current)
|
|
42
|
+
onClose();
|
|
43
|
+
}
|
|
44
|
+
return { dialogRef, handleNativeCancel, handleBackdropClick };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=ImagePreviewModal.hooks.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle } from "@jini-ai/agentic";
|
|
3
|
+
import { useImagePreviewModal } from "./ImagePreviewModal.hooks.js";
|
|
4
|
+
// Native dialog supplies focus trapping, Escape and a backdrop through the browser's top layer,
|
|
5
|
+
// avoiding a hand-built overlay and z-index policy. A confirm/cancel dialog's two-action contract
|
|
6
|
+
// does not fit a read-only image with one close affordance. The injectable hook owns lifecycle
|
|
7
|
+
// and DOM-environment fallbacks so this component stays focused on rendering.
|
|
8
|
+
/** Controlled native-dialog lightbox. The host supplies image copy and a translated close label. */
|
|
9
|
+
export function ImagePreviewModal({ open, src, alt, onClose, useModal = useImagePreviewModal, agentHandle: handle, closeLabel = "Close preview", }) {
|
|
10
|
+
const { dialogRef, handleNativeCancel, handleBackdropClick } = useModal({ open, onClose });
|
|
11
|
+
return (_jsxs("dialog", { ref: dialogRef, className: "image-preview-modal", "aria-label": alt, onCancel: handleNativeCancel, onClick: handleBackdropClick, children: [_jsx("button", { type: "button", className: "image-preview-modal-close", onClick: onClose, "aria-label": closeLabel, ...(handle ? agentHandle({ handle: handle }, { role: "button", label: closeLabel }) : {}), children: "\u00D7" }), _jsx("img", { src: src, alt: alt })] }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ImagePreviewModal.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useInfoTip } from "./InfoTip.hooks.js";
|
|
2
|
+
/**
|
|
3
|
+
* Native title tooltips have an OS-dependent hover delay, inconsistent screen-reader exposure
|
|
4
|
+
* and no touch visibility. Hover/focus opens this affordance; Escape dismisses without moving
|
|
5
|
+
* focus, which onBlur alone cannot do.
|
|
6
|
+
* A body portal escapes overflow:hidden/scrolling ancestors: z-index cannot rescue an absolutely
|
|
7
|
+
* positioned descendant from clipping. Measured viewport coordinates position it above by
|
|
8
|
+
* preference, with the hook's headroom guard choosing below near the viewport's top.
|
|
9
|
+
* Keep state and DOM measurement in the injectable hook so rendering can use fixed fake state.
|
|
10
|
+
*/
|
|
11
|
+
export interface InfoTipProps {
|
|
12
|
+
label: string;
|
|
13
|
+
useTip?: typeof useInfoTip | undefined;
|
|
14
|
+
agentHandle?: string | undefined;
|
|
15
|
+
}
|
|
16
|
+
/** Focus/hover tooltip that portals outside clipping ancestors; Escape dismisses in place. */
|
|
17
|
+
export declare function InfoTip({ label, useTip, agentHandle: handle }: InfoTipProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=InfoTip.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type KeyboardEvent } from "react";
|
|
2
|
+
export interface InfoTipController {
|
|
3
|
+
open: boolean;
|
|
4
|
+
placement: "above" | "below";
|
|
5
|
+
coords: {
|
|
6
|
+
top: number;
|
|
7
|
+
left: number;
|
|
8
|
+
};
|
|
9
|
+
iconRef: React.RefObject<HTMLSpanElement | null>;
|
|
10
|
+
show: () => void;
|
|
11
|
+
hide: () => void;
|
|
12
|
+
/** Escape closes in place; blur only covers leaving the trigger with Tab/Shift+Tab. */
|
|
13
|
+
handleIconKeyDown: (e: KeyboardEvent<HTMLSpanElement>) => void;
|
|
14
|
+
}
|
|
15
|
+
export declare function useInfoTip(): InfoTipController;
|
|
16
|
+
//# sourceMappingURL=InfoTip.hooks.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useRef, useState } from "react";
|
|
2
|
+
/** Separate the hook for injectable rendering state. Its only outside effect is synchronous DOM
|
|
3
|
+
* measurement, so another async dependency/port layer would provide no rejection seam to test. */
|
|
4
|
+
/** Above is a preference: require this much headroom before allowing an above-opening bubble. */
|
|
5
|
+
const ABOVE_HEADROOM_PX = 176;
|
|
6
|
+
/** Half the bubble's 18rem CSS max-width at a 16px root font. This worst-case width keeps narrow
|
|
7
|
+
* copy safe too. Pure icon-centering previously placed half a tip offscreen near a viewport edge. */
|
|
8
|
+
const HALF_MAX_BUBBLE_WIDTH_PX = 144;
|
|
9
|
+
/** Keep breathing room between the clamped bubble and either viewport edge. */
|
|
10
|
+
const EDGE_MARGIN_PX = 8;
|
|
11
|
+
/** Below 304px the clamp's minimum exceeds its maximum; center instead of using an inverted range. */
|
|
12
|
+
function clampBubbleLeft(idealLeft) {
|
|
13
|
+
const minLeft = EDGE_MARGIN_PX + HALF_MAX_BUBBLE_WIDTH_PX;
|
|
14
|
+
const maxLeft = window.innerWidth - EDGE_MARGIN_PX - HALF_MAX_BUBBLE_WIDTH_PX;
|
|
15
|
+
if (maxLeft < minLeft)
|
|
16
|
+
return window.innerWidth / 2;
|
|
17
|
+
return Math.min(Math.max(idealLeft, minLeft), maxLeft);
|
|
18
|
+
}
|
|
19
|
+
export function useInfoTip() {
|
|
20
|
+
const [open, setOpen] = useState(false);
|
|
21
|
+
const [placement, setPlacement] = useState("above");
|
|
22
|
+
const [coords, setCoords] = useState({ top: 0, left: 0 });
|
|
23
|
+
const iconRef = useRef(null);
|
|
24
|
+
const show = () => {
|
|
25
|
+
const rect = iconRef.current?.getBoundingClientRect();
|
|
26
|
+
if (!rect)
|
|
27
|
+
return;
|
|
28
|
+
const nextPlacement = rect.top < ABOVE_HEADROOM_PX ? "below" : "above";
|
|
29
|
+
setPlacement(nextPlacement);
|
|
30
|
+
setCoords({
|
|
31
|
+
top: nextPlacement === "above" ? rect.top : rect.bottom,
|
|
32
|
+
left: clampBubbleLeft(rect.left + rect.width / 2),
|
|
33
|
+
});
|
|
34
|
+
setOpen(true);
|
|
35
|
+
};
|
|
36
|
+
const hide = () => setOpen(false);
|
|
37
|
+
function handleIconKeyDown(e) {
|
|
38
|
+
if (e.key === "Escape" && open) {
|
|
39
|
+
e.stopPropagation();
|
|
40
|
+
hide();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return { open, placement, coords, iconRef, show, hide, handleIconKeyDown };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=InfoTip.hooks.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import { agentHandle } from "@jini-ai/agentic";
|
|
4
|
+
import { useInfoTip } from "./InfoTip.hooks.js";
|
|
5
|
+
/** Focus/hover tooltip that portals outside clipping ancestors; Escape dismisses in place. */
|
|
6
|
+
export function InfoTip({ label, useTip = useInfoTip, agentHandle: handle }) {
|
|
7
|
+
const { open, placement, coords, iconRef, show, hide, handleIconKeyDown } = useTip();
|
|
8
|
+
return (_jsxs("span", { className: "info-tip", children: [_jsx("span", { ref: iconRef, className: "info-tip-icon", tabIndex: 0, "aria-label": label, onMouseEnter: show, onMouseLeave: hide, onFocus: show, onBlur: hide, onKeyDown: handleIconKeyDown, ...(handle ? agentHandle({ handle: handle }, { role: "button", label }) : {}), children: "\u24D8" }), open
|
|
9
|
+
? createPortal(_jsx("span", { className: placement === "below" ? "info-tip-bubble info-tip-bubble-below" : "info-tip-bubble", role: "presentation", "aria-hidden": "true", style: { top: coords.top, left: coords.left }, children: label }), document.body)
|
|
10
|
+
: null] }));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=InfoTip.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useSeeMoreClamp } from "./SeeMore.hooks.js";
|
|
2
|
+
/**
|
|
3
|
+
* Clamp the rendered region instead of slicing children: hidden text must stay in the DOM so
|
|
4
|
+
* browser find and screen readers can still reach it. Truncating the string loses that content.
|
|
5
|
+
* State and DOM measurement live in the separate hook, keeping presentation independently
|
|
6
|
+
* renderable with an injected measurement seam and no real layout engine or ResizeObserver.
|
|
7
|
+
*/
|
|
8
|
+
export interface SeeMoreProps {
|
|
9
|
+
children: React.ReactNode;
|
|
10
|
+
lines?: number | undefined;
|
|
11
|
+
moreLabel?: string | undefined;
|
|
12
|
+
lessLabel?: string | undefined;
|
|
13
|
+
className?: string | undefined;
|
|
14
|
+
/** Keep caller typography on the text region; clamp mechanics should not dictate color or line-height. */
|
|
15
|
+
textClassName?: string | undefined;
|
|
16
|
+
toggleClassName?: string | undefined;
|
|
17
|
+
/** Distinguish repeated toggles in a screen reader's button list; expanded/controls are always set. */
|
|
18
|
+
toggleAriaLabel?: string | undefined;
|
|
19
|
+
/** Supply a fake measurement hook when rendering without real scrollHeight/clientHeight layout. */
|
|
20
|
+
useClamp?: typeof useSeeMoreClamp | undefined;
|
|
21
|
+
/** The handle identifies a rendered toggle only; fitting content has no control to address. */
|
|
22
|
+
agentHandle?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface SeeMoreView {
|
|
25
|
+
wrapperClassName: string;
|
|
26
|
+
textClassName: string;
|
|
27
|
+
toggleClassName: string;
|
|
28
|
+
toggleLabel: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveSeeMoreView({ expanded, }: {
|
|
31
|
+
expanded: boolean;
|
|
32
|
+
}, { moreLabel, lessLabel, className, textClassName, toggleClassName, }?: {
|
|
33
|
+
moreLabel?: string | undefined;
|
|
34
|
+
lessLabel?: string | undefined;
|
|
35
|
+
className?: string | undefined;
|
|
36
|
+
textClassName?: string | undefined;
|
|
37
|
+
toggleClassName?: string | undefined;
|
|
38
|
+
}): SeeMoreView;
|
|
39
|
+
/** Clamps overflowing text and exposes an accessible expand/collapse toggle. Labels are host-owned. */
|
|
40
|
+
export declare function SeeMore({ useClamp, agentHandle: handle, ...props }: SeeMoreProps): import("react").JSX.Element;
|
|
41
|
+
//# sourceMappingURL=SeeMore.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Separate measurement from JSX so callers can substitute a hook without a real layout engine.
|
|
2
|
+
* children participates in layout measurement so content changes are noticed as well as width reflow. */
|
|
3
|
+
export declare function useSeeMoreClamp({ lines, children }: {
|
|
4
|
+
lines: number;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}): {
|
|
7
|
+
expanded: boolean;
|
|
8
|
+
setExpanded: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
9
|
+
overflows: boolean;
|
|
10
|
+
textRef: import("react").RefObject<HTMLDivElement | null>;
|
|
11
|
+
regionId: string;
|
|
12
|
+
lineCount: number;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=SeeMore.hooks.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
2
|
+
/** Sub-pixel line-height rounding can make fitting text report a tiny overflow.
|
|
3
|
+
* One pixel avoids showing an expand control for an already visible single line. */
|
|
4
|
+
const OVERFLOW_TOLERANCE_PX = 1;
|
|
5
|
+
/** Separate measurement from JSX so callers can substitute a hook without a real layout engine.
|
|
6
|
+
* children participates in layout measurement so content changes are noticed as well as width reflow. */
|
|
7
|
+
export function useSeeMoreClamp({ lines, children }) {
|
|
8
|
+
// Collapsed by default, per the request that created this component.
|
|
9
|
+
const [expanded, setExpanded] = useState(false);
|
|
10
|
+
const [overflows, setOverflows] = useState(false);
|
|
11
|
+
const textRef = useRef(null);
|
|
12
|
+
const regionId = useId();
|
|
13
|
+
const lineCount = Math.max(1, Math.round(lines));
|
|
14
|
+
const measure = useCallback(() => {
|
|
15
|
+
const el = textRef.current;
|
|
16
|
+
if (!el)
|
|
17
|
+
return;
|
|
18
|
+
setOverflows(el.scrollHeight > el.clientHeight + OVERFLOW_TOLERANCE_PX);
|
|
19
|
+
}, []);
|
|
20
|
+
// Both measuring effects bail while expanded, and that is the whole design rather than an
|
|
21
|
+
// oversight: expanding removes the clamp, at which point `scrollHeight === clientHeight` by
|
|
22
|
+
// definition and the check would report "does not overflow" for text that plainly does — which
|
|
23
|
+
// would unmount the toggle and strand the user in the expanded state with no way back. So
|
|
24
|
+
// `overflows` deliberately goes stale while expanded and is re-measured the moment it collapses.
|
|
25
|
+
// The visible consequence is narrow and self-correcting: if the children change while expanded so
|
|
26
|
+
// that they no longer overflow, the toggle lingers until the next collapse, then disappears with
|
|
27
|
+
// the (now fully visible) text.
|
|
28
|
+
//
|
|
29
|
+
// `useLayoutEffect` so the toggle's presence is settled before paint — a `useEffect` here shows
|
|
30
|
+
// one frame of clamped text with no way to expand it, then pops the button in.
|
|
31
|
+
useLayoutEffect(() => {
|
|
32
|
+
if (expanded)
|
|
33
|
+
return;
|
|
34
|
+
measure();
|
|
35
|
+
// `children` is a fresh object on every parent render, so this re-runs whenever the host
|
|
36
|
+
// re-renders (the first caller is a dialog that re-renders on each keystroke). That is two DOM
|
|
37
|
+
// reads, deliberately accepted: the alternative is missing a genuine content change. The
|
|
38
|
+
// `ResizeObserver` below is the expensive thing, and it is kept out of this dependency list.
|
|
39
|
+
}, [expanded, lineCount, children, measure]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (expanded)
|
|
42
|
+
return;
|
|
43
|
+
const el = textRef.current;
|
|
44
|
+
// Guarded rather than assumed, the same way `Select.tsx` guards `elementFromPoint` and
|
|
45
|
+
// `scrollIntoView`: this app's jsdom test harness implements no `ResizeObserver` at all, so an
|
|
46
|
+
// unguarded `new ResizeObserver` throws on mount in every test that renders this component.
|
|
47
|
+
// Where it is missing, the layout effect above still measures on mount and on content change —
|
|
48
|
+
// only reflow-from-width-change goes unnoticed, which jsdom has no layout engine to produce.
|
|
49
|
+
if (!el || typeof ResizeObserver !== "function")
|
|
50
|
+
return;
|
|
51
|
+
const observer = new ResizeObserver(() => measure());
|
|
52
|
+
observer.observe(el);
|
|
53
|
+
return () => observer.disconnect();
|
|
54
|
+
}, [expanded, measure]);
|
|
55
|
+
return { expanded, setExpanded, overflows, textRef, regionId, lineCount };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=SeeMore.hooks.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { agentHandle } from "@jini-ai/agentic";
|
|
3
|
+
import { useSeeMoreClamp } from "./SeeMore.hooks.js";
|
|
4
|
+
const DEFAULT_LINES = 2;
|
|
5
|
+
// Presentation depends only on props and expanded state, so this decision needs no React render.
|
|
6
|
+
export function resolveSeeMoreView({ expanded, }, { moreLabel = "See more", lessLabel = "See less", className, textClassName, toggleClassName, } = {}) {
|
|
7
|
+
return {
|
|
8
|
+
wrapperClassName: className ? `see-more ${className}` : "see-more",
|
|
9
|
+
textClassName: `see-more-text${expanded ? " is-expanded" : ""}${textClassName ? ` ${textClassName}` : ""}`,
|
|
10
|
+
toggleClassName: toggleClassName ? `see-more-toggle ${toggleClassName}` : "see-more-toggle",
|
|
11
|
+
toggleLabel: expanded ? lessLabel : moreLabel,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** Clamps overflowing text and exposes an accessible expand/collapse toggle. Labels are host-owned. */
|
|
15
|
+
export function SeeMore({ useClamp = useSeeMoreClamp, agentHandle: handle, ...props }) {
|
|
16
|
+
const { children, lines = DEFAULT_LINES, moreLabel, lessLabel, className, textClassName, toggleClassName, toggleAriaLabel } = props;
|
|
17
|
+
const { expanded, setExpanded, overflows, textRef, regionId, lineCount } = useClamp({ lines, children });
|
|
18
|
+
const view = resolveSeeMoreView({ expanded }, { moreLabel, lessLabel, className, textClassName, toggleClassName });
|
|
19
|
+
return (_jsxs("div", { className: view.wrapperClassName, children: [_jsx("div", { ref: textRef, id: regionId, className: view.textClassName,
|
|
20
|
+
// The line count rides a custom property rather than a class-per-N (`.see-more-text--3`),
|
|
21
|
+
// so `lines` can be any integer a caller needs without this file growing a rule for each.
|
|
22
|
+
style: { "--see-more-lines": lineCount }, children: children }), overflows ? (_jsx("button", { type: "button", className: view.toggleClassName, "aria-expanded": expanded, "aria-controls": regionId, "aria-label": toggleAriaLabel, onClick: () => setExpanded((current) => !current), ...(handle ? agentHandle({ handle: handle }, { role: "button", label: toggleAriaLabel ?? view.toggleLabel }) : {}), children: view.toggleLabel })) : null] }));
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=SeeMore.js.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Translate } from "../../../i18n/dictionary-translator.js";
|
|
2
|
+
import { useSelectDropdown, type SelectOption } from "./Select.hooks.js";
|
|
3
|
+
export type { SelectOption };
|
|
4
|
+
/** Use this custom listbox when in-panel search is needed: a native OS option list cannot host it.
|
|
5
|
+
* Native selects otherwise avoid the accessibility/behavior tradeoffs of a simulated listbox.
|
|
6
|
+
* JSX stays separate from dropdown state/DOM effects so injected useDropdown can render against a
|
|
7
|
+
* fake without geometry or listeners. The body portal escapes clipping/stacking ancestors.
|
|
8
|
+
* Agent selection uses trigger/option clicks rather than native select_option; the -option namespace
|
|
9
|
+
* keeps caller values from colliding with literal segments. Explicit base handles are not silently
|
|
10
|
+
* sanitized: invalid caller choices should fail rather than publish a different handle. */
|
|
11
|
+
export interface SelectProps {
|
|
12
|
+
value: string;
|
|
13
|
+
onChange: (value: string) => void;
|
|
14
|
+
options: SelectOption[];
|
|
15
|
+
placeholder?: string | undefined;
|
|
16
|
+
id?: string | undefined;
|
|
17
|
+
"aria-label"?: string | undefined;
|
|
18
|
+
"aria-labelledby"?: string | undefined;
|
|
19
|
+
disabled?: boolean | undefined;
|
|
20
|
+
/** Injectable state/effect seam; rendering tests need not drive portal positioning or listeners. */
|
|
21
|
+
useDropdown?: typeof useSelectDropdown | undefined;
|
|
22
|
+
agentHandle?: string | undefined;
|
|
23
|
+
/** Caller-bound translation function; source copy is the default. */
|
|
24
|
+
translate?: Translate | undefined;
|
|
25
|
+
/** Legacy alias for callers porting the original select. */
|
|
26
|
+
t?: Translate | undefined;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveSelectTriggerLabel({ selectedOption, placeholder }: {
|
|
29
|
+
selectedOption: SelectOption | null;
|
|
30
|
+
placeholder: string | undefined;
|
|
31
|
+
}, { t }?: {
|
|
32
|
+
t?: Translate | undefined;
|
|
33
|
+
}): {
|
|
34
|
+
text: string;
|
|
35
|
+
className: string;
|
|
36
|
+
};
|
|
37
|
+
/** Controlled searchable listbox with portal positioning and keyboard navigation. */
|
|
38
|
+
export declare function Select(props: SelectProps): import("react").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=Select.d.ts.map
|