@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
|
@@ -3,19 +3,34 @@
|
|
|
3
3
|
* This file defines shared styling patterns used across all form components
|
|
4
4
|
* Individual component themes should extend these base styles
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* The inset-shadow field edge on its own — radius, resting border, hover edge and
|
|
8
|
+
* focus border+ring — with NO layout/paint extras (no `flex`, no fill, no
|
|
9
|
+
* `transition-all`).
|
|
10
|
+
*
|
|
11
|
+
* Split out of `inputGroupBaseStyle` (which is just this plus those extras) for the
|
|
12
|
+
* one control that cannot take `transition-all`: `InputCounter`'s root is a
|
|
13
|
+
* motion element carrying `layout`, and a CSS transition covering `transform`
|
|
14
|
+
* re-interpolates motion's per-frame writes (§12). It needs the same edge as every
|
|
15
|
+
* other control, but has to name its own transitioned properties — so the edge is
|
|
16
|
+
* defined once here and both consumers compose it.
|
|
17
|
+
*/
|
|
18
|
+
const inputGroupBorderStyle = "rounded-[var(--form-radius)] outline-none shadow-[inset_0_0_0_1px_var(--color-border)] " +
|
|
19
|
+
"focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-600)] " +
|
|
20
|
+
"focus-within:ring-4 focus-within:ring-[var(--color-primary)]/10 " +
|
|
21
|
+
// Hover edge: strengthen the border to --color-border-secondary on hover. Scoped with
|
|
22
|
+
// not-focus-within so focus (primary border) always wins; the token flips for dark mode.
|
|
23
|
+
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-border-secondary)] " +
|
|
24
|
+
// Dark focus mirror (fill comes from --color-surface, which flips automatically)
|
|
25
|
+
"dark:focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-500)] dark:focus-within:ring-[var(--color-primary-500)]/20";
|
|
6
26
|
// Common form theme configuration
|
|
7
27
|
const formsBaseTheme = {
|
|
8
28
|
// Common wrapper style
|
|
9
29
|
wrapperStyle: "relative w-full",
|
|
30
|
+
/** The field edge alone — for controls that must supply their own transition/fill. */
|
|
31
|
+
inputGroupBorderStyle,
|
|
10
32
|
// Common input group style with focus, hover, and state variations
|
|
11
|
-
inputGroupBaseStyle:
|
|
12
|
-
"focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-600)] " +
|
|
13
|
-
"focus-within:ring-4 focus-within:ring-[var(--color-primary)]/10 bg-[var(--field-fill)] transition-all " +
|
|
14
|
-
// Hover edge: strengthen the border to --color-border-secondary on hover. Scoped with
|
|
15
|
-
// not-focus-within so focus (primary border) always wins; the token flips for dark mode.
|
|
16
|
-
"not-focus-within:hover:shadow-[inset_0_0_0_1px_var(--color-border-secondary)] " +
|
|
17
|
-
// Dark focus mirror (fill comes from --color-surface, which flips automatically)
|
|
18
|
-
"dark:focus-within:shadow-[inset_0_0_0_1px_var(--color-primary-500)] dark:focus-within:ring-[var(--color-primary-500)]/20",
|
|
33
|
+
inputGroupBaseStyle: `relative flex bg-[var(--field-fill)] transition-all ${inputGroupBorderStyle}`,
|
|
19
34
|
// Common base input/control style
|
|
20
35
|
controlBaseStyle: "w-full bg-transparent text-sm text-[var(--color-text-primary)] " +
|
|
21
36
|
"placeholder:text-[var(--color-text-placeholder)] focus:outline-none",
|
|
@@ -103,6 +118,11 @@ const formsBaseTheme = {
|
|
|
103
118
|
helperText: "text-xs text-[var(--color-text-muted)] mt-1.5 [.state-disabled_&]:text-[var(--color-text-disabled)] [.state-invalid_&]:text-[var(--color-danger-500)] " +
|
|
104
119
|
"dark:[.state-invalid_&]:text-[var(--color-danger-400)]",
|
|
105
120
|
// Common icon styles
|
|
121
|
+
//
|
|
122
|
+
// `left`/`right`/`padding` are the size-BLIND originals (flat pr-3 / pr-10 at
|
|
123
|
+
// every size); the `*Sizes` maps below are the size-aware replacements. Adopt
|
|
124
|
+
// the maps in new work — Select already has — and treat the flat keys as the
|
|
125
|
+
// not-yet-migrated path for Input/Combobox/DatePicker/DateRangePicker/TimePicker.
|
|
106
126
|
iconStyles: {
|
|
107
127
|
left: "absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none text-[var(--color-text-muted)]",
|
|
108
128
|
right: "absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-[var(--color-text-muted)]",
|
|
@@ -110,6 +130,61 @@ const formsBaseTheme = {
|
|
|
110
130
|
left: "pl-10",
|
|
111
131
|
right: "pr-10",
|
|
112
132
|
},
|
|
133
|
+
/**
|
|
134
|
+
* The leading-icon slot, inset by the control's own horizontal padding —
|
|
135
|
+
* EXACTLY, not the trailing slot's `− 4px`. A leading icon stands where the
|
|
136
|
+
* text would have started, so matching `--form-px-*` keeps one constant left
|
|
137
|
+
* edge for a field's contents whether or not it has an icon. The trailing
|
|
138
|
+
* slot is chrome rather than content, which is why it insets tighter.
|
|
139
|
+
*/
|
|
140
|
+
leftSizes: {
|
|
141
|
+
sm: "absolute inset-y-0 left-0 flex items-center pl-[var(--form-px-sm)] pointer-events-none text-[var(--color-text-muted)]",
|
|
142
|
+
md: "absolute inset-y-0 left-0 flex items-center pl-[var(--form-px-md)] pointer-events-none text-[var(--color-text-muted)]",
|
|
143
|
+
lg: "absolute inset-y-0 left-0 flex items-center pl-[var(--form-px-lg)] pointer-events-none text-[var(--color-text-muted)]",
|
|
144
|
+
},
|
|
145
|
+
/** Text runway for the leading slot: inset + icon + an 8px gap (32/36/40). */
|
|
146
|
+
paddingLeftSizes: {
|
|
147
|
+
sm: "pl-[calc(var(--form-px-sm)_+_20px)]",
|
|
148
|
+
md: "pl-[calc(var(--form-px-md)_+_22px)]",
|
|
149
|
+
lg: "pl-[calc(var(--form-px-lg)_+_24px)]",
|
|
150
|
+
},
|
|
151
|
+
/**
|
|
152
|
+
* The trailing-icon slot, inset from the right edge by the control's own
|
|
153
|
+
* horizontal padding MINUS 4px (8 / 10 / 12 at the default theme). Tighter
|
|
154
|
+
* than the text inset on purpose: a chevron is mostly whitespace, so at the
|
|
155
|
+
* same metric distance it reads as further from the edge than a glyph does.
|
|
156
|
+
* Derived from `--form-px-*` rather than a literal, so retuning a theme's
|
|
157
|
+
* control padding moves the icon with it.
|
|
158
|
+
*/
|
|
159
|
+
rightSizes: {
|
|
160
|
+
sm: "absolute inset-y-0 right-0 flex items-center pr-[calc(var(--form-px-sm)_-_4px)] pointer-events-none text-[var(--color-text-muted)]",
|
|
161
|
+
md: "absolute inset-y-0 right-0 flex items-center pr-[calc(var(--form-px-md)_-_4px)] pointer-events-none text-[var(--color-text-muted)]",
|
|
162
|
+
lg: "absolute inset-y-0 right-0 flex items-center pr-[calc(var(--form-px-lg)_-_4px)] pointer-events-none text-[var(--color-text-muted)]",
|
|
163
|
+
},
|
|
164
|
+
/**
|
|
165
|
+
* Text runway reserved for that slot: inset + icon + an 8px gap, i.e.
|
|
166
|
+
* `--form-px-*` + 16/18/20 (28 / 32 / 36). It replaces a flat `pr-10` that
|
|
167
|
+
* over-reserved at every size.
|
|
168
|
+
*/
|
|
169
|
+
paddingRightSizes: {
|
|
170
|
+
sm: "pr-[calc(var(--form-px-sm)_+_16px)]",
|
|
171
|
+
md: "pr-[calc(var(--form-px-md)_+_18px)]",
|
|
172
|
+
lg: "pr-[calc(var(--form-px-lg)_+_20px)]",
|
|
173
|
+
},
|
|
174
|
+
/**
|
|
175
|
+
* The glyph itself, ramping with the control (12 / 14 / 16px) instead of a
|
|
176
|
+
* flat 16 — at `sm` a 16px icon out-weighed the 14px text beside it.
|
|
177
|
+
*
|
|
178
|
+
* 🔴 Reads --form-icon-size-*, not a Tailwind literal: icon size was the one
|
|
179
|
+
* axis of a field's geometry a theme could not retune, so a preset that
|
|
180
|
+
* scaled height/padding/type left every decorator at its hardcoded size.
|
|
181
|
+
* Not to be confused with --button-icon-square-*, which is a BUTTON's box.
|
|
182
|
+
*/
|
|
183
|
+
sizes: {
|
|
184
|
+
sm: "size-[var(--form-icon-size-sm)]",
|
|
185
|
+
md: "size-[var(--form-icon-size-md)]",
|
|
186
|
+
lg: "size-[var(--form-icon-size-lg)]",
|
|
187
|
+
},
|
|
113
188
|
},
|
|
114
189
|
// Dropdown/listbox styles for Select, Combobox, and similar components
|
|
115
190
|
dropdownStyles: {
|
|
@@ -130,13 +205,19 @@ const formsBaseTheme = {
|
|
|
130
205
|
// (utilities layer ⟶ win over that base-layer rule) suppress it here; scroll still works via
|
|
131
206
|
// wheel/trackpad/keyboard. Scoped to the dropdown panel only — app scrollbars are untouched.
|
|
132
207
|
"[scrollbar-width:none] [&::-webkit-scrollbar]:hidden " +
|
|
133
|
-
//
|
|
134
|
-
//
|
|
208
|
+
// Padding on ALL sides (never py-only): the rows are rounded (see `option`), so they must
|
|
209
|
+
// inset evenly — with vertical-only padding a row's rounded corners and its hover ring run
|
|
135
210
|
// flush into the panel's own edge and the radius reads as a rendering glitch. This lives
|
|
136
211
|
// here rather than at each call site because every consumer needs it and, when it was a
|
|
137
212
|
// call-site decision, two of four got it wrong.
|
|
138
|
-
|
|
139
|
-
|
|
213
|
+
// 🔴 --form-dropdown-padding, not a literal p-1: it also feeds
|
|
214
|
+
// --form-dropdown-inner-radius, which rounds the first/last row to match this panel's
|
|
215
|
+
// curve. A literal survives a themed radius change and silently breaks that.
|
|
216
|
+
"p-[var(--form-dropdown-padding)] " +
|
|
217
|
+
// --form-dropdown-radius, NOT --form-radius: this is a padded content container, so it
|
|
218
|
+
// needs a capped token. --form-radius is `var(--radius-base)` — the uncapped CONTROL
|
|
219
|
+
// radius — which on `ember` (base 24px) curved this panel 24px against 4px of padding.
|
|
220
|
+
"rounded-[var(--form-dropdown-radius)] backdrop-blur-md text-sm border border-[var(--color-border)] " +
|
|
140
221
|
"ring-1 ring-[var(--color-border)] focus:outline-none",
|
|
141
222
|
// Base option style — hover uses the shared `--color-surface-hover` interaction tint
|
|
142
223
|
// (§3): a translucent shade that composites over the dropdown's surface, darkening in
|
|
@@ -145,8 +226,16 @@ const formsBaseTheme = {
|
|
|
145
226
|
// The radius belongs here, not per-consumer: `container`'s gap-0.5 and this row's inset
|
|
146
227
|
// hover ring only read correctly on a rounded, inset row, so the base already assumes
|
|
147
228
|
// this treatment — withholding the radius just let call sites drift out of it.
|
|
229
|
+
// Radius mirrors the menu rows (MenuItem): interior rows are a flat 4px, and the two rows
|
|
230
|
+
// that MEET the panel's corners take --form-dropdown-inner-radius (the panel's radius minus
|
|
231
|
+
// its border and padding) so their curve is concentric with the panel's instead of bulging
|
|
232
|
+
// past it. It was a flat --radius-base on every row, which equalled the panel's own radius.
|
|
233
|
+
// 🔴 first:/last: resolve against DOM SIBLINGS — every consumer here renders its options as
|
|
234
|
+
// direct children of the panel (verified for Select/Combobox/InputTag/Mention). Wrapping
|
|
235
|
+
// them in a group element would make a row both first and last of its own subtree and round
|
|
236
|
+
// all four corners; see ContextMenuSub, which renders no element for exactly that reason.
|
|
148
237
|
option: "relative cursor-pointer select-none py-2 px-3 text-[var(--color-text-primary)] " +
|
|
149
|
-
"rounded-[var(--radius-
|
|
238
|
+
"rounded-[4px] first:rounded-t-[var(--form-dropdown-inner-radius)] last:rounded-b-[var(--form-dropdown-inner-radius)] " +
|
|
150
239
|
"hover:bg-[var(--color-surface-hover)] hover:shadow-[inset_0_0_0_1px_var(--color-border)]",
|
|
151
240
|
// Selected option modifier
|
|
152
241
|
optionSelected: "text-[var(--color-text-primary)] bg-[var(--color-surface-hover)] shadow-[inset_0_0_0_1px_var(--color-border)]",
|
|
@@ -40,6 +40,7 @@ export { sliderTheme } from './Slider/Slider.theme.js';
|
|
|
40
40
|
export { Signature } from './Signature/Signature.js';
|
|
41
41
|
export { signatureTheme } from './Signature/Signature.theme.js';
|
|
42
42
|
export { RichTextEditor } from './RichTextEditor/RichTextEditor.js';
|
|
43
|
+
import './RichTextEditor/RichTextToolbar.js';
|
|
43
44
|
export { richTextEditorTheme } from './RichTextEditor/RichTextEditor.theme.js';
|
|
44
45
|
export { InputOTP } from './InputOTP/InputOTP.js';
|
|
45
46
|
export { inputOTPTheme } from './InputOTP/InputOTP.theme.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { FormValues } from "./formScope";
|
|
3
|
+
export interface FormShellProps {
|
|
4
|
+
formId: string;
|
|
5
|
+
title?: React.ReactNode;
|
|
6
|
+
description?: React.ReactNode;
|
|
7
|
+
/** Label for the auto-rendered submit button. @default "Submit" */
|
|
8
|
+
submitLabel?: string;
|
|
9
|
+
/** Heading for the blocked-submit error summary. */
|
|
10
|
+
errorSummaryTitle?: string;
|
|
11
|
+
values?: FormValues;
|
|
12
|
+
defaultValues?: FormValues;
|
|
13
|
+
onValuesChange?: (values: FormValues) => void;
|
|
14
|
+
onSubmit: (values: FormValues) => void;
|
|
15
|
+
children?: React.ReactNode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generative-only form shell — the runtime half of the `Form` spec container.
|
|
19
|
+
* Sibling in spirit to `CardShell` in registry.tsx: it exists to serve the
|
|
20
|
+
* engine and is deliberately NOT a public library component.
|
|
21
|
+
*/
|
|
22
|
+
export declare function FormShell({ formId, title, description, submitLabel, errorSummaryTitle, values, defaultValues, onValuesChange, onSubmit, children, }: FormShellProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import React__default from 'react';
|
|
4
|
+
import { WarningCircle } from '@phosphor-icons/react';
|
|
5
|
+
import { Button } from '../core/Button/Button.js';
|
|
6
|
+
import { cn } from '../../utils/cn.js';
|
|
7
|
+
import { useFormScopeState, FormScopeContext } from './formScope.js';
|
|
8
|
+
|
|
9
|
+
// SSR-safe layout effect (house shim — see src/hooks/useScaleBackground.ts):
|
|
10
|
+
// `useLayoutEffect` warns during server rendering, so it must not be called
|
|
11
|
+
// bare in an SSR-safe library (CLAUDE.md §6/§11).
|
|
12
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? React__default.useLayoutEffect : React__default.useEffect;
|
|
13
|
+
/**
|
|
14
|
+
* Error-summary copy. Kept as props (not trapped strings) per CLAUDE.md §6:
|
|
15
|
+
* every built-in visible string must be overridable.
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_ERROR_SUMMARY_TITLE = "Please fix the following before continuing:";
|
|
18
|
+
/**
|
|
19
|
+
* Generative-only form shell — the runtime half of the `Form` spec container.
|
|
20
|
+
* Sibling in spirit to `CardShell` in registry.tsx: it exists to serve the
|
|
21
|
+
* engine and is deliberately NOT a public library component.
|
|
22
|
+
*/
|
|
23
|
+
function FormShell({ formId, title, description, submitLabel = "Submit", errorSummaryTitle = DEFAULT_ERROR_SUMMARY_TITLE, values, defaultValues, onValuesChange, onSubmit, children, }) {
|
|
24
|
+
const formRef = React__default.useRef(null);
|
|
25
|
+
const summaryRef = React__default.useRef(null);
|
|
26
|
+
const titleId = React__default.useId();
|
|
27
|
+
const summaryTitleId = React__default.useId();
|
|
28
|
+
// A blocked submit moves focus HERE, to the form-level summary — not to the
|
|
29
|
+
// first invalid control. That is a deliberate supersession of a per-field
|
|
30
|
+
// focus approach, and it is about coverage, not preference: only six of the
|
|
31
|
+
// thirteen curated controls even render a focusable primary element such a
|
|
32
|
+
// hook could target. Select/TimePicker spread no rest props onto one, and
|
|
33
|
+
// Combobox/Switch/Slider/InputOTP/InputTag land their root on a
|
|
34
|
+
// non-focusable wrapper `<div>`, where `.focus()` is a silent no-op.
|
|
35
|
+
// Closing that gap means changing those six core form components to
|
|
36
|
+
// forward a ref/rest props to their focusable element — a separate,
|
|
37
|
+
// dedicated pass, deferred and not yet started. Worse, the per-field
|
|
38
|
+
// *message* is thinner still: Switch and Rating render no error text and
|
|
39
|
+
// set no `aria-invalid` at all, so a required Switch ("accept the terms")
|
|
40
|
+
// produced a form whose Submit button did nothing, forever, with no
|
|
41
|
+
// programmatic state a screen reader could reach — a WCAG 3.3.1 failure.
|
|
42
|
+
// One summary covers all thirteen identically today and needs nothing from
|
|
43
|
+
// them. The per-field `state="invalid"` / `errorMessage` treatment still
|
|
44
|
+
// applies wherever a control declares those props (see FIELD_PROP_SUPPORT
|
|
45
|
+
// in GenerativeView.tsx); the summary is additive, not a replacement for it.
|
|
46
|
+
const [focusToken, setFocusToken] = React__default.useState(0);
|
|
47
|
+
const handleInvalid = React__default.useCallback(() => setFocusToken((t) => t + 1), []);
|
|
48
|
+
const scope = useFormScopeState({
|
|
49
|
+
formId,
|
|
50
|
+
values,
|
|
51
|
+
defaultValues,
|
|
52
|
+
onValuesChange,
|
|
53
|
+
onSubmit,
|
|
54
|
+
onInvalid: handleInvalid,
|
|
55
|
+
});
|
|
56
|
+
// Derived from `scope.errors` rather than held as its own state, so the
|
|
57
|
+
// summary clears itself the moment a user fixes a field (`setValue` drops
|
|
58
|
+
// that field's error) without a second source of truth to keep in sync.
|
|
59
|
+
const invalidNames = Object.keys(scope.errors);
|
|
60
|
+
// Focus after the summary has actually rendered: `onInvalid` fires inside
|
|
61
|
+
// `scope.submit()`, one React state update BEFORE `scope.errors` — and
|
|
62
|
+
// therefore the summary element — exists. A layout effect keyed on the token
|
|
63
|
+
// (not on `invalidNames`, which is unchanged when a second submit is blocked
|
|
64
|
+
// by the very same fields) re-focuses on every blocked attempt.
|
|
65
|
+
useIsomorphicLayoutEffect(() => {
|
|
66
|
+
var _a;
|
|
67
|
+
if (focusToken > 0)
|
|
68
|
+
(_a = summaryRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
69
|
+
}, [focusToken]);
|
|
70
|
+
// A child submit button suppresses the auto-rendered one. Checked on the
|
|
71
|
+
// rendered DOM rather than by inspecting children, so it works for buttons
|
|
72
|
+
// nested inside container nodes the model wrapped them in. The query
|
|
73
|
+
// excludes the auto-rendered button itself (via its marker attribute) —
|
|
74
|
+
// otherwise the very button this effect renders would be picked up as
|
|
75
|
+
// "a child submit button" and immediately hide itself.
|
|
76
|
+
//
|
|
77
|
+
// Runs in a LAYOUT effect (not a passive one) so the correction lands
|
|
78
|
+
// before the browser paints: a passive effect fires after paint, so a
|
|
79
|
+
// caller supplying a real child submit button would flash both buttons
|
|
80
|
+
// for one frame before the auto one is hidden (the same mount-then-correct
|
|
81
|
+
// anti-pattern already documented for chart container measurement).
|
|
82
|
+
const [hasChildSubmit, setHasChildSubmit] = React__default.useState(false);
|
|
83
|
+
useIsomorphicLayoutEffect(() => {
|
|
84
|
+
var _a;
|
|
85
|
+
const found = (_a = formRef.current) === null || _a === void 0 ? void 0 : _a.querySelector('button[type="submit"]:not([data-generative-auto-submit])');
|
|
86
|
+
setHasChildSubmit(!!found);
|
|
87
|
+
}, [children]);
|
|
88
|
+
return (jsx(FormScopeContext.Provider, { value: scope, children: jsxs("form", { ref: formRef, noValidate: true, "aria-labelledby": title ? titleId : undefined, className: "flex flex-col gap-4", onSubmit: (e) => {
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
scope.submit();
|
|
91
|
+
}, children: [title && (jsx("h3", { id: titleId, className: "text-base font-semibold text-[var(--color-text-primary)]", children: title })), description && (jsx("p", { className: "text-sm text-[var(--color-text-secondary)]", children: description })), invalidNames.length > 0 && (jsxs("div", { ref: summaryRef,
|
|
92
|
+
// `role="alert"` is an implicit assertive live region, so the list
|
|
93
|
+
// is announced even when focus does not land here (e.g. a consumer
|
|
94
|
+
// re-rendering the form). `tabIndex={-1}` makes it a programmatic
|
|
95
|
+
// focus target without adding a Tab stop.
|
|
96
|
+
role: "alert", tabIndex: -1, "aria-labelledby": summaryTitleId, className: cn("flex flex-col gap-1 rounded-[var(--alert-radius)] p-3 text-sm", "border border-[var(--color-danger-600)] dark:border-[var(--color-danger-400)]", "bg-[var(--color-danger-50)] dark:bg-[var(--color-danger-900)]/30", "text-[var(--color-danger-700)] dark:text-[var(--color-danger-300)]", "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-danger)]"), children: [jsxs("p", { id: summaryTitleId, className: "flex items-center gap-2 font-medium", children: [jsx(WarningCircle, { className: "size-4 shrink-0", "aria-hidden": "true" }), errorSummaryTitle] }), jsx("ul", { className: "list-disc pl-9", children: invalidNames.map((name) => {
|
|
97
|
+
var _a;
|
|
98
|
+
return (jsxs("li", { children: [(_a = scope.getLabel(name)) !== null && _a !== void 0 ? _a : name, ": ", scope.errors[name]] }, name));
|
|
99
|
+
}) })] })), children, !hasChildSubmit && (jsx(Button, { type: "submit", variant: "filled", color: "primary", "data-generative-auto-submit": "", className: cn("self-start"), children: submitLabel }))] }) }));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { FormShell };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { UISpec } from "./types";
|
|
2
2
|
import { GenerativeRegistry } from "./registry";
|
|
3
3
|
import { ActionHandler } from "./actions";
|
|
4
|
+
import { GenerativeValues } from "./formScope";
|
|
4
5
|
export interface GenerativeViewProps {
|
|
5
6
|
/** The serializable spec tree (one root or top-level siblings). */
|
|
6
7
|
spec: UISpec;
|
|
@@ -13,9 +14,59 @@ export interface GenerativeViewProps {
|
|
|
13
14
|
*/
|
|
14
15
|
onAction?: ActionHandler;
|
|
15
16
|
className?: string;
|
|
17
|
+
/** Controlled form values, keyed by form id then field name. */
|
|
18
|
+
values?: GenerativeValues;
|
|
19
|
+
/** Uncontrolled seed for form values. */
|
|
20
|
+
defaultValues?: GenerativeValues;
|
|
21
|
+
/** Fires with the complete next values bag whenever any field changes. */
|
|
22
|
+
onValuesChange?: (values: GenerativeValues) => void;
|
|
16
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Which props each curated field component actually DECLARES, and may
|
|
26
|
+
* therefore be handed. NOT every FIELD_BINDINGS entry supports all three —
|
|
27
|
+
* hand-verified against each component's OWN Props interface, not a sibling's
|
|
28
|
+
* (mirrors the same "don't infer from the name" caution as `fieldBinding.ts`'s
|
|
29
|
+
* own table):
|
|
30
|
+
* - Select/Combobox/Switch/Slider/TimePicker/InputTag accept `state` (for
|
|
31
|
+
* border styling) but declare NO `errorMessage` prop at all.
|
|
32
|
+
* - Checkbox accepts `state` but NOT `errorMessage` — `errorMessage` exists
|
|
33
|
+
* only on the separate `CheckboxGroupProps` (`Checkbox.Group`), not on
|
|
34
|
+
* `CheckboxProps` (what's actually registered/rendered here). Checkbox.tsx
|
|
35
|
+
* destructures known props and spreads the rest onto the native `<input>`
|
|
36
|
+
* (Checkbox.tsx:35,115), so this one is a real, reproducible DOM leak if
|
|
37
|
+
* gotten wrong, not a hypothetical — verified by reverting this row and
|
|
38
|
+
* confirming GenerativeView.test.tsx's Checkbox pinning test fails.
|
|
39
|
+
* - Rating has none of the three: it's a Core rating widget, not a
|
|
40
|
+
* FORMS_STANDARDS component.
|
|
41
|
+
* Forwarding a prop a component doesn't declare reaches the DOM as an
|
|
42
|
+
* unrecognized attribute (most of these spread unknown rest props onto
|
|
43
|
+
* their root element) and React logs it — see GenerativeView.test.tsx's
|
|
44
|
+
* "does not forward errorMessage/state to a control that doesn't declare
|
|
45
|
+
* them" tests (Switch and Checkbox each get their own).
|
|
46
|
+
*
|
|
47
|
+
* 🔴 `required` is on this table for FORWARDING ONLY. It is separately an
|
|
48
|
+
* ENGINE-SEMANTIC prop: `node.props.required` is read below to register the
|
|
49
|
+
* field's required-ness with the FormScope, which is what blocks submit —
|
|
50
|
+
* that happens for all 13 regardless of this table, and is why all 13 must
|
|
51
|
+
* declare `required` in the generated schema (see `REQUIRED_PROP` in
|
|
52
|
+
* packages/mcp/scripts/generativeManifest.ts). The four that decline it here
|
|
53
|
+
* (InputOTP/InputCounter/InputTag/Rating) extend
|
|
54
|
+
* `HTMLAttributes<HTMLDivElement>` and declare no `required` of their own, so
|
|
55
|
+
* forwarding would paint an invalid `required` attribute onto a `<div>` and
|
|
56
|
+
* buy nothing. Their required-ness is still enforced, and surfaced to the
|
|
57
|
+
* user by `FormShell`'s error summary rather than a per-field indicator.
|
|
58
|
+
* 🔴 The forwarding strip below is UNCONDITIONAL — it runs for every node,
|
|
59
|
+
* not only ones with a `name`/binding. A `required` prop with no `name` at
|
|
60
|
+
* all never registers with the scope, but it still rides along in `hydrated`
|
|
61
|
+
* and would otherwise reach a component's root element untouched.
|
|
62
|
+
*/
|
|
63
|
+
export declare const FIELD_PROP_SUPPORT: Record<string, {
|
|
64
|
+
state: boolean;
|
|
65
|
+
errorMessage: boolean;
|
|
66
|
+
required: boolean;
|
|
67
|
+
}>;
|
|
17
68
|
/**
|
|
18
69
|
* Render a serializable UINode spec with the given registry.
|
|
19
70
|
* Render-only in P1 — streaming (P3) and action dispatch (P4) layer on top.
|
|
20
71
|
*/
|
|
21
|
-
export declare function GenerativeView({ spec, registry, onAction, className, }: GenerativeViewProps): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
export declare function GenerativeView({ spec, registry, onAction, className, values, defaultValues, onValuesChange, }: GenerativeViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,7 +6,63 @@ import { defaultRegistry, CardShell } from './registry.js';
|
|
|
6
6
|
import { applyResolvers } from './resolvers.js';
|
|
7
7
|
import { SKELETON_NODE } from './streaming.js';
|
|
8
8
|
import { bindActionProps } from './actions.js';
|
|
9
|
+
import { getFieldBinding } from './fieldBinding.js';
|
|
10
|
+
import { useFormScope } from './formScope.js';
|
|
9
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Which props each curated field component actually DECLARES, and may
|
|
14
|
+
* therefore be handed. NOT every FIELD_BINDINGS entry supports all three —
|
|
15
|
+
* hand-verified against each component's OWN Props interface, not a sibling's
|
|
16
|
+
* (mirrors the same "don't infer from the name" caution as `fieldBinding.ts`'s
|
|
17
|
+
* own table):
|
|
18
|
+
* - Select/Combobox/Switch/Slider/TimePicker/InputTag accept `state` (for
|
|
19
|
+
* border styling) but declare NO `errorMessage` prop at all.
|
|
20
|
+
* - Checkbox accepts `state` but NOT `errorMessage` — `errorMessage` exists
|
|
21
|
+
* only on the separate `CheckboxGroupProps` (`Checkbox.Group`), not on
|
|
22
|
+
* `CheckboxProps` (what's actually registered/rendered here). Checkbox.tsx
|
|
23
|
+
* destructures known props and spreads the rest onto the native `<input>`
|
|
24
|
+
* (Checkbox.tsx:35,115), so this one is a real, reproducible DOM leak if
|
|
25
|
+
* gotten wrong, not a hypothetical — verified by reverting this row and
|
|
26
|
+
* confirming GenerativeView.test.tsx's Checkbox pinning test fails.
|
|
27
|
+
* - Rating has none of the three: it's a Core rating widget, not a
|
|
28
|
+
* FORMS_STANDARDS component.
|
|
29
|
+
* Forwarding a prop a component doesn't declare reaches the DOM as an
|
|
30
|
+
* unrecognized attribute (most of these spread unknown rest props onto
|
|
31
|
+
* their root element) and React logs it — see GenerativeView.test.tsx's
|
|
32
|
+
* "does not forward errorMessage/state to a control that doesn't declare
|
|
33
|
+
* them" tests (Switch and Checkbox each get their own).
|
|
34
|
+
*
|
|
35
|
+
* 🔴 `required` is on this table for FORWARDING ONLY. It is separately an
|
|
36
|
+
* ENGINE-SEMANTIC prop: `node.props.required` is read below to register the
|
|
37
|
+
* field's required-ness with the FormScope, which is what blocks submit —
|
|
38
|
+
* that happens for all 13 regardless of this table, and is why all 13 must
|
|
39
|
+
* declare `required` in the generated schema (see `REQUIRED_PROP` in
|
|
40
|
+
* packages/mcp/scripts/generativeManifest.ts). The four that decline it here
|
|
41
|
+
* (InputOTP/InputCounter/InputTag/Rating) extend
|
|
42
|
+
* `HTMLAttributes<HTMLDivElement>` and declare no `required` of their own, so
|
|
43
|
+
* forwarding would paint an invalid `required` attribute onto a `<div>` and
|
|
44
|
+
* buy nothing. Their required-ness is still enforced, and surfaced to the
|
|
45
|
+
* user by `FormShell`'s error summary rather than a per-field indicator.
|
|
46
|
+
* 🔴 The forwarding strip below is UNCONDITIONAL — it runs for every node,
|
|
47
|
+
* not only ones with a `name`/binding. A `required` prop with no `name` at
|
|
48
|
+
* all never registers with the scope, but it still rides along in `hydrated`
|
|
49
|
+
* and would otherwise reach a component's root element untouched.
|
|
50
|
+
*/
|
|
51
|
+
const FIELD_PROP_SUPPORT = {
|
|
52
|
+
Input: { state: true, errorMessage: true, required: true },
|
|
53
|
+
Textarea: { state: true, errorMessage: true, required: true },
|
|
54
|
+
Select: { state: true, errorMessage: false, required: true },
|
|
55
|
+
Combobox: { state: true, errorMessage: false, required: true },
|
|
56
|
+
Checkbox: { state: true, errorMessage: false, required: true },
|
|
57
|
+
Switch: { state: true, errorMessage: false, required: true },
|
|
58
|
+
Slider: { state: true, errorMessage: false, required: true },
|
|
59
|
+
InputOTP: { state: true, errorMessage: true, required: false },
|
|
60
|
+
TimePicker: { state: true, errorMessage: false, required: true },
|
|
61
|
+
InputDate: { state: true, errorMessage: true, required: true },
|
|
62
|
+
InputCounter: { state: true, errorMessage: true, required: false },
|
|
63
|
+
InputTag: { state: true, errorMessage: false, required: false },
|
|
64
|
+
Rating: { state: false, errorMessage: false, required: false },
|
|
65
|
+
};
|
|
10
66
|
const placeholderStyle = "rounded-lg border border-dashed border-[var(--color-border-secondary)] " +
|
|
11
67
|
"bg-[var(--color-surface-sunken)] p-3 text-xs text-[var(--color-text-muted)]";
|
|
12
68
|
/** The model asked for a component we didn't register — render, don't throw. */
|
|
@@ -43,23 +99,56 @@ class NodeBoundary extends React__default.Component {
|
|
|
43
99
|
return this.props.children;
|
|
44
100
|
}
|
|
45
101
|
}
|
|
46
|
-
function NodeRenderer({ node, registry, inShell, dispatch, }) {
|
|
47
|
-
var _a, _b, _c;
|
|
102
|
+
function NodeRenderer({ node, registry, inShell, dispatch, path, values, defaultValues, onFormValuesChange, }) {
|
|
103
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
104
|
+
const scope = useFormScope();
|
|
105
|
+
const fieldName = typeof ((_a = node.props) === null || _a === void 0 ? void 0 : _a.name) === "string" ? node.props.name : undefined;
|
|
106
|
+
const binding = fieldName ? getFieldBinding(node.component) : undefined;
|
|
107
|
+
const specSeed = binding
|
|
108
|
+
? ((_c = (_b = node.props) === null || _b === void 0 ? void 0 : _b[binding.valueProp]) !== null && _c !== void 0 ? _c : (binding.defaultValueProp
|
|
109
|
+
? (_d = node.props) === null || _d === void 0 ? void 0 : _d[binding.defaultValueProp]
|
|
110
|
+
: undefined))
|
|
111
|
+
: undefined;
|
|
112
|
+
// Registration is an effect, not a render side effect: a field that
|
|
113
|
+
// disappears when the model re-emits a different spec must stop
|
|
114
|
+
// contributing its stale value to the next submit. The seed (spec value,
|
|
115
|
+
// or the binding's "empty") is handed to the scope rather than committed
|
|
116
|
+
// here via `setValue` — `formScope`'s `register` commits it internally
|
|
117
|
+
// without notifying `onValuesChange`, since mounting a field isn't a
|
|
118
|
+
// user-driven change (see formScope.tsx).
|
|
119
|
+
const required = ((_e = node.props) === null || _e === void 0 ? void 0 : _e.required) === true;
|
|
120
|
+
// The field's own label, handed to the scope purely so `FormShell`'s error
|
|
121
|
+
// summary can name a blocked field the way the user sees it rather than by
|
|
122
|
+
// its submission key ("Email address", not "email_address").
|
|
123
|
+
const fieldLabel = typeof ((_f = node.props) === null || _f === void 0 ? void 0 : _f.label) === "string" ? node.props.label : undefined;
|
|
124
|
+
React__default.useEffect(() => {
|
|
125
|
+
if (!scope || !fieldName || !binding)
|
|
126
|
+
return;
|
|
127
|
+
scope.register(fieldName, { required, binding, label: fieldLabel, seed: specSeed !== null && specSeed !== void 0 ? specSeed : binding.empty });
|
|
128
|
+
return () => scope.unregister(fieldName);
|
|
129
|
+
// `specSeed` is intentionally omitted from the deps: it's read straight
|
|
130
|
+
// from `node.props` for this same field/binding pair, so it's already
|
|
131
|
+
// implied by `fieldName`/`binding` being unchanged — and `register`
|
|
132
|
+
// itself only ever applies a seed once (it no-ops once the scope holds
|
|
133
|
+
// a value for the name), so re-deriving it on an unrelated re-render
|
|
134
|
+
// would be a no-op anyway.
|
|
135
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
136
|
+
}, [scope, fieldName, binding, required, fieldLabel]);
|
|
48
137
|
if (node.component === SKELETON_NODE)
|
|
49
138
|
return jsx(SkeletonPlaceholder, { props: node.props });
|
|
50
139
|
const entry = registry.components[node.component];
|
|
51
140
|
if (!entry)
|
|
52
141
|
return jsx(UnknownNode, { name: node.component });
|
|
53
|
-
const hydrated = applyResolvers(((
|
|
142
|
+
const hydrated = applyResolvers(((_g = node.props) !== null && _g !== void 0 ? _g : {}), registry.resolvers, { icons: registry.icons, node });
|
|
54
143
|
const isContainer = entry.kind === "container";
|
|
55
|
-
if (process.env.NODE_ENV !== "production" && !isContainer && ((
|
|
144
|
+
if (process.env.NODE_ENV !== "production" && !isContainer && ((_h = node.children) === null || _h === void 0 ? void 0 : _h.length)) {
|
|
56
145
|
console.warn(`[GenerativeView]: "${node.component}" is not a container — its children are ignored`);
|
|
57
146
|
}
|
|
58
147
|
const childInShell = entry.providesShell ? true : inShell;
|
|
59
|
-
const children = isContainer && ((
|
|
148
|
+
const children = isContainer && ((_j = node.children) === null || _j === void 0 ? void 0 : _j.length)
|
|
60
149
|
? node.children.map((child, index) => {
|
|
61
|
-
var _a;
|
|
62
|
-
return (jsx(NodeBoundary, { name: child.component, children: jsx(NodeRenderer, { node: child, registry: registry, inShell: childInShell, dispatch: dispatch }) }, (
|
|
150
|
+
var _a, _b;
|
|
151
|
+
return (jsx(NodeBoundary, { name: child.component, children: jsx(NodeRenderer, { node: child, registry: registry, inShell: childInShell, dispatch: dispatch, path: `${path}.${(_a = child.id) !== null && _a !== void 0 ? _a : index}`, values: values, defaultValues: defaultValues, onFormValuesChange: onFormValuesChange }) }, (_b = child.id) !== null && _b !== void 0 ? _b : index));
|
|
63
152
|
})
|
|
64
153
|
: undefined;
|
|
65
154
|
// Shell-wrapped leaves: title/subtitle belong to the shell, not the component.
|
|
@@ -78,6 +167,89 @@ function NodeRenderer({ node, registry, inShell, dispatch, }) {
|
|
|
78
167
|
componentProps = bound.props;
|
|
79
168
|
unboundClick = bound.unboundClick;
|
|
80
169
|
}
|
|
170
|
+
// `required` is forwarded ONLY to a component whose FIELD_PROP_SUPPORT
|
|
171
|
+
// entry declares it — those need it for their own native `required`
|
|
172
|
+
// attribute and their FormLabel asterisk/"(required)" indicator (WCAG
|
|
173
|
+
// 3.3.2 — a required field must be identifiable before submit, not just
|
|
174
|
+
// after a rejected one). `FormShell` renders `<form noValidate>`, so the
|
|
175
|
+
// native attribute never interferes with `scope.submit()`'s own required
|
|
176
|
+
// check. This strip is UNCONDITIONAL — it must run whether or not this
|
|
177
|
+
// node has a `name`/`binding` at all: a node can carry `required` with no
|
|
178
|
+
// `name` (the field never registers, but `required` still rode along in
|
|
179
|
+
// `hydrated`) or a `name` for a component with no binding, and either way
|
|
180
|
+
// the component's own root element (e.g. Rating's `<div role="slider">`)
|
|
181
|
+
// must never receive an attribute it doesn't declare. Enforcement is
|
|
182
|
+
// unaffected either way: `node.props.required` was already read above and
|
|
183
|
+
// registered with the scope regardless of whether it survives forwarding.
|
|
184
|
+
if (!((_k = FIELD_PROP_SUPPORT[node.component]) === null || _k === void 0 ? void 0 : _k.required))
|
|
185
|
+
delete componentProps.required;
|
|
186
|
+
if (scope && fieldName && binding) {
|
|
187
|
+
const held = scope.getValue(fieldName);
|
|
188
|
+
const value = held !== undefined ? held : specSeed;
|
|
189
|
+
const existingChange = componentProps[binding.changeProp];
|
|
190
|
+
const support = FIELD_PROP_SUPPORT[node.component];
|
|
191
|
+
const next = { ...componentProps };
|
|
192
|
+
delete next.name; // consumed for registration; never forwarded
|
|
193
|
+
if (binding.defaultValueProp)
|
|
194
|
+
delete next[binding.defaultValueProp];
|
|
195
|
+
next[binding.valueProp] = value !== null && value !== void 0 ? value : binding.empty;
|
|
196
|
+
next[binding.changeProp] = (...args) => {
|
|
197
|
+
scope.setValue(fieldName, args[0]);
|
|
198
|
+
existingChange === null || existingChange === void 0 ? void 0 : existingChange(...args);
|
|
199
|
+
};
|
|
200
|
+
if (scope.errors[fieldName]) {
|
|
201
|
+
if (support === null || support === void 0 ? void 0 : support.state)
|
|
202
|
+
next.state = "invalid";
|
|
203
|
+
if (support === null || support === void 0 ? void 0 : support.errorMessage)
|
|
204
|
+
next.errorMessage = (_l = next.errorMessage) !== null && _l !== void 0 ? _l : scope.errors[fieldName];
|
|
205
|
+
}
|
|
206
|
+
componentProps = next;
|
|
207
|
+
}
|
|
208
|
+
else if (fieldName && binding) {
|
|
209
|
+
// A named FIELD-BINDING component outside a Form still renders; `name`
|
|
210
|
+
// is simply inert there. Strip it so it never reaches the DOM. A
|
|
211
|
+
// component with NO binding (e.g. `Avatar.name`, a person's display
|
|
212
|
+
// name) never entered this branch's condition for the wrong reason —
|
|
213
|
+
// `binding` here confirms it actually IS a field component, so its
|
|
214
|
+
// `name` prop is left alone and forwarded untouched.
|
|
215
|
+
const { name: _unused, ...rest } = componentProps;
|
|
216
|
+
componentProps = rest;
|
|
217
|
+
}
|
|
218
|
+
// Design spec §3.5: a `Button` inside a Form that declares no `actions` of
|
|
219
|
+
// its own IS that form's submit button. Core `Button` renders `type="button"`
|
|
220
|
+
// ahead of its rest-prop spread (Button.tsx:170), so injecting `type` here
|
|
221
|
+
// overrides it — and `FormShell`'s
|
|
222
|
+
// `button[type="submit"]:not([data-generative-auto-submit])` probe then finds
|
|
223
|
+
// it and suppresses the auto-rendered one, leaving exactly one button.
|
|
224
|
+
// `type` is deliberately NOT in the generative schema: the rule is the
|
|
225
|
+
// engine's to apply, not a knob the model can set (or forget to set).
|
|
226
|
+
// A Button WITH actions keeps its own click behaviour and never submits.
|
|
227
|
+
const declaresOwnActions = !!node.actions && Object.keys(node.actions).length > 0;
|
|
228
|
+
if (node.component === "Button" && scope && !declaresOwnActions) {
|
|
229
|
+
componentProps = { ...componentProps, type: "submit" };
|
|
230
|
+
}
|
|
231
|
+
if (entry.isForm) {
|
|
232
|
+
const formId = (_m = node.id) !== null && _m !== void 0 ? _m : `form-${path}`;
|
|
233
|
+
componentProps = {
|
|
234
|
+
...componentProps,
|
|
235
|
+
formId,
|
|
236
|
+
// `Object.hasOwn`, not `values?.[formId]`: `formId` comes from the spec's
|
|
237
|
+
// own `node.id`. `validate()` now rejects unsafe ids (see validate.ts),
|
|
238
|
+
// but `GenerativeView` also accepts RAW specs, where a plain-object bag
|
|
239
|
+
// would resolve `id: "toString"` to an inherited function instead of
|
|
240
|
+
// `undefined` — and hand `FormShell` a function as its `values` prop.
|
|
241
|
+
values: values && Object.hasOwn(values, formId) ? values[formId] : undefined,
|
|
242
|
+
defaultValues: defaultValues && Object.hasOwn(defaultValues, formId) ? defaultValues[formId] : undefined,
|
|
243
|
+
onValuesChange: (formValues) => onFormValuesChange === null || onFormValuesChange === void 0 ? void 0 : onFormValuesChange(formId, formValues),
|
|
244
|
+
onSubmit: (formValues) => {
|
|
245
|
+
var _a;
|
|
246
|
+
const descriptor = (_a = node.actions) === null || _a === void 0 ? void 0 : _a.submit;
|
|
247
|
+
if (!descriptor || !dispatch)
|
|
248
|
+
return;
|
|
249
|
+
dispatch(descriptor, { component: "Form", nodeId: node.id, values: formValues });
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
81
253
|
const Component = entry.component;
|
|
82
254
|
let inner;
|
|
83
255
|
if (entry.render)
|
|
@@ -106,12 +278,32 @@ function NodeRenderer({ node, registry, inShell, dispatch, }) {
|
|
|
106
278
|
* Render a serializable UINode spec with the given registry.
|
|
107
279
|
* Render-only in P1 — streaming (P3) and action dispatch (P4) layer on top.
|
|
108
280
|
*/
|
|
109
|
-
function GenerativeView({ spec, registry = defaultRegistry, onAction, className, }) {
|
|
281
|
+
function GenerativeView({ spec, registry = defaultRegistry, onAction, className, values, defaultValues, onValuesChange, }) {
|
|
110
282
|
const nodes = Array.isArray(spec) ? spec : [spec];
|
|
283
|
+
const isControlled = values !== undefined;
|
|
284
|
+
// `onValuesChange` is documented to fire with the COMPLETE next values bag,
|
|
285
|
+
// across every form in the spec. Controlled mode gets that for free: the
|
|
286
|
+
// consumer's `values` is the live bag, so merging onto it is correct.
|
|
287
|
+
// Uncontrolled mode does not — `defaultValues` is a static seed that never
|
|
288
|
+
// reflects what the user has since typed, so merging each form's callback
|
|
289
|
+
// onto it erased every OTHER form's live state (type in form A, then form B,
|
|
290
|
+
// and A's value vanished from the payload). This ref carries the last bag we
|
|
291
|
+
// emitted so the merge base stays current between forms.
|
|
292
|
+
const lastEmittedRef = React__default.useRef(defaultValues !== null && defaultValues !== void 0 ? defaultValues : {});
|
|
293
|
+
const handleFormValuesChange = React__default.useCallback((formId, formValues) => {
|
|
294
|
+
const base = isControlled ? (values !== null && values !== void 0 ? values : {}) : lastEmittedRef.current;
|
|
295
|
+
// A computed key in an object literal is a data-property definition, not
|
|
296
|
+
// an assignment, so a hostile `formId` cannot reach a prototype setter
|
|
297
|
+
// here even on a raw (unvalidated) spec.
|
|
298
|
+
const next = { ...base, [formId]: formValues };
|
|
299
|
+
if (!isControlled)
|
|
300
|
+
lastEmittedRef.current = next;
|
|
301
|
+
onValuesChange === null || onValuesChange === void 0 ? void 0 : onValuesChange(next);
|
|
302
|
+
}, [isControlled, values, onValuesChange]);
|
|
111
303
|
return (jsx("div", { className: className, children: nodes.map((node, index) => {
|
|
112
|
-
var _a;
|
|
113
|
-
return (jsx(NodeBoundary, { name: node.component, children: jsx(NodeRenderer, { node: node, registry: registry, inShell: false, dispatch: onAction }) }, (
|
|
304
|
+
var _a, _b;
|
|
305
|
+
return (jsx(NodeBoundary, { name: node.component, children: jsx(NodeRenderer, { node: node, registry: registry, inShell: false, dispatch: onAction, path: `${(_a = node.id) !== null && _a !== void 0 ? _a : index}`, values: values, defaultValues: defaultValues, onFormValuesChange: handleFormValuesChange }) }, (_b = node.id) !== null && _b !== void 0 ? _b : index));
|
|
114
306
|
}) }));
|
|
115
307
|
}
|
|
116
308
|
|
|
117
|
-
export { GenerativeView };
|
|
309
|
+
export { FIELD_PROP_SUPPORT, GenerativeView };
|
|
@@ -7,6 +7,11 @@ export interface ActionContext {
|
|
|
7
7
|
nodeId?: string;
|
|
8
8
|
/** Serializable callback payload (e.g. the clicked Table row). Never a DOM event. */
|
|
9
9
|
data?: JSONValue;
|
|
10
|
+
/**
|
|
11
|
+
* Present only on a Form's submit action: every registered field value,
|
|
12
|
+
* collected in one bag. Built with a null prototype.
|
|
13
|
+
*/
|
|
14
|
+
values?: Record<string, JSONValue>;
|
|
10
15
|
}
|
|
11
16
|
/** Consumer handler: first arg is the EXACT descriptor from the spec. */
|
|
12
17
|
export type ActionHandler = (action: ActionDescriptor, context: ActionContext) => void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useGenerativeChat, type UseGenerativeChatOptions, type UseGenerativeChatReturn, } from "./useGenerativeChat";
|