@flikk/ui 1.0.0-beta.31 → 1.0.0-beta.33
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 +497 -22
- 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/CodeBlock/CodeBlock.theme.js +1 -1
- package/dist/components/ai/PromptInput/PromptInput.js +2 -2
- package/dist/components/ai/PromptInput/PromptInput.theme.js +2 -2
- package/dist/components/ai/PromptSuggestion/PromptSuggestion.theme.js +2 -2
- package/dist/components/ai/Reasoning/Reasoning.js +27 -3
- 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 +58 -5
- 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 +2 -1
- package/dist/components/ai/StreamingResponse/AnimatedText.d.ts +7 -0
- package/dist/components/ai/StreamingResponse/AnimatedText.js +8 -7
- 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 +13 -7
- 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.theme.js +1 -1
- package/dist/components/ai/index.d.ts +3 -2
- package/dist/components/ai/index.js +4 -0
- package/dist/components/canvas/BaseNode.js +1 -1
- package/dist/components/canvas/CanvasToolbar.js +0 -1
- package/dist/components/canvas/Edge.js +2 -2
- package/dist/components/canvas/NodeControls.js +0 -1
- package/dist/components/canvas/NodeRenderer.js +2 -2
- package/dist/components/charts/ActivityRings/ActivityRings.js +2 -2
- package/dist/components/charts/ActivityRings/ActivityRings.theme.js +1 -1
- package/dist/components/charts/AreaChart/AreaChart.js +3 -3
- package/dist/components/charts/AreaChart/AreaChart.theme.js +3 -3
- package/dist/components/charts/BarChart/BarChart.js +4 -4
- package/dist/components/charts/ComboChart/BarRenderer.js +2 -2
- package/dist/components/charts/ComboChart/BarRenderer.types.d.ts +1 -1
- package/dist/components/charts/ComboChart/ComboChartCanvas.js +1 -1
- package/dist/components/charts/ComboChart/LineRenderer.js +1 -1
- 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.js +1 -1
- package/dist/components/charts/LineChart/LineChart.js +2 -2
- package/dist/components/charts/LollipopChart/LollipopChart.js +1 -1
- package/dist/components/charts/RadarChart/RadarChart.js +1 -1
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +3 -3
- package/dist/components/charts/hooks/useChartAccessibility.js +9 -6
- package/dist/components/charts/index.d.ts +4 -8
- package/dist/components/charts/index.js +2 -4
- 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 +3 -3
- package/dist/components/charts/utils/animation-utils.d.ts +12 -7
- package/dist/components/charts/utils/animation-utils.js +19 -19
- package/dist/components/core/Accordion/Accordion.theme.js +1 -1
- package/dist/components/core/Alert/Alert.animations.d.ts +11 -4
- package/dist/components/core/Alert/Alert.animations.js +11 -4
- package/dist/components/core/Alert/Alert.js +16 -2
- 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.theme.js +1 -1
- package/dist/components/core/Badge/Badge.animations.d.ts +0 -5
- package/dist/components/core/Badge/Badge.animations.js +5 -84
- package/dist/components/core/Badge/Badge.d.ts +7 -4
- package/dist/components/core/Badge/Badge.js +27 -64
- package/dist/components/core/Badge/Badge.theme.js +8 -12
- package/dist/components/core/Badge/Badge.types.d.ts +18 -34
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +4 -4
- package/dist/components/core/Button/Button.js +7 -43
- package/dist/components/core/Button/Button.theme.js +5 -5
- package/dist/components/core/Button/Button.types.d.ts +8 -12
- package/dist/components/core/Button/index.d.ts +0 -2
- package/dist/components/core/Calendar/Calendar.theme.js +1 -1
- 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 +29 -1
- 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/CardHeader.js +4 -1
- 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/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 +21 -8
- package/dist/components/core/DragDrop/DragDrop.theme.js +2 -2
- package/dist/components/core/Drawer/Drawer.theme.js +1 -1
- package/dist/components/core/Drawer/DrawerHeader.js +0 -1
- package/dist/components/core/Dropdown/DropdownMenu.js +22 -7
- package/dist/components/core/Link/Link.js +1 -1
- 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 +2 -0
- package/dist/components/core/Message/Message.theme.js +3 -3
- 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.js +5 -1
- package/dist/components/core/Modal/Modal.theme.js +1 -1
- package/dist/components/core/Modal/ModalHeader.js +0 -1
- package/dist/components/core/ModalStack/ModalStackModal.js +3 -1
- package/dist/components/core/NavItem/NavItem.js +3 -2
- package/dist/components/core/NavItem/NavItem.theme.js +1 -1
- package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +4 -2
- package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
- package/dist/components/core/Pagination/Pagination.theme.js +2 -2
- package/dist/components/core/Pill/Pill.js +34 -18
- package/dist/components/core/Pill/Pill.theme.js +4 -2
- package/dist/components/core/Pill/Pill.types.d.ts +14 -1
- 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.theme.js +1 -1
- 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 +3 -3
- 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/SidebarContent.js +1 -1
- package/dist/components/core/Sidebar/SidebarHeader.js +1 -1
- package/dist/components/core/Sidebar/SidebarSearch.js +2 -2
- package/dist/components/core/Sidebar/SidebarToggle.js +1 -1
- package/dist/components/core/Sidebar/SidebarUserProfile.js +1 -1
- package/dist/components/core/SlidingNumber/SlidingNumber.d.ts +8 -0
- package/dist/components/core/SlidingNumber/SlidingNumber.js +12 -3
- 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.theme.js +1 -1
- package/dist/components/core/Toast/ToastProvider.js +1 -1
- 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/data-display/GanttChart/GanttChart.theme.js +6 -6
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +1 -1
- package/dist/components/data-display/GanttChart/GanttTimelineHeader.js +1 -1
- package/dist/components/data-display/GanttChart/GanttToolbar.js +0 -1
- package/dist/components/data-display/KPI/KPI.js +11 -20
- package/dist/components/data-display/KPI/KPI.theme.js +8 -4
- package/dist/components/data-display/Metric/Metric.theme.js +4 -4
- package/dist/components/data-display/Table/Table.theme.js +2 -2
- package/dist/components/data-display/Table/TableColumnManager.js +1 -2
- package/dist/components/data-display/Table/TableContext.js +1 -0
- package/dist/components/data-display/Table/TableFilter.js +9 -2
- package/dist/components/data-display/Table/TableSelectionHeader.js +1 -1
- package/dist/components/data-display/Timeline/Timeline.theme.js +1 -1
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +1 -1
- package/dist/components/effects/CustomCursor/CustomCursor.js +1 -1
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +4 -4
- 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.theme.js +1 -1
- package/dist/components/forms/ColorPicker/ColorPicker.js +45 -3
- package/dist/components/forms/ColorPicker/ColorPickerBody.js +8 -4
- package/dist/components/forms/ColorPicker/ColorPickerHeader.js +1 -1
- package/dist/components/forms/ColorPicker/ColorPickerImage.js +1 -1
- package/dist/components/forms/Combobox/Combobox.js +10 -4
- package/dist/components/forms/Combobox/Combobox.theme.js +9 -0
- package/dist/components/forms/Combobox/Combobox.types.d.ts +13 -0
- package/dist/components/forms/DatePicker/DatePicker.js +19 -12
- package/dist/components/forms/DatePicker/DatePicker.theme.js +5 -0
- package/dist/components/forms/DatePicker/DatePicker.types.d.ts +8 -0
- package/dist/components/forms/DatePicker/DatePickerContext.d.ts +0 -1
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +5 -3
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +6 -1
- package/dist/components/forms/DateRangePicker/DateRangePicker.types.d.ts +8 -0
- package/dist/components/forms/DateRangePicker/DateRangePickerContext.js +1 -0
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +5 -3
- package/dist/components/forms/FileUpload/FileUpload.theme.js +2 -2
- package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +1 -1
- package/dist/components/forms/Input/Input.js +17 -12
- package/dist/components/forms/Input/Input.theme.js +10 -0
- package/dist/components/forms/Input/Input.types.d.ts +14 -0
- package/dist/components/forms/InputAddress/InputAddress.js +5 -5
- package/dist/components/forms/InputAddress/InputAddress.types.d.ts +9 -2
- package/dist/components/forms/InputCounter/InputCounter.js +194 -17
- package/dist/components/forms/InputCounter/InputCounter.theme.d.ts +12 -0
- package/dist/components/forms/InputCounter/InputCounter.theme.js +92 -2
- package/dist/components/forms/InputCounter/InputCounter.types.d.ts +47 -4
- package/dist/components/forms/InputCreditCard/InputCreditCard.js +4 -4
- package/dist/components/forms/InputCreditCard/InputCreditCard.types.d.ts +7 -0
- package/dist/components/forms/Mention/Mention.js +13 -11
- package/dist/components/forms/Radio/Radio.theme.js +1 -1
- package/dist/components/forms/RichTextEditor/RichTextEditor.d.ts +12 -16
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +174 -1680
- 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.js +19 -12
- package/dist/components/forms/Select/Select.theme.js +9 -1
- package/dist/components/forms/Select/Select.types.d.ts +86 -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.js +2 -1
- package/dist/components/forms/SelectableCard/SelectableCard.theme.js +1 -1
- package/dist/components/forms/Switch/Switch.theme.js +2 -2
- package/dist/components/forms/Textarea/Textarea.js +14 -25
- package/dist/components/forms/TimePicker/TimePicker.theme.js +10 -1
- package/dist/components/forms/TimePicker/TimePicker.types.d.ts +11 -0
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +7 -5
- package/dist/components/forms/forms.theme.d.ts +57 -0
- package/dist/components/forms/forms.theme.js +102 -13
- package/dist/components/forms/index.js +1 -0
- 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 +11 -10
- package/dist/components/generative/schema.generated.js +199 -293
- 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 +199 -293
- package/dist/index.js +1 -4
- package/dist/registry.json +2765 -2450
- package/dist/shadcn-compat.css +5 -5
- 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/themes/precision.css +232 -0
- package/dist/tools.json +200 -295
- package/dist/utils/composeEventHandlers.d.ts +19 -0
- package/dist/utils/composeEventHandlers.js +26 -0
- package/dist/utils/composeEventHandlers.test.d.ts +1 -0
- package/dist/utils/index.d.ts +1 -1
- package/package.json +31 -1
- package/src/global.scss +21 -28
- package/src/styles/theme.css +157 -50
- package/src/styles/theme.test.ts +119 -0
- package/tailwind.preset.cjs +30 -20
- 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 -208
- 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 -60
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +0 -19
- 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/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,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
3
|
+
import { MagnifyingGlass, GlobeSimple, FileText, TerminalWindow, PencilSimple, WarningCircle, Clock, Check, CircleNotch } from '@phosphor-icons/react';
|
|
4
|
+
import { useReducedMotion, motion } from 'motion/react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
|
|
7
|
+
const formatDuration = (duration) => {
|
|
8
|
+
const safe = Math.max(0, duration);
|
|
9
|
+
const rounded = safe < 60 ? Math.round(safe * 10) / 10 : Math.round(safe);
|
|
10
|
+
if (rounded < 60) {
|
|
11
|
+
return `${rounded.toFixed(Number.isInteger(rounded) ? 0 : 1)}s`;
|
|
12
|
+
}
|
|
13
|
+
return `${Math.floor(rounded / 60)}m ${rounded % 60}s`;
|
|
14
|
+
};
|
|
15
|
+
const statusTone = (status) => {
|
|
16
|
+
switch (status) {
|
|
17
|
+
case "active":
|
|
18
|
+
return "text-[var(--color-primary)]";
|
|
19
|
+
case "complete":
|
|
20
|
+
return "text-[var(--color-success)]";
|
|
21
|
+
case "pending":
|
|
22
|
+
return "text-[var(--color-text-placeholder)]";
|
|
23
|
+
case "error":
|
|
24
|
+
return "text-[var(--color-danger)]";
|
|
25
|
+
default:
|
|
26
|
+
return "text-[var(--color-text-muted)]";
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const stateGlyph = (step) => {
|
|
30
|
+
var _a;
|
|
31
|
+
if (step.icon)
|
|
32
|
+
return step.icon;
|
|
33
|
+
switch ((_a = step.status) !== null && _a !== void 0 ? _a : "complete") {
|
|
34
|
+
case "active":
|
|
35
|
+
return jsx(CircleNotch, { className: "size-3.5 animate-spin" });
|
|
36
|
+
case "complete":
|
|
37
|
+
return jsx(Check, { className: "size-3.5", weight: "bold" });
|
|
38
|
+
case "pending":
|
|
39
|
+
return jsx(Clock, { className: "size-3.5" });
|
|
40
|
+
case "error":
|
|
41
|
+
return jsx(WarningCircle, { className: "size-3.5", weight: "fill" });
|
|
42
|
+
default:
|
|
43
|
+
return jsx("span", { className: "size-1.5 rounded-full bg-current" });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const traceGlyph = (variant, step) => {
|
|
47
|
+
if (step.icon)
|
|
48
|
+
return step.icon;
|
|
49
|
+
if (variant === "steps")
|
|
50
|
+
return stateGlyph(step);
|
|
51
|
+
if (variant === "search" || step.kind === "source") {
|
|
52
|
+
return jsx(GlobeSimple, { className: "size-3.5" });
|
|
53
|
+
}
|
|
54
|
+
if (variant === "coding") {
|
|
55
|
+
switch (step.kind) {
|
|
56
|
+
case "edit":
|
|
57
|
+
return jsx(PencilSimple, { className: "size-3.5" });
|
|
58
|
+
case "command":
|
|
59
|
+
return jsx(TerminalWindow, { className: "size-3.5" });
|
|
60
|
+
default:
|
|
61
|
+
return jsx(FileText, { className: "size-3.5" });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return jsx("span", { className: "size-1.5 rounded-full bg-current" });
|
|
65
|
+
};
|
|
66
|
+
const ReasoningTrace = ({ variant, steps, query, remainingCount = 0, theme, }) => {
|
|
67
|
+
const shouldReduceMotion = useReducedMotion();
|
|
68
|
+
return (jsxs("div", { className: theme.traceStyle, "data-reasoning-variant": variant, children: [steps.length > 1 && (jsx("span", { className: theme.guideStyle, "data-reasoning-trace-guide": "", "aria-hidden": "true" })), query !== undefined && (jsxs(motion.div, { className: theme.queryStyle, initial: shouldReduceMotion ? false : { opacity: 0, y: -3 }, animate: { opacity: 1, y: 0 }, transition: { duration: shouldReduceMotion ? 0 : 0.18 }, children: [jsx("span", { className: theme.queryIconStyle, "aria-hidden": "true", children: jsx(MagnifyingGlass, { className: "size-full" }) }), jsx("span", { className: theme.queryTextStyle, children: query })] })), jsx("ol", { className: theme.listStyle, children: steps.map((step, index) => {
|
|
69
|
+
var _a, _b, _c, _d;
|
|
70
|
+
const status = (_a = step.status) !== null && _a !== void 0 ? _a : "complete";
|
|
71
|
+
const metadata = (_b = step.description) !== null && _b !== void 0 ? _b : (step.duration !== undefined ? formatDuration(step.duration) : undefined);
|
|
72
|
+
const rowClassName = cn(theme.itemStyle, step.href && theme.interactiveItemStyle);
|
|
73
|
+
const content = (jsxs(Fragment, { children: [jsx("span", { className: cn(theme.indicatorStyle, theme.indicatorSurfaceStyle, statusTone(variant === "steps" ? status : undefined)), "aria-hidden": "true", children: traceGlyph(variant, step) }), jsx("span", { className: variant === "reasoning"
|
|
74
|
+
? theme.reasoningPrimaryStyle
|
|
75
|
+
: theme.primaryStyle, children: step.label }), metadata !== undefined && (jsx("span", { className: cn(theme.secondaryStyle, step.mono && "font-mono"), children: metadata })), (step.additions !== undefined || step.deletions !== undefined) && (jsxs("span", { className: theme.diffStyle, "aria-label": "Code changes", children: [step.additions !== undefined && (jsxs("span", { className: theme.additionsStyle, children: ["+", step.additions] })), step.additions !== undefined && step.deletions !== undefined && " ", step.deletions !== undefined && (jsxs("span", { className: theme.deletionsStyle, children: ["\u2212", step.deletions] }))] }))] }));
|
|
76
|
+
return (jsx(motion.li, { initial: shouldReduceMotion ? false : { opacity: 0, y: -3 }, animate: { opacity: 1, y: 0 }, transition: {
|
|
77
|
+
duration: shouldReduceMotion ? 0 : 0.2,
|
|
78
|
+
delay: shouldReduceMotion ? 0 : index * 0.045,
|
|
79
|
+
ease: [0.23, 1, 0.32, 1],
|
|
80
|
+
}, className: "min-w-0", children: step.href ? (jsx("a", { href: step.href, target: step.target, rel: (_c = step.rel) !== null && _c !== void 0 ? _c : (step.target === "_blank" ? "noreferrer" : undefined), className: rowClassName, children: content })) : (jsx("div", { className: rowClassName, children: content })) }, (_d = step.id) !== null && _d !== void 0 ? _d : index));
|
|
81
|
+
}) }), remainingCount > 0 && (jsxs(motion.div, { className: theme.remainingStyle, initial: shouldReduceMotion ? false : { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: shouldReduceMotion ? 0 : 0.2 }, children: ["+", remainingCount, " more"] }))] }));
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export { ReasoningTrace };
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { Reasoning } from "./Reasoning";
|
|
2
|
-
export
|
|
2
|
+
export { reasoningTheme } from "./Reasoning.theme";
|
|
3
|
+
export type { ReasoningProps, ReasoningStepProps, ReasoningStepData, ReasoningStepKind, ReasoningTraceTheme, ReasoningVariant, ReasoningThemeOverrides, } from "./Reasoning.types";
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Only animates the most recent tokens for performance
|
|
5
5
|
*/
|
|
6
6
|
import React from 'react';
|
|
7
|
+
import type { StreamingTokenEffect } from './StreamingResponse.types';
|
|
7
8
|
export interface AnimatedTextProps {
|
|
8
9
|
/** The full accumulated text */
|
|
9
10
|
text: string;
|
|
@@ -15,6 +16,12 @@ export interface AnimatedTextProps {
|
|
|
15
16
|
enabled?: boolean;
|
|
16
17
|
/** Additional CSS classes */
|
|
17
18
|
className?: string;
|
|
19
|
+
/** Optional inline indicator rendered immediately after the text */
|
|
20
|
+
cursor?: React.ReactNode;
|
|
21
|
+
/** Visual treatment for newly arrived words */
|
|
22
|
+
tokenEffect?: StreamingTokenEffect;
|
|
23
|
+
/** New-word transition duration in seconds */
|
|
24
|
+
tokenDuration?: number;
|
|
18
25
|
}
|
|
19
26
|
/**
|
|
20
27
|
* AnimatedText renders streaming text with smooth per-token fade-in.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useMemo, useRef } from 'react';
|
|
4
4
|
import { useReducedMotion, motion } from 'motion/react';
|
|
5
|
-
import {
|
|
5
|
+
import { getTokenFadeIn } from './StreamingResponse.animations.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Splits text into tokens (words) preserving whitespace
|
|
@@ -18,9 +18,10 @@ const tokenize = (text) => {
|
|
|
18
18
|
* For performance, only the last N tokens are animated with motion.span,
|
|
19
19
|
* while older tokens are rendered as static text.
|
|
20
20
|
*/
|
|
21
|
-
const AnimatedText = ({ text, isStreaming, animateLastN = 12, enabled = true, className, }) => {
|
|
21
|
+
const AnimatedText = ({ text, isStreaming, animateLastN = 12, enabled = true, className, cursor, tokenEffect = 'fade', tokenDuration = 0.12, }) => {
|
|
22
22
|
const shouldReduceMotion = useReducedMotion();
|
|
23
|
-
const animate = enabled && !shouldReduceMotion;
|
|
23
|
+
const animate = enabled && tokenEffect !== 'none' && !shouldReduceMotion;
|
|
24
|
+
const tokenVariants = useMemo(() => getTokenFadeIn(tokenEffect), [tokenEffect]);
|
|
24
25
|
// Track which tokens have already been seen/animated
|
|
25
26
|
const settledCountRef = useRef(0);
|
|
26
27
|
const tokens = useMemo(() => tokenize(text), [text]);
|
|
@@ -38,9 +39,9 @@ const AnimatedText = ({ text, isStreaming, animateLastN = 12, enabled = true, cl
|
|
|
38
39
|
const animatedTokens = tokens.slice(settledCount);
|
|
39
40
|
if (!animate || !isStreaming) {
|
|
40
41
|
// No animation: render plain text
|
|
41
|
-
return (
|
|
42
|
+
return (jsxs("p", { className: className || 'whitespace-pre-wrap wrap-break-word', children: [text, cursor] }));
|
|
42
43
|
}
|
|
43
|
-
return (jsxs("p", { className: className || 'whitespace-pre-wrap wrap-break-word', children: [settledText, animatedTokens.map((token, i) => (jsx(motion.span, { variants:
|
|
44
|
+
return (jsxs("p", { className: className || 'whitespace-pre-wrap wrap-break-word', children: [settledText, animatedTokens.map((token, i) => (jsx(motion.span, { variants: tokenVariants, initial: "hidden", animate: "visible", transition: { duration: tokenDuration, ease: [0, 0, 0.2, 1] }, style: { display: 'inline' }, children: token }, `${settledCount + i}-${token}`))), cursor] }));
|
|
44
45
|
};
|
|
45
46
|
AnimatedText.displayName = 'AnimatedText';
|
|
46
47
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import type { MarkdownOptions } from './StreamingResponse.types';
|
|
9
|
+
import type { StreamingTokenEffect } from './StreamingResponse.types';
|
|
9
10
|
export interface MarkdownRendererProps {
|
|
10
11
|
/** Markdown content to render */
|
|
11
12
|
content: string;
|
|
@@ -19,6 +20,10 @@ export interface MarkdownRendererProps {
|
|
|
19
20
|
showCursor?: boolean;
|
|
20
21
|
/** Number of recent words to animate (default: 6) */
|
|
21
22
|
animateLastN?: number;
|
|
23
|
+
/** Visual treatment for newly arrived words */
|
|
24
|
+
tokenEffect?: StreamingTokenEffect;
|
|
25
|
+
/** New-word transition duration in seconds */
|
|
26
|
+
tokenDuration?: number;
|
|
22
27
|
}
|
|
23
28
|
/**
|
|
24
29
|
* MarkdownRenderer component for rendering markdown with syntax highlighting
|
|
@@ -52,7 +52,7 @@ const SkipWords = ({ children }) => {
|
|
|
52
52
|
* Supports GitHub Flavored Markdown (tables, task lists, strikethrough, etc.)
|
|
53
53
|
* Animates individual words during streaming with a fade-in + blur effect
|
|
54
54
|
*/
|
|
55
|
-
const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated = true, showCursor = true, animateLastN = 12, }) => {
|
|
55
|
+
const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated = true, showCursor = true, animateLastN = 12, tokenEffect = 'fade', tokenDuration = 0.12, }) => {
|
|
56
56
|
const { allowHtml = false, syntaxTheme = 'light', renderCodeBlock } = options;
|
|
57
57
|
const shouldReduceMotion = useReducedMotion();
|
|
58
58
|
const shouldAnimate = animated && isStreaming && !shouldReduceMotion;
|
|
@@ -111,7 +111,7 @@ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated
|
|
|
111
111
|
},
|
|
112
112
|
// Blockquotes — word-level animation
|
|
113
113
|
blockquote({ children }) {
|
|
114
|
-
return (jsx("blockquote", { className: "border-l-4 border-(--color-primary) pl-4 py-2 my-3 bg-(--color-
|
|
114
|
+
return (jsx("blockquote", { className: "border-l-4 border-(--color-primary) pl-4 py-2 my-3 bg-(--color-surface) italic text-(--color-text-secondary)", children: children }));
|
|
115
115
|
},
|
|
116
116
|
// Links
|
|
117
117
|
a({ href, children }) {
|
|
@@ -122,7 +122,7 @@ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated
|
|
|
122
122
|
return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx("div", { className: "overflow-x-auto my-3", children: jsx("table", { className: "min-w-full border-collapse border border-(--color-border)", children: children }) })] }));
|
|
123
123
|
},
|
|
124
124
|
thead({ children }) {
|
|
125
|
-
return jsx("thead", { className: "bg-(--color-
|
|
125
|
+
return jsx("thead", { className: "bg-(--color-surface)", children: children });
|
|
126
126
|
},
|
|
127
127
|
tbody({ children }) {
|
|
128
128
|
return jsx("tbody", { children: children });
|
|
@@ -153,7 +153,7 @@ const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated
|
|
|
153
153
|
return jsx("del", { className: "line-through text-(--color-text-secondary)", children: children });
|
|
154
154
|
},
|
|
155
155
|
}), [shouldAnimate, syntaxTheme, renderCodeBlock]);
|
|
156
|
-
return (jsx(WordAnimationProvider, { content: displayContent, enabled: shouldAnimate, animateLastN: animateLastN, hasCursor: isStreaming && showCursor, children: jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], skipHtml: !allowHtml, components: markdownComponents, children: displayContent }) }));
|
|
156
|
+
return (jsx(WordAnimationProvider, { content: displayContent, enabled: shouldAnimate, animateLastN: animateLastN, hasCursor: isStreaming && showCursor, tokenEffect: tokenEffect, tokenDuration: tokenDuration, children: jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], skipHtml: !allowHtml, components: markdownComponents, children: displayContent }) }));
|
|
157
157
|
};
|
|
158
158
|
MarkdownRenderer.displayName = 'MarkdownRenderer';
|
|
159
159
|
|
|
@@ -14,7 +14,7 @@ export interface StreamingCursorProps {
|
|
|
14
14
|
className?: string;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
* StreamingCursor renders a
|
|
18
|
-
*
|
|
17
|
+
* StreamingCursor renders a quiet inline caret that indicates active streaming.
|
|
18
|
+
* Its held blink avoids the restless pulsing commonly associated with loaders.
|
|
19
19
|
*/
|
|
20
20
|
export declare const StreamingCursor: React.FC<StreamingCursorProps>;
|
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { motion } from 'motion/react';
|
|
3
|
+
import { useReducedMotion, motion } from 'motion/react';
|
|
4
4
|
import { cn } from '../../../utils/cn.js';
|
|
5
5
|
import { cursorPulse } from './StreamingResponse.animations.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* StreamingCursor renders a
|
|
9
|
-
*
|
|
8
|
+
* StreamingCursor renders a quiet inline caret that indicates active streaming.
|
|
9
|
+
* Its held blink avoids the restless pulsing commonly associated with loaders.
|
|
10
10
|
*/
|
|
11
11
|
const StreamingCursor = ({ visible, enabled = true, cursor = "▏", className, }) => {
|
|
12
|
+
const shouldReduceMotion = useReducedMotion();
|
|
12
13
|
if (!visible)
|
|
13
14
|
return null;
|
|
14
15
|
const isDefaultCursor = cursor === "▏";
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
const shouldAnimate = enabled && !shouldReduceMotion;
|
|
17
|
+
if (!shouldAnimate) {
|
|
18
|
+
return isDefaultCursor ? (jsx("span", { className: cn("ml-0.5 inline-block h-[1.05em] w-px translate-y-[0.14em] rounded-full bg-current text-[var(--color-primary)]", className), "aria-hidden": "true" })) : (jsx("span", { className: cn("font-light ml-0.5 text-[var(--color-primary)]", className), "aria-hidden": "true", children: cursor }));
|
|
17
19
|
}
|
|
18
|
-
return (jsx(motion.span, { variants: cursorPulse, initial: "initial", animate: "animate", className: cn("
|
|
19
|
-
|
|
20
|
+
return (jsx(motion.span, { variants: cursorPulse, initial: "initial", animate: "animate", className: cn("ml-0.5 inline-block text-[var(--color-primary)]", isDefaultCursor
|
|
21
|
+
? "h-[1.05em] w-px translate-y-[0.14em] rounded-full bg-current"
|
|
22
|
+
: "font-light", className), "aria-hidden": "true", style: {
|
|
20
23
|
display: "inline-block",
|
|
21
24
|
}, children: !isDefaultCursor && cursor }));
|
|
22
25
|
};
|
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
* Motion variants for streaming text animations
|
|
4
4
|
*/
|
|
5
5
|
import type { Variants, Transition } from 'motion/react';
|
|
6
|
+
import type { StreamingMotionOptions, StreamingMotionPreset, StreamingTokenEffect } from './StreamingResponse.types';
|
|
7
|
+
export interface ResolvedStreamingMotion {
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
smoothLayout: boolean;
|
|
10
|
+
tokenEffect: StreamingTokenEffect;
|
|
11
|
+
tokenDuration: number;
|
|
12
|
+
layoutDuration: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const resolveStreamingMotion: (motion?: StreamingMotionPreset | StreamingMotionOptions, animated?: boolean) => ResolvedStreamingMotion;
|
|
15
|
+
export declare const getTokenFadeIn: (effect: StreamingTokenEffect) => Variants;
|
|
6
16
|
/**
|
|
7
17
|
* Token fade-in animation
|
|
8
18
|
* Each new token fades in with a slight upward movement
|
|
@@ -1,9 +1,54 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { easings } from '../../../theme/animations.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* StreamingResponse Animation Variants
|
|
5
5
|
* Motion variants for streaming text animations
|
|
6
6
|
*/
|
|
7
|
+
const motionPresets = {
|
|
8
|
+
none: {
|
|
9
|
+
enabled: false,
|
|
10
|
+
smoothLayout: false,
|
|
11
|
+
tokenEffect: 'none',
|
|
12
|
+
tokenDuration: 0,
|
|
13
|
+
layoutDuration: 0,
|
|
14
|
+
},
|
|
15
|
+
subtle: {
|
|
16
|
+
enabled: true,
|
|
17
|
+
smoothLayout: true,
|
|
18
|
+
tokenEffect: 'fade',
|
|
19
|
+
tokenDuration: 0.12,
|
|
20
|
+
layoutDuration: 0.2,
|
|
21
|
+
},
|
|
22
|
+
expressive: {
|
|
23
|
+
enabled: true,
|
|
24
|
+
smoothLayout: true,
|
|
25
|
+
tokenEffect: 'fade-blur',
|
|
26
|
+
tokenDuration: 0.18,
|
|
27
|
+
layoutDuration: 0.26,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const resolveStreamingMotion = (motion = 'subtle', animated = true) => {
|
|
31
|
+
if (!animated)
|
|
32
|
+
return motionPresets.none;
|
|
33
|
+
if (typeof motion === 'string')
|
|
34
|
+
return motionPresets[motion];
|
|
35
|
+
const preset = motionPresets[motion.preset || 'subtle'];
|
|
36
|
+
return {
|
|
37
|
+
...preset,
|
|
38
|
+
...motion,
|
|
39
|
+
enabled: preset.enabled,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const getTokenFadeIn = (effect) => ({
|
|
43
|
+
hidden: {
|
|
44
|
+
opacity: 0,
|
|
45
|
+
filter: effect === 'fade-blur' ? 'blur(1px)' : 'blur(0px)',
|
|
46
|
+
},
|
|
47
|
+
visible: {
|
|
48
|
+
opacity: 1,
|
|
49
|
+
filter: 'blur(0px)',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
7
52
|
/**
|
|
8
53
|
* Token fade-in animation
|
|
9
54
|
* Each new token fades in with a slight upward movement
|
|
@@ -11,17 +56,15 @@ import { springs, easings } from '../../../theme/animations.js';
|
|
|
11
56
|
const tokenFadeIn = {
|
|
12
57
|
hidden: {
|
|
13
58
|
opacity: 0,
|
|
14
|
-
|
|
15
|
-
filter: 'blur(3px)',
|
|
59
|
+
filter: 'blur(0px)',
|
|
16
60
|
},
|
|
17
61
|
visible: {
|
|
18
62
|
opacity: 1,
|
|
19
|
-
y: 0,
|
|
20
63
|
filter: 'blur(0px)',
|
|
21
64
|
},
|
|
22
65
|
};
|
|
23
66
|
const tokenTransition = {
|
|
24
|
-
duration: 0.
|
|
67
|
+
duration: 0.18,
|
|
25
68
|
ease: easings.easeOut,
|
|
26
69
|
};
|
|
27
70
|
/**
|
|
@@ -31,15 +74,14 @@ const tokenTransition = {
|
|
|
31
74
|
const blockSlideIn = {
|
|
32
75
|
hidden: {
|
|
33
76
|
opacity: 0,
|
|
34
|
-
y: 6,
|
|
35
77
|
},
|
|
36
78
|
visible: {
|
|
37
79
|
opacity: 1,
|
|
38
|
-
y: 0,
|
|
39
80
|
},
|
|
40
81
|
};
|
|
41
82
|
const blockTransition = {
|
|
42
|
-
|
|
83
|
+
duration: 0.28,
|
|
84
|
+
ease: easings.easeOut,
|
|
43
85
|
};
|
|
44
86
|
/**
|
|
45
87
|
* Streaming cursor (caret/particle) animation
|
|
@@ -47,38 +89,22 @@ const blockTransition = {
|
|
|
47
89
|
*/
|
|
48
90
|
const cursorPulse = {
|
|
49
91
|
initial: {
|
|
50
|
-
opacity:
|
|
51
|
-
scale: 0.85,
|
|
92
|
+
opacity: 1,
|
|
52
93
|
},
|
|
53
94
|
animate: {
|
|
54
|
-
opacity: [1, 0.
|
|
55
|
-
scale: [1.1, 0.85, 1.1],
|
|
95
|
+
opacity: [1, 1, 0.18, 0.18, 1],
|
|
56
96
|
transition: {
|
|
57
|
-
duration:
|
|
97
|
+
duration: 1.1,
|
|
58
98
|
repeat: Infinity,
|
|
59
|
-
|
|
99
|
+
repeatDelay: 0.05,
|
|
100
|
+
times: [0, 0.48, 0.5, 0.92, 1],
|
|
101
|
+
ease: 'linear',
|
|
60
102
|
},
|
|
61
103
|
},
|
|
62
104
|
};
|
|
63
|
-
|
|
64
|
-
* Inline token fade-in animation
|
|
65
|
-
* Used for word-by-word animation inside markdown prose elements
|
|
66
|
-
* No y-movement to prevent layout jitter in inline text
|
|
67
|
-
*/
|
|
68
|
-
const inlineTokenFadeIn = {
|
|
69
|
-
hidden: {
|
|
70
|
-
opacity: 0,
|
|
71
|
-
filter: 'blur(3px)',
|
|
72
|
-
},
|
|
73
|
-
visible: {
|
|
74
|
-
opacity: 1,
|
|
75
|
-
filter: 'blur(0px)',
|
|
76
|
-
},
|
|
77
|
-
};
|
|
78
|
-
const inlineTokenTransition = {
|
|
79
|
-
duration: 0.25,
|
|
105
|
+
({
|
|
80
106
|
ease: easings.easeOut,
|
|
81
|
-
};
|
|
107
|
+
});
|
|
82
108
|
/**
|
|
83
109
|
* Container animation for staggered children
|
|
84
110
|
*/
|
|
@@ -90,4 +116,4 @@ const staggerContainer = {
|
|
|
90
116
|
},
|
|
91
117
|
};
|
|
92
118
|
|
|
93
|
-
export { blockSlideIn, blockTransition, cursorPulse,
|
|
119
|
+
export { blockSlideIn, blockTransition, cursorPulse, getTokenFadeIn, resolveStreamingMotion, staggerContainer, tokenFadeIn, tokenTransition };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx
|
|
3
|
-
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useRef, useEffect, useMemo } from 'react';
|
|
4
|
+
import { AnimatePresence, motion } from 'motion/react';
|
|
4
5
|
import { useStreamingSSE } from '../../../hooks/useStreamingSSE.js';
|
|
5
6
|
import { Message } from '../../core/Message/Message.js';
|
|
6
7
|
import { TypeWriter } from '../../core/Message/TypeWriter.js';
|
|
@@ -12,6 +13,8 @@ import { ErrorDisplay } from './ErrorDisplay.js';
|
|
|
12
13
|
import { MarkdownRenderer } from './MarkdownRenderer.js';
|
|
13
14
|
import { AnimatedText } from './AnimatedText.js';
|
|
14
15
|
import { StreamingCursor } from './StreamingCursor.js';
|
|
16
|
+
import { StreamingSurface } from './StreamingSurface.js';
|
|
17
|
+
import { resolveStreamingMotion } from './StreamingResponse.animations.js';
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* StreamingResponse component for AI/LLM streaming responses
|
|
@@ -35,9 +38,9 @@ url, method = 'POST', headers, body, format = 'openai', autoStart = true,
|
|
|
35
38
|
// Callbacks
|
|
36
39
|
onToken, onComplete, onError, onStart, onAbort,
|
|
37
40
|
// Display options
|
|
38
|
-
typingSpeed = 100, enableTypewriter =
|
|
41
|
+
typingSpeed = 100, enableTypewriter = false, enableMarkdown = true, markdownOptions,
|
|
39
42
|
// Animation
|
|
40
|
-
animated = true, showCursor = true, animateLastN = 12,
|
|
43
|
+
animated = true, showCursor = true, animateLastN = 12, motion: motion$1 = 'subtle', streamingIndicator = false,
|
|
41
44
|
// Message component props
|
|
42
45
|
role = 'assistant', avatar, showTimestamp = true, showActions = true, onCopy, onRegenerate,
|
|
43
46
|
// Error handling
|
|
@@ -62,6 +65,7 @@ className, }) => {
|
|
|
62
65
|
onStart,
|
|
63
66
|
onAbort,
|
|
64
67
|
});
|
|
68
|
+
const resolvedMotion = useMemo(() => resolveStreamingMotion(motion$1, animated), [animated, motion$1]);
|
|
65
69
|
// Determine content to display
|
|
66
70
|
let messageContent;
|
|
67
71
|
if (error && showError) {
|
|
@@ -70,11 +74,11 @@ className, }) => {
|
|
|
70
74
|
}
|
|
71
75
|
else if (enableMarkdown) {
|
|
72
76
|
// Render markdown with block-level slide-in animations and streaming cursor
|
|
73
|
-
messageContent = (jsx(MarkdownRenderer, { content: accumulatedText, options: markdownOptions, isStreaming: isStreaming, animated:
|
|
77
|
+
messageContent = (jsx(MarkdownRenderer, { content: accumulatedText, options: markdownOptions, isStreaming: isStreaming, animated: resolvedMotion.enabled && resolvedMotion.tokenEffect !== 'none', showCursor: showCursor, animateLastN: animateLastN, tokenEffect: resolvedMotion.tokenEffect, tokenDuration: resolvedMotion.tokenDuration }));
|
|
74
78
|
}
|
|
75
79
|
else if (isStreaming) {
|
|
76
80
|
// During streaming without markdown: use per-token fade-in animation
|
|
77
|
-
messageContent = (
|
|
81
|
+
messageContent = (jsx(AnimatedText, { text: accumulatedText, isStreaming: isStreaming, animateLastN: animateLastN, enabled: resolvedMotion.enabled, tokenEffect: resolvedMotion.tokenEffect, tokenDuration: resolvedMotion.tokenDuration, cursor: jsx(StreamingCursor, { visible: showCursor, enabled: resolvedMotion.enabled }) }));
|
|
78
82
|
}
|
|
79
83
|
else if (enableTypewriter && isComplete && accumulatedText) {
|
|
80
84
|
// Use typewriter animation after streaming completes
|
|
@@ -84,8 +88,10 @@ className, }) => {
|
|
|
84
88
|
// Show raw text (streaming complete, typewriter disabled)
|
|
85
89
|
messageContent = (jsx("p", { className: "whitespace-pre-wrap wrap-break-word", children: accumulatedText }));
|
|
86
90
|
}
|
|
91
|
+
const contentState = error && showError ? 'error' : 'content';
|
|
92
|
+
const animatedContent = (jsx(StreamingSurface, { isStreaming: isStreaming, enabled: resolvedMotion.enabled && resolvedMotion.smoothLayout, duration: resolvedMotion.layoutDuration, children: jsx(AnimatePresence, { initial: false, mode: "popLayout", children: jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, transition: { duration: resolvedMotion.enabled ? 0.12 : 0 }, children: messageContent }, contentState) }) }));
|
|
87
93
|
// Render with Message component
|
|
88
|
-
return (jsx(Message, { role: role, content:
|
|
94
|
+
return (jsx(Message, { role: role, content: animatedContent, avatar: avatar, timestamp: startTimeRef.current, showTimestamp: showTimestamp, isStreaming: isStreaming, streamingIndicator: streamingIndicator, showActions: showActions && !error, onCopy: onCopy, onRegenerate: onRegenerate, className: className }));
|
|
89
95
|
};
|
|
90
96
|
StreamingResponse.displayName = 'StreamingResponse';
|
|
91
97
|
|
|
@@ -25,6 +25,24 @@ export interface MarkdownOptions {
|
|
|
25
25
|
/** Custom code block renderer */
|
|
26
26
|
renderCodeBlock?: (code: string, language: string) => ReactNode;
|
|
27
27
|
}
|
|
28
|
+
export type StreamingMotionPreset = "none" | "subtle" | "expressive";
|
|
29
|
+
export type StreamingTokenEffect = "none" | "fade" | "fade-blur";
|
|
30
|
+
/**
|
|
31
|
+
* High-level motion controls for streamed content.
|
|
32
|
+
* Presets cover the common cases; individual fields are intended for product-level tuning.
|
|
33
|
+
*/
|
|
34
|
+
export interface StreamingMotionOptions {
|
|
35
|
+
/** Base motion treatment (default: "subtle") */
|
|
36
|
+
preset?: StreamingMotionPreset;
|
|
37
|
+
/** Smooth changes in rendered content height as lines wrap (default: true) */
|
|
38
|
+
smoothLayout?: boolean;
|
|
39
|
+
/** Treatment applied only to newly arrived words */
|
|
40
|
+
tokenEffect?: StreamingTokenEffect;
|
|
41
|
+
/** New-word transition duration in seconds */
|
|
42
|
+
tokenDuration?: number;
|
|
43
|
+
/** Content-height transition duration in seconds */
|
|
44
|
+
layoutDuration?: number;
|
|
45
|
+
}
|
|
28
46
|
/**
|
|
29
47
|
* Props for StreamingResponse component
|
|
30
48
|
*/
|
|
@@ -53,7 +71,10 @@ export interface StreamingResponseProps {
|
|
|
53
71
|
onAbort?: () => void;
|
|
54
72
|
/** Typewriter animation speed in ms per word (default: 100) */
|
|
55
73
|
typingSpeed?: number;
|
|
56
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Replay completed plain text with a typewriter animation (default: false).
|
|
76
|
+
* Usually unnecessary when the user has already watched the response stream.
|
|
77
|
+
*/
|
|
57
78
|
enableTypewriter?: boolean;
|
|
58
79
|
/** Enable markdown rendering (default: true) */
|
|
59
80
|
enableMarkdown?: boolean;
|
|
@@ -63,8 +84,18 @@ export interface StreamingResponseProps {
|
|
|
63
84
|
animated?: boolean;
|
|
64
85
|
/** Show blinking cursor while streaming (default: true) */
|
|
65
86
|
showCursor?: boolean;
|
|
66
|
-
/** Number of recent words to animate during streaming (default:
|
|
87
|
+
/** Number of recent words to animate during streaming (default: 12) */
|
|
67
88
|
animateLastN?: number;
|
|
89
|
+
/**
|
|
90
|
+
* Streaming motion preset or focused overrides (default: "subtle").
|
|
91
|
+
* `animated={false}` continues to disable all motion for backwards compatibility.
|
|
92
|
+
*/
|
|
93
|
+
motion?: StreamingMotionPreset | StreamingMotionOptions;
|
|
94
|
+
/**
|
|
95
|
+
* Optional footer status shown while streaming. Pass `false` to hide it.
|
|
96
|
+
* The premium default is false because the inline caret already communicates activity.
|
|
97
|
+
*/
|
|
98
|
+
streamingIndicator?: ReactNode | false;
|
|
68
99
|
/** Message role (default: 'assistant') */
|
|
69
100
|
role?: MessageRole;
|
|
70
101
|
/** Avatar configuration */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface StreamingSurfaceProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
isStreaming: boolean;
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
duration?: number;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Smooths intrinsic height changes without scaling or distorting text.
|
|
11
|
+
* ResizeObserver tracks the natural content height; only the clipping frame animates.
|
|
12
|
+
*/
|
|
13
|
+
export declare const StreamingSurface: React.FC<StreamingSurfaceProps>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useRef, useState, useLayoutEffect } from 'react';
|
|
4
|
+
import { useReducedMotion, motion } from 'motion/react';
|
|
5
|
+
import { cn } from '../../../utils/cn.js';
|
|
6
|
+
import { easings } from '../../../theme/animations.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Smooths intrinsic height changes without scaling or distorting text.
|
|
10
|
+
* ResizeObserver tracks the natural content height; only the clipping frame animates.
|
|
11
|
+
*/
|
|
12
|
+
const StreamingSurface = ({ children, isStreaming, enabled = true, duration = 0.22, className, }) => {
|
|
13
|
+
const contentRef = useRef(null);
|
|
14
|
+
const hasMeasuredRef = useRef(false);
|
|
15
|
+
const shouldReduceMotion = useReducedMotion();
|
|
16
|
+
const [height, setHeight] = useState();
|
|
17
|
+
const shouldAnimate = enabled && !shouldReduceMotion;
|
|
18
|
+
useLayoutEffect(() => {
|
|
19
|
+
const element = contentRef.current;
|
|
20
|
+
if (!element || typeof ResizeObserver === "undefined")
|
|
21
|
+
return;
|
|
22
|
+
const measure = () => {
|
|
23
|
+
const nextHeight = element.getBoundingClientRect().height;
|
|
24
|
+
hasMeasuredRef.current = true;
|
|
25
|
+
setHeight((currentHeight) => currentHeight === nextHeight ? currentHeight : nextHeight);
|
|
26
|
+
};
|
|
27
|
+
measure();
|
|
28
|
+
const observer = new ResizeObserver(measure);
|
|
29
|
+
observer.observe(element);
|
|
30
|
+
return () => observer.disconnect();
|
|
31
|
+
}, []);
|
|
32
|
+
return (jsx(motion.div, { initial: false, animate: shouldAnimate && hasMeasuredRef.current && height !== undefined
|
|
33
|
+
? { height }
|
|
34
|
+
: undefined, transition: { duration, ease: easings.easeOut }, className: cn(shouldAnimate && "overflow-hidden", className), style: !shouldAnimate && height !== undefined ? { height: "auto" } : undefined, "aria-busy": isStreaming, "aria-live": isStreaming ? "off" : "polite", children: jsx("div", { ref: contentRef, children: children }) }));
|
|
35
|
+
};
|
|
36
|
+
StreamingSurface.displayName = "StreamingSurface";
|
|
37
|
+
|
|
38
|
+
export { StreamingSurface };
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* all markdown elements (paragraphs, headings, lists, blockquotes, etc.).
|
|
6
6
|
*/
|
|
7
7
|
import React from "react";
|
|
8
|
+
import type { StreamingTokenEffect } from "./StreamingResponse.types";
|
|
8
9
|
interface WordAnimationContextValue {
|
|
9
10
|
/** Process children of a prose element, animating recent words */
|
|
10
11
|
processChildren: (children: React.ReactNode) => React.ReactNode;
|
|
@@ -22,6 +23,10 @@ export interface WordAnimationProviderProps {
|
|
|
22
23
|
animateLastN?: number;
|
|
23
24
|
/** Whether cursor is present in content */
|
|
24
25
|
hasCursor?: boolean;
|
|
26
|
+
/** Visual treatment for newly arrived words */
|
|
27
|
+
tokenEffect?: StreamingTokenEffect;
|
|
28
|
+
/** New-word transition duration in seconds */
|
|
29
|
+
tokenDuration?: number;
|
|
25
30
|
}
|
|
26
31
|
export declare const WordAnimationProvider: React.FC<WordAnimationProviderProps>;
|
|
27
32
|
export {};
|