rift-ds 1.9.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/behaviors/useFocusScope.d.ts +12 -6
- package/behaviors/useFocusScope.js +12 -2
- package/behaviors/useLayer.d.ts +39 -15
- package/behaviors/useLayer.js +23 -11
- package/bin/templates/chat/app/api/chat/route.ts +3 -0
- package/chat/AssistantTurn.d.ts +18 -1
- package/chat/AssistantTurn.js +25 -5
- package/chat/ChatAgentPane.d.ts +22 -4
- package/chat/ChatAgentPane.js +20 -6
- package/chat/ChatArtifactPane.d.ts +16 -1
- package/chat/ChatArtifactPane.js +12 -10
- package/chat/ChatLauncher.d.ts +12 -5
- package/chat/ChatLauncher.js +3 -1
- package/chat/ChatProvider.d.ts +5 -4
- package/chat/ChatProvider.js +1 -1
- package/chat/ChatTabs.d.ts +6 -1
- package/chat/ChatTabs.js +3 -2
- package/chat/ChatThreads.d.ts +19 -4
- package/chat/ChatThreads.js +22 -3
- package/chat/ChatWidget.css +5 -4
- package/chat/ChatWidget.d.ts +119 -5
- package/chat/ChatWidget.js +159 -70
- package/chat/DemoWelcome.js +17 -5
- package/chat/FollowupSuggestions.d.ts +10 -4
- package/chat/FollowupSuggestions.js +13 -5
- package/chat/ResponseActions.d.ts +14 -0
- package/chat/ResponseActions.js +15 -6
- package/chat/TurnQuestion.d.ts +24 -0
- package/chat/TurnQuestion.js +46 -0
- package/chat/demo-card-components.js +2 -1
- package/chat/demo-script.js +256 -50
- package/chat/followups.d.ts +2 -2
- package/chat/followups.js +1 -0
- package/chat/index.d.ts +3 -2
- package/chat/index.js +11 -0
- package/chat/queries.d.ts +2 -2
- package/chat/queries.js +3 -2
- package/chat/questions.d.ts +97 -0
- package/chat/questions.js +140 -0
- package/chat/registry.json.d.ts +3 -2
- package/chat/registry.json.js +1 -1
- package/chat/server.d.ts +19 -0
- package/chat/server.js +45 -1
- package/chat/sim.d.ts +12 -1
- package/chat/sim.js +19 -3
- package/chat/threads.d.ts +17 -0
- package/chat/threads.js +22 -14
- package/chat/types.d.ts +58 -1
- package/chat/types.js +1 -0
- package/chat/useChat.d.ts +24 -3
- package/chat/useChat.js +42 -4
- package/components/Accordion/Accordion.d.ts +18 -3
- package/components/Accordion/Accordion.js +71 -69
- package/components/AgentPlan/AgentPlan.d.ts +16 -0
- package/components/AgentPlan/AgentPlan.js +8 -3
- package/components/AgentRail/AgentRail.d.ts +24 -4
- package/components/AgentRail/AgentRail.js +13 -6
- package/components/AgentStatus/AgentStatus.css +1 -0
- package/components/AiButton/AiButton.css +3 -1
- package/components/AiButton/AiButton.d.ts +7 -1
- package/components/AiButton/AiButton.js +6 -3
- package/components/Alert/Alert.d.ts +15 -4
- package/components/Alert/Alert.js +46 -40
- package/components/AlertDialog/AlertDialog.css +1 -1
- package/components/AlertDialog/AlertDialog.d.ts +21 -5
- package/components/AlertDialog/AlertDialog.js +34 -15
- package/components/AnchorNav/AnchorNav.css +1 -1
- package/components/AnchorNav/AnchorNav.d.ts +4 -1
- package/components/AnchorNav/AnchorNav.js +8 -8
- package/components/AppLayout/AppLayout.d.ts +10 -2
- package/components/AppLayout/AppLayout.js +55 -42
- package/components/AppSidebar/AppSidebar.css +9 -9
- package/components/AppSidebar/AppSidebar.d.ts +27 -2
- package/components/AppSidebar/AppSidebar.js +30 -15
- package/components/ArtifactPanel/ArtifactPanel.d.ts +3 -0
- package/components/ArtifactPanel/ArtifactPanel.js +6 -5
- package/components/Attachment/Attachment.css +4 -1
- package/components/Attachment/AttachmentGroup.d.ts +6 -0
- package/components/Attachment/AttachmentGroup.js +10 -1
- package/components/Attachment/AttachmentTile.d.ts +2 -0
- package/components/Attachment/AttachmentTile.js +3 -2
- package/components/Attachment/AttachmentViewer.js +4 -4
- package/components/Attachment/fileTypes.d.ts +8 -0
- package/components/Avatar/Avatar.css +3 -3
- package/components/Avatar/Avatar.d.ts +11 -3
- package/components/Avatar/Avatar.js +56 -51
- package/components/AvatarGroup/AvatarGroup.css +3 -3
- package/components/AvatarGroup/AvatarGroup.d.ts +6 -3
- package/components/AvatarGroup/AvatarGroup.js +5 -2
- package/components/Badge/Badge.d.ts +9 -2
- package/components/Badge/Badge.js +10 -10
- package/components/Banner/Banner.d.ts +2 -0
- package/components/Banner/Banner.js +2 -1
- package/components/BentoTile/BentoTile.css +527 -0
- package/components/BentoTile/BentoTile.d.ts +64 -0
- package/components/BentoTile/BentoTile.js +303 -0
- package/components/BentoTile/BentoTileArt.d.ts +28 -0
- package/components/BentoTile/BentoTileArt.js +19 -0
- package/components/BottomNav/BottomNav.css +3 -3
- package/components/BottomNav/BottomNav.d.ts +6 -0
- package/components/BottomNav/BottomNav.js +3 -1
- package/components/Breadcrumb/Breadcrumb.d.ts +16 -5
- package/components/Breadcrumb/Breadcrumb.js +32 -33
- package/components/Button/Button.css +123 -20
- package/components/Button/Button.d.ts +18 -3
- package/components/Button/Button.js +19 -2
- package/components/ButtonGroup/ButtonGroup.d.ts +17 -3
- package/components/ButtonGroup/ButtonGroup.js +24 -24
- package/components/CardStack/CardStack.d.ts +5 -0
- package/components/CardStack/CardStack.js +3 -7
- package/components/Carousel/Carousel.d.ts +33 -3
- package/components/Carousel/Carousel.js +178 -137
- package/components/Chart/AreaChart.d.ts +11 -3
- package/components/Chart/AreaChart.js +20 -11
- package/components/Chart/BarChart.d.ts +11 -3
- package/components/Chart/BarChart.js +19 -9
- package/components/Chart/Chart.css +1 -0
- package/components/Chart/ComboChart.d.ts +11 -3
- package/components/Chart/ComboChart.js +21 -11
- package/components/Chart/LineChart.d.ts +11 -3
- package/components/Chart/LineChart.js +19 -10
- package/components/Chart/PieChart.d.ts +11 -3
- package/components/Chart/PieChart.js +18 -9
- package/components/Chart/RadarChart.d.ts +11 -3
- package/components/Chart/RadarChart.js +20 -11
- package/components/Chart/RadialChart.d.ts +11 -3
- package/components/Chart/RadialChart.js +18 -9
- package/components/Chart/ScatterChart.d.ts +11 -3
- package/components/Chart/ScatterChart.js +23 -11
- package/components/Chart/StackedBarChart.d.ts +11 -3
- package/components/Chart/StackedBarChart.js +19 -10
- package/components/Chart/Treemap.d.ts +13 -3
- package/components/Chart/Treemap.js +23 -13
- package/components/Chart/palette.d.ts +9 -0
- package/components/Chart/palette.js +8 -1
- package/components/Chart/useChartAnimation.d.ts +42 -0
- package/components/Chart/useChartAnimation.js +32 -0
- package/components/ChatMessage/ChatMessage.css +1 -0
- package/components/ChatThread/ChatThread.css +21 -0
- package/components/ChatThread/ChatThread.d.ts +12 -1
- package/components/ChatThread/ChatThread.js +48 -1
- package/components/Checkbox/Checkbox.d.ts +12 -2
- package/components/Checkbox/Checkbox.js +13 -3
- package/components/Chip/Chip.css +24 -1
- package/components/Chip/Chip.d.ts +28 -7
- package/components/Chip/Chip.js +80 -64
- package/components/CircularButton/CircularButton.css +127 -1
- package/components/CircularButton/CircularButton.d.ts +18 -4
- package/components/CircularButton/CircularButton.js +14 -2
- package/components/CodeBlock/CodeBlock.d.ts +24 -3
- package/components/CodeBlock/CodeBlock.js +93 -80
- package/components/CodeDiff/CodeDiff.d.ts +30 -4
- package/components/CodeDiff/CodeDiff.js +64 -20
- package/components/ColorPicker/ColorPicker.css +1 -1
- package/components/ColorPicker/ColorPicker.d.ts +18 -0
- package/components/ColorPicker/ColorPicker.js +27 -21
- package/components/ColourSwatch/ColourSwatch.css +1 -1
- package/components/Combobox/Combobox.css +2 -1
- package/components/Combobox/Combobox.d.ts +26 -8
- package/components/Combobox/Combobox.js +30 -17
- package/components/CommandPalette/CommandPalette.css +13 -1
- package/components/CommandPalette/CommandPalette.d.ts +27 -4
- package/components/CommandPalette/CommandPalette.js +108 -70
- package/components/Composer/Composer.css +2 -1
- package/components/Composer/Composer.d.ts +10 -0
- package/components/Composer/Composer.js +7 -0
- package/components/ContactCard/ContactCard.css +1 -1
- package/components/ContactCard/ContactCard.d.ts +34 -5
- package/components/ContactCard/ContactCard.js +72 -58
- package/components/ContextMenu/ContextMenu.css +4 -4
- package/components/ContextMenu/ContextMenu.js +7 -10
- package/components/ContributionGraph/ContributionGraph.d.ts +37 -3
- package/components/ContributionGraph/ContributionGraph.js +32 -31
- package/components/DataTable/DataTable.d.ts +29 -0
- package/components/DataTable/DataTable.js +15 -10
- package/components/DateInput/DateInput.js +2 -2
- package/components/DatePicker/DatePicker.css +19 -4
- package/components/DatePicker/DatePicker.d.ts +31 -0
- package/components/DatePicker/DatePicker.js +145 -61
- package/components/Dialog/Dialog.css +1 -1
- package/components/Dialog/Dialog.d.ts +2 -0
- package/components/Dialog/Dialog.js +4 -3
- package/components/Divider/Divider.d.ts +10 -2
- package/components/Divider/Divider.js +56 -25
- package/components/DocumentChip/DocumentChip.d.ts +3 -1
- package/components/DocumentChip/DocumentChip.js +3 -2
- package/components/Drawer/Drawer.css +2 -1
- package/components/Drawer/Drawer.d.ts +2 -0
- package/components/Drawer/Drawer.js +4 -3
- package/components/Dropdown/Dropdown.css +1 -1
- package/components/Dropdown/Dropdown.d.ts +9 -2
- package/components/Dropdown/Dropdown.js +26 -16
- package/components/DropdownMenu/DropdownMenu.css +5 -5
- package/components/DropdownMenu/DropdownMenu.d.ts +13 -4
- package/components/DropdownMenu/DropdownMenu.js +41 -22
- package/components/EmptyState/EmptyState.d.ts +12 -4
- package/components/EmptyState/EmptyState.js +30 -26
- package/components/EntityCard/EntityCard.d.ts +7 -2
- package/components/EntityCard/EntityCard.js +19 -21
- package/components/EventCalendar/EventCalendar.d.ts +28 -0
- package/components/EventCalendar/EventCalendar.js +29 -27
- package/components/Figure/Figure.d.ts +14 -5
- package/components/Figure/Figure.js +19 -21
- package/components/FileInput/FileInput.d.ts +6 -0
- package/components/FileInput/FileInput.js +9 -9
- package/components/FilterBar/FilterBar.css +3 -3
- package/components/FilterBar/FilterBar.d.ts +6 -1
- package/components/FilterBar/FilterBar.js +15 -11
- package/components/FunnelChart/FunnelChart.d.ts +13 -1
- package/components/FunnelChart/FunnelChart.js +8 -1
- package/components/GanttChart/GanttChart.css +1 -1
- package/components/GanttChart/GanttChart.d.ts +19 -2
- package/components/GanttChart/GanttChart.js +17 -8
- package/components/Gauge/Gauge.d.ts +4 -1
- package/components/Globe/Globe.css +23 -0
- package/components/Globe/Globe.d.ts +19 -2
- package/components/Globe/Globe.js +66 -19
- package/components/HoverCard/HoverCard.css +1 -1
- package/components/HoverCard/HoverCard.d.ts +4 -1
- package/components/HoverCard/HoverCard.js +26 -15
- package/components/ImageCompare/ImageCompare.d.ts +4 -0
- package/components/ImageCompare/ImageCompare.js +4 -2
- package/components/Input/Input.js +2 -2
- package/components/Inspector/Inspector.css +55 -38
- package/components/Inspector/InspectorDropdown.d.ts +6 -1
- package/components/Inspector/InspectorDropdown.js +2 -0
- package/components/Inspector/InspectorSegmentedControl.d.ts +4 -3
- package/components/Inspector/InspectorSegmentedControl.js +63 -11
- package/components/Inspector/InspectorToggleSwitch.d.ts +4 -3
- package/components/Inspector/InspectorToggleSwitch.js +35 -2
- package/components/Instructions/Instructions.css +1 -1
- package/components/Instructions/Instructions.d.ts +16 -5
- package/components/Instructions/Instructions.js +31 -26
- package/components/InterruptCard/InterruptCard.d.ts +13 -2
- package/components/InterruptCard/InterruptCard.js +9 -7
- package/components/Lightbox/Lightbox.css +1 -1
- package/components/Lightbox/Lightbox.d.ts +8 -0
- package/components/Lightbox/Lightbox.js +10 -6
- package/components/LinkList/LinkList.css +2 -2
- package/components/LinkList/LinkList.d.ts +11 -2
- package/components/LinkList/LinkList.js +40 -36
- package/components/Mention/Mention.d.ts +4 -1
- package/components/MessageActions/MessageActions.css +8 -0
- package/components/MessageActions/MessageActions.d.ts +2 -0
- package/components/MessageActions/MessageActions.js +2 -1
- package/components/MessageCard/MessageCard.d.ts +4 -1
- package/components/Meter/Meter.d.ts +5 -1
- package/components/ModelPicker/ModelPicker.css +2 -2
- package/components/ModelPicker/ModelPicker.d.ts +12 -1
- package/components/ModelPicker/ModelPicker.js +27 -16
- package/components/MotionSwatch/MotionSwatch.d.ts +3 -1
- package/components/MotionSwatch/MotionSwatch.js +2 -1
- package/components/Nav/Nav.d.ts +2 -2
- package/components/Nav/Nav.js +17 -21
- package/components/NavList/NavList.d.ts +4 -0
- package/components/NavList/NavList.js +3 -1
- package/components/NotificationCenter/NotificationCenter.css +1 -1
- package/components/NotificationCenter/NotificationCenter.d.ts +48 -5
- package/components/NotificationCenter/NotificationCenter.js +32 -15
- package/components/NumberInput/NumberInput.d.ts +4 -0
- package/components/NumberInput/NumberInput.js +4 -2
- package/components/Pagination/Pagination.d.ts +33 -7
- package/components/Pagination/Pagination.js +67 -55
- package/components/PinInput/PinInput.d.ts +6 -0
- package/components/PinInput/PinInput.js +3 -1
- package/components/Popover/Popover.css +1 -1
- package/components/Popover/Popover.d.ts +21 -5
- package/components/Popover/Popover.js +102 -97
- package/components/ProgressBar/ProgressBar.d.ts +10 -3
- package/components/ProgressBar/ProgressBar.js +34 -22
- package/components/PromptSuggestions/PromptSuggestions.css +67 -0
- package/components/PromptSuggestions/PromptSuggestions.d.ts +10 -0
- package/components/PromptSuggestions/PromptSuggestions.js +41 -26
- package/components/QuestionCard/QuestionCard.css +358 -0
- package/components/QuestionCard/QuestionCard.d.ts +138 -0
- package/components/QuestionCard/QuestionCard.js +378 -0
- package/components/Quote/Quote.d.ts +8 -3
- package/components/Quote/Quote.js +18 -21
- package/components/RadioButton/RadioButton.d.ts +6 -1
- package/components/RadioButton/RadioButton.js +7 -2
- package/components/Rating/Rating.d.ts +6 -0
- package/components/Rating/Rating.js +4 -2
- package/components/Reasoning/Reasoning.css +1 -0
- package/components/Reasoning/Reasoning.d.ts +7 -1
- package/components/Reasoning/Reasoning.js +4 -1
- package/components/RichDropdown/RichDropdown.css +1 -1
- package/components/RichDropdown/RichDropdown.d.ts +3 -1
- package/components/RichDropdown/RichDropdown.js +20 -15
- package/components/SectionTitle/SectionTitle.d.ts +15 -3
- package/components/SectionTitle/SectionTitle.js +15 -17
- package/components/SegmentedControl/SegmentedControl.css +3 -2
- package/components/SegmentedControl/SegmentedControl.d.ts +49 -7
- package/components/SegmentedControl/SegmentedControl.js +248 -223
- package/components/SelectionCard/SelectionCard.d.ts +7 -1
- package/components/SelectionCard/SelectionCard.js +16 -2
- package/components/ShaderField/ShaderField.js +2 -1
- package/components/ShaderField/useShaderField.js +3 -2
- package/components/SidebarPanel/SidebarPanel.d.ts +6 -1
- package/components/SidebarPanel/SidebarPanel.js +2 -1
- package/components/Skeleton/Skeleton.d.ts +12 -3
- package/components/Skeleton/Skeleton.js +53 -19
- package/components/Slider/Slider.d.ts +11 -2
- package/components/Slider/Slider.js +11 -6
- package/components/SourceChip/SourceChip.css +1 -1
- package/components/SourceChip/SourceChip.d.ts +5 -2
- package/components/SourceChip/SourceChip.js +14 -13
- package/components/SourceTrail/SourceTrail.d.ts +15 -0
- package/components/SourceTrail/SourceTrail.js +10 -4
- package/components/Sparkline/Sparkline.d.ts +4 -3
- package/components/Sparkline/Sparkline.js +2 -1
- package/components/Spinner/Spinner.d.ts +21 -4
- package/components/Spinner/Spinner.js +38 -37
- package/components/SplitButton/SplitButton.d.ts +10 -1
- package/components/SplitButton/SplitButton.js +13 -3
- package/components/Stat/Stat.d.ts +7 -2
- package/components/Stat/Stat.js +30 -25
- package/components/StatusDot/StatusDot.css +1 -0
- package/components/Stepper/Stepper.css +13 -0
- package/components/Stepper/Stepper.d.ts +6 -0
- package/components/Stepper/Stepper.js +2 -0
- package/components/StreamingText/StreamingText.d.ts +4 -4
- package/components/StreamingText/StreamingText.js +3 -2
- package/components/Tabs/Tabs.d.ts +41 -6
- package/components/Tabs/Tabs.js +99 -69
- package/components/TagInput/TagInput.d.ts +2 -0
- package/components/TagInput/TagInput.js +7 -2
- package/components/Textarea/Textarea.d.ts +6 -1
- package/components/Textarea/Textarea.js +11 -5
- package/components/ThreadPanel/ThreadPanel.css +1 -1
- package/components/ThreadPanel/ThreadPanel.d.ts +11 -4
- package/components/ThreadPanel/ThreadPanel.js +3 -1
- package/components/ThreadTabs/ThreadTabs.d.ts +7 -2
- package/components/ThreadTabs/ThreadTabs.js +1 -1
- package/components/TimePicker/TimePicker.css +1 -1
- package/components/TimePicker/TimePicker.d.ts +14 -1
- package/components/TimePicker/TimePicker.js +22 -17
- package/components/Timeline/Timeline.css +2 -2
- package/components/Timeline/Timeline.d.ts +11 -2
- package/components/Timeline/Timeline.js +37 -26
- package/components/Toast/Toast.css +2 -2
- package/components/Toast/Toast.d.ts +24 -6
- package/components/Toast/Toast.js +50 -41
- package/components/ToggleGroup/ToggleGroup.css +3 -2
- package/components/ToggleGroup/ToggleGroup.d.ts +26 -4
- package/components/ToggleGroup/ToggleGroup.js +12 -5
- package/components/ToggleSwitch/ToggleSwitch.d.ts +6 -1
- package/components/ToggleSwitch/ToggleSwitch.js +7 -2
- package/components/ToolCall/ToolCall.js +1 -1
- package/components/Tooltip/Tooltip.css +5 -5
- package/components/Tooltip/Tooltip.d.ts +15 -4
- package/components/Tooltip/Tooltip.js +80 -61
- package/components/TopAppBar/TopAppBar.css +1 -1
- package/components/TopAppBar/TopAppBar.d.ts +9 -1
- package/components/TopAppBar/TopAppBar.js +3 -1
- package/components/TypographySwatch/TypographySwatch.css +1 -1
- package/components/UsageCard/UsageCard.d.ts +4 -1
- package/components/Waveform/Waveform.css +1 -0
- package/components/Waveform/Waveform.d.ts +1 -1
- package/components/WorldMap/WorldMap.d.ts +12 -0
- package/components/WorldMap/WorldMap.js +11 -5
- package/components/registry.json +44 -19
- package/components/registry.json.d.ts +44 -19
- package/components/registry.json.js +1 -1
- package/index.d.ts +3 -0
- package/index.js +7 -0
- package/package.json +5 -1
- package/tokens/breakpoints.d.ts +60 -0
- package/tokens/breakpoints.js +92 -0
- package/tokens/motion.d.ts +14 -0
- package/tokens/motion.js +15 -1
- package/tokens/registry.d.ts +1 -1
- package/tokens/registry.json +21 -0
- package/tokens/registry.json.d.ts +21 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-dark.css +7 -0
- package/tokens/tokens-light.css +41 -0
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ An open source React design system built for AI products and coding agents: comp
|
|
|
13
13
|
|
|
14
14
|
## Why Rift DS
|
|
15
15
|
|
|
16
|
-
- **<!-- component-count -->
|
|
16
|
+
- **<!-- component-count -->155<!-- /component-count --> components.** Buttons, forms and tables through to charts, navigation and overlays, each typed and documented with live examples. Every one forwards a ref and your own attributes to its element, state you can own works controlled or uncontrolled (a modal opens when your app says so, by design), and every word a component writes has a prop you can localise. The build checks the first two on every component, and the words wherever they sit in markup. React and React DOM are the only required peer dependencies.
|
|
17
17
|
- **AI patterns, the whole chat and templates, ready to use.** Composer, streaming chat thread, tool calls, reasoning and thread panel are in the box, the complete AI chat ships assembled as one widget that one command scaffolds, and the docs site has complete template screens built from them.
|
|
18
18
|
- **Fully themeable.** The shipped themes are complete looks to start from, each in light and dark. One `data-brand` attribute applies a theme, and a few CSS overrides make your own.
|
|
19
19
|
- **Ready for coding agents.** One command installs the agent skills, and a public MCP endpoint serves every component's props, so your agent builds with the library as it actually is. No key, no account.
|
|
@@ -94,13 +94,13 @@ import 'rift-ds/tokens/presets/presets.css';
|
|
|
94
94
|
|
|
95
95
|
## Components
|
|
96
96
|
|
|
97
|
-
<!-- component-count -->
|
|
97
|
+
<!-- component-count -->155<!-- /component-count --> components, including a chat set for AI products (Chat thread, Composer, Tool call, Reasoning, Thread panel) and Shader field, a WebGL2 ambient background whose light sources read your colour tokens at runtime, so it re-themes with everything else. Details and live examples are on the [docs site](https://rift-ds.com/components).
|
|
98
98
|
|
|
99
99
|
<details>
|
|
100
100
|
<summary>The full list</summary>
|
|
101
101
|
|
|
102
102
|
<!-- component-list:start -->
|
|
103
|
-
Accordion · Agent plan · Agent rail · Agent status · AI button · Alert · Alert dialog · Anchor nav · Animated number · App layout · App sidebar · Area chart · Artifact card · Artifact panel · Attachment drop zone · Attachment group · Attachment tile · Attachment viewer · Avatar · Avatar group · Badge · Banner · Bar chart · Bottom nav · Breadcrumb · Button · Button group · Card · Card stack · Carousel · Chat header · Chat marker · Chat message · Chat thread · Checkbox · Chip · Circular button · Code block · Code diff · Colour picker · Combo chart · Combobox · Command palette · Composer · Contact card · Context menu · Contribution graph · Data table · Date input · Date picker · Dialog · Divider · Document chip · Drawer · Dropdown · Dropdown menu · Empty state · Entity card · Event calendar · Field · Figure · File input · Filter bar · Funnel chart · Gantt chart · Gauge · Globe · Hover card · Image compare · Input · Inspector colour picker · Inspector dropdown · Inspector input · Inspector section · Inspector segments · Inspector slider · Inspector toggle switch · Instructions · Interrupt card · Kbd · Legend tile · Lightbox · Line chart · Link list · Map callout · Map legend · Mention · Message actions · Message card · Meter · Model picker · Nav · Nav list · Notification centre · Number input · Pagination · Panel · Pie chart · Pin input · Pixel avatar · Popover · Progress bar · Prompt suggestions · Prose · Quote · Radar chart · Radial chart · Radio button · Rating · Reasoning · Rich dropdown · Scatter chart · Section title · Segmented control · Selection card · Shader field · Sidebar panel · Skeleton · Slider · Source chip · Source trail · Sparkline · Spinner · Split button · Split pane · Stacked bar chart · Stat · Status dot · Stepper · Streaming text · Swatch · Table · Tabs · Tag input · Textarea · Thread panel · Thread tabs · Time picker · Timeline · Toast · Toggle group · Toggle switch · Tool call · Toolbar · Tooltip · Top app bar · Tree view · Treemap · Usage card · Waveform · Widget · World map
|
|
103
|
+
Accordion · Agent plan · Agent rail · Agent status · AI button · Alert · Alert dialog · Anchor nav · Animated number · App layout · App sidebar · Area chart · Artifact card · Artifact panel · Attachment drop zone · Attachment group · Attachment tile · Attachment viewer · Avatar · Avatar group · Badge · Banner · Bar chart · Bento tile · Bento tile art · Bottom nav · Breadcrumb · Button · Button group · Card · Card stack · Carousel · Chat header · Chat marker · Chat message · Chat thread · Checkbox · Chip · Circular button · Code block · Code diff · Colour picker · Combo chart · Combobox · Command palette · Composer · Contact card · Context menu · Contribution graph · Data table · Date input · Date picker · Dialog · Divider · Document chip · Drawer · Dropdown · Dropdown menu · Empty state · Entity card · Event calendar · Field · Figure · File input · Filter bar · Funnel chart · Gantt chart · Gauge · Globe · Hover card · Image compare · Input · Inspector colour picker · Inspector dropdown · Inspector input · Inspector section · Inspector segments · Inspector slider · Inspector toggle switch · Instructions · Interrupt card · Kbd · Legend tile · Lightbox · Line chart · Link list · Map callout · Map legend · Mention · Message actions · Message card · Meter · Model picker · Nav · Nav list · Notification centre · Number input · Pagination · Panel · Pie chart · Pin input · Pixel avatar · Popover · Progress bar · Prompt suggestions · Prose · Question card · Quote · Radar chart · Radial chart · Radio button · Rating · Reasoning · Rich dropdown · Scatter chart · Section title · Segmented control · Selection card · Shader field · Sidebar panel · Skeleton · Slider · Source chip · Source trail · Sparkline · Spinner · Split button · Split pane · Stacked bar chart · Stat · Status dot · Stepper · Streaming text · Swatch · Table · Tabs · Tag input · Textarea · Thread panel · Thread tabs · Time picker · Timeline · Toast · Toggle group · Toggle switch · Tool call · Toolbar · Tooltip · Top app bar · Tree view · Treemap · Usage card · Waveform · Widget · World map
|
|
104
104
|
<!-- component-list:end -->
|
|
105
105
|
|
|
106
106
|
</details>
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
* Focus containment for modal overlays: initial focus, Tab wrapping, focus
|
|
3
3
|
* restore, and background isolation.
|
|
4
4
|
*
|
|
5
|
-
* Restore is guarded
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Restore is guarded twice. The element that opened a dialog can be gone by
|
|
6
|
+
* the time it closes (a row the dialog itself deleted), and it can still be in
|
|
7
|
+
* the document but hidden: a button inside a popover that closed underneath
|
|
8
|
+
* the dialog sits in a `display: none` panel, and `.focus()` on it silently
|
|
9
|
+
* drops focus to `<body>`. A detached element is skipped; a hidden one hands
|
|
10
|
+
* focus to the first visible control of its nearest visible ancestor, which
|
|
11
|
+
* for a closed popover is its trigger. It also runs when the component
|
|
12
|
+
* unmounts while open, which the per-component implementations this replaced
|
|
13
|
+
* never handled.
|
|
10
14
|
*
|
|
11
15
|
* Background isolation uses `inert`, not `aria-hidden`: a JS focus trap only
|
|
12
16
|
* fences the Tab key, while a screen reader's virtual cursor walks the page
|
|
@@ -17,7 +21,9 @@
|
|
|
17
21
|
* inert set is recomputed only when a scope activates or deactivates, so a
|
|
18
22
|
* portal that mounts *while* a modal is open (a toast, say) is not inerted
|
|
19
23
|
* until the stack next changes — under `aria-modal` that content is outside
|
|
20
|
-
* the dialog's world anyway.
|
|
24
|
+
* the dialog's world anyway. Live regions are never inerted: a toast region
|
|
25
|
+
* (`aria-live`, a direct child of the body) must keep announcing, and keep
|
|
26
|
+
* its actions pressable, while a modal is open.
|
|
21
27
|
*/
|
|
22
28
|
type FocusScopeOptions = {
|
|
23
29
|
/** Whether the scope is active — the overlay's open state. */
|
|
@@ -8,6 +8,7 @@ const applyInert = () => {
|
|
|
8
8
|
for (const child of Array.from(document.body.children)) {
|
|
9
9
|
if (!(child instanceof HTMLElement)) continue;
|
|
10
10
|
if (child.tagName === "SCRIPT" || child.tagName === "STYLE") continue;
|
|
11
|
+
if (child.hasAttribute("aria-live")) continue;
|
|
11
12
|
const shouldBeInert = top !== void 0 && !child.contains(top.panel);
|
|
12
13
|
if (shouldBeInert && !child.inert) {
|
|
13
14
|
child.inert = true;
|
|
@@ -22,6 +23,15 @@ const applyInert = () => {
|
|
|
22
23
|
inerted.clear();
|
|
23
24
|
}
|
|
24
25
|
};
|
|
26
|
+
const isVisible = (el) => el.getClientRects().length > 0;
|
|
27
|
+
const restoreTarget = (previous) => {
|
|
28
|
+
if (!document.contains(previous)) return null;
|
|
29
|
+
if (isVisible(previous)) return previous;
|
|
30
|
+
for (let el = previous.parentElement; el && el !== document.body; el = el.parentElement) {
|
|
31
|
+
if (isVisible(el)) return getFocusable(el)[0] ?? null;
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
};
|
|
25
35
|
function useFocusScope(ref, options) {
|
|
26
36
|
const optionsRef = useRef(options);
|
|
27
37
|
useEffect(() => {
|
|
@@ -71,8 +81,8 @@ function useFocusScope(ref, options) {
|
|
|
71
81
|
inertScopes.splice(index, 1);
|
|
72
82
|
applyInert();
|
|
73
83
|
}
|
|
74
|
-
if (optionsRef.current.restoreFocus !== false && previousFocus
|
|
75
|
-
previousFocus
|
|
84
|
+
if (optionsRef.current.restoreFocus !== false && previousFocus) {
|
|
85
|
+
restoreTarget(previousFocus)?.focus();
|
|
76
86
|
}
|
|
77
87
|
};
|
|
78
88
|
}, [active, ref]);
|
package/behaviors/useLayer.d.ts
CHANGED
|
@@ -1,19 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The dismissal layer stack — the single owner of the document-level Escape
|
|
3
|
-
* and outside-press listeners for every overlay in the library
|
|
3
|
+
* and outside-press listeners for every overlay in the library, modal and
|
|
4
|
+
* non-modal alike.
|
|
4
5
|
*
|
|
5
6
|
* Before this existed, each open overlay registered its own document keydown,
|
|
6
|
-
* so Escape over a stacked Dialog-in-Drawer closed both at once
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* so Escape over a stacked Dialog-in-Drawer closed both at once, and a
|
|
8
|
+
* popover or menu open inside a Dialog closed together with it. The stack
|
|
9
|
+
* routes each interaction by stack order:
|
|
10
|
+
*
|
|
11
|
+
* - **Escape** goes to the topmost open layer only: it dismisses it, or is
|
|
12
|
+
* swallowed when that layer is not Escape-dismissible (a lower layer must
|
|
13
|
+
* never close through a blocking one). One press, one layer. An Escape a
|
|
14
|
+
* component has already handled (`event.preventDefault()`, say an input
|
|
15
|
+
* clearing its own text) is left alone.
|
|
16
|
+
* - **An outside press** walks down from the top: every layer the press
|
|
17
|
+
* lands outside of, and that opts into light dismiss, closes; the walk
|
|
18
|
+
* stops at the first layer that contains the press or does not
|
|
19
|
+
* light-dismiss (a modal, which owns its backdrop). So a press on a
|
|
20
|
+
* Dialog's body closes the menus open above it and leaves the Dialog.
|
|
21
|
+
* - **Backdrop clicks** stay with the modal that draws the backdrop, but a
|
|
22
|
+
* press that began while another layer was on top was that layer's press:
|
|
23
|
+
* `ownsPress()` tells the modal so, and it keeps itself open. Without it, a
|
|
24
|
+
* press on the backdrop closed the open menu at pointerdown and then the
|
|
25
|
+
* Dialog on click, two layers for one press.
|
|
12
26
|
*
|
|
13
27
|
* Exactly two document listeners exist while any layer is open, and none
|
|
14
|
-
* while the stack is empty. Registration order is stack order
|
|
15
|
-
*
|
|
16
|
-
*
|
|
28
|
+
* while the stack is empty. Registration order is stack order: overlays open
|
|
29
|
+
* in the order they are stacked, so stack order and paint order agree
|
|
30
|
+
* without reading z-index.
|
|
17
31
|
*/
|
|
18
32
|
type LayerOptions = {
|
|
19
33
|
/** The overlay's open state — the layer registers while true. */
|
|
@@ -23,21 +37,31 @@ type LayerOptions = {
|
|
|
23
37
|
/** Whether Escape dismisses this layer. Default true. */
|
|
24
38
|
dismissOnEscape?: boolean;
|
|
25
39
|
/**
|
|
26
|
-
* Whether a pointerdown outside `getElements()` dismisses this layer
|
|
27
|
-
* Default false — modal components
|
|
28
|
-
* which is part of their DOM and
|
|
40
|
+
* Whether a pointerdown outside `getElements()` dismisses this layer (light
|
|
41
|
+
* dismiss: popovers, menus, listboxes). Default false — modal components
|
|
42
|
+
* keep their own backdrop click handler, which is part of their DOM, and
|
|
43
|
+
* gate it on `ownsPress()`.
|
|
29
44
|
*/
|
|
30
45
|
dismissOnOutsidePress?: boolean;
|
|
31
46
|
/**
|
|
32
47
|
* The elements that count as "inside" for outside-press checks — typically
|
|
33
|
-
* the panel and its trigger.
|
|
48
|
+
* the panel and its trigger. Read when `dismissOnOutsidePress` is on, and
|
|
49
|
+
* also to stop the outside-press walk at a layer that contains the press.
|
|
34
50
|
*/
|
|
35
51
|
getElements?: () => (HTMLElement | null | undefined)[];
|
|
36
52
|
};
|
|
53
|
+
export type LayerHandle = {
|
|
54
|
+
/**
|
|
55
|
+
* Whether the current press belongs to this layer: it was the topmost
|
|
56
|
+
* layer when the press began (or, outside a press, is topmost now). Gate a
|
|
57
|
+
* backdrop click on it.
|
|
58
|
+
*/
|
|
59
|
+
ownsPress: () => boolean;
|
|
60
|
+
};
|
|
37
61
|
/**
|
|
38
62
|
* Register an overlay on the dismissal stack while `open` is true. Options
|
|
39
63
|
* are read at event time, so a `dismissOnEscape` toggle takes effect without
|
|
40
64
|
* re-registering (which would wrongly move the layer to the top).
|
|
41
65
|
*/
|
|
42
|
-
export declare function useLayer(options: LayerOptions):
|
|
66
|
+
export declare function useLayer(options: LayerOptions): LayerHandle;
|
|
43
67
|
export {};
|
package/behaviors/useLayer.js
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useRef, useEffect } from "react";
|
|
2
|
+
import { useRef, useEffect, useCallback } from "react";
|
|
3
3
|
const layers = [];
|
|
4
4
|
let listenersInstalled = false;
|
|
5
|
+
let pressOwner = null;
|
|
6
|
+
const contains = (layer, target) => (layer.optionsRef.current.getElements?.() ?? []).some((el) => el?.contains(target));
|
|
5
7
|
const handleKeyDown = (event) => {
|
|
6
|
-
if (event.key !== "Escape") return;
|
|
8
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
7
9
|
const top = layers[layers.length - 1];
|
|
8
10
|
if (!top) return;
|
|
9
11
|
const options = top.optionsRef.current;
|
|
10
|
-
if (options.dismissOnEscape === false) return;
|
|
11
12
|
event.preventDefault();
|
|
13
|
+
if (options.dismissOnEscape === false) return;
|
|
12
14
|
options.onDismiss?.();
|
|
13
15
|
};
|
|
14
16
|
const handlePointerDown = (event) => {
|
|
15
|
-
|
|
16
|
-
if (!top) return;
|
|
17
|
-
const options = top.optionsRef.current;
|
|
18
|
-
if (!options.dismissOnOutsidePress) return;
|
|
17
|
+
pressOwner = layers[layers.length - 1] ?? null;
|
|
19
18
|
const target = event.target instanceof Node ? event.target : null;
|
|
20
19
|
if (!target) return;
|
|
21
|
-
const
|
|
22
|
-
|
|
20
|
+
for (const layer of [...layers].reverse()) {
|
|
21
|
+
const options = layer.optionsRef.current;
|
|
22
|
+
if (!options.dismissOnOutsidePress || contains(layer, target)) break;
|
|
23
|
+
options.onDismiss?.();
|
|
24
|
+
}
|
|
23
25
|
};
|
|
24
26
|
const syncListeners = () => {
|
|
25
27
|
if (layers.length > 0 && !listenersInstalled) {
|
|
26
28
|
document.addEventListener("keydown", handleKeyDown);
|
|
27
|
-
document.addEventListener("pointerdown", handlePointerDown);
|
|
29
|
+
document.addEventListener("pointerdown", handlePointerDown, true);
|
|
28
30
|
listenersInstalled = true;
|
|
29
31
|
} else if (layers.length === 0 && listenersInstalled) {
|
|
30
32
|
document.removeEventListener("keydown", handleKeyDown);
|
|
31
|
-
document.removeEventListener("pointerdown", handlePointerDown);
|
|
33
|
+
document.removeEventListener("pointerdown", handlePointerDown, true);
|
|
32
34
|
listenersInstalled = false;
|
|
35
|
+
pressOwner = null;
|
|
33
36
|
}
|
|
34
37
|
};
|
|
35
38
|
function useLayer(options) {
|
|
36
39
|
const optionsRef = useRef(options);
|
|
40
|
+
const layerRef = useRef(null);
|
|
37
41
|
useEffect(() => {
|
|
38
42
|
optionsRef.current = options;
|
|
39
43
|
});
|
|
@@ -41,14 +45,22 @@ function useLayer(options) {
|
|
|
41
45
|
useEffect(() => {
|
|
42
46
|
if (!open) return;
|
|
43
47
|
const layer = { optionsRef };
|
|
48
|
+
layerRef.current = layer;
|
|
44
49
|
layers.push(layer);
|
|
45
50
|
syncListeners();
|
|
46
51
|
return () => {
|
|
47
52
|
const index = layers.indexOf(layer);
|
|
48
53
|
if (index !== -1) layers.splice(index, 1);
|
|
54
|
+
layerRef.current = null;
|
|
49
55
|
syncListeners();
|
|
50
56
|
};
|
|
51
57
|
}, [open]);
|
|
58
|
+
const ownsPress = useCallback(() => {
|
|
59
|
+
const layer = layerRef.current;
|
|
60
|
+
if (!layer) return false;
|
|
61
|
+
return pressOwner ? pressOwner === layer : layers[layers.length - 1] === layer;
|
|
62
|
+
}, []);
|
|
63
|
+
return { ownsPress };
|
|
52
64
|
}
|
|
53
65
|
export {
|
|
54
66
|
useLayer
|
|
@@ -23,6 +23,9 @@ const handler = createChatHandler({
|
|
|
23
23
|
models: CHAT_MODELS,
|
|
24
24
|
defaultModel: DEFAULT_CHAT_MODEL,
|
|
25
25
|
// tools: [], // Deterministic lookups the model may call; a tool can answer with a card.
|
|
26
|
+
// A reply can end in a question with answers to pick, drawn as a card the
|
|
27
|
+
// visitor taps. Asking ends the exchange; the answer arrives as the next message.
|
|
28
|
+
askUser: true,
|
|
26
29
|
guardrails,
|
|
27
30
|
});
|
|
28
31
|
|
package/chat/AssistantTurn.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
+
import { CodeBlockProps } from '../components/CodeBlock/CodeBlock';
|
|
2
|
+
import { PromptSuggestionsProps } from '../components/PromptSuggestions/PromptSuggestions';
|
|
3
|
+
import { QuestionCardLabels } from '../components/QuestionCard/QuestionCard';
|
|
1
4
|
import { ChatTurn, LiveResponse } from './types';
|
|
2
|
-
|
|
5
|
+
/** The words an assistant turn's parts write, set from ChatWidget's label props. Every key left out keeps the part's English. */
|
|
6
|
+
export interface AssistantTurnLabels {
|
|
7
|
+
/** The fenced-code CodeBlocks in a reply; `codeLabel` is given the fence's language. */
|
|
8
|
+
codeBlock?: Pick<CodeBlockProps, 'copyLabel' | 'copyText' | 'copiedLabel'> & {
|
|
9
|
+
codeLabel?: (language: string | undefined) => string;
|
|
10
|
+
};
|
|
11
|
+
/** The reasoning disclosure's summary once thinking is over, given the seconds it took when known. */
|
|
12
|
+
reasoning?: (durationSeconds: number | undefined) => string;
|
|
13
|
+
/** The question card a reply ends in. */
|
|
14
|
+
questionCard?: Partial<QuestionCardLabels>;
|
|
15
|
+
/** The follow-up row's hidden "(chosen)" text. */
|
|
16
|
+
promptSuggestions?: Pick<PromptSuggestionsProps, 'chosenLabel'>;
|
|
17
|
+
}
|
|
18
|
+
export declare function AssistantTurn({ turn, live, labels, }: {
|
|
3
19
|
turn?: ChatTurn;
|
|
4
20
|
live?: LiveResponse;
|
|
21
|
+
labels?: AssistantTurnLabels;
|
|
5
22
|
}): import("react").JSX.Element;
|
package/chat/AssistantTurn.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
3
4
|
import ReactMarkdown from "react-markdown";
|
|
4
5
|
import remarkGfm from "remark-gfm";
|
|
5
6
|
import { AgentStatus } from "../components/AgentStatus/AgentStatus.js";
|
|
@@ -12,6 +13,8 @@ import { DOCK_QUERY } from "./queries.js";
|
|
|
12
13
|
import { FollowupSuggestions } from "./FollowupSuggestions.js";
|
|
13
14
|
import { ResponseActions } from "./ResponseActions.js";
|
|
14
15
|
import { TurnCard } from "./TurnContent.js";
|
|
16
|
+
import { TurnQuestion } from "./TurnQuestion.js";
|
|
17
|
+
const CodeBlockLabelsContext = createContext(void 0);
|
|
15
18
|
function MarkdownLink({ href, children }) {
|
|
16
19
|
const { view, setOpen, renderLink, isInternalHref } = useChatWidget();
|
|
17
20
|
if (!href || !isInternalHref(href)) return /* @__PURE__ */ jsx(Fragment, { children });
|
|
@@ -25,26 +28,39 @@ function MarkdownLink({ href, children }) {
|
|
|
25
28
|
}
|
|
26
29
|
const hastText = (node) => node.type === "text" ? node.value ?? "" : (node.children ?? []).map(hastText).join("");
|
|
27
30
|
function MarkdownPre({ node, children, ...props }) {
|
|
31
|
+
const { codeLabel, ...labels } = useContext(CodeBlockLabelsContext) ?? {};
|
|
28
32
|
const code = node?.children?.find(
|
|
29
33
|
(child) => child.type === "element" && child.tagName === "code"
|
|
30
34
|
);
|
|
31
35
|
if (!code) return /* @__PURE__ */ jsx("pre", { ...props, children });
|
|
32
36
|
const classes = code.properties?.className;
|
|
33
37
|
const language = (Array.isArray(classes) ? classes : []).map(String).find((name) => name.startsWith("language-"))?.slice("language-".length);
|
|
34
|
-
return /* @__PURE__ */ jsx(
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
CodeBlock,
|
|
40
|
+
{
|
|
41
|
+
...labels,
|
|
42
|
+
codeLabel: codeLabel?.(language),
|
|
43
|
+
code: hastText(code).replace(/\n$/, ""),
|
|
44
|
+
language
|
|
45
|
+
}
|
|
46
|
+
);
|
|
35
47
|
}
|
|
36
48
|
const markdownComponents = {
|
|
37
49
|
a: MarkdownLink,
|
|
38
50
|
pre: MarkdownPre,
|
|
39
51
|
table: ({ children, ...props }) => /* @__PURE__ */ jsx("table", { tabIndex: 0, ...props, children })
|
|
40
52
|
};
|
|
41
|
-
function AssistantTurn({
|
|
53
|
+
function AssistantTurn({
|
|
54
|
+
turn,
|
|
55
|
+
live,
|
|
56
|
+
labels
|
|
57
|
+
}) {
|
|
42
58
|
const thinking = live?.phase === "thinking";
|
|
43
59
|
const tracePoints = live ? live.tracePoints : turn?.tracePoints ?? [];
|
|
44
60
|
const durationSeconds = live ? live.durationSeconds : turn?.durationSeconds;
|
|
45
61
|
const text = live ? live.text : turn?.text ?? "";
|
|
46
62
|
const { turns, live: liveTurn, freshFollowupsId } = useChatWidget();
|
|
47
|
-
const followupsPending = !!turn && turn.text !== "" && !!turn.exchangeId && !turn.followups && !liveTurn && turns[turns.length - 1]?.id === turn.id;
|
|
63
|
+
const followupsPending = !!turn && turn.text !== "" && !!turn.exchangeId && !turn.followups && !turn.question && !liveTurn && turns[turns.length - 1]?.id === turn.id;
|
|
48
64
|
return /* @__PURE__ */ jsx(
|
|
49
65
|
ChatMessage,
|
|
50
66
|
{
|
|
@@ -56,7 +72,9 @@ function AssistantTurn({ turn, live }) {
|
|
|
56
72
|
{
|
|
57
73
|
turnId: turn.id,
|
|
58
74
|
suggestions: turn.followups,
|
|
59
|
-
|
|
75
|
+
chosen: turn.followupChosen,
|
|
76
|
+
entrance: turn.id === freshFollowupsId,
|
|
77
|
+
chosenLabel: labels?.promptSuggestions?.chosenLabel
|
|
60
78
|
}
|
|
61
79
|
) : followupsPending && turn ? /* @__PURE__ */ jsx(FollowupSuggestions, { turnId: turn.id, suggestions: [], pending: true }) : void 0,
|
|
62
80
|
children: /* @__PURE__ */ jsxs("div", { className: "ds-chat-widget__response", children: [
|
|
@@ -66,13 +84,15 @@ function AssistantTurn({ turn, live }) {
|
|
|
66
84
|
streaming: thinking,
|
|
67
85
|
summaryOnly: tracePoints.length === 0,
|
|
68
86
|
duration: durationSeconds,
|
|
87
|
+
label: labels?.reasoning && !thinking ? labels.reasoning(durationSeconds) : void 0,
|
|
69
88
|
summary: thinking && live ? /* @__PURE__ */ jsx(AgentStatus, { state: "working", label: live.statusLabel }) : void 0,
|
|
70
89
|
children: tracePoints.length > 0 && /* @__PURE__ */ jsx("ul", { children: tracePoints.map((point, index) => /* @__PURE__ */ jsx("li", { children: point }, `${index}-${point.slice(0, 24)}`)) })
|
|
71
90
|
}
|
|
72
91
|
),
|
|
73
92
|
turn?.content,
|
|
74
93
|
turn?.card && /* @__PURE__ */ jsx(TurnCard, { card: turn.card }),
|
|
75
|
-
text !== "" && /* @__PURE__ */ jsx(Prose, { children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: text }) })
|
|
94
|
+
text !== "" && /* @__PURE__ */ jsx(CodeBlockLabelsContext.Provider, { value: labels?.codeBlock, children: /* @__PURE__ */ jsx(Prose, { children: /* @__PURE__ */ jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], components: markdownComponents, children: text }) }) }),
|
|
95
|
+
turn?.question && /* @__PURE__ */ jsx(TurnQuestion, { turn, labels: labels?.questionCard })
|
|
76
96
|
] })
|
|
77
97
|
}
|
|
78
98
|
);
|
package/chat/ChatAgentPane.d.ts
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
|
-
import { AgentRailProfile, AgentRailTab } from '../components/AgentRail/AgentRail';
|
|
1
|
+
import { AgentRailProfile, AgentRailProps, AgentRailTab } from '../components/AgentRail/AgentRail';
|
|
2
2
|
export interface ChatAgentPaneProps {
|
|
3
3
|
/** The agent this pane belongs to: the portrait block at the top. */
|
|
4
4
|
profile: AgentRailProfile;
|
|
5
5
|
/** The panes, in display order: activity, approvals, automations, personalisation, or whatever the agent has. */
|
|
6
6
|
tabs: AgentRailTab[];
|
|
7
|
-
/** The tab on stage, when the host owns the state; otherwise the pane keeps its own
|
|
8
|
-
|
|
7
|
+
/** The tab on stage, when the host owns the state; otherwise the pane keeps its own, seeded from `defaultValue`. */
|
|
8
|
+
value?: string;
|
|
9
|
+
/** The tab on stage first when the pane keeps its own state. Defaults to the first tab. */
|
|
10
|
+
defaultValue?: string;
|
|
9
11
|
/** Fires with the chosen tab's id. */
|
|
12
|
+
onValueChange?: (id: string) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Legacy name for `value`.
|
|
15
|
+
*
|
|
16
|
+
* @deprecated Use `value` instead.
|
|
17
|
+
*/
|
|
18
|
+
activeTab?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Legacy change callback; fires alongside `onValueChange`.
|
|
21
|
+
*
|
|
22
|
+
* @deprecated Use `onValueChange` instead.
|
|
23
|
+
*/
|
|
10
24
|
onTabChange?: (id: string) => void;
|
|
11
25
|
/** The widget seated the pane as a bottom sheet, where it fills the width instead of holding its own column. */
|
|
12
26
|
overlay: boolean;
|
|
13
27
|
/** Fires from the pane's own close button, a cross in its top trailing corner. Omit for a pane with no close of its own. */
|
|
14
28
|
onClose?: () => void;
|
|
29
|
+
/** Accessible name of the pane's own close button. Defaults to "Close the agent panel". */
|
|
30
|
+
closeLabel?: string;
|
|
31
|
+
/** The words the AgentRail writes, merged over its English defaults: the tab strip's name ("Agent views"). */
|
|
32
|
+
agentRailLabels?: Pick<AgentRailProps, 'tabsLabel'>;
|
|
15
33
|
}
|
|
16
34
|
/**
|
|
17
35
|
* The built-in agent pane: an AgentRail the widget seats on the
|
|
@@ -21,4 +39,4 @@ export interface ChatAgentPaneProps {
|
|
|
21
39
|
* pane carries a close of its own in its top corner, where a panel's way
|
|
22
40
|
* out is looked for.
|
|
23
41
|
*/
|
|
24
|
-
export declare function ChatAgentPane({ profile, tabs, activeTab, onTabChange, overlay, onClose }: ChatAgentPaneProps): import("react").JSX.Element;
|
|
42
|
+
export declare function ChatAgentPane({ profile, tabs, value, defaultValue, onValueChange, activeTab, onTabChange, overlay, onClose, closeLabel, agentRailLabels, }: ChatAgentPaneProps): import("react").JSX.Element;
|
package/chat/ChatAgentPane.js
CHANGED
|
@@ -3,21 +3,35 @@ import { jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { AgentRail } from "../components/AgentRail/AgentRail.js";
|
|
5
5
|
import "./ChatAgentPane.css";
|
|
6
|
-
function ChatAgentPane({
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
function ChatAgentPane({
|
|
7
|
+
profile,
|
|
8
|
+
tabs,
|
|
9
|
+
value,
|
|
10
|
+
defaultValue,
|
|
11
|
+
onValueChange,
|
|
12
|
+
activeTab,
|
|
13
|
+
onTabChange,
|
|
14
|
+
overlay,
|
|
15
|
+
onClose,
|
|
16
|
+
closeLabel = "Close the agent panel",
|
|
17
|
+
agentRailLabels
|
|
18
|
+
}) {
|
|
19
|
+
const [ownTab, setOwnTab] = useState(defaultValue ?? tabs[0]?.id ?? "");
|
|
20
|
+
const current = value ?? activeTab ?? ownTab;
|
|
9
21
|
return /* @__PURE__ */ jsx(
|
|
10
22
|
AgentRail,
|
|
11
23
|
{
|
|
24
|
+
...agentRailLabels,
|
|
12
25
|
className: overlay ? "ds-chat-agent-pane--sheet" : void 0,
|
|
13
26
|
profile,
|
|
14
27
|
tabs,
|
|
15
|
-
|
|
28
|
+
value: current,
|
|
16
29
|
onCollapse: onClose,
|
|
17
30
|
collapseVariant: "close",
|
|
18
|
-
collapseLabel:
|
|
19
|
-
|
|
31
|
+
collapseLabel: closeLabel,
|
|
32
|
+
onValueChange: (id) => {
|
|
20
33
|
setOwnTab(id);
|
|
34
|
+
onValueChange?.(id);
|
|
21
35
|
onTabChange?.(id);
|
|
22
36
|
}
|
|
23
37
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ArtifactPanelProps } from '../components/ArtifactPanel/ArtifactPanel';
|
|
1
2
|
import { ChatArtifact } from './types';
|
|
2
3
|
export interface ChatArtifactPaneProps {
|
|
3
4
|
/** The artifact on stage, or null for the empty state: the panel opened before the conversation has made anything. */
|
|
@@ -8,6 +9,20 @@ export interface ChatArtifactPaneProps {
|
|
|
8
9
|
onExpandedChange?: (expanded: boolean) => void;
|
|
9
10
|
/** Fires from the pane's close button; omit where another control closes the seat. */
|
|
10
11
|
onClose?: () => void;
|
|
12
|
+
/** The panel's title while nothing is on stage. Defaults to "Artifacts". */
|
|
13
|
+
emptyPanelTitle?: string;
|
|
14
|
+
/** The empty state's heading. Defaults to "Nothing here yet". */
|
|
15
|
+
emptyTitle?: string;
|
|
16
|
+
/** The empty state's description. Defaults to "What the chat makes for you, like a dashboard or a page, opens in this panel." */
|
|
17
|
+
emptyDescription?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The words the ArtifactPanel writes, merged over its English defaults:
|
|
20
|
+
* the view switch's segments and name ("Preview", "Code", "Artifact
|
|
21
|
+
* view"), the expand toggle and close button's names ("Expand the
|
|
22
|
+
* artifact", "Collapse the artifact", "Close the artifact"), and the code
|
|
23
|
+
* view's copy button and region (`codeBlockLabels`).
|
|
24
|
+
*/
|
|
25
|
+
artifactPanelLabels?: Pick<ArtifactPanelProps, 'previewLabel' | 'codeLabel' | 'viewLabel' | 'expandLabel' | 'collapseLabel' | 'closeLabel' | 'codeBlockLabels'>;
|
|
11
26
|
}
|
|
12
27
|
/**
|
|
13
28
|
* The built-in artifact pane: an ArtifactPanel drawn from a `ChatArtifact`.
|
|
@@ -15,4 +30,4 @@ export interface ChatArtifactPaneProps {
|
|
|
15
30
|
* otherwise the artifact's document, URL or source decides the preview. The
|
|
16
31
|
* widget owns the seat (beside the conversation, or a sheet over it).
|
|
17
32
|
*/
|
|
18
|
-
export declare function ChatArtifactPane({ artifact, expanded, onExpandedChange, onClose }: ChatArtifactPaneProps): import("react").JSX.Element;
|
|
33
|
+
export declare function ChatArtifactPane({ artifact, expanded, onExpandedChange, onClose, emptyPanelTitle, emptyTitle, emptyDescription, artifactPanelLabels, }: ChatArtifactPaneProps): import("react").JSX.Element;
|
package/chat/ChatArtifactPane.js
CHANGED
|
@@ -4,18 +4,19 @@ import { ArtifactPanel } from "../components/ArtifactPanel/ArtifactPanel.js";
|
|
|
4
4
|
import { EmptyState } from "../components/EmptyState/EmptyState.js";
|
|
5
5
|
import { useChatWidget } from "./context.js";
|
|
6
6
|
const FRAMEABLE_URL = /^(?:https?:\/\/|\/(?!\/))/i;
|
|
7
|
-
function ChatArtifactPane({
|
|
7
|
+
function ChatArtifactPane({
|
|
8
|
+
artifact,
|
|
9
|
+
expanded,
|
|
10
|
+
onExpandedChange,
|
|
11
|
+
onClose,
|
|
12
|
+
emptyPanelTitle = "Artifacts",
|
|
13
|
+
emptyTitle = "Nothing here yet",
|
|
14
|
+
emptyDescription = "What the chat makes for you, like a dashboard or a page, opens in this panel.",
|
|
15
|
+
artifactPanelLabels
|
|
16
|
+
}) {
|
|
8
17
|
const { artifactRenderers } = useChatWidget();
|
|
9
18
|
if (!artifact) {
|
|
10
|
-
return /* @__PURE__ */ jsx(ArtifactPanel, { title:
|
|
11
|
-
EmptyState,
|
|
12
|
-
{
|
|
13
|
-
size: "compact",
|
|
14
|
-
icon: "draft",
|
|
15
|
-
title: "Nothing here yet",
|
|
16
|
-
description: "What the chat makes for you, like a dashboard or a page, opens in this panel."
|
|
17
|
-
}
|
|
18
|
-
) }) });
|
|
19
|
+
return /* @__PURE__ */ jsx(ArtifactPanel, { ...artifactPanelLabels, title: emptyPanelTitle, icon: "space_dashboard", onClose, children: /* @__PURE__ */ jsx("div", { className: "ds-chat-widget__artifact-empty", children: /* @__PURE__ */ jsx(EmptyState, { size: "compact", icon: "draft", title: emptyTitle, description: emptyDescription }) }) });
|
|
19
20
|
}
|
|
20
21
|
const custom = Object.hasOwn(artifactRenderers, artifact.kind);
|
|
21
22
|
const render = artifactRenderers[artifact.kind];
|
|
@@ -23,6 +24,7 @@ function ChatArtifactPane({ artifact, expanded, onExpandedChange, onClose }) {
|
|
|
23
24
|
return /* @__PURE__ */ jsx(
|
|
24
25
|
ArtifactPanel,
|
|
25
26
|
{
|
|
27
|
+
...artifactPanelLabels,
|
|
26
28
|
title: artifact.title,
|
|
27
29
|
meta: artifact.meta,
|
|
28
30
|
icon: artifact.icon,
|
package/chat/ChatLauncher.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { AiButtonSummary } from '../components/AiButton/AiButton';
|
|
2
|
+
import { AiButtonProps, AiButtonSummary } from '../components/AiButton/AiButton';
|
|
3
3
|
import { ChatWidgetProps } from './ChatWidget';
|
|
4
4
|
/** The id the panel carries, for a host control's `aria-controls`. */
|
|
5
5
|
export declare const CHAT_PANEL_ID = "ds-chat-panel";
|
|
@@ -11,8 +11,10 @@ export interface ChatLauncherProps {
|
|
|
11
11
|
/**
|
|
12
12
|
* A TLDR panel the button summons on hover: a pre-written summary and
|
|
13
13
|
* prompt chips. A tapped chip opens the chat and sends the chip's
|
|
14
|
-
* `prompt`.
|
|
15
|
-
*
|
|
14
|
+
* `prompt`. The launcher hands it to the closed button's AiButton, which
|
|
15
|
+
* opens the panel on pointer hover; it does no device or hydration gating
|
|
16
|
+
* of its own, so a host that wants the panel on hover-capable devices only,
|
|
17
|
+
* or kept out of server HTML, passes `summary` only there.
|
|
16
18
|
*/
|
|
17
19
|
summary?: AiButtonSummary & {
|
|
18
20
|
chips?: {
|
|
@@ -21,7 +23,10 @@ export interface ChatLauncherProps {
|
|
|
21
23
|
prompt: string;
|
|
22
24
|
}[];
|
|
23
25
|
};
|
|
24
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Render nothing at all: for routes that carry no chrome.
|
|
28
|
+
* Note: not the native `hidden` attribute, which keeps an element mounted and only hides it; the launcher unmounts its button and panel, and spreads no native attributes.
|
|
29
|
+
*/
|
|
25
30
|
hidden?: boolean;
|
|
26
31
|
/** The panel's DOM id, for a host control's `aria-controls`. */
|
|
27
32
|
panelId?: string;
|
|
@@ -33,6 +38,8 @@ export interface ChatLauncherProps {
|
|
|
33
38
|
hostAttribute?: string | false;
|
|
34
39
|
/** Accessible name for the panel. */
|
|
35
40
|
panelLabel?: string;
|
|
41
|
+
/** The words of the floating button's summary panel, over AiButton's English defaults: the panel's name, given the summary's title ("Summary: <title>"), its dismiss button ("Dismiss summary") and its chips' group ("Suggested prompts"). */
|
|
42
|
+
aiButtonLabels?: Pick<AiButtonProps, 'summaryRegionLabel' | 'dismissLabel' | 'suggestionsLabel'>;
|
|
36
43
|
/** Everything the widget takes. The launcher sets the responsive ones itself. */
|
|
37
44
|
widget?: Omit<ChatWidgetProps, 'fullscreenEnabled' | 'placementEnabled' | 'compact' | 'phone'>;
|
|
38
45
|
/** Rendered inside the panel after the widget: for a host's extra chrome. */
|
|
@@ -61,4 +68,4 @@ export interface ChatLauncherProps {
|
|
|
61
68
|
* touch the host's body). The panel's geometry reads `--ds-chat-width`,
|
|
62
69
|
* `--ds-chat-inset` and `--ds-chat-float-height`, defaulted on `:root`.
|
|
63
70
|
*/
|
|
64
|
-
export declare function ChatLauncher({ label, icon, summary, hidden, panelId, hostAttribute, panelLabel, widget, children, }: ChatLauncherProps): import("react").JSX.Element | null;
|
|
71
|
+
export declare function ChatLauncher({ label, icon, summary, hidden, panelId, hostAttribute, panelLabel, aiButtonLabels, widget, children, }: ChatLauncherProps): import("react").JSX.Element | null;
|
package/chat/ChatLauncher.js
CHANGED
|
@@ -42,6 +42,7 @@ function ChatLauncher({
|
|
|
42
42
|
panelId = CHAT_PANEL_ID,
|
|
43
43
|
hostAttribute = "data-chat",
|
|
44
44
|
panelLabel = "Chat",
|
|
45
|
+
aiButtonLabels,
|
|
45
46
|
widget,
|
|
46
47
|
children
|
|
47
48
|
}) {
|
|
@@ -223,6 +224,7 @@ function ChatLauncher({
|
|
|
223
224
|
return /* @__PURE__ */ jsx("div", { className: "ds-chat-launcher__fab", children: /* @__PURE__ */ jsx(
|
|
224
225
|
AiButton,
|
|
225
226
|
{
|
|
227
|
+
...aiButtonLabels,
|
|
226
228
|
label,
|
|
227
229
|
icon,
|
|
228
230
|
"aria-expanded": false,
|
|
@@ -244,7 +246,7 @@ function ChatLauncher({
|
|
|
244
246
|
}
|
|
245
247
|
const handleKeyDown = (event) => {
|
|
246
248
|
if (event.key === "Escape") {
|
|
247
|
-
setOpen(false);
|
|
249
|
+
if (!event.defaultPrevented) setOpen(false);
|
|
248
250
|
return;
|
|
249
251
|
}
|
|
250
252
|
if (modal && event.key === "Tab" && panelRef.current) {
|
package/chat/ChatProvider.d.ts
CHANGED
|
@@ -18,11 +18,12 @@ export interface ChatProviderProps {
|
|
|
18
18
|
defaultPlacement?: ChatPlacement;
|
|
19
19
|
/**
|
|
20
20
|
* Where follow-up questions come from after an answer commits: a source
|
|
21
|
-
* function, an endpoint for the built-in fetcher, or `false` for none
|
|
22
|
-
*
|
|
21
|
+
* function, an endpoint for the built-in fetcher, or `false` for none:
|
|
22
|
+
* with `false` no chips show under an answer at all, not even the written
|
|
23
|
+
* `fallbackFollowups`. Defaults to the fetcher against `/api/chat/followups`.
|
|
23
24
|
*/
|
|
24
25
|
followups?: FollowupsSource | string | false;
|
|
25
|
-
/** The written questions offered when the source returns none. */
|
|
26
|
+
/** The written questions offered when the source returns none or fails. Unused when `followups` is `false`. */
|
|
26
27
|
fallbackFollowups?: readonly string[];
|
|
27
28
|
/**
|
|
28
29
|
* Where a thumbs verdict goes: a sink function, an endpoint for the
|
|
@@ -41,7 +42,7 @@ export interface ChatProviderProps {
|
|
|
41
42
|
isInternalHref?: (href: string) => boolean;
|
|
42
43
|
/** Seeds the thread lifecycle behind the `threads` and `tabs` slots. */
|
|
43
44
|
threads?: ThreadsOptions;
|
|
44
|
-
/** Replacement copy for the hook
|
|
45
|
+
/** Replacement copy for the words the hook writes itself, merged over the English defaults: the status line of a reply that has not started ("Thinking") and the placeholder replies for an empty, stopped or failed turn. */
|
|
45
46
|
placeholders?: Partial<ChatPlaceholderCopy>;
|
|
46
47
|
children: ReactNode;
|
|
47
48
|
}
|