@flikk/ui 1.0.0-beta.30 → 1.0.0-beta.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +375 -5
- package/dist/components/ai/AgentRequest/AgentRequest.animations.d.ts +25 -0
- package/dist/components/ai/AgentRequest/AgentRequest.animations.js +81 -0
- package/dist/components/ai/AgentRequest/AgentRequest.d.ts +3 -0
- package/dist/components/ai/AgentRequest/AgentRequest.js +435 -0
- package/dist/components/ai/AgentRequest/AgentRequest.theme.d.ts +2 -0
- package/dist/components/ai/AgentRequest/AgentRequest.theme.js +106 -0
- package/dist/components/ai/AgentRequest/AgentRequest.types.d.ts +241 -0
- package/dist/components/ai/AgentRequest/index.d.ts +3 -0
- package/dist/components/ai/AgentStatus/AgentStatus.d.ts +3 -0
- package/dist/components/ai/AgentStatus/AgentStatus.js +144 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.d.ts +2 -0
- package/dist/components/ai/AgentStatus/AgentStatus.theme.js +37 -0
- package/dist/components/ai/AgentStatus/AgentStatus.types.d.ts +116 -0
- package/dist/components/ai/AgentStatus/index.d.ts +3 -0
- package/dist/components/ai/CodeBlock/CodeBlock.js +3 -3
- package/dist/components/ai/CodeBlock/CodeBlock.theme.js +2 -2
- package/dist/components/ai/PromptInput/PromptInput.js +13 -14
- package/dist/components/ai/PromptInput/PromptInput.theme.js +3 -3
- package/dist/components/ai/PromptInput/VoiceRecorder.js +3 -3
- package/dist/components/ai/PromptSuggestion/PromptSuggestion.theme.js +2 -2
- package/dist/components/ai/Reasoning/Reasoning.d.ts +5 -0
- package/dist/components/ai/Reasoning/Reasoning.js +40 -0
- package/dist/components/ai/Reasoning/Reasoning.theme.d.ts +6 -0
- package/dist/components/ai/Reasoning/Reasoning.theme.js +36 -0
- package/dist/components/ai/Reasoning/Reasoning.types.d.ts +73 -0
- package/dist/components/ai/Reasoning/ReasoningTrace.d.ts +11 -0
- package/dist/components/ai/Reasoning/ReasoningTrace.js +84 -0
- package/dist/components/ai/Reasoning/index.d.ts +3 -0
- package/dist/components/ai/SourceCitation/SourceCitation.d.ts +4 -0
- package/dist/components/ai/SourceCitation/SourceCitation.js +29 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.d.ts +2 -0
- package/dist/components/ai/SourceCitation/SourceCitation.theme.js +23 -0
- package/dist/components/ai/SourceCitation/SourceCitation.types.d.ts +55 -0
- package/dist/components/ai/SourceCitation/index.d.ts +3 -0
- package/dist/components/ai/StreamingResponse/AnimatedText.d.ts +7 -0
- package/dist/components/ai/StreamingResponse/AnimatedText.js +8 -7
- package/dist/components/ai/StreamingResponse/ErrorDisplay.js +2 -2
- package/dist/components/ai/StreamingResponse/MarkdownRenderer.d.ts +5 -0
- package/dist/components/ai/StreamingResponse/MarkdownRenderer.js +4 -4
- package/dist/components/ai/StreamingResponse/StreamingCursor.d.ts +2 -2
- package/dist/components/ai/StreamingResponse/StreamingCursor.js +10 -7
- package/dist/components/ai/StreamingResponse/StreamingResponse.animations.d.ts +10 -0
- package/dist/components/ai/StreamingResponse/StreamingResponse.animations.js +59 -33
- package/dist/components/ai/StreamingResponse/StreamingResponse.js +14 -10
- package/dist/components/ai/StreamingResponse/StreamingResponse.theme.js +3 -1
- package/dist/components/ai/StreamingResponse/StreamingResponse.types.d.ts +33 -2
- package/dist/components/ai/StreamingResponse/StreamingSurface.d.ts +13 -0
- package/dist/components/ai/StreamingResponse/StreamingSurface.js +38 -0
- package/dist/components/ai/StreamingResponse/WordAnimationContext.d.ts +5 -0
- package/dist/components/ai/StreamingResponse/WordAnimationContext.js +5 -4
- package/dist/components/ai/StreamingResponse/index.d.ts +4 -2
- package/dist/components/ai/TokenCounter/TokenCounter.js +2 -2
- package/dist/components/ai/TokenCounter/TokenCounter.theme.js +1 -1
- package/dist/components/ai/index.d.ts +6 -2
- package/dist/components/ai/index.js +10 -3
- package/dist/components/ai/shared/StatusIndicator.d.ts +8 -0
- package/dist/components/ai/shared/StatusIndicator.js +34 -0
- package/dist/components/canvas/BaseNode.js +1 -1
- package/dist/components/canvas/CanvasToolbar.js +2 -3
- package/dist/components/canvas/Edge.js +2 -2
- package/dist/components/canvas/NodeControls.js +2 -3
- package/dist/components/canvas/NodeRenderer.js +4 -4
- package/dist/components/charts/ActivityRings/ActivityRings.js +4 -4
- package/dist/components/charts/ActivityRings/ActivityRings.theme.js +1 -1
- package/dist/components/charts/AreaChart/AreaChart.js +24 -35
- package/dist/components/charts/AreaChart/AreaChart.theme.d.ts +1 -6
- package/dist/components/charts/AreaChart/AreaChart.theme.js +10 -22
- package/dist/components/charts/AreaChart/AreaChart.types.d.ts +18 -11
- package/dist/components/charts/AreaChart/AreaChart.types.js +10 -3
- package/dist/components/charts/AreaChart/index.d.ts +1 -1
- package/dist/components/charts/BarChart/BarChart.js +13 -32
- package/dist/components/charts/BarChart/BarChart.types.d.ts +20 -16
- package/dist/components/charts/BarChart/BarChart.types.js +11 -4
- package/dist/components/charts/ComboChart/BarRenderer.js +10 -7
- package/dist/components/charts/ComboChart/BarRenderer.types.d.ts +1 -1
- package/dist/components/charts/ComboChart/ComboChart.js +11 -24
- package/dist/components/charts/ComboChart/ComboChart.types.d.ts +15 -13
- package/dist/components/charts/ComboChart/ComboChart.types.js +14 -2
- package/dist/components/charts/ComboChart/ComboChartCanvas.js +1 -1
- package/dist/components/charts/ComboChart/LineRenderer.js +16 -11
- package/dist/components/charts/ComboChart/LineRenderer.types.d.ts +1 -1
- package/dist/components/charts/DonutChart/DonutChart.theme.js +4 -4
- package/dist/components/charts/DonutChart/MultiSegmentDonutChart.theme.js +1 -1
- package/dist/components/charts/Heatmap/Heatmap.js +49 -42
- package/dist/components/charts/Heatmap/Heatmap.theme.d.ts +6 -2
- package/dist/components/charts/Heatmap/Heatmap.theme.js +20 -8
- package/dist/components/charts/Heatmap/Heatmap.types.d.ts +49 -82
- package/dist/components/charts/Heatmap/HeatmapCell.js +30 -81
- package/dist/components/charts/Heatmap/HeatmapLegend.d.ts +7 -6
- package/dist/components/charts/Heatmap/HeatmapLegend.js +6 -6
- package/dist/components/charts/Heatmap/index.d.ts +1 -1
- package/dist/components/charts/Heatmap/utils/heatmapUtils.d.ts +7 -12
- package/dist/components/charts/Heatmap/utils/heatmapUtils.js +16 -61
- package/dist/components/charts/Heatmap/utils/heatmapUtils.test.d.ts +1 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.d.ts +16 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.js +237 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.d.ts +62 -0
- package/dist/components/charts/HorizontalBarChart/HorizontalBarChart.types.js +21 -0
- package/dist/components/charts/HorizontalBarChart/index.d.ts +3 -0
- package/dist/components/charts/LineChart/LineChart.js +11 -28
- package/dist/components/charts/LineChart/LineChart.types.d.ts +11 -14
- package/dist/components/charts/LineChart/LineChart.types.js +11 -3
- package/dist/components/charts/LollipopChart/LollipopChart.d.ts +3 -0
- package/dist/components/charts/LollipopChart/LollipopChart.js +361 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.d.ts +42 -0
- package/dist/components/charts/LollipopChart/LollipopChart.types.js +12 -0
- package/dist/components/charts/LollipopChart/index.d.ts +3 -0
- package/dist/components/charts/RadarChart/RadarChart.js +1 -1
- package/dist/components/charts/StackedBarChart/StackedBarChart.js +151 -133
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.d.ts +20 -18
- package/dist/components/charts/StackedBarChart/StackedBarChart.types.js +10 -4
- package/dist/components/charts/hooks/useChartAccessibility.d.ts +1 -1
- package/dist/components/charts/hooks/useChartAccessibility.js +12 -6
- package/dist/components/charts/hooks/useTooltipPosition.js +18 -6
- package/dist/components/charts/index.d.ts +10 -8
- package/dist/components/charts/index.js +8 -4
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/CategoryYAxis.js +35 -0
- package/dist/components/charts/shared/ChartAxis/ChartAxis.types.d.ts +69 -8
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.d.ts +14 -0
- package/dist/components/charts/shared/ChartAxis/ValueXAxis.js +64 -0
- package/dist/components/charts/shared/ChartAxis/XAxis.js +1 -1
- package/dist/components/charts/shared/ChartAxis/YAxis.js +2 -2
- package/dist/components/charts/shared/ChartAxis/index.d.ts +3 -1
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.d.ts +0 -2
- package/dist/components/charts/shared/ChartGrid/HorizontalGrid.js +1 -1
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.d.ts +29 -0
- package/dist/components/charts/shared/ChartGrid/VerticalGrid.js +26 -0
- package/dist/components/charts/shared/ChartGrid/index.d.ts +2 -0
- package/dist/components/charts/shared/ChartMarker/ChartMarker.js +7 -1
- package/dist/components/charts/shared/ChartText/ChartText.theme.js +1 -1
- package/dist/components/charts/shared/index.d.ts +1 -1
- package/dist/components/charts/theme/chart.theme.js +21 -26
- package/dist/components/charts/types/chart.types.d.ts +9 -5
- package/dist/components/charts/types/chart.types.js +1 -7
- package/dist/components/charts/utils/animation-utils.d.ts +12 -7
- package/dist/components/charts/utils/animation-utils.js +19 -21
- package/dist/components/charts/utils/bar-emphasis.d.ts +32 -3
- package/dist/components/charts/utils/bar-emphasis.js +24 -8
- package/dist/components/charts/utils/index.d.ts +1 -0
- package/dist/components/charts/utils/series-color.d.ts +7 -0
- package/dist/components/charts/utils/series-color.js +20 -0
- package/dist/components/core/Accordion/Accordion.theme.js +3 -3
- package/dist/components/core/Accordion/AccordionTrigger.js +2 -2
- package/dist/components/core/Alert/Alert.animations.d.ts +11 -3
- package/dist/components/core/Alert/Alert.animations.js +30 -8
- package/dist/components/core/Alert/Alert.js +23 -9
- package/dist/components/core/Alert/Alert.theme.js +1 -1
- package/dist/components/core/Alert/Alert.types.d.ts +4 -2
- package/dist/components/core/AlertDialog/AlertDialog.js +2 -2
- package/dist/components/core/Avatar/Avatar.js +50 -42
- package/dist/components/core/Avatar/Avatar.theme.d.ts +8 -4
- package/dist/components/core/Avatar/Avatar.theme.js +64 -8
- package/dist/components/core/Avatar/Avatar.types.d.ts +13 -2
- package/dist/components/core/Avatar/index.d.ts +1 -1
- package/dist/components/core/AvatarGroup/AvatarGroup.js +6 -8
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.d.ts +1 -2
- package/dist/components/core/AvatarGroup/AvatarGroup.theme.js +2 -6
- package/dist/components/core/AvatarGroup/AvatarGroup.types.d.ts +0 -6
- package/dist/components/core/AvatarGroup/index.d.ts +1 -1
- package/dist/components/core/Badge/Badge.animations.d.ts +0 -5
- package/dist/components/core/Badge/Badge.animations.js +5 -82
- package/dist/components/core/Badge/Badge.d.ts +7 -4
- package/dist/components/core/Badge/Badge.js +33 -65
- package/dist/components/core/Badge/Badge.theme.js +26 -24
- package/dist/components/core/Badge/Badge.types.d.ts +18 -34
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.d.ts +1 -4
- package/dist/components/core/Breadcrumbs/Breadcrumbs.theme.js +6 -6
- package/dist/components/core/Button/Button.js +14 -58
- package/dist/components/core/Button/Button.theme.d.ts +2 -0
- package/dist/components/core/Button/Button.theme.js +35 -22
- package/dist/components/core/Button/Button.types.d.ts +26 -13
- package/dist/components/core/Button/index.d.ts +0 -2
- package/dist/components/core/Calendar/Calendar.js +20 -5
- package/dist/components/core/Calendar/Calendar.theme.js +15 -23
- package/dist/components/core/Calendar/Calendar.types.d.ts +0 -1
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.js +3 -3
- package/dist/components/core/Calendar/CalendarMini/CalendarMini.theme.js +2 -2
- package/dist/components/core/Card/Card.js +7 -2
- package/dist/components/core/Card/Card.theme.js +40 -4
- package/dist/components/core/Card/Card.types.d.ts +20 -0
- package/dist/components/core/Card/CardBody.js +9 -1
- package/dist/components/core/Card/CardContext.d.ts +13 -0
- package/dist/components/core/Card/CardContext.js +14 -0
- package/dist/components/core/Card/CardFooter.js +1 -1
- package/dist/components/core/Card/CardHeader.js +4 -1
- package/dist/components/core/CommandPalette/CommandPalette.js +5 -4
- package/dist/components/core/CommandPalette/CommandPalette.theme.js +3 -7
- package/dist/components/core/CommandPalette/CommandPalette.types.d.ts +2 -0
- package/dist/components/core/ContextMenu/ContextMenu.theme.js +4 -3
- package/dist/components/core/ContextMenu/ContextMenu.types.d.ts +8 -1
- package/dist/components/core/ContextMenu/ContextMenuItem.js +2 -2
- package/dist/components/core/ContextMenu/ContextMenuSub.d.ts +11 -1
- package/dist/components/core/ContextMenu/ContextMenuSub.js +35 -22
- package/dist/components/core/ContextMenu/ContextMenuSubBody.js +14 -3
- package/dist/components/core/ContextMenu/ContextMenuSubTrigger.js +22 -9
- package/dist/components/core/DragDrop/DragDrop.theme.js +2 -2
- package/dist/components/core/Drawer/Drawer.theme.js +7 -4
- package/dist/components/core/Drawer/DrawerHeader.js +2 -3
- package/dist/components/core/Dropdown/Dropdown.theme.js +3 -1
- package/dist/components/core/Dropdown/DropdownItem.js +2 -2
- package/dist/components/core/Dropdown/DropdownMenu.js +22 -7
- package/dist/components/core/Dropdown/DropdownTrigger.js +16 -5
- package/dist/components/core/HeroCard/HeroCard.theme.js +5 -2
- package/dist/components/core/Kbd/Kbd.theme.js +4 -2
- package/dist/components/core/Link/Link.js +7 -5
- package/dist/components/core/Masonry/Masonry.theme.js +1 -1
- package/dist/components/core/MenuItem/MenuItem.js +2 -1
- package/dist/components/core/MenuItem/MenuItem.theme.js +13 -1
- package/dist/components/core/Message/Message.js +4 -2
- package/dist/components/core/Message/Message.theme.js +8 -10
- package/dist/components/core/Message/MessageAudio.js +2 -2
- package/dist/components/core/Message/MessageFile.js +2 -2
- package/dist/components/core/Message/MessageLink.js +2 -2
- package/dist/components/core/Message/MessageStatusIndicator.js +5 -5
- package/dist/components/core/Modal/Modal.animations.d.ts +1 -1
- package/dist/components/core/Modal/Modal.animations.js +50 -11
- package/dist/components/core/Modal/Modal.d.ts +1 -1
- package/dist/components/core/Modal/Modal.js +6 -2
- package/dist/components/core/Modal/Modal.theme.js +9 -4
- package/dist/components/core/Modal/ModalHeader.js +2 -3
- package/dist/components/core/ModalStack/ModalStackModal.js +4 -2
- package/dist/components/core/NavItem/NavItem.js +8 -7
- package/dist/components/core/NavItem/NavItem.theme.js +1 -1
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.d.ts +22 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.animations.js +54 -0
- package/dist/components/core/OfflineIndicator/OfflineIndicator.js +23 -24
- package/dist/components/core/OfflineIndicator/OfflineIndicator.theme.js +27 -6
- package/dist/components/core/OfflineIndicator/OfflineIndicator.types.d.ts +17 -0
- package/dist/components/core/PageHeading/PageHeading.theme.js +1 -1
- package/dist/components/core/PageHeading/PageHeadingBackButton.js +2 -2
- package/dist/components/core/Pagination/Pagination.js +3 -3
- package/dist/components/core/Pagination/Pagination.theme.js +5 -5
- package/dist/components/core/Pill/Pill.js +5 -2
- package/dist/components/core/Pill/Pill.theme.js +9 -5
- package/dist/components/core/Popover/PopoverBody.js +16 -5
- package/dist/components/core/Progress/Progress.d.ts +0 -25
- package/dist/components/core/Progress/Progress.js +79 -11
- package/dist/components/core/Progress/Progress.theme.js +17 -0
- package/dist/components/core/Progress/Progress.types.d.ts +47 -1
- package/dist/components/core/Rating/Rating.js +4 -5
- package/dist/components/core/Rating/Rating.theme.js +2 -2
- package/dist/components/core/Rating/Rating.types.d.ts +3 -2
- package/dist/components/core/ScrollArea/ScrollArea.js +1 -1
- package/dist/components/core/ScrollArea/ScrollArea.theme.js +1 -1
- package/dist/components/core/Segmented/Segmented.theme.js +10 -7
- package/dist/components/core/Segmented/SegmentedContext.js +1 -0
- package/dist/components/core/Sidebar/Sidebar.js +5 -2
- package/dist/components/core/Sidebar/Sidebar.theme.js +2 -2
- package/dist/components/core/Sidebar/Sidebar.types.d.ts +4 -2
- package/dist/components/core/Sidebar/SidebarContent.js +1 -1
- package/dist/components/core/Sidebar/SidebarHeader.js +3 -3
- package/dist/components/core/Sidebar/SidebarMobileTrigger.js +2 -2
- package/dist/components/core/Sidebar/SidebarSearch.js +4 -4
- package/dist/components/core/Sidebar/SidebarToggle.js +3 -3
- package/dist/components/core/Sidebar/SidebarUserProfile.js +3 -3
- package/dist/components/core/Sortable/Sortable.js +2 -2
- package/dist/components/core/Sortable/Sortable.theme.js +1 -1
- package/dist/components/core/Tabs/Tabs.theme.js +1 -1
- package/dist/components/core/Tag/Tag.js +2 -2
- package/dist/components/core/Tag/Tag.theme.js +5 -3
- package/dist/components/core/Toast/Toast.js +3 -3
- package/dist/components/core/Toast/Toast.types.d.ts +1 -1
- package/dist/components/core/Toast/ToastProvider.js +1 -1
- package/dist/components/core/Toast/useToast.js +5 -5
- package/dist/components/core/Tooltip/Tooltip.d.ts +1 -1
- package/dist/components/core/Tooltip/Tooltip.js +42 -10
- package/dist/components/core/Tooltip/Tooltip.types.d.ts +25 -0
- package/dist/components/core/Tree/Tree.js +2 -2
- package/dist/components/core/Tree/Tree.theme.js +1 -1
- package/dist/components/core/index.d.ts +0 -2
- package/dist/components/core/index.js +0 -4
- package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.d.ts +4 -0
- package/dist/components/core/shared/ChartTooltip/ChartTooltip.animations.js +20 -0
- package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.js +1 -1
- package/dist/components/core/shared/Ripple.d.ts +16 -0
- package/dist/components/core/shared/Ripple.js +141 -0
- package/dist/components/core/shared/interaction.animations.d.ts +51 -0
- package/dist/components/core/shared/interaction.animations.js +59 -0
- package/dist/components/data-display/Feed/Feed.js +2 -2
- package/dist/components/data-display/GanttChart/GanttChart.theme.js +7 -7
- package/dist/components/data-display/GanttChart/GanttChartPanel.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTableGroupRow.js +3 -3
- package/dist/components/data-display/GanttChart/GanttTaskBar.js +1 -1
- package/dist/components/data-display/GanttChart/GanttTaskContextMenu.js +2 -2
- package/dist/components/data-display/GanttChart/GanttTimelineHeader.js +1 -1
- package/dist/components/data-display/GanttChart/GanttToolbar.js +2 -3
- package/dist/components/data-display/KPI/KPI.js +12 -21
- package/dist/components/data-display/KPI/KPI.theme.js +8 -4
- package/dist/components/data-display/Metric/Metric.js +2 -2
- package/dist/components/data-display/Metric/Metric.theme.js +25 -8
- package/dist/components/data-display/Metric/Metric.types.d.ts +1 -1
- package/dist/components/data-display/Table/Table.theme.js +11 -11
- package/dist/components/data-display/Table/TableActions.js +2 -2
- package/dist/components/data-display/Table/TableActionsMenu.js +1 -1
- package/dist/components/data-display/Table/TableColumnManager.js +2 -3
- package/dist/components/data-display/Table/TableContext.js +1 -0
- package/dist/components/data-display/Table/TableDeclarative.js +3 -3
- package/dist/components/data-display/Table/TableFilter.js +13 -6
- package/dist/components/data-display/Table/TableHeader.js +3 -3
- package/dist/components/data-display/Table/TableRow.js +2 -2
- package/dist/components/data-display/Table/TableSelectionHeader.js +4 -4
- package/dist/components/data-display/Timeline/Timeline.theme.js +1 -1
- package/dist/components/data-display/Timeline/TimelineMarker.js +2 -2
- package/dist/components/effects/CustomCursor/CustomCursor.d.ts +1 -1
- package/dist/components/effects/CustomCursor/CustomCursor.js +3 -3
- package/dist/components/effects/CustomCursor/CustomCursor.theme.js +4 -4
- package/dist/components/effects/DotPattern/DotPattern.js +6 -0
- package/dist/components/effects/DotPattern/DotPattern.types.d.ts +4 -2
- package/dist/components/effects/MeshGradient/MeshGradient.utils.d.ts +1 -1
- package/dist/components/effects/MeshGradient/MeshGradient.utils.js +1 -1
- package/dist/components/effects/Neumorphic/InsetCircleButton.js +1 -1
- package/dist/components/effects/Overlay/Overlay.js +7 -3
- package/dist/components/effects/index.d.ts +0 -32
- package/dist/components/effects/index.js +0 -16
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.d.ts +0 -2
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.js +1 -93
- package/dist/components/effects/shared/ShaderCanvas/ShaderCanvas.types.d.ts +0 -10
- package/dist/components/effects/shared/ShaderCanvas/index.d.ts +1 -1
- package/dist/components/effects/shared/index.d.ts +1 -3
- package/dist/components/effects/shared/shaderNoise.glsl.d.ts +1 -1
- package/dist/components/effects/shared/shaderNoise.glsl.js +2 -11
- package/dist/components/forms/Checkbox/Checkbox.js +2 -1
- package/dist/components/forms/Checkbox/Checkbox.theme.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerEyeDropper.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerGradient.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerHeader.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerImage.js +3 -3
- package/dist/components/forms/ColorPicker/ColorPickerInput.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerPresets.js +2 -2
- package/dist/components/forms/ColorPicker/ColorPickerSavedColors.js +2 -2
- package/dist/components/forms/Combobox/Combobox.js +5 -3
- package/dist/components/forms/Combobox/Combobox.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePicker.animations.js +16 -25
- package/dist/components/forms/DatePicker/DatePicker.theme.js +2 -2
- package/dist/components/forms/DatePicker/DatePickerBody.js +1 -1
- package/dist/components/forms/DatePicker/DatePickerTrigger.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePicker.theme.js +4 -4
- package/dist/components/forms/DateRangePicker/DateRangePickerBody.js +1 -1
- package/dist/components/forms/DateRangePicker/DateRangePickerContext.js +1 -0
- package/dist/components/forms/DateRangePicker/DateRangePickerPresets.js +2 -2
- package/dist/components/forms/DateRangePicker/DateRangePickerTrigger.js +2 -2
- package/dist/components/forms/FileUpload/FileUpload.js +4 -4
- package/dist/components/forms/FileUpload/FileUpload.theme.js +7 -3
- package/dist/components/forms/FileUpload/FileUploadProgress.js +7 -7
- package/dist/components/forms/FileUpload/FileUploadProgress.theme.js +1 -1
- package/dist/components/forms/Input/Input.js +6 -7
- package/dist/components/forms/Input/Input.theme.js +19 -15
- package/dist/components/forms/InputAddress/InputAddress.js +10 -3
- package/dist/components/forms/InputAddress/InputAddress.types.d.ts +2 -2
- package/dist/components/forms/InputCounter/InputCounter.js +3 -3
- package/dist/components/forms/InputOTP/InputOTP.d.ts +3 -12
- package/dist/components/forms/InputOTP/InputOTP.js +140 -151
- package/dist/components/forms/InputOTP/InputOTP.theme.d.ts +5 -1
- package/dist/components/forms/InputOTP/InputOTP.theme.js +40 -5
- package/dist/components/forms/InputOTP/InputOTP.types.d.ts +45 -2
- package/dist/components/forms/InputOTP/index.d.ts +1 -1
- package/dist/components/forms/InputTag/InputTag.js +5 -5
- package/dist/components/forms/InputTag/InputTag.theme.js +1 -2
- package/dist/components/forms/Mention/Mention.theme.js +3 -5
- package/dist/components/forms/Radio/Radio.js +3 -2
- package/dist/components/forms/Radio/Radio.theme.js +3 -3
- package/dist/components/forms/RichTextEditor/RichTextEditor.d.ts +12 -16
- package/dist/components/forms/RichTextEditor/RichTextEditor.js +165 -1681
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.d.ts +12 -56
- package/dist/components/forms/RichTextEditor/RichTextEditor.theme.js +60 -118
- package/dist/components/forms/RichTextEditor/RichTextEditor.types.d.ts +62 -126
- package/dist/components/forms/RichTextEditor/RichTextLinkField.d.ts +18 -0
- package/dist/components/forms/RichTextEditor/RichTextLinkField.js +46 -0
- package/dist/components/forms/RichTextEditor/RichTextToolbar.d.ts +15 -0
- package/dist/components/forms/RichTextEditor/RichTextToolbar.js +93 -0
- package/dist/components/forms/RichTextEditor/editorCommands.d.ts +50 -0
- package/dist/components/forms/RichTextEditor/editorCommands.js +58 -0
- package/dist/components/forms/RichTextEditor/editorState.d.ts +19 -0
- package/dist/components/forms/RichTextEditor/editorState.js +103 -0
- package/dist/components/forms/RichTextEditor/index.d.ts +5 -3
- package/dist/components/forms/RichTextEditor/sanitizeHtml.d.ts +38 -0
- package/dist/components/forms/RichTextEditor/sanitizeHtml.js +179 -0
- package/dist/components/forms/RichTextEditor/sanitizeHtml.test.d.ts +1 -0
- package/dist/components/forms/Select/Select.d.ts +5 -1
- package/dist/components/forms/Select/Select.js +14 -13
- package/dist/components/forms/Select/Select.theme.js +4 -4
- package/dist/components/forms/Select/Select.types.d.ts +74 -8
- package/dist/components/forms/Select/useSelectState.d.ts +9 -3
- package/dist/components/forms/Select/useSelectState.js +4 -1
- package/dist/components/forms/SelectableCard/SelectableCard.animations.d.ts +1 -2
- package/dist/components/forms/SelectableCard/SelectableCard.animations.js +6 -7
- package/dist/components/forms/SelectableCard/SelectableCard.js +3 -2
- package/dist/components/forms/SelectableCard/SelectableCard.theme.js +1 -1
- package/dist/components/forms/Signature/Signature.js +1 -1
- package/dist/components/forms/Slider/Slider.js +24 -11
- package/dist/components/forms/Slider/Slider.theme.js +9 -3
- package/dist/components/forms/Switch/Switch.theme.js +3 -3
- package/dist/components/forms/TimePicker/TimePicker.theme.js +7 -8
- package/dist/components/forms/TimePicker/TimePickerContent.js +1 -1
- package/dist/components/forms/TimePicker/TimePickerTrigger.js +3 -3
- package/dist/components/forms/forms.theme.js +38 -13
- package/dist/components/forms/index.js +2 -1
- package/dist/components/generative/FormShell.d.ts +22 -0
- package/dist/components/generative/FormShell.js +102 -0
- package/dist/components/generative/GenerativeView.d.ts +52 -1
- package/dist/components/generative/GenerativeView.js +203 -11
- package/dist/components/generative/actions.d.ts +5 -0
- package/dist/components/generative/ai-sdk/index.d.ts +1 -0
- package/dist/components/generative/ai-sdk/index.js +1 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.d.ts +52 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.js +73 -0
- package/dist/components/generative/ai-sdk/useGenerativeChat.test.d.ts +1 -0
- package/dist/components/generative/fieldBinding.d.ts +31 -0
- package/dist/components/generative/fieldBinding.js +33 -0
- package/dist/components/generative/fieldBinding.test.d.ts +1 -0
- package/dist/components/generative/formScope.d.ts +71 -0
- package/dist/components/generative/formScope.js +135 -0
- package/dist/components/generative/index.d.ts +4 -0
- package/dist/components/generative/index.js +4 -0
- package/dist/components/generative/registry.d.ts +2 -0
- package/dist/components/generative/registry.js +197 -4
- package/dist/components/generative/resolvers.js +16 -16
- package/dist/components/generative/schema.generated.js +2522 -328
- package/dist/components/generative/toToolResult.d.ts +21 -0
- package/dist/components/generative/toToolResult.js +15 -0
- package/dist/components/generative/toToolResult.test.d.ts +1 -0
- package/dist/components/generative/validate.d.ts +10 -1
- package/dist/components/generative/validate.js +126 -11
- package/dist/components/layout/Grid/Grid.js +1 -0
- package/dist/components/layout/Section/Section.theme.js +1 -1
- package/dist/components/layout/Stack/Stack.js +1 -0
- package/dist/generative.schema.json +2522 -328
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/useElapsedTime.d.ts +28 -0
- package/dist/hooks/useElapsedTime.js +37 -0
- package/dist/hooks/useSelectPortal.d.ts +10 -2
- package/dist/hooks/useSelectPortal.js +6 -3
- package/dist/index.js +2 -5
- package/dist/registry.json +3262 -2464
- package/dist/shadcn-compat.css +6 -6
- package/dist/styles/theme.test.d.ts +1 -0
- package/dist/styles.css +1 -1
- package/dist/test/render.d.ts +17 -0
- package/dist/theme.css +5 -1
- package/dist/themes/ember.css +131 -0
- package/dist/themes/iris.css +94 -0
- package/dist/themes/jade.css +139 -0
- package/dist/themes/precision.css +232 -0
- package/dist/tools.json +2557 -328
- package/dist/utils/colorUtils.d.ts +6 -6
- package/dist/utils/colorUtils.js +8 -8
- package/dist/utils/index.d.ts +0 -1
- package/package.json +39 -6
- package/src/global.scss +32 -28
- package/src/styles/theme.css +547 -176
- package/src/styles/theme.test.ts +119 -0
- package/tailwind.preset.cjs +66 -38
- package/dist/components/charts/FunnelChart/FunnelChart.animations.d.ts +0 -35
- package/dist/components/charts/FunnelChart/FunnelChart.animations.js +0 -59
- package/dist/components/charts/FunnelChart/FunnelChart.d.ts +0 -8
- package/dist/components/charts/FunnelChart/FunnelChart.js +0 -410
- package/dist/components/charts/FunnelChart/FunnelChart.theme.d.ts +0 -2
- package/dist/components/charts/FunnelChart/FunnelChart.theme.js +0 -12
- package/dist/components/charts/FunnelChart/FunnelChart.types.d.ts +0 -105
- package/dist/components/charts/FunnelChart/index.d.ts +0 -4
- package/dist/components/charts/ScatterPlot/ScatterPlot.d.ts +0 -9
- package/dist/components/charts/ScatterPlot/ScatterPlot.js +0 -207
- package/dist/components/charts/ScatterPlot/ScatterPlot.theme.d.ts +0 -18
- package/dist/components/charts/ScatterPlot/ScatterPlot.theme.js +0 -42
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.d.ts +0 -65
- package/dist/components/charts/ScatterPlot/ScatterPlot.types.js +0 -12
- package/dist/components/charts/ScatterPlot/index.d.ts +0 -3
- package/dist/components/core/Button/Button.ripple.d.ts +0 -71
- package/dist/components/core/Button/Button.ripple.js +0 -236
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.d.ts +0 -4
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.theme.d.ts +0 -12
- package/dist/components/core/Calendar/CalendarEvent/CalendarEvent.types.d.ts +0 -23
- package/dist/components/core/Calendar/CalendarEvent/index.d.ts +0 -2
- package/dist/components/core/CardStack/CardStack.animations.d.ts +0 -47
- package/dist/components/core/CardStack/CardStack.d.ts +0 -3
- package/dist/components/core/CardStack/CardStack.js +0 -187
- package/dist/components/core/CardStack/CardStack.theme.d.ts +0 -6
- package/dist/components/core/CardStack/CardStack.theme.js +0 -33
- package/dist/components/core/CardStack/CardStack.types.d.ts +0 -139
- package/dist/components/core/CardStack/index.d.ts +0 -7
- package/dist/components/core/Carousel/Carousel.d.ts +0 -3
- package/dist/components/core/Carousel/Carousel.js +0 -83
- package/dist/components/core/Carousel/Carousel.theme.d.ts +0 -10
- package/dist/components/core/Carousel/Carousel.theme.js +0 -20
- package/dist/components/core/Carousel/Carousel.types.d.ts +0 -113
- package/dist/components/core/Carousel/CarouselBody.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselBody.js +0 -59
- package/dist/components/core/Carousel/CarouselContext.d.ts +0 -3
- package/dist/components/core/Carousel/CarouselContext.js +0 -13
- package/dist/components/core/Carousel/CarouselItem.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselItem.js +0 -11
- package/dist/components/core/Carousel/CarouselNext.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselNext.js +0 -16
- package/dist/components/core/Carousel/CarouselPrevious.d.ts +0 -4
- package/dist/components/core/Carousel/CarouselPrevious.js +0 -16
- package/dist/components/core/Carousel/index.d.ts +0 -3
- package/dist/components/core/Pill/Pill.animations.d.ts +0 -32
- package/dist/components/core/Pill/Pill.animations.js +0 -16
- package/dist/components/effects/ColorPanels/ColorPanels.d.ts +0 -8
- package/dist/components/effects/ColorPanels/ColorPanels.js +0 -66
- package/dist/components/effects/ColorPanels/ColorPanels.shaders.d.ts +0 -12
- package/dist/components/effects/ColorPanels/ColorPanels.shaders.js +0 -218
- package/dist/components/effects/ColorPanels/ColorPanels.types.d.ts +0 -29
- package/dist/components/effects/ColorPanels/ColorPanels.types.js +0 -3
- package/dist/components/effects/ColorPanels/index.d.ts +0 -2
- package/dist/components/effects/FlutedGlass/FlutedGlass.d.ts +0 -9
- package/dist/components/effects/FlutedGlass/FlutedGlass.js +0 -80
- package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.d.ts +0 -12
- package/dist/components/effects/FlutedGlass/FlutedGlass.shaders.js +0 -335
- package/dist/components/effects/FlutedGlass/FlutedGlass.types.d.ts +0 -61
- package/dist/components/effects/FlutedGlass/FlutedGlass.types.js +0 -16
- package/dist/components/effects/FlutedGlass/index.d.ts +0 -3
- package/dist/components/effects/GlassEffect/GlassEffect.d.ts +0 -15
- package/dist/components/effects/GlassEffect/GlassEffect.js +0 -38
- package/dist/components/effects/GlassEffect/GlassEffect.types.d.ts +0 -19
- package/dist/components/effects/GlassEffect/index.d.ts +0 -2
- package/dist/components/effects/GlassSurface/GlassSurface.d.ts +0 -8
- package/dist/components/effects/GlassSurface/GlassSurface.js +0 -250
- package/dist/components/effects/GlassSurface/GlassSurface.types.d.ts +0 -66
- package/dist/components/effects/GlassSurface/index.d.ts +0 -2
- package/dist/components/effects/GodRays/GodRays.d.ts +0 -8
- package/dist/components/effects/GodRays/GodRays.js +0 -68
- package/dist/components/effects/GodRays/GodRays.shaders.d.ts +0 -10
- package/dist/components/effects/GodRays/GodRays.shaders.js +0 -128
- package/dist/components/effects/GodRays/GodRays.types.d.ts +0 -25
- package/dist/components/effects/GodRays/GodRays.types.js +0 -3
- package/dist/components/effects/GodRays/index.d.ts +0 -2
- package/dist/components/effects/GridPattern/GridPattern.d.ts +0 -18
- package/dist/components/effects/GridPattern/GridPattern.js +0 -65
- package/dist/components/effects/GridPattern/GridPattern.types.d.ts +0 -47
- package/dist/components/effects/GridPattern/index.d.ts +0 -2
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.d.ts +0 -10
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.js +0 -78
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.d.ts +0 -22
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.shaders.js +0 -239
- package/dist/components/effects/HalftoneCmyk/HalftoneCmyk.types.d.ts +0 -52
- package/dist/components/effects/HalftoneCmyk/index.d.ts +0 -2
- package/dist/components/effects/HalftoneDots/HalftoneDots.d.ts +0 -9
- package/dist/components/effects/HalftoneDots/HalftoneDots.js +0 -68
- package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.d.ts +0 -13
- package/dist/components/effects/HalftoneDots/HalftoneDots.shaders.js +0 -296
- package/dist/components/effects/HalftoneDots/HalftoneDots.types.d.ts +0 -43
- package/dist/components/effects/HalftoneDots/HalftoneDots.types.js +0 -12
- package/dist/components/effects/HalftoneDots/index.d.ts +0 -3
- package/dist/components/effects/ImageDithering/ImageDithering.d.ts +0 -9
- package/dist/components/effects/ImageDithering/ImageDithering.js +0 -68
- package/dist/components/effects/ImageDithering/ImageDithering.shaders.d.ts +0 -12
- package/dist/components/effects/ImageDithering/ImageDithering.shaders.js +0 -117
- package/dist/components/effects/ImageDithering/ImageDithering.types.d.ts +0 -30
- package/dist/components/effects/ImageDithering/ImageDithering.types.js +0 -8
- package/dist/components/effects/ImageDithering/index.d.ts +0 -3
- package/dist/components/effects/MagneticElement/MagneticElement.d.ts +0 -30
- package/dist/components/effects/MagneticElement/MagneticElement.js +0 -111
- package/dist/components/effects/MagneticElement/MagneticElement.types.d.ts +0 -44
- package/dist/components/effects/MagneticElement/index.d.ts +0 -2
- package/dist/components/effects/Metaballs/Metaballs.d.ts +0 -8
- package/dist/components/effects/Metaballs/Metaballs.js +0 -59
- package/dist/components/effects/Metaballs/Metaballs.shaders.d.ts +0 -10
- package/dist/components/effects/Metaballs/Metaballs.shaders.js +0 -102
- package/dist/components/effects/Metaballs/Metaballs.types.d.ts +0 -16
- package/dist/components/effects/Metaballs/Metaballs.types.js +0 -3
- package/dist/components/effects/Metaballs/index.d.ts +0 -2
- package/dist/components/effects/PaperTexture/PaperTexture.d.ts +0 -9
- package/dist/components/effects/PaperTexture/PaperTexture.js +0 -61
- package/dist/components/effects/PaperTexture/PaperTexture.shaders.d.ts +0 -22
- package/dist/components/effects/PaperTexture/PaperTexture.shaders.js +0 -145
- package/dist/components/effects/PaperTexture/PaperTexture.types.d.ts +0 -19
- package/dist/components/effects/PaperTexture/index.d.ts +0 -2
- package/dist/components/effects/PulsingBorder/PulsingBorder.d.ts +0 -27
- package/dist/components/effects/PulsingBorder/PulsingBorder.js +0 -174
- package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.d.ts +0 -14
- package/dist/components/effects/PulsingBorder/PulsingBorder.shaders.js +0 -258
- package/dist/components/effects/PulsingBorder/PulsingBorder.types.d.ts +0 -75
- package/dist/components/effects/PulsingBorder/PulsingBorder.types.js +0 -3
- package/dist/components/effects/PulsingBorder/index.d.ts +0 -2
- package/dist/components/effects/SmokeRing/SmokeRing.d.ts +0 -8
- package/dist/components/effects/SmokeRing/SmokeRing.js +0 -62
- package/dist/components/effects/SmokeRing/SmokeRing.shaders.d.ts +0 -14
- package/dist/components/effects/SmokeRing/SmokeRing.shaders.js +0 -130
- package/dist/components/effects/SmokeRing/SmokeRing.types.d.ts +0 -22
- package/dist/components/effects/SmokeRing/SmokeRing.types.js +0 -3
- package/dist/components/effects/SmokeRing/index.d.ts +0 -2
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.d.ts +0 -9
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.js +0 -59
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.d.ts +0 -14
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.shaders.js +0 -129
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.d.ts +0 -23
- package/dist/components/effects/StaticGradientMesh/StaticGradientMesh.types.js +0 -3
- package/dist/components/effects/StaticGradientMesh/index.d.ts +0 -2
- package/dist/components/effects/Water/Water.d.ts +0 -9
- package/dist/components/effects/Water/Water.js +0 -65
- package/dist/components/effects/Water/Water.shaders.d.ts +0 -11
- package/dist/components/effects/Water/Water.shaders.js +0 -123
- package/dist/components/effects/Water/Water.types.d.ts +0 -25
- package/dist/components/effects/Water/index.d.ts +0 -2
- package/dist/components/effects/shared/bayerMatrices.glsl.d.ts +0 -10
- package/dist/components/effects/shared/bayerMatrices.glsl.js +0 -44
- package/dist/components/effects/shared/imageUV.glsl.d.ts +0 -12
- package/dist/components/effects/shared/imageUV.glsl.js +0 -26
- package/dist/components/forms/RichTextEditor/RichTextEditor.animations.d.ts +0 -7
- package/dist/components/forms/RichTextEditor/RichTextEditor.animations.js +0 -32
- package/dist/utils/calendarUtils.d.ts +0 -60
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.theme.js +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltip.types.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/ChartTooltipContent.d.ts +0 -0
- /package/dist/components/{charts → core}/shared/ChartTooltip/index.d.ts +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { ArrowUUpRight, ArrowUUpLeft, Eraser, Code, Quotes, ListNumbers, ListBullets, LinkSimple, TextStrikethrough, TextUnderline, TextItalic, TextB } from '@phosphor-icons/react';
|
|
4
|
+
import { Button } from '../../core/Button/Button.js';
|
|
5
|
+
import { Select } from '../Select/Select.js';
|
|
6
|
+
import '../Select/Select.theme.js';
|
|
7
|
+
import { cn } from '../../../utils/cn.js';
|
|
8
|
+
import 'react';
|
|
9
|
+
import { richTextEditorTheme } from './RichTextEditor.theme.js';
|
|
10
|
+
|
|
11
|
+
/** The compact default: block style, inline marks, links, lists, history. */
|
|
12
|
+
const DEFAULT_TOOLBAR_TOOLS = [
|
|
13
|
+
"blockStyle",
|
|
14
|
+
"separator",
|
|
15
|
+
"bold",
|
|
16
|
+
"italic",
|
|
17
|
+
"underline",
|
|
18
|
+
"strikethrough",
|
|
19
|
+
"separator",
|
|
20
|
+
"link",
|
|
21
|
+
"bulletList",
|
|
22
|
+
"orderedList",
|
|
23
|
+
"separator",
|
|
24
|
+
"blockquote",
|
|
25
|
+
"code",
|
|
26
|
+
"clearFormat",
|
|
27
|
+
"separator",
|
|
28
|
+
"undo",
|
|
29
|
+
"redo",
|
|
30
|
+
];
|
|
31
|
+
const BLOCK_OPTIONS = [
|
|
32
|
+
{ id: "paragraph", value: "paragraph", label: "Paragraph" },
|
|
33
|
+
{ id: "h1", value: "h1", label: "Heading 1" },
|
|
34
|
+
{ id: "h2", value: "h2", label: "Heading 2" },
|
|
35
|
+
{ id: "h3", value: "h3", label: "Heading 3" },
|
|
36
|
+
{ id: "h4", value: "h4", label: "Heading 4" },
|
|
37
|
+
];
|
|
38
|
+
/** Icon + accessible name for every button-shaped tool. */
|
|
39
|
+
const TOOL_META = {
|
|
40
|
+
bold: { icon: jsx(TextB, {}), label: "Bold" },
|
|
41
|
+
italic: { icon: jsx(TextItalic, {}), label: "Italic" },
|
|
42
|
+
underline: { icon: jsx(TextUnderline, {}), label: "Underline" },
|
|
43
|
+
strikethrough: { icon: jsx(TextStrikethrough, {}), label: "Strikethrough" },
|
|
44
|
+
link: { icon: jsx(LinkSimple, {}), label: "Link" },
|
|
45
|
+
bulletList: { icon: jsx(ListBullets, {}), label: "Bulleted list" },
|
|
46
|
+
orderedList: { icon: jsx(ListNumbers, {}), label: "Numbered list" },
|
|
47
|
+
blockquote: { icon: jsx(Quotes, {}), label: "Blockquote" },
|
|
48
|
+
code: { icon: jsx(Code, {}), label: "Code" },
|
|
49
|
+
clearFormat: { icon: jsx(Eraser, {}), label: "Clear formatting" },
|
|
50
|
+
undo: { icon: jsx(ArrowUUpLeft, {}), label: "Undo" },
|
|
51
|
+
redo: { icon: jsx(ArrowUUpRight, {}), label: "Redo" },
|
|
52
|
+
};
|
|
53
|
+
/** Which tools report a pressed state, and where to read it from. */
|
|
54
|
+
const PRESSED_KEY = {
|
|
55
|
+
bold: "bold",
|
|
56
|
+
italic: "italic",
|
|
57
|
+
underline: "underline",
|
|
58
|
+
strikethrough: "strikethrough",
|
|
59
|
+
bulletList: "bulletList",
|
|
60
|
+
orderedList: "orderedList",
|
|
61
|
+
blockquote: "blockquote",
|
|
62
|
+
code: "code",
|
|
63
|
+
};
|
|
64
|
+
const RichTextToolbar = ({ tools, formatting, disabled, size, className, onCommand, onBlockChange, }) => {
|
|
65
|
+
const controlSize = size === "lg" ? "md" : "sm";
|
|
66
|
+
return (jsx("div", { role: "toolbar", "aria-label": "Formatting", "aria-orientation": "horizontal", className: cn(richTextEditorTheme.toolbarStyle, className), children: tools.map((tool, index) => {
|
|
67
|
+
if (tool === "separator") {
|
|
68
|
+
return (jsx("span", { "aria-hidden": "true", className: richTextEditorTheme.separatorStyle }, `separator-${index}`));
|
|
69
|
+
}
|
|
70
|
+
if (tool === "blockStyle") {
|
|
71
|
+
return (jsx(Select, { "aria-label": "Block style", options: BLOCK_OPTIONS, value: formatting.block, onChange: onBlockChange, disabled: disabled, size: controlSize,
|
|
72
|
+
// 🔴 wrapperClassName, not className: per CLAUDE.md §9 `className`
|
|
73
|
+
// targets Select's trigger button, while its wrapper carries the
|
|
74
|
+
// shared `relative w-full`. Sizing the trigger alone left the
|
|
75
|
+
// wrapper stretching the whole toolbar row, so `flex-wrap` pushed
|
|
76
|
+
// every button onto a second line.
|
|
77
|
+
wrapperClassName: "w-36 shrink-0" }, "blockStyle"));
|
|
78
|
+
}
|
|
79
|
+
const meta = TOOL_META[tool];
|
|
80
|
+
if (!meta)
|
|
81
|
+
return null;
|
|
82
|
+
const pressedKey = PRESSED_KEY[tool];
|
|
83
|
+
const isPressed = tool === "link" ? formatting.link !== null : pressedKey ? formatting[pressedKey] : undefined;
|
|
84
|
+
return (jsx(Button, { type: "button", iconOnly: true, variant: isPressed ? "soft" : "ghost", color: "mono", size: controlSize, state: disabled ? "disabled" : "default", "aria-label": meta.label, "aria-pressed": isPressed, iconStart: meta.icon,
|
|
85
|
+
// 🔴 Load-bearing: without this the button takes focus on press and the
|
|
86
|
+
// editor's selection collapses, so the command would apply to nothing.
|
|
87
|
+
// preventDefault on mousedown keeps focus (and the Range) in the editor.
|
|
88
|
+
onMouseDown: (event) => event.preventDefault(), onClick: () => onCommand(tool) }, tool));
|
|
89
|
+
}) }));
|
|
90
|
+
};
|
|
91
|
+
RichTextToolbar.displayName = "RichTextToolbar";
|
|
92
|
+
|
|
93
|
+
export { DEFAULT_TOOLBAR_TOOLS, RichTextToolbar };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONLY module permitted to call `document.execCommand`.
|
|
3
|
+
*
|
|
4
|
+
* `execCommand` is deprecated, and every non-deprecated alternative is an editor
|
|
5
|
+
* framework (ProseMirror/Lexical) — a dependency this library does not take. For
|
|
6
|
+
* a semantic editor the API maps almost 1:1 onto the tools we ship, and
|
|
7
|
+
* hand-rolling list nesting and block splitting from `Range` is where custom
|
|
8
|
+
* editors accumulate their worst selection bugs.
|
|
9
|
+
*
|
|
10
|
+
* Two things contain the risk:
|
|
11
|
+
* 1. Its practical weakness is inconsistent markup across browsers (`<b>` vs
|
|
12
|
+
* `<strong>`, stray `<div>`, `<font>`), which `sanitizeHtml`'s normalizer
|
|
13
|
+
* resolves on every read — so the value we store is identical everywhere.
|
|
14
|
+
* 2. It is confined to this file. Adopting a real engine later means
|
|
15
|
+
* reimplementing this module and nothing else.
|
|
16
|
+
*
|
|
17
|
+
* State is deliberately NOT read here: `queryCommandState` is unreliable for
|
|
18
|
+
* block-level state. See `editorState.ts`.
|
|
19
|
+
*/
|
|
20
|
+
import type { BlockStyle } from "./RichTextEditor.types";
|
|
21
|
+
export declare const toggleBold: () => void;
|
|
22
|
+
export declare const toggleItalic: () => void;
|
|
23
|
+
export declare const toggleUnderline: () => void;
|
|
24
|
+
export declare const toggleStrikethrough: () => void;
|
|
25
|
+
export declare const toggleBulletList: () => void;
|
|
26
|
+
export declare const toggleOrderedList: () => void;
|
|
27
|
+
export declare const undo: () => void;
|
|
28
|
+
export declare const redo: () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Clear inline formatting. `removeFormat` leaves list/quote structure alone,
|
|
31
|
+
* which is what "clear formatting" should mean — it unbolds text, it does not
|
|
32
|
+
* silently destroy the list the user is standing in.
|
|
33
|
+
*/
|
|
34
|
+
export declare const clearFormatting: () => void;
|
|
35
|
+
export declare const setBlockStyle: (block: BlockStyle) => void;
|
|
36
|
+
/** Toggle blockquote by comparing against the block the selection is already in. */
|
|
37
|
+
export declare const toggleBlockquote: (isActive: boolean) => void;
|
|
38
|
+
/** Toggle `<pre>` for code blocks, same shape as blockquote. */
|
|
39
|
+
export declare const toggleCodeBlock: (isActive: boolean) => void;
|
|
40
|
+
export declare const createLink: (href: string) => void;
|
|
41
|
+
export declare const removeLink: () => void;
|
|
42
|
+
/**
|
|
43
|
+
* Insert already-sanitized HTML at the caret.
|
|
44
|
+
*
|
|
45
|
+
* 🔴 Callers MUST pass output of `sanitizeHtml`. This is the paste/drop path and
|
|
46
|
+
* the one command that writes caller-supplied markup into the document.
|
|
47
|
+
*/
|
|
48
|
+
export declare const insertSanitizedHtml: (html: string) => void;
|
|
49
|
+
/** Insert plain text, letting the browser handle escaping. */
|
|
50
|
+
export declare const insertText: (text: string) => void;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
function run(command, value) {
|
|
3
|
+
try {
|
|
4
|
+
document.execCommand(command, false, value);
|
|
5
|
+
}
|
|
6
|
+
catch (error) {
|
|
7
|
+
if (process.env.NODE_ENV !== "production") {
|
|
8
|
+
// eslint-disable-next-line no-console
|
|
9
|
+
console.warn(`[RichTextEditor]: execCommand("${command}") failed`, error);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const toggleBold = () => run("bold");
|
|
14
|
+
const toggleItalic = () => run("italic");
|
|
15
|
+
const toggleUnderline = () => run("underline");
|
|
16
|
+
const toggleStrikethrough = () => run("strikeThrough");
|
|
17
|
+
const toggleBulletList = () => run("insertUnorderedList");
|
|
18
|
+
const toggleOrderedList = () => run("insertOrderedList");
|
|
19
|
+
const undo = () => run("undo");
|
|
20
|
+
const redo = () => run("redo");
|
|
21
|
+
/**
|
|
22
|
+
* Clear inline formatting. `removeFormat` leaves list/quote structure alone,
|
|
23
|
+
* which is what "clear formatting" should mean — it unbolds text, it does not
|
|
24
|
+
* silently destroy the list the user is standing in.
|
|
25
|
+
*/
|
|
26
|
+
const clearFormatting = () => run("removeFormat");
|
|
27
|
+
const BLOCK_TAG = {
|
|
28
|
+
paragraph: "P",
|
|
29
|
+
h1: "H1",
|
|
30
|
+
h2: "H2",
|
|
31
|
+
h3: "H3",
|
|
32
|
+
h4: "H4",
|
|
33
|
+
};
|
|
34
|
+
const setBlockStyle = (block) => {
|
|
35
|
+
// Angle brackets are required by Firefox and harmless in Chromium/WebKit.
|
|
36
|
+
run("formatBlock", `<${BLOCK_TAG[block]}>`);
|
|
37
|
+
};
|
|
38
|
+
/** Toggle blockquote by comparing against the block the selection is already in. */
|
|
39
|
+
const toggleBlockquote = (isActive) => {
|
|
40
|
+
run("formatBlock", isActive ? "<P>" : "<BLOCKQUOTE>");
|
|
41
|
+
};
|
|
42
|
+
/** Toggle `<pre>` for code blocks, same shape as blockquote. */
|
|
43
|
+
const toggleCodeBlock = (isActive) => {
|
|
44
|
+
run("formatBlock", isActive ? "<P>" : "<PRE>");
|
|
45
|
+
};
|
|
46
|
+
const createLink = (href) => run("createLink", href);
|
|
47
|
+
const removeLink = () => run("unlink");
|
|
48
|
+
/**
|
|
49
|
+
* Insert already-sanitized HTML at the caret.
|
|
50
|
+
*
|
|
51
|
+
* 🔴 Callers MUST pass output of `sanitizeHtml`. This is the paste/drop path and
|
|
52
|
+
* the one command that writes caller-supplied markup into the document.
|
|
53
|
+
*/
|
|
54
|
+
const insertSanitizedHtml = (html) => run("insertHTML", html);
|
|
55
|
+
/** Insert plain text, letting the browser handle escaping. */
|
|
56
|
+
const insertText = (text) => run("insertText", text);
|
|
57
|
+
|
|
58
|
+
export { clearFormatting, createLink, insertSanitizedHtml, insertText, redo, removeLink, setBlockStyle, toggleBlockquote, toggleBold, toggleBulletList, toggleCodeBlock, toggleItalic, toggleOrderedList, toggleStrikethrough, toggleUnderline, undo };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the formatting active at the current selection by walking the DOM
|
|
3
|
+
* ancestors of the selection anchor, up to (but not including) the editor root.
|
|
4
|
+
*
|
|
5
|
+
* This replaces `document.queryCommandState`, which is unreliable — notably for
|
|
6
|
+
* block-level state, where browsers disagree about what "active" means inside
|
|
7
|
+
* nested lists and quotes. An ancestor walk is deterministic, needs no
|
|
8
|
+
* deprecated API, and answers block and inline questions with the same code.
|
|
9
|
+
*/
|
|
10
|
+
import type { FormattingState } from "./RichTextEditor.types";
|
|
11
|
+
export declare const EMPTY_FORMATTING_STATE: FormattingState;
|
|
12
|
+
/**
|
|
13
|
+
* Compute the formatting state for `selection` within `root`.
|
|
14
|
+
*
|
|
15
|
+
* Returns `EMPTY_FORMATTING_STATE` when there is no selection, or when the
|
|
16
|
+
* selection lies outside `root` — a toolbar must not report state for text the
|
|
17
|
+
* user selected somewhere else on the page.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readFormattingState(root: HTMLElement | null, selection: Selection | null): FormattingState;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads the formatting active at the current selection by walking the DOM
|
|
3
|
+
* ancestors of the selection anchor, up to (but not including) the editor root.
|
|
4
|
+
*
|
|
5
|
+
* This replaces `document.queryCommandState`, which is unreliable — notably for
|
|
6
|
+
* block-level state, where browsers disagree about what "active" means inside
|
|
7
|
+
* nested lists and quotes. An ancestor walk is deterministic, needs no
|
|
8
|
+
* deprecated API, and answers block and inline questions with the same code.
|
|
9
|
+
*/
|
|
10
|
+
const EMPTY_FORMATTING_STATE = {
|
|
11
|
+
bold: false,
|
|
12
|
+
italic: false,
|
|
13
|
+
underline: false,
|
|
14
|
+
strikethrough: false,
|
|
15
|
+
bulletList: false,
|
|
16
|
+
orderedList: false,
|
|
17
|
+
blockquote: false,
|
|
18
|
+
code: false,
|
|
19
|
+
link: null,
|
|
20
|
+
block: "paragraph",
|
|
21
|
+
};
|
|
22
|
+
const BLOCK_FOR_TAG = {
|
|
23
|
+
H1: "h1",
|
|
24
|
+
H2: "h2",
|
|
25
|
+
H3: "h3",
|
|
26
|
+
H4: "h4",
|
|
27
|
+
P: "paragraph",
|
|
28
|
+
};
|
|
29
|
+
/** The element the selection sits in (text nodes resolve to their parent). */
|
|
30
|
+
function selectionElement(selection) {
|
|
31
|
+
const node = selection.anchorNode;
|
|
32
|
+
if (!node)
|
|
33
|
+
return null;
|
|
34
|
+
return node.nodeType === Node.ELEMENT_NODE
|
|
35
|
+
? node
|
|
36
|
+
: node.parentElement;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Compute the formatting state for `selection` within `root`.
|
|
40
|
+
*
|
|
41
|
+
* Returns `EMPTY_FORMATTING_STATE` when there is no selection, or when the
|
|
42
|
+
* selection lies outside `root` — a toolbar must not report state for text the
|
|
43
|
+
* user selected somewhere else on the page.
|
|
44
|
+
*/
|
|
45
|
+
function readFormattingState(root, selection) {
|
|
46
|
+
if (!root || !selection || selection.rangeCount === 0)
|
|
47
|
+
return EMPTY_FORMATTING_STATE;
|
|
48
|
+
const start = selectionElement(selection);
|
|
49
|
+
if (!start || !root.contains(start))
|
|
50
|
+
return EMPTY_FORMATTING_STATE;
|
|
51
|
+
const state = { ...EMPTY_FORMATTING_STATE };
|
|
52
|
+
let blockFound = false;
|
|
53
|
+
let node = start;
|
|
54
|
+
while (node && node !== root) {
|
|
55
|
+
switch (node.tagName) {
|
|
56
|
+
case "STRONG":
|
|
57
|
+
case "B":
|
|
58
|
+
state.bold = true;
|
|
59
|
+
break;
|
|
60
|
+
case "EM":
|
|
61
|
+
case "I":
|
|
62
|
+
state.italic = true;
|
|
63
|
+
break;
|
|
64
|
+
case "U":
|
|
65
|
+
state.underline = true;
|
|
66
|
+
break;
|
|
67
|
+
case "S":
|
|
68
|
+
case "STRIKE":
|
|
69
|
+
case "DEL":
|
|
70
|
+
state.strikethrough = true;
|
|
71
|
+
break;
|
|
72
|
+
case "CODE":
|
|
73
|
+
case "PRE":
|
|
74
|
+
state.code = true;
|
|
75
|
+
break;
|
|
76
|
+
case "BLOCKQUOTE":
|
|
77
|
+
state.blockquote = true;
|
|
78
|
+
break;
|
|
79
|
+
case "UL":
|
|
80
|
+
// Only the nearest list wins — a <ul> inside an <ol> is a bullet list.
|
|
81
|
+
if (!state.orderedList)
|
|
82
|
+
state.bulletList = true;
|
|
83
|
+
break;
|
|
84
|
+
case "OL":
|
|
85
|
+
if (!state.bulletList)
|
|
86
|
+
state.orderedList = true;
|
|
87
|
+
break;
|
|
88
|
+
case "A":
|
|
89
|
+
if (state.link === null)
|
|
90
|
+
state.link = node.getAttribute("href");
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
// The nearest block ancestor determines the block style; outer ones do not.
|
|
94
|
+
if (!blockFound && node.tagName in BLOCK_FOR_TAG) {
|
|
95
|
+
state.block = BLOCK_FOR_TAG[node.tagName];
|
|
96
|
+
blockFound = true;
|
|
97
|
+
}
|
|
98
|
+
node = node.parentElement;
|
|
99
|
+
}
|
|
100
|
+
return state;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export { EMPTY_FORMATTING_STATE, readFormattingState };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export { RichTextEditor
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
1
|
+
export { RichTextEditor } from './RichTextEditor';
|
|
2
|
+
export { RichTextToolbar, DEFAULT_TOOLBAR_TOOLS } from './RichTextToolbar';
|
|
3
|
+
export { sanitizeHtml } from './sanitizeHtml';
|
|
4
|
+
export type { RichTextEditorProps, RichTextEditorSize, RichTextEditorState, ToolbarConfig, ToolbarTool, BlockStyle, FormattingState, RichTextEditorTheme, RichTextEditorThemeOverrides, } from './RichTextEditor.types';
|
|
5
|
+
export { richTextEditorTheme } from './RichTextEditor.theme';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML sanitizer for RichTextEditor.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 SECURITY BOUNDARY. Every path that writes markup into the editor's DOM, and
|
|
5
|
+
* every value handed back to the consumer, passes through `sanitizeHtml`:
|
|
6
|
+
* the `value` prop, paste, drop, and the string emitted to `onChange`. Never add
|
|
7
|
+
* a write path that skips it.
|
|
8
|
+
*
|
|
9
|
+
* Deny-by-default: an element is dropped unless it is in ALLOWED_TAGS, and an
|
|
10
|
+
* attribute is dropped unless it is in that tag's allowlist. The allowlist is
|
|
11
|
+
* small because we also control what the editor PRODUCES — this sanitizes the
|
|
12
|
+
* output of a semantic editor, not the arbitrary web.
|
|
13
|
+
*
|
|
14
|
+
* ── On not using DOMPurify ────────────────────────────────────────────────────
|
|
15
|
+
* DOMPurify exists because sanitizing arbitrary HTML is hard; its hardest class
|
|
16
|
+
* of bug is mutation XSS, where sanitized output re-parses differently once
|
|
17
|
+
* assigned to `innerHTML`. Two properties keep a hand-rolled allowlist
|
|
18
|
+
* defensible here:
|
|
19
|
+
*
|
|
20
|
+
* 1. The known mXSS vectors route through namespace confusion (`svg`, `math`)
|
|
21
|
+
* and through `template`/`noscript`/`style`/`xmp`. All of those are in
|
|
22
|
+
* DROP_WITH_CHILDREN, so they are never present in our output.
|
|
23
|
+
* 2. `sanitizeHtml` runs to a FIXED POINT (below). Markup that is unstable
|
|
24
|
+
* under re-parsing is reduced to plain text rather than trusted.
|
|
25
|
+
*
|
|
26
|
+
* Consumers rendering hostile third-party HTML should still pass a hardened
|
|
27
|
+
* sanitizer via the `sanitize` prop.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Sanitize `html` to the allowlist.
|
|
31
|
+
*
|
|
32
|
+
* Runs to a fixed point: if a second pass over the first pass's output differs,
|
|
33
|
+
* the markup re-parses differently than it serializes — the shape of a mutation
|
|
34
|
+
* XSS — and we fall back to plain text. The cost is one extra parse of
|
|
35
|
+
* editor-sized content; the benefit is that the failure mode is lost formatting
|
|
36
|
+
* rather than script execution.
|
|
37
|
+
*/
|
|
38
|
+
export declare function sanitizeHtml(html: string): string;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML sanitizer for RichTextEditor.
|
|
3
|
+
*
|
|
4
|
+
* 🔴 SECURITY BOUNDARY. Every path that writes markup into the editor's DOM, and
|
|
5
|
+
* every value handed back to the consumer, passes through `sanitizeHtml`:
|
|
6
|
+
* the `value` prop, paste, drop, and the string emitted to `onChange`. Never add
|
|
7
|
+
* a write path that skips it.
|
|
8
|
+
*
|
|
9
|
+
* Deny-by-default: an element is dropped unless it is in ALLOWED_TAGS, and an
|
|
10
|
+
* attribute is dropped unless it is in that tag's allowlist. The allowlist is
|
|
11
|
+
* small because we also control what the editor PRODUCES — this sanitizes the
|
|
12
|
+
* output of a semantic editor, not the arbitrary web.
|
|
13
|
+
*
|
|
14
|
+
* ── On not using DOMPurify ────────────────────────────────────────────────────
|
|
15
|
+
* DOMPurify exists because sanitizing arbitrary HTML is hard; its hardest class
|
|
16
|
+
* of bug is mutation XSS, where sanitized output re-parses differently once
|
|
17
|
+
* assigned to `innerHTML`. Two properties keep a hand-rolled allowlist
|
|
18
|
+
* defensible here:
|
|
19
|
+
*
|
|
20
|
+
* 1. The known mXSS vectors route through namespace confusion (`svg`, `math`)
|
|
21
|
+
* and through `template`/`noscript`/`style`/`xmp`. All of those are in
|
|
22
|
+
* DROP_WITH_CHILDREN, so they are never present in our output.
|
|
23
|
+
* 2. `sanitizeHtml` runs to a FIXED POINT (below). Markup that is unstable
|
|
24
|
+
* under re-parsing is reduced to plain text rather than trusted.
|
|
25
|
+
*
|
|
26
|
+
* Consumers rendering hostile third-party HTML should still pass a hardened
|
|
27
|
+
* sanitizer via the `sanitize` prop.
|
|
28
|
+
*/
|
|
29
|
+
/** Elements the editor may emit, and that may survive a paste. */
|
|
30
|
+
const ALLOWED_TAGS = new Set([
|
|
31
|
+
"P", "BR",
|
|
32
|
+
"STRONG", "EM", "U", "S", "CODE",
|
|
33
|
+
"H1", "H2", "H3", "H4",
|
|
34
|
+
"UL", "OL", "LI",
|
|
35
|
+
"BLOCKQUOTE", "PRE",
|
|
36
|
+
"A",
|
|
37
|
+
]);
|
|
38
|
+
/** Per-tag attribute allowlist. Everything not listed here is stripped. */
|
|
39
|
+
const ALLOWED_ATTRS = {
|
|
40
|
+
A: new Set(["href"]),
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Dropped along with their subtree. Everything here either executes, loads, or
|
|
44
|
+
* (for the parser-confusing set) is an mXSS vector — in no case is the text
|
|
45
|
+
* inside worth preserving.
|
|
46
|
+
*/
|
|
47
|
+
const DROP_WITH_CHILDREN = new Set([
|
|
48
|
+
"SCRIPT", "STYLE", "IFRAME", "OBJECT", "EMBED", "APPLET",
|
|
49
|
+
"LINK", "META", "BASE", "TITLE",
|
|
50
|
+
"SVG", "MATH", "NOSCRIPT", "TEMPLATE", "XMP",
|
|
51
|
+
"FORM", "INPUT", "BUTTON", "SELECT", "TEXTAREA", "OPTION",
|
|
52
|
+
]);
|
|
53
|
+
/**
|
|
54
|
+
* Presentational tags browsers still emit (notably via `execCommand`) mapped to
|
|
55
|
+
* their semantic equivalent. This is what makes `execCommand`'s cross-browser
|
|
56
|
+
* markup inconsistency a non-issue: whatever the browser produces, the value we
|
|
57
|
+
* store and emit is normalized.
|
|
58
|
+
*/
|
|
59
|
+
const TAG_ALIASES = {
|
|
60
|
+
B: "STRONG",
|
|
61
|
+
I: "EM",
|
|
62
|
+
STRIKE: "S",
|
|
63
|
+
DEL: "S",
|
|
64
|
+
INS: "U",
|
|
65
|
+
DIV: "P",
|
|
66
|
+
};
|
|
67
|
+
/** Schemes permitted in `href`. Relative URLs are allowed and need no scheme. */
|
|
68
|
+
const ALLOWED_SCHEMES = new Set(["http:", "https:", "mailto:", "tel:"]);
|
|
69
|
+
function isSafeHref(value) {
|
|
70
|
+
const trimmed = value.trim();
|
|
71
|
+
// Reject embedded control characters outright. NUL/newline/tab inside a scheme
|
|
72
|
+
// ("java\nscript:") is the classic way past a naive prefix check, since browsers
|
|
73
|
+
// strip them before resolving the URL. U+FFFD is included because the HTML parser
|
|
74
|
+
// has already rewritten any NUL to the replacement character by the time we read
|
|
75
|
+
// the attribute — that form is inert, but it is still junk we refuse to store.
|
|
76
|
+
// eslint-disable-next-line no-control-regex
|
|
77
|
+
if (/[\u0000-\u001F\u007F\uFFFD]/.test(trimmed))
|
|
78
|
+
return false;
|
|
79
|
+
// Relative URLs (no scheme) are safe and common.
|
|
80
|
+
if (/^[^a-zA-Z]/.test(trimmed) || !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(trimmed)) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
return ALLOWED_SCHEMES.has(new URL(trimmed, "https://example.invalid").protocol);
|
|
85
|
+
}
|
|
86
|
+
catch (_a) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Recursively copy `source`'s allowed children into `target`. */
|
|
91
|
+
function cleanChildren(source, target, doc) {
|
|
92
|
+
source.childNodes.forEach((child) => {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
95
|
+
target.appendChild(doc.createTextNode((_a = child.nodeValue) !== null && _a !== void 0 ? _a : ""));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (child.nodeType !== Node.ELEMENT_NODE)
|
|
99
|
+
return; // comments, PIs, doctypes
|
|
100
|
+
const element = child;
|
|
101
|
+
const rawTag = element.tagName.toUpperCase();
|
|
102
|
+
if (DROP_WITH_CHILDREN.has(rawTag))
|
|
103
|
+
return;
|
|
104
|
+
const tag = (_b = TAG_ALIASES[rawTag]) !== null && _b !== void 0 ? _b : rawTag;
|
|
105
|
+
// Unknown but harmless (e.g. <span>, <font>): drop the element, keep its
|
|
106
|
+
// content, so pasted text survives while its styling does not.
|
|
107
|
+
if (!ALLOWED_TAGS.has(tag)) {
|
|
108
|
+
cleanChildren(element, target, doc);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const clean = doc.createElement(tag);
|
|
112
|
+
const allowed = ALLOWED_ATTRS[tag];
|
|
113
|
+
if (allowed) {
|
|
114
|
+
for (const attr of Array.from(element.attributes)) {
|
|
115
|
+
const name = attr.name.toLowerCase();
|
|
116
|
+
if (!allowed.has(name))
|
|
117
|
+
continue;
|
|
118
|
+
if (name === "href" && !isSafeHref(attr.value))
|
|
119
|
+
continue;
|
|
120
|
+
clean.setAttribute(name, attr.value);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// An anchor that lost its href is no longer a link; keep only its text.
|
|
124
|
+
if (tag === "A" && !clean.hasAttribute("href")) {
|
|
125
|
+
cleanChildren(element, target, doc);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (tag === "A") {
|
|
129
|
+
// Defence in depth for consumers rendering the stored HTML with target=_blank.
|
|
130
|
+
clean.setAttribute("rel", "noopener noreferrer");
|
|
131
|
+
}
|
|
132
|
+
cleanChildren(element, clean, doc);
|
|
133
|
+
target.appendChild(clean);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/** One sanitization pass. Parsing happens in an inert document — nothing executes. */
|
|
137
|
+
function sanitizeOnce(html) {
|
|
138
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
139
|
+
const output = doc.createElement("div");
|
|
140
|
+
cleanChildren(doc.body, output, doc);
|
|
141
|
+
return output.innerHTML;
|
|
142
|
+
}
|
|
143
|
+
/** Strip every tag, keeping text. The fallback when markup will not stabilize. */
|
|
144
|
+
function toPlainText(html) {
|
|
145
|
+
var _a;
|
|
146
|
+
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
147
|
+
const text = (_a = doc.body.textContent) !== null && _a !== void 0 ? _a : "";
|
|
148
|
+
const escaped = doc.createElement("div");
|
|
149
|
+
escaped.textContent = text;
|
|
150
|
+
return escaped.innerHTML;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Sanitize `html` to the allowlist.
|
|
154
|
+
*
|
|
155
|
+
* Runs to a fixed point: if a second pass over the first pass's output differs,
|
|
156
|
+
* the markup re-parses differently than it serializes — the shape of a mutation
|
|
157
|
+
* XSS — and we fall back to plain text. The cost is one extra parse of
|
|
158
|
+
* editor-sized content; the benefit is that the failure mode is lost formatting
|
|
159
|
+
* rather than script execution.
|
|
160
|
+
*/
|
|
161
|
+
function sanitizeHtml(html) {
|
|
162
|
+
if (!html)
|
|
163
|
+
return "";
|
|
164
|
+
// SSR / non-DOM environments have no parser; never return unsanitized markup.
|
|
165
|
+
if (typeof DOMParser === "undefined")
|
|
166
|
+
return "";
|
|
167
|
+
const first = sanitizeOnce(html);
|
|
168
|
+
const second = sanitizeOnce(first);
|
|
169
|
+
if (first !== second) {
|
|
170
|
+
if (process.env.NODE_ENV !== "production") {
|
|
171
|
+
// eslint-disable-next-line no-console
|
|
172
|
+
console.warn("[RichTextEditor]: markup did not stabilize under sanitization and was reduced to plain text.");
|
|
173
|
+
}
|
|
174
|
+
return toPlainText(html);
|
|
175
|
+
}
|
|
176
|
+
return first;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export { sanitizeHtml };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -14,6 +14,8 @@ export interface SelectContextValue<T = any> extends UseSelectStateReturn<T> {
|
|
|
14
14
|
theme: SelectThemeOverrides;
|
|
15
15
|
/** Whether search is enabled */
|
|
16
16
|
searchable: boolean;
|
|
17
|
+
/** Placeholder text for the search input */
|
|
18
|
+
searchPlaceholder: string;
|
|
17
19
|
/** Whether typeahead is enabled */
|
|
18
20
|
enableTypeahead: boolean;
|
|
19
21
|
/** Button ref (alias for triggerRef for backward compatibility) */
|
|
@@ -44,6 +46,8 @@ export interface SelectProviderProps<T = any> {
|
|
|
44
46
|
theme?: SelectThemeOverrides;
|
|
45
47
|
/** Whether search is enabled */
|
|
46
48
|
searchable?: boolean;
|
|
49
|
+
/** Placeholder text for the search input */
|
|
50
|
+
searchPlaceholder?: string;
|
|
47
51
|
/** Whether typeahead is enabled */
|
|
48
52
|
enableTypeahead?: boolean;
|
|
49
53
|
}
|
|
@@ -68,7 +72,7 @@ export interface SelectProviderProps<T = any> {
|
|
|
68
72
|
* </SelectProvider>
|
|
69
73
|
* ```
|
|
70
74
|
*/
|
|
71
|
-
export declare function SelectProvider<T = any>({ children, selectState, size, componentState, theme: themeOverrides, searchable, enableTypeahead, }: SelectProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
75
|
+
export declare function SelectProvider<T = any>({ children, selectState, size, componentState, theme: themeOverrides, searchable, searchPlaceholder, enableTypeahead, }: SelectProviderProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
72
76
|
/**
|
|
73
77
|
* Select Button Component
|
|
74
78
|
*/
|