@flikk/ui 1.0.0-beta.30 → 1.0.0-beta.32
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 +375 -5
- package/dist/components/ai/AgentRequest/AgentRequest.animations.d.ts +25 -0
- package/dist/components/ai/AgentRequest/AgentRequest.animations.js +81 -0
- package/dist/components/ai/AgentRequest/AgentRequest.d.ts +3 -0
- package/dist/components/ai/AgentRequest/AgentRequest.js +435 -0
- package/dist/components/ai/AgentRequest/AgentRequest.theme.d.ts +2 -0
- package/dist/components/ai/AgentRequest/AgentRequest.theme.js +106 -0
- package/dist/components/ai/AgentRequest/AgentRequest.types.d.ts +241 -0
- package/dist/components/ai/AgentRequest/index.d.ts +3 -0
- package/dist/components/ai/AgentStatus/AgentStatus.d.ts +3 -0
- package/dist/components/ai/AgentStatus/AgentStatus.js +144 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.d.ts +2 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.js +37 -0
- package/dist/components/ai/AgentStatus/AgentStatus.types.d.ts +116 -0
- package/dist/components/ai/AgentStatus/index.d.ts +3 -0
- package/dist/components/ai/CodeBlock/CodeBlock.js +3 -3
- package/dist/components/ai/CodeBlock/CodeBlock.theme.js +2 -2
- package/dist/components/ai/PromptInput/PromptInput.js +13 -14
- package/dist/components/ai/PromptInput/PromptInput.theme.js +3 -3
- package/dist/components/ai/PromptInput/VoiceRecorder.js +3 -3
- package/dist/components/ai/PromptSuggestion/PromptSuggestion.theme.js +2 -2
- package/dist/components/ai/Reasoning/Reasoning.d.ts +5 -0
- package/dist/components/ai/Reasoning/Reasoning.js +40 -0
- package/dist/components/ai/Reasoning/Reasoning.theme.d.ts +6 -0
- package/dist/components/ai/Reasoning/Reasoning.theme.js +36 -0
- package/dist/components/ai/Reasoning/Reasoning.types.d.ts +73 -0
- package/dist/components/ai/Reasoning/ReasoningTrace.d.ts +11 -0
- package/dist/components/ai/Reasoning/ReasoningTrace.js +84 -0
- package/dist/components/ai/Reasoning/index.d.ts +3 -0
- package/dist/components/ai/SourceCitation/SourceCitation.d.ts +4 -0
- package/dist/components/ai/SourceCitation/SourceCitation.js +29 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.d.ts +2 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.js +23 -0
- package/dist/components/ai/SourceCitation/SourceCitation.types.d.ts +55 -0
- package/dist/components/ai/SourceCitation/index.d.ts +3 -0
- package/dist/components/ai/StreamingResponse/AnimatedText.d.ts +7 -0
- package/dist/components/ai/StreamingResponse/AnimatedText.js +8 -7
- package/dist/components/ai/StreamingResponse/ErrorDisplay.js +2 -2
- package/dist/components/ai/StreamingResponse/MarkdownRenderer.d.ts +5 -0
- package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +4 -4
- package/dist/components/ai/StreamingResponse/StreamingCursor.d.ts +2 -2
- package/dist/components/ai/StreamingResponse/StreamingCursor.js +10 -7
- package/dist/components/ai/StreamingResponse/StreamingResponse.animations.d.ts +10 -0
- package/dist/components/ai/StreamingResponse/StreamingResponse.animations.js +59 -33
- package/dist/components/ai/StreamingResponse/StreamingResponse.js +14 -10
- package/dist/components/ai/StreamingResponse/StreamingResponse.theme.js +3 -1
- package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +33 -2
- package/dist/components/ai/StreamingResponse/StreamingSurface.d.ts +13 -0
- package/dist/components/ai/StreamingResponse/StreamingSurface.js +38 -0
- package/dist/components/ai/StreamingResponse/WordAnimationContext.d.ts +5 -0
- package/dist/components/ai/StreamingResponse/WordAnimationContext.js +5 -4
- package/dist/components/ai/StreamingResponse/index.d.ts +4 -2
- package/dist/components/ai/TokenCounter/TokenCounter.js +2 -2
- package/dist/components/ai/TokenCounter/TokenCounter.theme.js +1 -1
- package/dist/components/ai/index.d.ts +6 -2
- package/dist/components/ai/index.js +10 -3
- package/dist/components/ai/shared/StatusIndicator.d.ts +8 -0
- package/dist/components/ai/shared/StatusIndicator.js +34 -0
- package/dist/components/canvas/BaseNode.js +1 -1
- package/dist/components/canvas/CanvasToolbar.js +2 -3
- package/dist/components/canvas/Edge.js +2 -2
- package/dist/components/canvas/NodeControls.js +2 -3
- package/dist/components/canvas/NodeRenderer.js +4 -4
- package/dist/components/charts/ActivityRings/ActivityRings.js +4 -4
- package/dist/components/charts/ActivityRings/ActivityRings.theme.js +1 -1
- package/dist/components/charts/AreaChart/AreaChart.js +24 -35
- package/dist/components/charts/AreaChart/AreaChart.theme.d.ts +1 -6
- package/dist/components/charts/AreaChart/AreaChart.theme.js +10 -22
- package/dist/components/charts/AreaChart/AreaChart.types.d.ts +18 -11
- package/dist/components/charts/AreaChart/AreaChart.types.js +10 -3
- package/dist/components/charts/AreaChart/index.d.ts +1 -1
- package/dist/components/charts/BarChart/BarChart.js +13 -32
- package/dist/components/charts/BarChart/BarChart.types.d.ts +20 -16
- package/dist/components/charts/BarChart/BarChart.types.js +11 -4
- package/dist/components/charts/ComboChart/BarRenderer.js +10 -7
- package/dist/components/charts/ComboChart/BarRenderer.types.d.ts +1 -1
- package/dist/components/charts/ComboChart/ComboChart.js +11 -24
- package/dist/components/charts/ComboChart/ComboChart.types.d.ts +15 -13
- package/dist/components/charts/ComboChart/ComboChart.types.js +14 -2
- package/dist/components/charts/ComboChart/ComboChartCanvas.js +1 -1
- package/dist/components/charts/ComboChart/LineRenderer.js +16 -11
- package/dist/components/charts/ComboChart/LineRenderer.types.d.ts +1 -1
- package/dist/components/charts/DonutChart/DonutChart.theme.js +4 -4
- package/dist/components/charts/DonutChart/MultiSegmentDonutChart.theme.js +1 -1
- package/dist/components/charts/Heatmap/Heatmap.js +49 -42
- package/dist/components/charts/Heatmap/Heatmap.theme.d.ts +6 -2
- package/dist/components/charts/Heatmap/Heatmap.theme.js +20 -8
- package/dist/components/charts/Heatmap/Heatmap.types.d.ts +49 -82
- package/dist/components/charts/Heatmap/HeatmapCell.js +30 -81
- package/dist/components/charts/Heatmap/HeatmapLegend.d.ts +7 -6
- package/dist/components/charts/Heatmap/HeatmapLegend.js +6 -6
- package/dist/components/charts/Heatmap/index.d.ts +1 -1
- package/dist/components/charts/Heatmap/utils/heatmapUtils.d.ts +7 -12
- package/dist/components/charts/Heatmap/utils/heatmapUtils.js +16 -61
- package/dist/components/charts/Heatmap/utils/heatmapUtils.test.d.ts +1 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.d.ts +16 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.js +237 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.d.ts +62 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.js +21 -0
- package/dist/components/charts/HorizontalBarChart/index.d.ts +3 -0
- package/dist/components/charts/LineChart/LineChart.js +11 -28
- package/dist/components/charts/LineChart/LineChart.types.d.ts +11 -14
- package/dist/components/charts/LineChart/LineChart.types.js +11 -3
- package/dist/components/charts/LollipopChart/LollipopChart.d.ts +3 -0
- package/dist/components/charts/LollipopChart/LollipopChart.js +361 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.d.ts +42 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.js +12 -0
- package/dist/components/charts/LollipopChart/index.d.ts +3 -0
- package/dist/components/charts/RadarChart/RadarChart.js +1 -1
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +151 -133
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +20 -18
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.js +10 -4
- package/dist/components/charts/hooks/useChartAccessibility.d.ts +1 -1
- package/dist/components/charts/hooks/useChartAccessibility.js +12 -6
- package/dist/components/charts/hooks/useTooltipPosition.js +18 -6
- package/dist/components/charts/index.d.ts +10 -8
- package/dist/components/charts/index.js +8 -4
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.js +35 -0
- package/dist/components/charts/shared/ChartAxis/ChartAxis.types.d.ts +69 -8
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.js +64 -0
- package/dist/components/charts/shared/ChartAxis/XAxis.js +1 -1
- package/dist/components/charts/shared/ChartAxis/YAxis.js +2 -2
- package/dist/components/charts/shared/ChartAxis/index.d.ts +3 -1
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +0 -2
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +1 -1
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.d.ts +29 -0
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.js +26 -0
- package/dist/components/charts/shared/ChartGrid/index.d.ts +2 -0
- package/dist/components/charts/shared/ChartMarker/ChartMarker.js +7 -1
- package/dist/components/charts/shared/ChartText/ChartText.theme.js +1 -1
- package/dist/components/charts/shared/index.d.ts +1 -1
- package/dist/components/charts/theme/chart.theme.js +21 -26
- package/dist/components/charts/types/chart.types.d.ts +9 -5
- package/dist/components/charts/types/chart.types.js +1 -7
- package/dist/components/charts/utils/animation-utils.d.ts +12 -7
- package/dist/components/charts/utils/animation-utils.js +19 -21
- package/dist/components/charts/utils/bar-emphasis.d.ts +32 -3
- package/dist/components/charts/utils/bar-emphasis.js +24 -8
- package/dist/components/charts/utils/index.d.ts +1 -0
- package/dist/components/charts/utils/series-color.d.ts +7 -0
- package/dist/components/charts/utils/series-color.js +20 -0
- package/dist/components/core/Accordion/Accordion.theme.js +3 -3
- package/dist/components/core/Accordion/AccordionTrigger.js +2 -2
- package/dist/components/core/Alert/Alert.animations.d.ts +11 -3
- package/dist/components/core/Alert/Alert.animations.js +30 -8
- package/dist/components/core/Alert/Alert.js +23 -9
- package/dist/components/core/Alert/Alert.theme.js +1 -1
- package/dist/components/core/Alert/Alert.types.d.ts +4 -2
- package/dist/components/core/AlertDialog/AlertDialog.js +2 -2
- package/dist/components/core/Avatar/Avatar.js +50 -42
- package/dist/components/core/Avatar/Avatar.theme.d.ts +8 -4
- package/dist/components/core/Avatar/Avatar.theme.js +64 -8
- package/dist/components/core/Avatar/Avatar.types.d.ts +13 -2
- package/dist/components/core/Avatar/index.d.ts +1 -1
- package/dist/components/core/AvatarGroup/AvatarGroup.js +6 -8
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.d.ts +1 -2
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +2 -6
- package/dist/components/core/AvatarGroup/AvatarGroup.types.d.ts +0 -6
- package/dist/components/core/AvatarGroup/index.d.ts +1 -1
- package/dist/components/core/Badge/Badge.animations.d.ts +0 -5
- package/dist/components/core/Badge/Badge.animations.js +5 -82
- package/dist/components/core/Badge/Badge.d.ts +7 -4
- package/dist/components/core/Badge/Badge.js +33 -65
- package/dist/components/core/Badge/Badge.theme.js +26 -24
- package/dist/components/core/Badge/Badge.types.d.ts +18 -34
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.d.ts +1 -4
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +6 -6
- package/dist/components/core/Button/Button.js +14 -58
- package/dist/components/core/Button/Button.theme.d.ts +2 -0
- package/dist/components/core/Button/Button.theme.js +35 -22
- package/dist/components/core/Button/Button.types.d.ts +26 -13
- package/dist/components/core/Button/index.d.ts +0 -2
- package/dist/components/core/Calendar/Calendar.js +20 -5
- package/dist/components/core/Calendar/Calendar.theme.js +15 -23
- package/dist/components/core/Calendar/Calendar.types.d.ts +0 -1
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +3 -3
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +2 -2
- package/dist/components/core/Card/Card.js +7 -2
- package/dist/components/core/Card/Card.theme.js +40 -4
- package/dist/components/core/Card/Card.types.d.ts +20 -0
- package/dist/components/core/Card/CardBody.js +9 -1
- package/dist/components/core/Card/CardContext.d.ts +13 -0
- package/dist/components/core/Card/CardContext.js +14 -0
- package/dist/components/core/Card/CardFooter.js +1 -1
- package/dist/components/core/Card/CardHeader.js +4 -1
- package/dist/components/core/CommandPalette/CommandPalette.js +5 -4
- package/dist/components/core/CommandPalette/CommandPalette.theme.js +3 -7
- package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +2 -0
- package/dist/components/core/ContextMenu/ContextMenu.theme.js +4 -3
- package/dist/components/core/ContextMenu/ContextMenu.types.d.ts +8 -1
- package/dist/components/core/ContextMenu/ContextMenuItem.js +2 -2
- package/dist/components/core/ContextMenu/ContextMenuSub.d.ts +11 -1
- package/dist/components/core/ContextMenu/ContextMenuSub.js +35 -22
- package/dist/components/core/ContextMenu/ContextMenuSubBody.js +14 -3
- package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +22 -9
- package/dist/components/core/DragDrop/DragDrop.theme.js +2 -2
- package/dist/components/core/Drawer/Drawer.theme.js +7 -4
- package/dist/components/core/Drawer/DrawerHeader.js +2 -3
- package/dist/components/core/Dropdown/Dropdown.theme.js +3 -1
- package/dist/components/core/Dropdown/DropdownItem.js +2 -2
- package/dist/components/core/Dropdown/DropdownMenu.js +22 -7
- package/dist/components/core/Dropdown/DropdownTrigger.js +16 -5
- package/dist/components/core/HeroCard/HeroCard.theme.js +5 -2
- package/dist/components/core/Kbd/Kbd.theme.js +4 -2
- package/dist/components/core/Link/Link.js +7 -5
- package/dist/components/core/Masonry/Masonry.theme.js +1 -1
- package/dist/components/core/MenuItem/MenuItem.js +2 -1
- package/dist/components/core/MenuItem/MenuItem.theme.js +13 -1
- package/dist/components/core/Message/Message.js +4 -2
- package/dist/components/core/Message/Message.theme.js +8 -10
- package/dist/components/core/Message/MessageAudio.js +2 -2
- package/dist/components/core/Message/MessageFile.js +2 -2
- package/dist/components/core/Message/MessageLink.js +2 -2
- package/dist/components/core/Message/MessageStatusIndicator.js +5 -5
- package/dist/components/core/Modal/Modal.animations.d.ts +1 -1
- package/dist/components/core/Modal/Modal.animations.js +50 -11
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +6 -2
- package/dist/components/core/Modal/Modal.theme.js +9 -4
- package/dist/components/core/Modal/ModalHeader.js +2 -3
- package/dist/components/core/ModalStack/ModalStackModal.js +4 -2
- package/dist/components/core/NavItem/NavItem.js +8 -7
- package/dist/components/core/NavItem/NavItem.theme.js +1 -1
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.d.ts +22 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.js +54 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.js +23 -24
- package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +27 -6
- package/dist/components/core/OfflineIndicator/OfflineIndicator.types.d.ts +17 -0
- package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
- package/dist/components/core/PageHeading/PageHeadingBackButton.js +2 -2
- package/dist/components/core/Pagination/Pagination.js +3 -3
- package/dist/components/core/Pagination/Pagination.theme.js +5 -5
- package/dist/components/core/Pill/Pill.js +5 -2
- package/dist/components/core/Pill/Pill.theme.js +9 -5
- package/dist/components/core/Popover/PopoverBody.js +16 -5
- package/dist/components/core/Progress/Progress.d.ts +0 -25
- package/dist/components/core/Progress/Progress.js +79 -11
- package/dist/components/core/Progress/Progress.theme.js +17 -0
- package/dist/components/core/Progress/Progress.types.d.ts +47 -1
- package/dist/components/core/Rating/Rating.js +4 -5
- package/dist/components/core/Rating/Rating.theme.js +2 -2
- package/dist/components/core/Rating/Rating.types.d.ts +3 -2
- package/dist/components/core/ScrollArea/ScrollArea.js +1 -1
- package/dist/components/core/ScrollArea/ScrollArea.theme.js +1 -1
- package/dist/components/core/Segmented/Segmented.theme.js +10 -7
- package/dist/components/core/Segmented/SegmentedContext.js +1 -0
- package/dist/components/core/Sidebar/Sidebar.js +5 -2
- package/dist/components/core/Sidebar/Sidebar.theme.js +2 -2
- package/dist/components/core/Sidebar/Sidebar.types.d.ts +4 -2
- package/dist/components/core/Sidebar/SidebarContent.js +1 -1
- package/dist/components/core/Sidebar/SidebarHeader.js +3 -3
- package/dist/components/core/Sidebar/SidebarMobileTrigger.js +2 -2
- package/dist/components/core/Sidebar/SidebarSearch.js +4 -4
- package/dist/components/core/Sidebar/SidebarToggle.js +3 -3
- package/dist/components/core/Sidebar/SidebarUserProfile.js +3 -3
- package/dist/components/core/Sortable/Sortable.js +2 -2
- package/dist/components/core/Sortable/Sortable.theme.js +1 -1
- package/dist/components/core/Tabs/Tabs.theme.js +1 -1
- package/dist/components/core/Tag/Tag.js +2 -2
- package/dist/components/core/Tag/Tag.theme.js +5 -3
- package/dist/components/core/Toast/Toast.js +3 -3
- package/dist/components/core/Toast/Toast.types.d.ts +1 -1
- package/dist/components/core/Toast/ToastProvider.js +1 -1
- package/dist/components/core/Toast/useToast.js +5 -5
- package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/core/Tooltip/Tooltip.js +42 -10
- package/dist/components/core/Tooltip/Tooltip.types.d.ts +25 -0
- package/dist/components/core/Tree/Tree.js +2 -2
- package/dist/components/core/Tree/Tree.theme.js +1 -1
- package/dist/components/core/index.d.ts +0 -2
- package/dist/components/core/index.js +0 -4
- package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.d.ts +4 -0
- package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.js +20 -0
- package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.js +1 -1
- package/dist/components/core/shared/Ripple.d.ts +16 -0
- package/dist/components/core/shared/Ripple.js +141 -0
- package/dist/components/core/shared/interaction.animations.d.ts +51 -0
- package/dist/components/core/shared/interaction.animations.js +59 -0
- package/dist/components/data-display/Feed/Feed.js +2 -2
- package/dist/components/data-display/GanttChart/GanttChart.theme.js +7 -7
- package/dist/components/data-display/GanttChart/GanttChartPanel.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTableGroupRow.js +3 -3
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +1 -1
- package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTimelineHeader.js +1 -1
- package/dist/components/data-display/GanttChart/GanttToolbar.js +2 -3
- package/dist/components/data-display/KPI/KPI.js +12 -21
- package/dist/components/data-display/KPI/KPI.theme.js +8 -4
- package/dist/components/data-display/Metric/Metric.js +2 -2
- package/dist/components/data-display/Metric/Metric.theme.js +25 -8
- package/dist/components/data-display/Metric/Metric.types.d.ts +1 -1
- package/dist/components/data-display/Table/Table.theme.js +11 -11
- package/dist/components/data-display/Table/TableActions.js +2 -2
- package/dist/components/data-display/Table/TableActionsMenu.js +1 -1
- package/dist/components/data-display/Table/TableColumnManager.js +2 -3
- package/dist/components/data-display/Table/TableContext.js +1 -0
- package/dist/components/data-display/Table/TableDeclarative.js +3 -3
- package/dist/components/data-display/Table/TableFilter.js +13 -6
- package/dist/components/data-display/Table/TableHeader.js +3 -3
- package/dist/components/data-display/Table/TableRow.js +2 -2
- package/dist/components/data-display/Table/TableSelectionHeader.js +4 -4
- package/dist/components/data-display/Timeline/Timeline.theme.js +1 -1
- package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +1 -1
- package/dist/components/effects/CustomCursor/CustomCursor.js +3 -3
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +4 -4
- package/dist/components/effects/DotPattern/DotPattern.js +6 -0
- package/dist/components/effects/DotPattern/DotPattern.types.d.ts +4 -2
- package/dist/components/effects/MeshGradient/MeshGradient.utils.d.ts +1 -1
- package/dist/components/effects/MeshGradient/MeshGradient.utils.js +1 -1
- package/dist/components/effects/Neumorphic/InsetCircleButton.js +1 -1
- package/dist/components/effects/Overlay/Overlay.js +7 -3
- package/dist/components/effects/index.d.ts +0 -32
- package/dist/components/effects/index.js +0 -16
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.d.ts +0 -2
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.js +1 -93
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.types.d.ts +0 -10
- package/dist/components/effects/shared/ShaderCanvas/index.d.ts +1 -1
- package/dist/components/effects/shared/index.d.ts +1 -3
- package/dist/components/effects/shared/shaderNoise.glsl.d.ts +1 -1
- package/dist/components/effects/shared/shaderNoise.glsl.js +2 -11
- package/dist/components/forms/Checkbox/Checkbox.js +2 -1
- package/dist/components/forms/Checkbox/Checkbox.theme.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerGradient.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerHeader.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerImage.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerInput.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerPresets.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerSavedColors.js +2 -2
- package/dist/components/forms/Combobox/Combobox.js +5 -3
- package/dist/components/forms/Combobox/Combobox.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePicker.animations.js +16 -25
- package/dist/components/forms/DatePicker/DatePicker.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +4 -4
- package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -1
- package/dist/components/forms/DateRangePicker/DateRangePickerContext.js +1 -0
- package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
- package/dist/components/forms/FileUpload/FileUpload.js +4 -4
- package/dist/components/forms/FileUpload/FileUpload.theme.js +7 -3
- package/dist/components/forms/FileUpload/FileUploadProgress.js +7 -7
- package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +1 -1
- package/dist/components/forms/Input/Input.js +6 -7
- package/dist/components/forms/Input/Input.theme.js +19 -15
- package/dist/components/forms/InputAddress/InputAddress.js +10 -3
- package/dist/components/forms/InputAddress/InputAddress.types.d.ts +2 -2
- package/dist/components/forms/InputCounter/InputCounter.js +3 -3
- package/dist/components/forms/InputOTP/InputOTP.d.ts +3 -12
- package/dist/components/forms/InputOTP/InputOTP.js +140 -151
- package/dist/components/forms/InputOTP/InputOTP.theme.d.ts +5 -1
- package/dist/components/forms/InputOTP/InputOTP.theme.js +40 -5
- package/dist/components/forms/InputOTP/InputOTP.types.d.ts +45 -2
- package/dist/components/forms/InputOTP/index.d.ts +1 -1
- package/dist/components/forms/InputTag/InputTag.js +5 -5
- package/dist/components/forms/InputTag/InputTag.theme.js +1 -2
- package/dist/components/forms/Mention/Mention.theme.js +3 -5
- package/dist/components/forms/Radio/Radio.js +3 -2
- package/dist/components/forms/Radio/Radio.theme.js +3 -3
- package/dist/components/forms/RichTextEditor/RichTextEditor.d.ts +12 -16
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +165 -1681
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.d.ts +12 -56
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +60 -118
- package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +62 -126
- package/dist/components/forms/RichTextEditor/RichTextLinkField.d.ts +18 -0
- package/dist/components/forms/RichTextEditor/RichTextLinkField.js +46 -0
- package/dist/components/forms/RichTextEditor/RichTextToolbar.d.ts +15 -0
- package/dist/components/forms/RichTextEditor/RichTextToolbar.js +93 -0
- package/dist/components/forms/RichTextEditor/editorCommands.d.ts +50 -0
- package/dist/components/forms/RichTextEditor/editorCommands.js +58 -0
- package/dist/components/forms/RichTextEditor/editorState.d.ts +19 -0
- package/dist/components/forms/RichTextEditor/editorState.js +103 -0
- package/dist/components/forms/RichTextEditor/index.d.ts +5 -3
- package/dist/components/forms/RichTextEditor/sanitizeHtml.d.ts +38 -0
- package/dist/components/forms/RichTextEditor/sanitizeHtml.js +179 -0
- package/dist/components/forms/RichTextEditor/sanitizeHtml.test.d.ts +1 -0
- package/dist/components/forms/Select/Select.d.ts +5 -1
- package/dist/components/forms/Select/Select.js +14 -13
- package/dist/components/forms/Select/Select.theme.js +4 -4
- package/dist/components/forms/Select/Select.types.d.ts +74 -8
- package/dist/components/forms/Select/useSelectState.d.ts +9 -3
- package/dist/components/forms/Select/useSelectState.js +4 -1
- package/dist/components/forms/SelectableCard/SelectableCard.animations.d.ts +1 -2
- package/dist/components/forms/SelectableCard/SelectableCard.animations.js +6 -7
- package/dist/components/forms/SelectableCard/SelectableCard.js +3 -2
- package/dist/components/forms/SelectableCard/SelectableCard.theme.js +1 -1
- package/dist/components/forms/Signature/Signature.js +1 -1
- package/dist/components/forms/Slider/Slider.js +24 -11
- package/dist/components/forms/Slider/Slider.theme.js +9 -3
- package/dist/components/forms/Switch/Switch.theme.js +3 -3
- package/dist/components/forms/TimePicker/TimePicker.theme.js +7 -8
- package/dist/components/forms/TimePicker/TimePickerContent.js +1 -1
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +3 -3
- package/dist/components/forms/forms.theme.js +38 -13
- package/dist/components/forms/index.js +2 -1
- package/dist/components/generative/FormShell.d.ts +22 -0
- package/dist/components/generative/FormShell.js +102 -0
- package/dist/components/generative/GenerativeView.d.ts +52 -1
- package/dist/components/generative/GenerativeView.js +203 -11
- package/dist/components/generative/actions.d.ts +5 -0
- package/dist/components/generative/ai-sdk/index.d.ts +1 -0
- package/dist/components/generative/ai-sdk/index.js +1 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.d.ts +52 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.js +73 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.test.d.ts +1 -0
- package/dist/components/generative/fieldBinding.d.ts +31 -0
- package/dist/components/generative/fieldBinding.js +33 -0
- package/dist/components/generative/fieldBinding.test.d.ts +1 -0
- package/dist/components/generative/formScope.d.ts +71 -0
- package/dist/components/generative/formScope.js +135 -0
- package/dist/components/generative/index.d.ts +4 -0
- package/dist/components/generative/index.js +4 -0
- package/dist/components/generative/registry.d.ts +2 -0
- package/dist/components/generative/registry.js +197 -4
- package/dist/components/generative/resolvers.js +16 -16
- package/dist/components/generative/schema.generated.js +2522 -328
- package/dist/components/generative/toToolResult.d.ts +21 -0
- package/dist/components/generative/toToolResult.js +15 -0
- package/dist/components/generative/toToolResult.test.d.ts +1 -0
- package/dist/components/generative/validate.d.ts +10 -1
- package/dist/components/generative/validate.js +126 -11
- package/dist/components/layout/Grid/Grid.js +1 -0
- package/dist/components/layout/Section/Section.theme.js +1 -1
- package/dist/components/layout/Stack/Stack.js +1 -0
- package/dist/generative.schema.json +2522 -328
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useElapsedTime.d.ts +28 -0
- package/dist/hooks/useElapsedTime.js +37 -0
- package/dist/hooks/useSelectPortal.d.ts +10 -2
- package/dist/hooks/useSelectPortal.js +6 -3
- package/dist/index.js +2 -5
- package/dist/registry.json +3262 -2464
- package/dist/shadcn-compat.css +6 -6
- package/dist/styles/theme.test.d.ts +1 -0
- package/dist/styles.css +1 -1
- package/dist/test/render.d.ts +17 -0
- package/dist/theme.css +5 -1
- package/dist/themes/ember.css +131 -0
- package/dist/themes/iris.css +94 -0
- package/dist/themes/jade.css +139 -0
- package/dist/themes/precision.css +232 -0
- package/dist/tools.json +2557 -328
- package/dist/utils/colorUtils.d.ts +6 -6
- package/dist/utils/colorUtils.js +8 -8
- package/dist/utils/index.d.ts +0 -1
- package/package.json +39 -6
- package/src/global.scss +32 -28
- package/src/styles/theme.css +547 -176
- package/src/styles/theme.test.ts +119 -0
- package/tailwind.preset.cjs +66 -38
- package/dist/components/charts/FunnelChart/FunnelChart.animations.d.ts +0 -35
- package/dist/components/charts/FunnelChart/FunnelChart.animations.js +0 -59
- package/dist/components/charts/FunnelChart/FunnelChart.d.ts +0 -8
- package/dist/components/charts/FunnelChart/FunnelChart.js +0 -410
- package/dist/components/charts/FunnelChart/FunnelChart.theme.d.ts +0 -2
- package/dist/components/charts/FunnelChart/FunnelChart.theme.js +0 -12
- package/dist/components/charts/FunnelChart/FunnelChart.types.d.ts +0 -105
- package/dist/components/charts/FunnelChart/index.d.ts +0 -4
- package/dist/components/charts/ScatterPlot/ScatterPlot.d.ts +0 -9
- package/dist/components/charts/ScatterPlot/ScatterPlot.js +0 -207
- package/dist/components/charts/ScatterPlot/ScatterPlot.theme.d.ts +0 -18
- package/dist/components/charts/ScatterPlot/ScatterPlot.theme.js +0 -42
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +0 -65
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +0 -12
- package/dist/components/charts/ScatterPlot/index.d.ts +0 -3
- package/dist/components/core/Button/Button.ripple.d.ts +0 -71
- package/dist/components/core/Button/Button.ripple.js +0 -236
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.d.ts +0 -4
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.theme.d.ts +0 -12
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +0 -23
- package/dist/components/core/Calendar/CalendarEvent/index.d.ts +0 -2
- package/dist/components/core/CardStack/CardStack.animations.d.ts +0 -47
- package/dist/components/core/CardStack/CardStack.d.ts +0 -3
- package/dist/components/core/CardStack/CardStack.js +0 -187
- package/dist/components/core/CardStack/CardStack.theme.d.ts +0 -6
- package/dist/components/core/CardStack/CardStack.theme.js +0 -33
- package/dist/components/core/CardStack/CardStack.types.d.ts +0 -139
- package/dist/components/core/CardStack/index.d.ts +0 -7
- package/dist/components/core/Carousel/Carousel.d.ts +0 -3
- package/dist/components/core/Carousel/Carousel.js +0 -83
- package/dist/components/core/Carousel/Carousel.theme.d.ts +0 -10
- package/dist/components/core/Carousel/Carousel.theme.js +0 -20
- package/dist/components/core/Carousel/Carousel.types.d.ts +0 -113
- package/dist/components/core/Carousel/CarouselBody.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselBody.js +0 -59
- package/dist/components/core/Carousel/CarouselContext.d.ts +0 -3
- package/dist/components/core/Carousel/CarouselContext.js +0 -13
- package/dist/components/core/Carousel/CarouselItem.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselItem.js +0 -11
- package/dist/components/core/Carousel/CarouselNext.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselNext.js +0 -16
- package/dist/components/core/Carousel/CarouselPrevious.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselPrevious.js +0 -16
- package/dist/components/core/Carousel/index.d.ts +0 -3
- package/dist/components/core/Pill/Pill.animations.d.ts +0 -32
- package/dist/components/core/Pill/Pill.animations.js +0 -16
- package/dist/components/effects/ColorPanels/ColorPanels.d.ts +0 -8
- package/dist/components/effects/ColorPanels/ColorPanels.js +0 -66
- package/dist/components/effects/ColorPanels/ColorPanels.shaders.d.ts +0 -12
- package/dist/components/effects/ColorPanels/ColorPanels.shaders.js +0 -218
- package/dist/components/effects/ColorPanels/ColorPanels.types.d.ts +0 -29
- package/dist/components/effects/ColorPanels/ColorPanels.types.js +0 -3
- package/dist/components/effects/ColorPanels/index.d.ts +0 -2
- package/dist/components/effects/FlutedGlass/FlutedGlass.d.ts +0 -9
- package/dist/components/effects/FlutedGlass/FlutedGlass.js +0 -80
- package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.d.ts +0 -12
- package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.js +0 -335
- package/dist/components/effects/FlutedGlass/FlutedGlass.types.d.ts +0 -61
- package/dist/components/effects/FlutedGlass/FlutedGlass.types.js +0 -16
- package/dist/components/effects/FlutedGlass/index.d.ts +0 -3
- package/dist/components/effects/GlassEffect/GlassEffect.d.ts +0 -15
- package/dist/components/effects/GlassEffect/GlassEffect.js +0 -38
- package/dist/components/effects/GlassEffect/GlassEffect.types.d.ts +0 -19
- package/dist/components/effects/GlassEffect/index.d.ts +0 -2
- package/dist/components/effects/GlassSurface/GlassSurface.d.ts +0 -8
- package/dist/components/effects/GlassSurface/GlassSurface.js +0 -250
- package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +0 -66
- package/dist/components/effects/GlassSurface/index.d.ts +0 -2
- package/dist/components/effects/GodRays/GodRays.d.ts +0 -8
- package/dist/components/effects/GodRays/GodRays.js +0 -68
- package/dist/components/effects/GodRays/GodRays.shaders.d.ts +0 -10
- package/dist/components/effects/GodRays/GodRays.shaders.js +0 -128
- package/dist/components/effects/GodRays/GodRays.types.d.ts +0 -25
- package/dist/components/effects/GodRays/GodRays.types.js +0 -3
- package/dist/components/effects/GodRays/index.d.ts +0 -2
- package/dist/components/effects/GridPattern/GridPattern.d.ts +0 -18
- package/dist/components/effects/GridPattern/GridPattern.js +0 -65
- package/dist/components/effects/GridPattern/GridPattern.types.d.ts +0 -47
- package/dist/components/effects/GridPattern/index.d.ts +0 -2
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.d.ts +0 -10
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.js +0 -78
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.d.ts +0 -22
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.js +0 -239
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.types.d.ts +0 -52
- package/dist/components/effects/HalftoneCmyk/index.d.ts +0 -2
- package/dist/components/effects/HalftoneDots/HalftoneDots.d.ts +0 -9
- package/dist/components/effects/HalftoneDots/HalftoneDots.js +0 -68
- package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.d.ts +0 -13
- package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.js +0 -296
- package/dist/components/effects/HalftoneDots/HalftoneDots.types.d.ts +0 -43
- package/dist/components/effects/HalftoneDots/HalftoneDots.types.js +0 -12
- package/dist/components/effects/HalftoneDots/index.d.ts +0 -3
- package/dist/components/effects/ImageDithering/ImageDithering.d.ts +0 -9
- package/dist/components/effects/ImageDithering/ImageDithering.js +0 -68
- package/dist/components/effects/ImageDithering/ImageDithering.shaders.d.ts +0 -12
- package/dist/components/effects/ImageDithering/ImageDithering.shaders.js +0 -117
- package/dist/components/effects/ImageDithering/ImageDithering.types.d.ts +0 -30
- package/dist/components/effects/ImageDithering/ImageDithering.types.js +0 -8
- package/dist/components/effects/ImageDithering/index.d.ts +0 -3
- package/dist/components/effects/MagneticElement/MagneticElement.d.ts +0 -30
- package/dist/components/effects/MagneticElement/MagneticElement.js +0 -111
- package/dist/components/effects/MagneticElement/MagneticElement.types.d.ts +0 -44
- package/dist/components/effects/MagneticElement/index.d.ts +0 -2
- package/dist/components/effects/Metaballs/Metaballs.d.ts +0 -8
- package/dist/components/effects/Metaballs/Metaballs.js +0 -59
- package/dist/components/effects/Metaballs/Metaballs.shaders.d.ts +0 -10
- package/dist/components/effects/Metaballs/Metaballs.shaders.js +0 -102
- package/dist/components/effects/Metaballs/Metaballs.types.d.ts +0 -16
- package/dist/components/effects/Metaballs/Metaballs.types.js +0 -3
- package/dist/components/effects/Metaballs/index.d.ts +0 -2
- package/dist/components/effects/PaperTexture/PaperTexture.d.ts +0 -9
- package/dist/components/effects/PaperTexture/PaperTexture.js +0 -61
- package/dist/components/effects/PaperTexture/PaperTexture.shaders.d.ts +0 -22
- package/dist/components/effects/PaperTexture/PaperTexture.shaders.js +0 -145
- package/dist/components/effects/PaperTexture/PaperTexture.types.d.ts +0 -19
- package/dist/components/effects/PaperTexture/index.d.ts +0 -2
- package/dist/components/effects/PulsingBorder/PulsingBorder.d.ts +0 -27
- package/dist/components/effects/PulsingBorder/PulsingBorder.js +0 -174
- package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.d.ts +0 -14
- package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.js +0 -258
- package/dist/components/effects/PulsingBorder/PulsingBorder.types.d.ts +0 -75
- package/dist/components/effects/PulsingBorder/PulsingBorder.types.js +0 -3
- package/dist/components/effects/PulsingBorder/index.d.ts +0 -2
- package/dist/components/effects/SmokeRing/SmokeRing.d.ts +0 -8
- package/dist/components/effects/SmokeRing/SmokeRing.js +0 -62
- package/dist/components/effects/SmokeRing/SmokeRing.shaders.d.ts +0 -14
- package/dist/components/effects/SmokeRing/SmokeRing.shaders.js +0 -130
- package/dist/components/effects/SmokeRing/SmokeRing.types.d.ts +0 -22
- package/dist/components/effects/SmokeRing/SmokeRing.types.js +0 -3
- package/dist/components/effects/SmokeRing/index.d.ts +0 -2
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.d.ts +0 -9
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.js +0 -59
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.d.ts +0 -14
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.js +0 -129
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.d.ts +0 -23
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.js +0 -3
- package/dist/components/effects/StaticGradientMesh/index.d.ts +0 -2
- package/dist/components/effects/Water/Water.d.ts +0 -9
- package/dist/components/effects/Water/Water.js +0 -65
- package/dist/components/effects/Water/Water.shaders.d.ts +0 -11
- package/dist/components/effects/Water/Water.shaders.js +0 -123
- package/dist/components/effects/Water/Water.types.d.ts +0 -25
- package/dist/components/effects/Water/index.d.ts +0 -2
- package/dist/components/effects/shared/bayerMatrices.glsl.d.ts +0 -10
- package/dist/components/effects/shared/bayerMatrices.glsl.js +0 -44
- package/dist/components/effects/shared/imageUV.glsl.d.ts +0 -12
- package/dist/components/effects/shared/imageUV.glsl.js +0 -26
- package/dist/components/forms/RichTextEditor/RichTextEditor.animations.d.ts +0 -7
- package/dist/components/forms/RichTextEditor/RichTextEditor.animations.js +0 -32
- package/dist/utils/calendarUtils.d.ts +0 -60
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.js +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.types.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltipContent.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/index.d.ts +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
/**
|
|
3
|
+
* Motion for the agent-request panel.
|
|
4
|
+
*
|
|
5
|
+
* One question is on screen at a time and the panel resizes to fit it, so the
|
|
6
|
+
* motion is a two-part gesture: the question SLIDES in the direction of travel
|
|
7
|
+
* (forward = in from the right, back = in from the left, so the arrows have a
|
|
8
|
+
* physical meaning), while the panel HEIGHT tweens to the incoming question's
|
|
9
|
+
* measured height. `AnimatePresence mode="wait"` keeps them from crossing over
|
|
10
|
+
* — the outgoing question is gone before the incoming one starts, which is what
|
|
11
|
+
* makes a taller or shorter next question read as a resize rather than a jump.
|
|
12
|
+
*
|
|
13
|
+
* These are motion/react values (seconds, JS numbers) and therefore do NOT
|
|
14
|
+
* track `--motion-duration-*` — per §12 that token family covers CSS
|
|
15
|
+
* transitions only. They are tuned to sit alongside those tiers, so if a theme
|
|
16
|
+
* retunes the CSS durations these want adjusting to match.
|
|
17
|
+
*/
|
|
18
|
+
/** Expo-out. Weighted settle — fast departure, long soft landing. */
|
|
19
|
+
const EXPO = [0.32, 0.72, 0, 1];
|
|
20
|
+
/** How far a question travels on the way in/out. */
|
|
21
|
+
const SLIDE = 14;
|
|
22
|
+
const INSTANT = { duration: 0 };
|
|
23
|
+
const panelAnimations = {
|
|
24
|
+
hidden: { opacity: 0, y: 14, scale: 0.97 },
|
|
25
|
+
visible: {
|
|
26
|
+
opacity: 1,
|
|
27
|
+
y: 0,
|
|
28
|
+
scale: 1,
|
|
29
|
+
transition: { duration: 0.4, ease: EXPO, when: "beforeChildren" },
|
|
30
|
+
},
|
|
31
|
+
exit: {
|
|
32
|
+
opacity: 0,
|
|
33
|
+
y: 10,
|
|
34
|
+
scale: 0.98,
|
|
35
|
+
transition: { duration: 0.3, ease: EXPO },
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The question swap. `custom` is the direction of travel: 1 when advancing,
|
|
40
|
+
* -1 when the user arrows back. Exit is deliberately quicker than enter — the
|
|
41
|
+
* outgoing question should clear out of the way, not perform.
|
|
42
|
+
*/
|
|
43
|
+
const questionAnimations = {
|
|
44
|
+
enter: (direction = 1) => ({ opacity: 0, x: direction * SLIDE }),
|
|
45
|
+
center: {
|
|
46
|
+
opacity: 1,
|
|
47
|
+
x: 0,
|
|
48
|
+
transition: { duration: 0.28, ease: EXPO },
|
|
49
|
+
},
|
|
50
|
+
exit: (direction = 1) => ({
|
|
51
|
+
opacity: 0,
|
|
52
|
+
x: direction * -SLIDE,
|
|
53
|
+
transition: { duration: 0.14, ease: "easeOut" },
|
|
54
|
+
}),
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Reduced-motion twins of the two variant sets above.
|
|
58
|
+
*
|
|
59
|
+
* 🔴 They exist because a variant's OWN `transition` overrides the element's
|
|
60
|
+
* `transition` prop in motion — so passing `INSTANT` down alongside variants
|
|
61
|
+
* that each carry a transition does nothing, and the opt-out silently animates
|
|
62
|
+
* anyway. §12's rule ("motion props apply only when both allow") therefore has
|
|
63
|
+
* to be honoured by swapping the VARIANTS, not the transition. The states are
|
|
64
|
+
* kept identical so `initial`/`animate`/`exit` don't have to branch: only the
|
|
65
|
+
* travel (y/x/scale) and the duration are dropped, and the opacity states stay
|
|
66
|
+
* so `AnimatePresence` still has something to resolve against.
|
|
67
|
+
*/
|
|
68
|
+
const panelAnimationsInstant = {
|
|
69
|
+
hidden: { opacity: 0, y: 0, scale: 1 },
|
|
70
|
+
visible: { opacity: 1, y: 0, scale: 1, transition: INSTANT },
|
|
71
|
+
exit: { opacity: 0, y: 0, scale: 1, transition: INSTANT },
|
|
72
|
+
};
|
|
73
|
+
const questionAnimationsInstant = {
|
|
74
|
+
enter: { opacity: 0, x: 0 },
|
|
75
|
+
center: { opacity: 1, x: 0, transition: INSTANT },
|
|
76
|
+
exit: { opacity: 0, x: 0, transition: INSTANT },
|
|
77
|
+
};
|
|
78
|
+
/** The panel growing/shrinking to the measured height of the new question. */
|
|
79
|
+
const HEIGHT_TRANSITION = { duration: 0.32, ease: EXPO };
|
|
80
|
+
|
|
81
|
+
export { HEIGHT_TRANSITION, INSTANT, panelAnimations, panelAnimationsInstant, questionAnimations, questionAnimationsInstant };
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import React__default, { useMemo, useId, useRef, useState, useCallback, useEffect } from 'react';
|
|
4
|
+
import { CaretLeft, CaretRight, X, Check } from '@phosphor-icons/react';
|
|
5
|
+
import { motion, useReducedMotion, AnimatePresence } from 'motion/react';
|
|
6
|
+
import { cn } from '../../../utils/cn.js';
|
|
7
|
+
import { Button } from '../../core/Button/Button.js';
|
|
8
|
+
import { Card } from '../../core/Card/Card.js';
|
|
9
|
+
import { Input } from '../../forms/Input/Input.js';
|
|
10
|
+
import '../../forms/Input/Input.theme.js';
|
|
11
|
+
import { Radio } from '../../forms/Radio/Radio.js';
|
|
12
|
+
import { Checkbox } from '../../forms/Checkbox/Checkbox.js';
|
|
13
|
+
import { agentRequestTheme } from './AgentRequest.theme.js';
|
|
14
|
+
import { panelAnimationsInstant, panelAnimations, INSTANT, HEIGHT_TRANSITION, questionAnimationsInstant, questionAnimations } from './AgentRequest.animations.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The panel IS a `Card` — it takes the surface, the elevation shadow and the
|
|
18
|
+
* `--field-fill` its controls need from the relative-elevation engine instead
|
|
19
|
+
* of hand-painting them (§3). `motion.create` because it also has to animate
|
|
20
|
+
* in and out of the composer slot; Card forwards its ref and spreads the rest
|
|
21
|
+
* of its props onto its root element, which is everything motion needs.
|
|
22
|
+
*
|
|
23
|
+
* 🔴 The SURFACE only — no `Card.Body`. Card's slots pad by `--card-px/py`
|
|
24
|
+
* (24px) and this panel's inset is 16px; stacking the two put the heading at
|
|
25
|
+
* 40px while its own options and actions sat at 24px.
|
|
26
|
+
*/
|
|
27
|
+
const MotionCard = motion.create(Card);
|
|
28
|
+
/**
|
|
29
|
+
* Display text for an option. `label` is a ReactNode, but an answer's `label`
|
|
30
|
+
* has to be a plain string (it lands in the answer payload and in the answered
|
|
31
|
+
* chip), so fall back to the value when the label isn't stringy.
|
|
32
|
+
*/
|
|
33
|
+
const optionText = (option) => option === undefined
|
|
34
|
+
? ""
|
|
35
|
+
: typeof option.label === "string"
|
|
36
|
+
? option.label
|
|
37
|
+
: option.value;
|
|
38
|
+
const defaultProgressLabel = (current, total) => `${current} of ${total}`;
|
|
39
|
+
/**
|
|
40
|
+
* The free-text entry inside a recorded answer, if it has one.
|
|
41
|
+
*
|
|
42
|
+
* A value that is not on the option list can only have come from `allowOther`,
|
|
43
|
+
* so on revisit it belongs back in that row. Without this it sat inside
|
|
44
|
+
* `selection` with no checkbox to render it — invisible, uneditable, and still
|
|
45
|
+
* silently attached to the answer on every re-confirm.
|
|
46
|
+
*/
|
|
47
|
+
const offListAnswer = (question, answer) => {
|
|
48
|
+
var _a;
|
|
49
|
+
if (question.kind !== "choice" || !question.allowOther)
|
|
50
|
+
return "";
|
|
51
|
+
if ((answer === null || answer === void 0 ? void 0 : answer.outcome) !== "resolved")
|
|
52
|
+
return "";
|
|
53
|
+
const values = Array.isArray(answer.value) ? answer.value : [answer.value];
|
|
54
|
+
return (_a = values.find((v) => !question.options.some((o) => o.value === v))) !== null && _a !== void 0 ? _a : "";
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* One question's body.
|
|
58
|
+
*
|
|
59
|
+
* A component rather than a render function so that its drafts (typed text,
|
|
60
|
+
* ticked boxes) are OWNED BY THE MOUNT: it is keyed by question id inside the
|
|
61
|
+
* `AnimatePresence`, so moving to another question remounts it and the drafts
|
|
62
|
+
* reset, and arrowing back re-seeds them from the recorded answer. Doing that
|
|
63
|
+
* with effects in the parent meant a controlled consumer handing back a fresh
|
|
64
|
+
* `answers` array on every render could wipe half-typed text.
|
|
65
|
+
*/
|
|
66
|
+
const QuestionBody = ({ question, answer, theme, fieldId, questionTextId, navReserve, scroll, onAnswer, }) => {
|
|
67
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
68
|
+
const [draft, setDraft] = useState(() => question.kind === "input" &&
|
|
69
|
+
(answer === null || answer === void 0 ? void 0 : answer.outcome) === "resolved" &&
|
|
70
|
+
typeof answer.value === "string"
|
|
71
|
+
? answer.value
|
|
72
|
+
: "");
|
|
73
|
+
// The off-list value is pulled OUT of the ticked set and back into the
|
|
74
|
+
// free-text row it came from, so the two drafts never both hold it.
|
|
75
|
+
const [selection, setSelection] = useState(() => {
|
|
76
|
+
if (!answer || !Array.isArray(answer.value))
|
|
77
|
+
return [];
|
|
78
|
+
const off = offListAnswer(question, answer);
|
|
79
|
+
return off ? answer.value.filter((v) => v !== off) : answer.value;
|
|
80
|
+
});
|
|
81
|
+
/** The free-text draft for the "something else" row. */
|
|
82
|
+
const [other, setOther] = useState(() => offListAnswer(question, answer));
|
|
83
|
+
const toggleSelection = useCallback((value, checked) => {
|
|
84
|
+
setSelection((current) => checked
|
|
85
|
+
? current.includes(value)
|
|
86
|
+
? current
|
|
87
|
+
: [...current, value]
|
|
88
|
+
: current.filter((v) => v !== value));
|
|
89
|
+
}, []);
|
|
90
|
+
// Discriminate on `question.kind` directly at each branch — hoisting it into
|
|
91
|
+
// a `kind` variable does NOT narrow the union, so `question.options` would
|
|
92
|
+
// not type-check inside the choice branch.
|
|
93
|
+
const isMulti = question.kind === "choice" && question.multiple === true;
|
|
94
|
+
const minSelected = isMulti ? ((_a = question.minSelected) !== null && _a !== void 0 ? _a : 0) : 0;
|
|
95
|
+
const maxSelected = isMulti ? question.maxSelected : undefined;
|
|
96
|
+
/**
|
|
97
|
+
* 🔴 The multi-choice bounds, checked in the COMMIT path and not only in the
|
|
98
|
+
* Confirm button's disabled state. The free-text row commits straight from
|
|
99
|
+
* its Enter key, which walked past both `minSelected` and `maxSelected`
|
|
100
|
+
* however the button was rendered.
|
|
101
|
+
*/
|
|
102
|
+
const withinBounds = (count) => count > 0 &&
|
|
103
|
+
count >= minSelected &&
|
|
104
|
+
(maxSelected === undefined || count <= maxSelected);
|
|
105
|
+
/**
|
|
106
|
+
* Human-readable label for a set of selected values. The `|| v` fallback is
|
|
107
|
+
* load-bearing: a value that isn't on the option list came from `allowOther`,
|
|
108
|
+
* and without it the join left an empty segment behind ("#a, , #b").
|
|
109
|
+
*/
|
|
110
|
+
const labelFor = (values) => question.kind === "choice"
|
|
111
|
+
? values
|
|
112
|
+
.map((v) => optionText(question.options.find((o) => o.value === v)) || v)
|
|
113
|
+
.join(", ")
|
|
114
|
+
: values.join(", ");
|
|
115
|
+
/**
|
|
116
|
+
* Commit the "something else" text. On a multi-choice question it joins the
|
|
117
|
+
* ticked options rather than replacing them, so the answer keeps the array
|
|
118
|
+
* shape the question's type promises.
|
|
119
|
+
*/
|
|
120
|
+
const submitOther = () => {
|
|
121
|
+
if (question.kind !== "choice")
|
|
122
|
+
return;
|
|
123
|
+
const text = other.trim();
|
|
124
|
+
if (!text)
|
|
125
|
+
return;
|
|
126
|
+
if (question.multiple) {
|
|
127
|
+
const values = [...selection, text];
|
|
128
|
+
if (!withinBounds(values.length))
|
|
129
|
+
return;
|
|
130
|
+
onAnswer(values, labelFor(values));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
onAnswer(text, text);
|
|
134
|
+
};
|
|
135
|
+
/** Clears the nav, which is absolutely positioned on this same line. */
|
|
136
|
+
const actionsInset = navReserve ? { paddingLeft: navReserve } : undefined;
|
|
137
|
+
/**
|
|
138
|
+
* Skip — the same control on every kind, so it is built once. `approval`
|
|
139
|
+
* carries `optional` too: it has no free-text row to fall back on, so this is
|
|
140
|
+
* the only way out of a permission gate the user can neither approve nor deny.
|
|
141
|
+
*/
|
|
142
|
+
const skipAction = question.optional ? (jsx("div", { className: theme.actionsStartStyle, children: jsx(Button, { size: "sm", color: "mono", variant: "outline", onClick: () => { var _a; return onAnswer("__skipped__", (_a = question.skipLabel) !== null && _a !== void 0 ? _a : "Skipped", "deferred"); }, children: (_b = question.skipLabel) !== null && _b !== void 0 ? _b : "Skip" }) })) : null;
|
|
143
|
+
// 🔴 Split into CONTENT and ACTIONS rather than one per-kind block: only the
|
|
144
|
+
// content goes inside the height cap, and the actions row is the footer the
|
|
145
|
+
// nav is absolutely positioned onto. Fold them back together and a capped
|
|
146
|
+
// question scrolls its own Confirm button out of reach, with the nav painted
|
|
147
|
+
// on top of whatever ends up at the bottom edge.
|
|
148
|
+
const content = (jsxs(Fragment, { children: [(question.kind === undefined || question.kind === "approval") &&
|
|
149
|
+
question.payload && (jsx("div", { className: theme.bodyInnerStyle, children: jsx("div", { className: theme.payloadStyle, children: question.payload }) })), question.kind === "choice" && (jsxs("div", { className: theme.bodyInnerStyle, children: [jsx("div", { className: theme.optionListStyle, role: isMulti ? "group" : "radiogroup", "aria-labelledby": questionTextId, children: question.options.map((option) => {
|
|
150
|
+
// Pre-selected when revisiting: the recorded answer is what the
|
|
151
|
+
// controls show, so going back reads as "here is what you said"
|
|
152
|
+
// rather than as a blank question.
|
|
153
|
+
const checked = isMulti
|
|
154
|
+
? selection.includes(option.value)
|
|
155
|
+
: (answer === null || answer === void 0 ? void 0 : answer.value) === option.value;
|
|
156
|
+
const atMax = isMulti &&
|
|
157
|
+
!checked &&
|
|
158
|
+
question.maxSelected !== undefined &&
|
|
159
|
+
selection.length >= question.maxSelected;
|
|
160
|
+
const shared = {
|
|
161
|
+
value: option.value,
|
|
162
|
+
label: option.label,
|
|
163
|
+
description: option.description,
|
|
164
|
+
size: "sm",
|
|
165
|
+
className: theme.optionStyle,
|
|
166
|
+
};
|
|
167
|
+
return isMulti ? (jsx(Checkbox, { ...shared, checked: checked, state: atMax ? "disabled" : "default", onChange: (next) => toggleSelection(option.value, next) }, option.value)) : (jsx(Radio, { ...shared, name: fieldId, checked: checked, onChange: () => onAnswer(option.value, optionText(option)) }, option.value));
|
|
168
|
+
}) }), question.allowOther && (jsx(Input, { size: "sm", "aria-label": (_c = question.otherPlaceholder) !== null && _c !== void 0 ? _c : "Something else", placeholder: (_d = question.otherPlaceholder) !== null && _d !== void 0 ? _d : "Something else", wrapperClassName: theme.otherInputStyle, value: other, onChange: (event) => setOther(event.target.value), onKeyDown: (event) => {
|
|
169
|
+
if (event.key === "Enter" && other.trim()) {
|
|
170
|
+
event.preventDefault();
|
|
171
|
+
submitOther();
|
|
172
|
+
}
|
|
173
|
+
} }))] })), question.kind === "input" && (
|
|
174
|
+
/* The real Input, not a hand-rolled <input>: it owns the form-control
|
|
175
|
+
geometry tokens (--form-px/min-h/radius) and the inset box-shadow
|
|
176
|
+
border system from §9. Rolling our own here bypassed all of it and
|
|
177
|
+
mis-rendered under a large --radius-base. */
|
|
178
|
+
jsx("div", { className: theme.bodyInnerStyle, children: jsx(Input, { size: "sm", "aria-labelledby": questionTextId, wrapperClassName: theme.inputStyle, placeholder: question.placeholder, value: draft, onChange: (event) => setDraft(event.target.value), onKeyDown: (event) => {
|
|
179
|
+
if (event.key === "Enter" && draft.trim()) {
|
|
180
|
+
event.preventDefault();
|
|
181
|
+
onAnswer(draft.trim(), draft.trim());
|
|
182
|
+
}
|
|
183
|
+
} }) }))] }));
|
|
184
|
+
const actions = (jsxs(Fragment, { children: [(question.kind === undefined || question.kind === "approval") && (
|
|
185
|
+
/* Primary action rightmost — the row is right-anchored, so "Approve"
|
|
186
|
+
is the last thing before the panel edge. */
|
|
187
|
+
jsxs("div", { className: theme.actionsStyle, style: actionsInset, children: [skipAction, question.allowAlways && (jsx(Button, { size: "sm", color: "mono", variant: "outline", onClick: () => { var _a; return onAnswer("always", (_a = question.alwaysAllowLabel) !== null && _a !== void 0 ? _a : "Always allowed"); }, children: (_e = question.alwaysAllowLabel) !== null && _e !== void 0 ? _e : "Always allow" })), jsx(Button, { size: "sm", color: "danger", variant: "outline", onClick: () => { var _a; return onAnswer("denied", (_a = question.denyLabel) !== null && _a !== void 0 ? _a : "Denied", "rejected"); }, children: (_f = question.denyLabel) !== null && _f !== void 0 ? _f : "Deny" }), jsx(Button, { size: "sm", color: "primary", variant: "filled", onClick: () => { var _a; return onAnswer("approved", (_a = question.approveLabel) !== null && _a !== void 0 ? _a : "Approved"); }, children: (_g = question.approveLabel) !== null && _g !== void 0 ? _g : "Approve" })] })), question.kind === "choice" &&
|
|
188
|
+
(isMulti || question.optional || other.trim() || navReserve > 0) && (jsxs("div", { className: theme.actionsStyle, style: actionsInset, children: [skipAction, isMulti ? (jsx(Button, { size: "sm", color: "primary", variant: "filled", state: withinBounds(selection.length + (other.trim() ? 1 : 0))
|
|
189
|
+
? "default"
|
|
190
|
+
: "disabled", onClick: () => {
|
|
191
|
+
if (other.trim()) {
|
|
192
|
+
submitOther();
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
onAnswer(selection, labelFor(selection));
|
|
196
|
+
}, children: (_h = question.confirmLabel) !== null && _h !== void 0 ? _h : "Confirm" })) : (other.trim() && (jsx(Button, { size: "sm", color: "primary", variant: "filled", onClick: submitOther, children: (_j = question.otherSubmitLabel) !== null && _j !== void 0 ? _j : "Send" })))] })), question.kind === "input" && (jsxs("div", { className: theme.actionsStyle, style: actionsInset, children: [skipAction, jsx(Button, { size: "sm", color: "primary", variant: "filled", state: draft.trim() ? "default" : "disabled", onClick: () => onAnswer(draft.trim(), draft.trim()), children: (_k = question.submitLabel) !== null && _k !== void 0 ? _k : "Submit" })] }))] }));
|
|
197
|
+
return (jsxs(Fragment, { children: [jsxs("div", { className: "relative", children: [scroll.maxHeight && (jsx("div", { className: cn(theme.fadeStyle, theme.fadeTopStyle, scroll.edges.top ? "opacity-100" : "opacity-0"), "aria-hidden": "true" })), jsx("div", { ref: scroll.ref, className: cn(scroll.maxHeight && theme.scrollAreaStyle), style: scroll.maxHeight ? { maxHeight: scroll.maxHeight } : undefined, onScroll: scroll.onScroll, children: content }), scroll.maxHeight && (jsx("div", { className: cn(theme.fadeStyle, theme.fadeBottomStyle, scroll.edges.bottom ? "opacity-100" : "opacity-0"), "aria-hidden": "true" }))] }), actions] }));
|
|
198
|
+
};
|
|
199
|
+
const AgentRequest = React__default.forwardRef(({ questions, children, title, value, defaultValue, onValueChange, onAnswer, onComplete, maxHeight, previousLabel = "Previous question", nextLabel = "Next question", progressLabel = defaultProgressLabel, className, theme: themeOverrides, ...rest }, ref) => {
|
|
200
|
+
var _a;
|
|
201
|
+
const theme = useMemo(() => ({
|
|
202
|
+
...agentRequestTheme,
|
|
203
|
+
...themeOverrides,
|
|
204
|
+
badgeStates: {
|
|
205
|
+
...agentRequestTheme.badgeStates,
|
|
206
|
+
...themeOverrides === null || themeOverrides === void 0 ? void 0 : themeOverrides.badgeStates,
|
|
207
|
+
},
|
|
208
|
+
}), [themeOverrides]);
|
|
209
|
+
const reactId = useId();
|
|
210
|
+
const shouldReduceMotion = useReducedMotion();
|
|
211
|
+
const panelRef = useRef(null);
|
|
212
|
+
const scrollerRef = useRef(null);
|
|
213
|
+
const contentRef = useRef(null);
|
|
214
|
+
const navRef = useRef(null);
|
|
215
|
+
/**
|
|
216
|
+
* Set when an ANSWER moved the cursor — see the focus-recovery effect for
|
|
217
|
+
* why the effect can't just look at `document.activeElement`.
|
|
218
|
+
*/
|
|
219
|
+
const recoverFocus = useRef(false);
|
|
220
|
+
const [edges, setEdges] = useState({ top: false, bottom: false });
|
|
221
|
+
const [bodyHeight, setBodyHeight] = useState(null);
|
|
222
|
+
const [navWidth, setNavWidth] = useState(0);
|
|
223
|
+
const isControlled = value !== undefined;
|
|
224
|
+
const [uncontrolled, setUncontrolled] = useState(defaultValue !== null && defaultValue !== void 0 ? defaultValue : []);
|
|
225
|
+
const answers = isControlled ? value : uncontrolled;
|
|
226
|
+
const list = useMemo(() => questions !== null && questions !== void 0 ? questions : [], [questions]);
|
|
227
|
+
/**
|
|
228
|
+
* The one-at-a-time cursor. Answers are looked up BY ID, never by index —
|
|
229
|
+
* the cursor moves independently of how many questions are answered, which
|
|
230
|
+
* is the whole point of being able to arrow back into one and change it.
|
|
231
|
+
*/
|
|
232
|
+
const nextOpenIn = useCallback((against) => list.findIndex((q) => !against.some((a) => a.id === q.id)), [list]);
|
|
233
|
+
const [cursor, setCursor] = useState(() => {
|
|
234
|
+
const seed = (questions !== null && questions !== void 0 ? questions : []).findIndex((q) => { var _a; return !((_a = value !== null && value !== void 0 ? value : defaultValue) !== null && _a !== void 0 ? _a : []).some((a) => a.id === q.id); });
|
|
235
|
+
return seed === -1 ? 0 : seed;
|
|
236
|
+
});
|
|
237
|
+
/** Travel direction, so the swap slides the way the arrows point. */
|
|
238
|
+
const [direction, setDirection] = useState(1);
|
|
239
|
+
const total = list.length;
|
|
240
|
+
// Clamped rather than corrected in an effect: `questions` can shrink at any
|
|
241
|
+
// time and a render must never index off the end.
|
|
242
|
+
const safeCursor = Math.min(cursor, Math.max(0, total - 1));
|
|
243
|
+
const current = list[safeCursor];
|
|
244
|
+
const currentAnswer = current
|
|
245
|
+
? answers.find((a) => a.id === current.id)
|
|
246
|
+
: undefined;
|
|
247
|
+
const isComplete = total > 0 && nextOpenIn(answers) === -1;
|
|
248
|
+
const hasQuestions = questions !== undefined && questions.length > 0;
|
|
249
|
+
const hasChildren = children !== undefined;
|
|
250
|
+
const showNav = total > 1;
|
|
251
|
+
useEffect(() => {
|
|
252
|
+
if (process.env.NODE_ENV === "production")
|
|
253
|
+
return;
|
|
254
|
+
/* eslint-disable no-console */
|
|
255
|
+
if (hasQuestions && hasChildren) {
|
|
256
|
+
console.warn("[AgentRequest]: both `questions` and `children` were provided — `questions` takes precedence.");
|
|
257
|
+
}
|
|
258
|
+
if (isControlled && defaultValue !== undefined) {
|
|
259
|
+
console.warn("[AgentRequest]: both `value` and `defaultValue` were provided — `value` (controlled) wins.");
|
|
260
|
+
}
|
|
261
|
+
if (isControlled && onValueChange === undefined) {
|
|
262
|
+
console.warn("[AgentRequest]: `value` was provided without `onValueChange`, so answers can never be recorded. Pass `defaultValue` for uncontrolled usage.");
|
|
263
|
+
}
|
|
264
|
+
if (hasQuestions) {
|
|
265
|
+
const ids = new Set();
|
|
266
|
+
for (const q of questions) {
|
|
267
|
+
if (ids.has(q.id)) {
|
|
268
|
+
console.warn(`[AgentRequest]: duplicate question id "${q.id}" — answers are keyed by id and will collide.`);
|
|
269
|
+
}
|
|
270
|
+
ids.add(q.id);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/* eslint-enable no-console */
|
|
274
|
+
}, [
|
|
275
|
+
hasQuestions,
|
|
276
|
+
hasChildren,
|
|
277
|
+
isControlled,
|
|
278
|
+
defaultValue,
|
|
279
|
+
onValueChange,
|
|
280
|
+
questions,
|
|
281
|
+
]);
|
|
282
|
+
const recomputeEdges = useCallback(() => {
|
|
283
|
+
const el = scrollerRef.current;
|
|
284
|
+
if (!el)
|
|
285
|
+
return;
|
|
286
|
+
const overflowing = el.scrollHeight > el.clientHeight + 2;
|
|
287
|
+
setEdges({
|
|
288
|
+
top: overflowing && el.scrollTop > 4,
|
|
289
|
+
bottom: overflowing && el.scrollTop + el.clientHeight < el.scrollHeight - 4,
|
|
290
|
+
});
|
|
291
|
+
}, []);
|
|
292
|
+
/**
|
|
293
|
+
* Measure the question so the panel can tween its own height to it. The
|
|
294
|
+
* measured node wraps the `AnimatePresence`, not the question itself, so
|
|
295
|
+
* with `mode="wait"` it always reports exactly one question's height.
|
|
296
|
+
* `safeCursor` is a dependency so the fade edges are recomputed for the
|
|
297
|
+
* incoming question even when it happens to be exactly as tall as the one
|
|
298
|
+
* it replaced (no resize, so no observer callback).
|
|
299
|
+
*/
|
|
300
|
+
useEffect(() => {
|
|
301
|
+
const el = contentRef.current;
|
|
302
|
+
if (!el)
|
|
303
|
+
return;
|
|
304
|
+
const measure = () => {
|
|
305
|
+
setBodyHeight(el.offsetHeight);
|
|
306
|
+
recomputeEdges();
|
|
307
|
+
};
|
|
308
|
+
measure();
|
|
309
|
+
const observer = new ResizeObserver(measure);
|
|
310
|
+
observer.observe(el);
|
|
311
|
+
return () => observer.disconnect();
|
|
312
|
+
}, [isComplete, safeCursor, recomputeEdges]);
|
|
313
|
+
/**
|
|
314
|
+
* Measure the nav so the heading's floated spacer reserves exactly its
|
|
315
|
+
* lane. It can't be a literal width: `progressLabel` is a consumer-supplied
|
|
316
|
+
* i18n string, and a fixed one fitted the built-in "1 of 3" and let a
|
|
317
|
+
* longer label run underneath the arrows.
|
|
318
|
+
*/
|
|
319
|
+
useEffect(() => {
|
|
320
|
+
const el = navRef.current;
|
|
321
|
+
if (!el) {
|
|
322
|
+
setNavWidth(0);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const measure = () => setNavWidth(el.offsetWidth);
|
|
326
|
+
measure();
|
|
327
|
+
const observer = new ResizeObserver(measure);
|
|
328
|
+
observer.observe(el);
|
|
329
|
+
return () => observer.disconnect();
|
|
330
|
+
}, [isComplete, showNav]);
|
|
331
|
+
/**
|
|
332
|
+
* Answering unmounts the control that had focus, which drops the keyboard
|
|
333
|
+
* on the floor — tab order restarts at the top of the page. Move focus to
|
|
334
|
+
* the panel instead, but ONLY when an answer is what moved the cursor: the
|
|
335
|
+
* arrows stay mounted and keep their own focus, so a second press still
|
|
336
|
+
* lands on them.
|
|
337
|
+
*
|
|
338
|
+
* 🔴 Do NOT go back to deciding this from `document.activeElement === body`.
|
|
339
|
+
* `AnimatePresence mode="wait"` keeps the outgoing question — and the button
|
|
340
|
+
* that was just clicked — mounted for its exit, so at the moment this effect
|
|
341
|
+
* runs focus has not been lost YET. It is lost a frame later, when nothing
|
|
342
|
+
* is listening, and the panel silently stopped recovering it.
|
|
343
|
+
*/
|
|
344
|
+
useEffect(() => {
|
|
345
|
+
var _a, _b;
|
|
346
|
+
if (!recoverFocus.current)
|
|
347
|
+
return;
|
|
348
|
+
recoverFocus.current = false;
|
|
349
|
+
const active = document.activeElement;
|
|
350
|
+
// Never yank focus out of something the user moved to themselves.
|
|
351
|
+
if (active && active !== document.body && !((_a = panelRef.current) === null || _a === void 0 ? void 0 : _a.contains(active)))
|
|
352
|
+
return;
|
|
353
|
+
(_b = panelRef.current) === null || _b === void 0 ? void 0 : _b.focus({ preventScroll: true });
|
|
354
|
+
}, [safeCursor]);
|
|
355
|
+
const commit = useCallback((question, next) => {
|
|
356
|
+
// Replace by id, not push: arrowing back and answering again OVERWRITES
|
|
357
|
+
// that question's answer and leaves every other answer alone.
|
|
358
|
+
const existing = answers.some((a) => a.id === question.id);
|
|
359
|
+
const updated = existing
|
|
360
|
+
? answers.map((a) => (a.id === question.id ? next : a))
|
|
361
|
+
: [...answers, next];
|
|
362
|
+
if (!isControlled)
|
|
363
|
+
setUncontrolled(updated);
|
|
364
|
+
onValueChange === null || onValueChange === void 0 ? void 0 : onValueChange(updated);
|
|
365
|
+
onAnswer === null || onAnswer === void 0 ? void 0 : onAnswer(next);
|
|
366
|
+
// Land on the first question that is still open — so editing an early
|
|
367
|
+
// answer returns the user to where they were, not back through
|
|
368
|
+
// questions they have already dealt with.
|
|
369
|
+
const open = nextOpenIn(updated);
|
|
370
|
+
if (open === -1) {
|
|
371
|
+
onComplete === null || onComplete === void 0 ? void 0 : onComplete(updated);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// The control that was just used is about to unmount with the question.
|
|
375
|
+
if (open !== safeCursor)
|
|
376
|
+
recoverFocus.current = true;
|
|
377
|
+
setDirection(open >= safeCursor ? 1 : -1);
|
|
378
|
+
setCursor(open);
|
|
379
|
+
}, [
|
|
380
|
+
answers,
|
|
381
|
+
isControlled,
|
|
382
|
+
onValueChange,
|
|
383
|
+
onAnswer,
|
|
384
|
+
onComplete,
|
|
385
|
+
nextOpenIn,
|
|
386
|
+
safeCursor,
|
|
387
|
+
]);
|
|
388
|
+
const answerCurrent = useCallback((value_, label, outcome = "resolved") => {
|
|
389
|
+
if (!current)
|
|
390
|
+
return;
|
|
391
|
+
commit(current, { id: current.id, value: value_, label, outcome });
|
|
392
|
+
}, [commit, current]);
|
|
393
|
+
const goTo = useCallback((index, travel) => {
|
|
394
|
+
setDirection(travel);
|
|
395
|
+
setCursor(index);
|
|
396
|
+
}, []);
|
|
397
|
+
if (total === 0 && !hasChildren)
|
|
398
|
+
return null;
|
|
399
|
+
const canGoBack = safeCursor > 0;
|
|
400
|
+
// Forward only over ground already covered — an unanswered question is not
|
|
401
|
+
// something to skip past, it is the thing being asked.
|
|
402
|
+
const canGoForward = safeCursor < total - 1 && currentAnswer !== undefined;
|
|
403
|
+
// 🔴 Reduced motion swaps the VARIANTS, not the transition — a variant's own
|
|
404
|
+
// transition overrides the element's `transition` prop, so passing INSTANT
|
|
405
|
+
// alongside these would animate anyway. See AgentRequest.animations.ts.
|
|
406
|
+
const panelVariants = shouldReduceMotion
|
|
407
|
+
? panelAnimationsInstant
|
|
408
|
+
: panelAnimations;
|
|
409
|
+
const questionVariants = shouldReduceMotion
|
|
410
|
+
? questionAnimationsInstant
|
|
411
|
+
: questionAnimations;
|
|
412
|
+
const labelId = `${reactId}-title`;
|
|
413
|
+
const questionTextId = current ? `${reactId}-${current.id}-q` : undefined;
|
|
414
|
+
const defaultTitle = `Agent needs ${total} decision${total === 1 ? "" : "s"}`;
|
|
415
|
+
return (jsx("div", { ref: ref, className: cn(theme.baseStyle, className), ...rest, children: jsx(AnimatePresence, { initial: false, children: !isComplete && (jsx(MotionCard, { ref: panelRef, elevation: "overlay", className: theme.panelStyle, role: "region", "aria-labelledby": labelId,
|
|
416
|
+
// Not a tab stop — a focus target. See the focus-recovery effect.
|
|
417
|
+
tabIndex: -1, variants: panelVariants, initial: "hidden", animate: "visible", exit: "exit", children: jsxs(Fragment, { children: [jsx("span", { id: labelId, className: "sr-only", children: title !== null && title !== void 0 ? title : defaultTitle }), showNav && (jsxs("div", { ref: navRef, className: theme.navStyle, children: [jsx(Button, { size: "sm", color: "mono", variant: "ghost", iconOnly: true, className: theme.navButtonStyle, "aria-label": previousLabel, state: canGoBack ? "default" : "disabled", onClick: () => goTo(safeCursor - 1, -1), children: jsx(CaretLeft, { className: "size-3.5", weight: "bold" }) }), jsx("span", { className: theme.navCountStyle, "aria-live": "polite", children: progressLabel(safeCursor + 1, total) }), jsx(Button, { size: "sm", color: "mono", variant: "ghost", iconOnly: true, className: theme.navButtonStyle, "aria-label": nextLabel, state: canGoForward ? "default" : "disabled", onClick: () => goTo(safeCursor + 1, 1), children: jsx(CaretRight, { className: "size-3.5", weight: "bold" }) })] })), jsx(motion.div, { className: theme.bodyStyle,
|
|
418
|
+
// `auto` until the first measurement lands (and in jsdom,
|
|
419
|
+
// where offsetHeight is always 0) so the panel can never
|
|
420
|
+
// collapse the question it is meant to be showing.
|
|
421
|
+
animate: { height: bodyHeight ? bodyHeight : "auto" }, initial: false, transition: shouldReduceMotion ? INSTANT : HEIGHT_TRANSITION, children: jsx("div", { ref: contentRef, className: theme.contentStyle, children: jsx(AnimatePresence, { mode: "wait", initial: false, custom: direction, children: current ? (jsxs(motion.div, { custom: direction, variants: questionVariants, initial: "enter", animate: "center", exit: "exit", "data-risk": current.risk === "destructive"
|
|
422
|
+
? "destructive"
|
|
423
|
+
: undefined, children: [jsxs("div", { className: theme.headerStyle, children: [currentAnswer && (jsxs("span", { className: theme.answeredChipStyle, children: [jsx("span", { className: cn(theme.badgeStyle, theme.badgeStates[currentAnswer.outcome]), "aria-hidden": "true", children: currentAnswer.outcome === "rejected" ? (jsx(X, { className: "size-2.5", weight: "bold" })) : (jsx(Check, { className: "size-2.5", weight: "bold" })) }), jsx("span", { className: theme.answerStyle, children: currentAnswer.label })] })), jsx("div", { id: questionTextId, className: theme.questionStyle, children: (_a = current.question) !== null && _a !== void 0 ? _a : current.label }), current.meta && (jsx("div", { className: theme.metaStyle, children: current.meta }))] }), jsx(QuestionBody, { question: current, answer: currentAnswer, theme: theme, fieldId: `${reactId}-${current.id}`, questionTextId: questionTextId,
|
|
424
|
+
// The +4 is the 4px the nav is pulled out by,
|
|
425
|
+
// plus the gutter between it and the actions.
|
|
426
|
+
navReserve: showNav && navWidth ? navWidth + 4 : 0, scroll: {
|
|
427
|
+
maxHeight,
|
|
428
|
+
ref: scrollerRef,
|
|
429
|
+
onScroll: recomputeEdges,
|
|
430
|
+
edges,
|
|
431
|
+
}, onAnswer: answerCurrent })] }, current.id)) : (hasChildren && (jsx(motion.div, { variants: questionVariants, initial: "enter", animate: "center", exit: "exit", children: jsx("div", { className: cn(theme.bodyInnerStyle, "pt-4"), children: children }) }, "children"))) }) }) })] }) })) }) }));
|
|
432
|
+
});
|
|
433
|
+
AgentRequest.displayName = "AgentRequest";
|
|
434
|
+
|
|
435
|
+
export { AgentRequest };
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const agentRequestTheme = {
|
|
2
|
+
baseStyle: "w-full min-w-0",
|
|
3
|
+
// GEOMETRY ONLY — no bg, no shadow. The panel is a `Card` pinned to the
|
|
4
|
+
// overlay rung, so the elevation engine paints the surface, the shadow and
|
|
5
|
+
// `--field-fill` (which is what makes the Input/Radio/Checkbox inside fill
|
|
6
|
+
// correctly against a lifted panel). It used to hand-paint
|
|
7
|
+
// `bg-[var(--color-surface)] shadow-surface-5` — a rung-3 background under a
|
|
8
|
+
// rung-5 shadow, and hardcoded, so it never lifted when nested.
|
|
9
|
+
// The radius stays ours: the panel sits where the composer was and takes the
|
|
10
|
+
// sm cap tier, NOT `--card-radius` (lg). See docs/THEMING.md.
|
|
11
|
+
panelStyle: "relative w-full min-w-0 overflow-hidden rounded-[var(--agent-request-radius)]",
|
|
12
|
+
// Bottom-LEFT, sharing the footer line with the question's own actions: the
|
|
13
|
+
// arrows are navigation, the right-hand button is the answer, and putting
|
|
14
|
+
// them on one line separates "where am I" from "what do I do".
|
|
15
|
+
// 🔴 Still ABSOLUTE, and that is deliberate: the question swaps inside an
|
|
16
|
+
// AnimatePresence, and a nav rendered inside that swap would unmount on every
|
|
17
|
+
// step — taking keyboard focus with it, so a second press of the back arrow
|
|
18
|
+
// would land on nothing. Which is also why the actions row reserves its lane
|
|
19
|
+
// by padding rather than by holding it as a flex child.
|
|
20
|
+
// Pulled 4px out of the panel's 16px inset so the caret GLYPHS line up with
|
|
21
|
+
// the content edge — the ghost button boxes are wider than the marks in them.
|
|
22
|
+
// `bottom-5` centres the 24px nav against the 32px `size="sm"` button sitting
|
|
23
|
+
// on the panel's 16px bottom inset.
|
|
24
|
+
navStyle: "absolute bottom-5 left-3 z-[2] flex shrink-0 items-center gap-0.5",
|
|
25
|
+
// Overrides Button's `iconOnly` sizing (--button-icon-size-sm is the FORM
|
|
26
|
+
// control height — too heavy for a quiet header affordance). Plain utilities,
|
|
27
|
+
// not `!important`: Button puts `className` last in its own `cn(...)`, so
|
|
28
|
+
// twMerge already resolves these against the size/padding it set.
|
|
29
|
+
navButtonStyle: "size-6 p-0 text-[var(--color-text-muted)]",
|
|
30
|
+
navCountStyle: "px-0.5 text-xs tabular-nums text-[var(--color-text-muted)] select-none",
|
|
31
|
+
// 🔴 The panel's own inset, and it lives HERE rather than on a `Card.Body`.
|
|
32
|
+
// Card's body/header slots pad by `--card-px/py` (24px); this panel sits in
|
|
33
|
+
// the composer slot at 16px, which is also what earns it the sm radius cap
|
|
34
|
+
// instead of Card's lg (docs/THEMING.md). Wrapping the question in
|
|
35
|
+
// `Card.Body` stacked the two — the heading sat at 40px while its own
|
|
36
|
+
// options and actions sat at 24px, a 16px stagger down the left edge — so
|
|
37
|
+
// only Card's SURFACE is taken and the padding is ours.
|
|
38
|
+
contentStyle: "px-4 pb-4",
|
|
39
|
+
// The question IS the heading — there is no separate title row, and with the
|
|
40
|
+
// nav moved down to the footer the heading gets the full width.
|
|
41
|
+
headerStyle: "flex flex-col gap-1 pt-3.5 pb-3",
|
|
42
|
+
questionStyle: "min-w-0 text-base font-semibold leading-snug text-[var(--color-text-primary)]",
|
|
43
|
+
metaStyle: "text-sm text-[var(--color-text-secondary)]",
|
|
44
|
+
// Shown above the question when the user has arrowed BACK to one they already
|
|
45
|
+
// answered. The controls below are pre-selected too, but an approval has no
|
|
46
|
+
// control that can hold a selection, so this is the only record of it.
|
|
47
|
+
answeredChipStyle: "flex items-center gap-1.5",
|
|
48
|
+
badgeStyle: "grid size-4 shrink-0 place-items-center rounded-full",
|
|
49
|
+
badgeStates: {
|
|
50
|
+
resolved: "bg-[var(--color-success)] text-[var(--color-success-contrast)]",
|
|
51
|
+
rejected: "bg-[var(--color-danger)] text-[var(--color-danger-contrast)]",
|
|
52
|
+
deferred: "bg-[var(--color-mono)] text-[var(--color-mono-contrast)]",
|
|
53
|
+
},
|
|
54
|
+
// A rem cap, not a percentage — Tailwind v4 emits no rule for a percentage
|
|
55
|
+
// arbitrary max-width, so `max-w-[52%]` would silently never truncate.
|
|
56
|
+
answerStyle: "max-w-[14rem] truncate text-[11px] font-medium text-[var(--color-text-muted)]",
|
|
57
|
+
// The height-animated shell. `overflow-hidden` is load-bearing — it clips the
|
|
58
|
+
// outgoing question while the panel resizes to the incoming one.
|
|
59
|
+
bodyStyle: "relative w-full min-w-0 overflow-hidden",
|
|
60
|
+
// Applied only when `maxHeight` is set, and only to the ANSWERING controls —
|
|
61
|
+
// the question heading sits above the scroller. Capping the whole question
|
|
62
|
+
// let the user scroll the question itself out of sight while picking from its
|
|
63
|
+
// own option list. overscroll-contain stops a flick inside the body from
|
|
64
|
+
// scrolling the transcript behind it.
|
|
65
|
+
scrollAreaStyle: "overflow-y-auto overscroll-contain",
|
|
66
|
+
fadeStyle: "pointer-events-none absolute inset-x-0 z-[2] h-6 transition-opacity duration-[var(--motion-duration-base)] ease-out",
|
|
67
|
+
// `--surface-5`, not `--color-surface`: the panel paints the overlay rung, so
|
|
68
|
+
// a rung-3 gradient would band against it in dark mode.
|
|
69
|
+
fadeTopStyle: "top-0 bg-gradient-to-b from-[var(--surface-5)] to-transparent",
|
|
70
|
+
fadeBottomStyle: "bottom-0 bg-gradient-to-t from-[var(--surface-5)] to-transparent",
|
|
71
|
+
bodyInnerStyle: "min-w-0",
|
|
72
|
+
// Tight inner well — takes the xs-capped token, one tier below the panel it
|
|
73
|
+
// sits in. A bare `--radius-base` put a 24px curve on 10px of padding.
|
|
74
|
+
payloadStyle: "whitespace-pre-wrap break-words rounded-[var(--agent-request-well-radius)] bg-[var(--color-surface-sunken)] px-2.5 py-2 font-mono text-[11px] leading-relaxed text-[var(--color-text-secondary)]",
|
|
75
|
+
// ── option rows ────────────────────────────────────────────────────────────
|
|
76
|
+
// One connected group: a single perimeter on the list, hairline dividers
|
|
77
|
+
// between items, and only the first/last corners rounded. `overflow-hidden`
|
|
78
|
+
// is what rounds the children's outer corners — which is also why the option
|
|
79
|
+
// focus ring below MUST be `ring-inset`, or it gets clipped on the first and
|
|
80
|
+
// last rows. Takes the well radius (xs cap) so a large `--radius-base` theme
|
|
81
|
+
// can't round a 10px-padded row past its own padding.
|
|
82
|
+
optionListStyle: "flex flex-col overflow-hidden rounded-[var(--agent-request-well-radius)] shadow-[inset_0_0_0_1px_var(--color-border)]",
|
|
83
|
+
// The rows are the real `Radio`/`Checkbox` — this styles the row they sit in,
|
|
84
|
+
// nothing more. `first-of-type` (not `first`) is exact here because every
|
|
85
|
+
// child is one of those controls.
|
|
86
|
+
optionStyle: "flex w-full cursor-pointer items-center gap-2.5 border-t border-[var(--color-border)] px-2.5 py-2 text-left text-sm transition-[background-color] duration-[var(--motion-duration-fast)] ease-out first-of-type:border-t-0 hover:bg-[var(--color-surface-hover)] focus:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--color-primary)]",
|
|
87
|
+
// No optionRadioStyle / optionDescriptionStyle — the real `Radio` and
|
|
88
|
+
// `Checkbox` own the control mark and the per-option `description`
|
|
89
|
+
// (§9: `description` is the per-option slot, distinct from `helperText`).
|
|
90
|
+
// The escape hatch: a plain `Input` under the options, nothing bespoke.
|
|
91
|
+
otherInputStyle: "mt-2",
|
|
92
|
+
// The footer line. Right-anchored: the primary action is the rightmost thing
|
|
93
|
+
// in the panel. `actionsStartStyle`'s `mr-auto` is what pushes it there, and
|
|
94
|
+
// it also holds the row open when the escape hatches are the only things
|
|
95
|
+
// present. `min-h-8` keeps the line tall enough for the absolutely-positioned
|
|
96
|
+
// nav even on a question whose only content is the nav itself; the left inset
|
|
97
|
+
// that clears the nav is applied inline, since its width is measured.
|
|
98
|
+
actionsStyle: "flex min-h-8 flex-wrap items-center justify-end gap-2 pt-3",
|
|
99
|
+
actionsStartStyle: "mr-auto flex items-center gap-2",
|
|
100
|
+
// Spacing ONLY — the box (height, padding, radius, border, focus ring) comes
|
|
101
|
+
// from the real `Input` component and its --form-* tokens. This used to be a
|
|
102
|
+
// hand-rolled <input> that reimplemented all of that and got it wrong.
|
|
103
|
+
inputStyle: "",
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export { agentRequestTheme };
|