dishui 0.0.106 → 0.0.110
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/dist/.release-verified.json +3 -2
- package/dist/components/Accordion/index.js.map +1 -1
- package/dist/components/Avatar/index.js.map +1 -1
- package/dist/components/Badge/index.js.map +1 -1
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/ButtonMenu/index.js.map +1 -1
- package/dist/components/Card/Metric2.js.map +1 -1
- package/dist/components/Card/Ticket2.js.map +1 -1
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/Chart/Chart.js.map +1 -1
- package/dist/components/Checkbox/index.js.map +1 -1
- package/dist/components/ChoicePicker/index.js.map +1 -1
- package/dist/components/Column/index.js.map +1 -1
- package/dist/components/ConfirmDialog/index.js.map +1 -1
- package/dist/components/DateTimeInput/index.js.map +1 -1
- package/dist/components/Demo/index.js.map +1 -1
- package/dist/components/Demo/source.js.map +1 -1
- package/dist/components/Divider/index.js.map +1 -1
- package/dist/components/EmptyState/index.js.map +1 -1
- package/dist/components/Field/index.js.map +1 -1
- package/dist/components/FileUploader/DropZone.js.map +1 -1
- package/dist/components/FileUploader/FileItem.js.map +1 -1
- package/dist/components/FileUploader/FileUploader.js.map +1 -1
- package/dist/components/FileUploader/UploadQueue.js.map +1 -1
- package/dist/components/GroupButton/index.js.map +1 -1
- package/dist/components/GroupedTable/index.js.map +1 -1
- package/dist/components/Icon/index.js.map +1 -1
- package/dist/components/Image/index.js.map +1 -1
- package/dist/components/Input/index.js.map +1 -1
- package/dist/components/Label/index.js.map +1 -1
- package/dist/components/Layout/index.js.map +1 -1
- package/dist/components/LayoutSuite/DashboardSuite.js.map +1 -1
- package/dist/components/LayoutSuite/index.js.map +1 -1
- package/dist/components/List/index.js.map +1 -1
- package/dist/components/Markdown/Markdown.js.map +1 -1
- package/dist/components/Markdown/codeThemes.js.map +1 -1
- package/dist/components/Markdown/markdownComponents.js.map +1 -1
- package/dist/components/Markdown/parseCodeBlockMeta.js.map +1 -1
- package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
- package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
- package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
- package/dist/components/Modal/focusScope.js.map +1 -1
- package/dist/components/Modal/index.js.map +1 -1
- package/dist/components/MultipleChoice/index.js.map +1 -1
- package/dist/components/NavigationList/index.js.map +1 -1
- package/dist/components/Page/Float2.js.map +1 -1
- package/dist/components/Page/index.js.map +1 -1
- package/dist/components/Page/resize2.js.map +1 -1
- package/dist/components/PageHeader/index.js.map +1 -1
- package/dist/components/PagePanel/index.js.map +1 -1
- package/dist/components/ProtectedRoute/index.js.map +1 -1
- package/dist/components/Resizable/ResizeGrip.js.map +1 -1
- package/dist/components/Resizable/index.js.map +1 -1
- package/dist/components/Resizable/useResize.js.map +1 -1
- package/dist/components/Row/index.js.map +1 -1
- package/dist/components/Section/index.js.map +1 -1
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/SidebarToggleButton/index.js.map +1 -1
- package/dist/components/Skeleton/index.js.map +1 -1
- package/dist/components/Slider/index.js.map +1 -1
- package/dist/components/Switch/index.js.map +1 -1
- package/dist/components/Tab/index.js.map +1 -1
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/Tabs/index.js.map +1 -1
- package/dist/components/Tabs/tabNavigation.js.map +1 -1
- package/dist/components/Text/index.js.map +1 -1
- package/dist/components/Textarea/index.js.map +1 -1
- package/dist/components/Tooltip/index.js.map +1 -1
- package/dist/components/Tree/Tree.js.map +1 -1
- package/dist/components/ai/AgentChat/index.js.map +1 -1
- package/dist/components/ai/AgentRunCard/index.js.map +1 -1
- package/dist/components/ai/AgentScreen/index.js.map +1 -1
- package/dist/components/ai/ApprovalCard/index.js.map +1 -1
- package/dist/components/ai/CodeView/index.js.map +1 -1
- package/dist/components/ai/CommandSearch/index.js.map +1 -1
- package/dist/components/ai/ContextCards/index.js.map +1 -1
- package/dist/components/ai/DiffTable/index.js.map +1 -1
- package/dist/components/ai/FilterTable/index.js.map +1 -1
- package/dist/components/ai/FineTuneCard/index.js.map +1 -1
- package/dist/components/ai/InsightCards/index.js.map +1 -1
- package/dist/components/ai/IssueCard/index.js.map +1 -1
- package/dist/components/ai/LoadingState/index.js.map +1 -1
- package/dist/components/ai/PromptBar/index.js.map +1 -1
- package/dist/components/ai/RecommendationCard/index.js.map +1 -1
- package/dist/components/ai/RecordsTable/index.js.map +1 -1
- package/dist/components/ai/SelectionActions/index.js.map +1 -1
- package/dist/components/ai/StateFlow/index.js.map +1 -1
- package/dist/components/ai/StreamingText/index.js.map +1 -1
- package/dist/components/ai/TaskRows/index.js.map +1 -1
- package/dist/components/ai/Thinking/index.js.map +1 -1
- package/dist/components/ai/ToolChips/index.js.map +1 -1
- package/dist/components/ai/shared.js.map +1 -1
- package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
- package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
- package/dist/components/pro/ArticleControl/buildHeadingTree.js.map +1 -1
- package/dist/components/pro/ArticleControl/useArticleToc.js.map +1 -1
- package/dist/components/pro/Calendar/Calendar.js +165 -160
- package/dist/components/pro/Calendar/Calendar.js.map +1 -1
- package/dist/components/pro/Calendar/hooks/useCalendarDrag.js.map +1 -1
- package/dist/components/pro/Calendar/hooks/useCalendarState.js +31 -31
- package/dist/components/pro/Calendar/hooks/useCalendarState.js.map +1 -1
- package/dist/components/pro/Calendar/utils.js.map +1 -1
- package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
- package/dist/components/pro/CodeEditor/editors/markdownExtensions.js.map +1 -1
- package/dist/components/pro/CodeEditor/extensions/contextMenu.js.map +1 -1
- package/dist/components/pro/CodeEditor/extensions/index.js.map +1 -1
- package/dist/components/pro/CodeEditor/langs/index.js.map +1 -1
- package/dist/components/pro/CodeEditor/langs/javascript.js.map +1 -1
- package/dist/components/pro/CodeEditor/langs/python.js.map +1 -1
- package/dist/components/pro/CodeEditor/langs/snippets.js.map +1 -1
- package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
- package/dist/components/pro/CodeEditor/panels/HistoryPanel.js +65 -59
- package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
- package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
- package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
- package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
- package/dist/components/pro/CodeEditor/themes.js.map +1 -1
- package/dist/components/pro/CodeEditor/utils.js.map +1 -1
- package/dist/components/pro/DataTable/DataTable.js.map +1 -1
- package/dist/components/pro/DataTable/Filters.js.map +1 -1
- package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
- package/dist/components/pro/DataTable/PivotView.js.map +1 -1
- package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
- package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
- package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
- package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
- package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
- package/dist/components/pro/DataTable/extension.js.map +1 -1
- package/dist/components/pro/DataTable/pivotEngine.js.map +1 -1
- package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
- package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
- package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
- package/dist/components/pro/DataTable/useColumnDragReorder.js.map +1 -1
- package/dist/components/pro/DataTable/useDataTableModel.js +119 -104
- package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -1
- package/dist/components/pro/DataTable/utils.js.map +1 -1
- package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
- package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
- package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
- package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
- package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
- package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
- package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
- package/dist/components/pro/Flow/Flow.js.map +1 -1
- package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
- package/dist/components/pro/Flow/archify/build.js.map +1 -1
- package/dist/components/pro/Flow/archify/convert.js.map +1 -1
- package/dist/components/pro/Flow/archify/palette.js.map +1 -1
- package/dist/components/pro/Flow/archify/presets.js.map +1 -1
- package/dist/components/pro/Flow/archify/spec.js.map +1 -1
- package/dist/components/pro/Flow/canvas/AlignmentGuides.js.map +1 -1
- package/dist/components/pro/Flow/canvas/GridRenderer.js.map +1 -1
- package/dist/components/pro/Flow/canvas/MiniMapRenderer.js.map +1 -1
- package/dist/components/pro/Flow/canvas/PixiApp.js.map +1 -1
- package/dist/components/pro/Flow/canvas/SelectionOverlay.js.map +1 -1
- package/dist/components/pro/Flow/canvas/ViewportContainer.js.map +1 -1
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowContext.js.map +1 -1
- package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
- package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
- package/dist/components/pro/Flow/edges/edgeMarkers.js.map +1 -1
- package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useAlignmentGuides.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useCompactMode.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useDraggablePanel.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
- package/dist/components/pro/Flow/hooks/usePdfExport.js.map +1 -1
- package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useResizablePanel.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useSelection.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useUndoRedo.js.map +1 -1
- package/dist/components/pro/Flow/hooks/useViewport.js.map +1 -1
- package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
- package/dist/components/pro/Flow/lines/GeometricLineTool.js.map +1 -1
- package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
- package/dist/components/pro/Flow/lines/lineSmoothing.js.map +1 -1
- package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
- package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
- package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
- package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
- package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
- package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
- package/dist/components/pro/Flow/nodes/aiClient.js.map +1 -1
- package/dist/components/pro/Flow/nodes/animAnchors.js.map +1 -1
- package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -1
- package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
- package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -1
- package/dist/components/pro/Flow/nodes/nodeUtils.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/nodes/svgIconTexture.js.map +1 -1
- package/dist/components/pro/Flow/nodes/svgIcons.js.map +1 -1
- package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
- package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
- package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
- package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
- package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
- package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
- package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
- package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
- package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
- package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
- package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
- package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
- package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
- package/dist/components/pro/Flow/types.js.map +1 -1
- package/dist/components/pro/Flow/utils/dashedLine.js.map +1 -1
- package/dist/components/pro/Flow/utils/gradient.js.map +1 -1
- package/dist/components/pro/Flow/utils/pdfExport.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
- package/dist/components/pro/Gantt/Gantt.js.map +1 -1
- package/dist/components/pro/Gantt/hooks/useGanttDrag.js.map +1 -1
- package/dist/components/pro/Gantt/hooks/useGanttState.js +79 -71
- package/dist/components/pro/Gantt/hooks/useGanttState.js.map +1 -1
- package/dist/components/pro/Gantt/utils.js.map +1 -1
- package/dist/components/pro/Kanban/Kanban.js.map +1 -1
- package/dist/components/pro/Kanban/Swimlanes.js.map +1 -1
- package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -1
- package/dist/components/pro/Kanban/utils.js.map +1 -1
- package/dist/components/pro/RichTextEditor/AIRewrite.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/AIRewrite.js +109 -88
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
- package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
- package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
- package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +133 -132
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/CommentMark.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/FontSize.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js.map +1 -1
- package/dist/components/pro/RichTextEditor/extensions/legacyMermaid.js.map +1 -1
- package/dist/components/pro/RichTextEditor/types.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/types.js.map +1 -1
- package/dist/components/pro/Sprite/Molly/animations.d.ts +6 -0
- package/dist/components/pro/Sprite/Molly/animations.js +52 -0
- package/dist/components/pro/Sprite/Molly/animations.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/events.d.ts +2 -0
- package/dist/components/pro/Sprite/Molly/events.js +46 -0
- package/dist/components/pro/Sprite/Molly/events.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/index.d.ts +1 -0
- package/dist/components/pro/Sprite/Molly/index.js +12 -0
- package/dist/components/pro/Sprite/Molly/index.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/legFlexion.d.ts +3 -0
- package/dist/components/pro/Sprite/Molly/legFlexion.js +48 -0
- package/dist/components/pro/Sprite/Molly/legFlexion.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/locomotion.d.ts +4 -0
- package/dist/components/pro/Sprite/Molly/locomotion.js +51 -0
- package/dist/components/pro/Sprite/Molly/locomotion.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/model.d.ts +23 -0
- package/dist/components/pro/Sprite/Molly/model.js +614 -0
- package/dist/components/pro/Sprite/Molly/model.js.map +1 -0
- package/dist/components/pro/Sprite/Molly/rig.d.ts +25 -0
- package/dist/components/pro/Sprite/Molly/rig.js +102 -0
- package/dist/components/pro/Sprite/Molly/rig.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/animations.d.ts +6 -0
- package/dist/components/pro/Sprite/Ruby/animations.js +58 -0
- package/dist/components/pro/Sprite/Ruby/animations.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/events.d.ts +2 -0
- package/dist/components/pro/Sprite/Ruby/events.js +46 -0
- package/dist/components/pro/Sprite/Ruby/events.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/index.d.ts +1 -0
- package/dist/components/pro/Sprite/Ruby/index.js +12 -0
- package/dist/components/pro/Sprite/Ruby/index.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/locomotion.d.ts +4 -0
- package/dist/components/pro/Sprite/Ruby/locomotion.js +41 -0
- package/dist/components/pro/Sprite/Ruby/locomotion.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/model.d.ts +23 -0
- package/dist/components/pro/Sprite/Ruby/model.js +605 -0
- package/dist/components/pro/Sprite/Ruby/model.js.map +1 -0
- package/dist/components/pro/Sprite/Ruby/rig.d.ts +26 -0
- package/dist/components/pro/Sprite/Ruby/rig.js +112 -0
- package/dist/components/pro/Sprite/Ruby/rig.js.map +1 -0
- package/dist/components/pro/Sprite/Sprite.d.ts +23 -0
- package/dist/components/pro/Sprite/Sprite2.js +224 -0
- package/dist/components/pro/Sprite/Sprite2.js.map +1 -0
- package/dist/components/pro/Sprite/actions.d.ts +3 -0
- package/dist/components/pro/Sprite/actions.js +16 -0
- package/dist/components/pro/Sprite/actions.js.map +1 -0
- package/dist/components/pro/Sprite/createSpriteScene.d.ts +4 -0
- package/dist/components/pro/Sprite/createSpriteScene.js +14 -0
- package/dist/components/pro/Sprite/createSpriteScene.js.map +1 -0
- package/dist/components/pro/Sprite/index.d.ts +4 -0
- package/dist/components/pro/Sprite/shared/animation.d.ts +33 -0
- package/dist/components/pro/Sprite/shared/animation.js +39 -0
- package/dist/components/pro/Sprite/shared/animation.js.map +1 -0
- package/dist/components/pro/Sprite/shared/createSpriteStage.d.ts +14 -0
- package/dist/components/pro/Sprite/shared/createSpriteStage.js +127 -0
- package/dist/components/pro/Sprite/shared/createSpriteStage.js.map +1 -0
- package/dist/components/pro/Sprite/shared/events.d.ts +5 -0
- package/dist/components/pro/Sprite/shared/events.js +21 -0
- package/dist/components/pro/Sprite/shared/events.js.map +1 -0
- package/dist/components/pro/Sprite/shared/face.d.ts +15 -0
- package/dist/components/pro/Sprite/shared/face.js +33 -0
- package/dist/components/pro/Sprite/shared/face.js.map +1 -0
- package/dist/components/pro/Sprite/shared/faceSurface.d.ts +6 -0
- package/dist/components/pro/Sprite/shared/faceSurface.js +66 -0
- package/dist/components/pro/Sprite/shared/faceSurface.js.map +1 -0
- package/dist/components/pro/Sprite/shared/gait.d.ts +5 -0
- package/dist/components/pro/Sprite/shared/gait.js +19 -0
- package/dist/components/pro/Sprite/shared/gait.js.map +1 -0
- package/dist/components/pro/Sprite/shared/geometry.d.ts +8 -0
- package/dist/components/pro/Sprite/shared/geometry.js +59 -0
- package/dist/components/pro/Sprite/shared/geometry.js.map +1 -0
- package/dist/components/pro/Sprite/shared/magicEffect.d.ts +27 -0
- package/dist/components/pro/Sprite/shared/magicEffect.js +61 -0
- package/dist/components/pro/Sprite/shared/magicEffect.js.map +1 -0
- package/dist/components/pro/Sprite/shared/playback.d.ts +8 -0
- package/dist/components/pro/Sprite/shared/playback.js +74 -0
- package/dist/components/pro/Sprite/shared/playback.js.map +1 -0
- package/dist/components/pro/Sprite/shared/rig.d.ts +6 -0
- package/dist/components/pro/Sprite/shared/rig.js +48 -0
- package/dist/components/pro/Sprite/shared/rig.js.map +1 -0
- package/dist/components/pro/Sprite/shared/scene.d.ts +9 -0
- package/dist/components/pro/Sprite/shared/scene.js +21 -0
- package/dist/components/pro/Sprite/shared/scene.js.map +1 -0
- package/dist/components/pro/Sprite/shared/sculptor.d.ts +14 -0
- package/dist/components/pro/Sprite/shared/sculptor.js +78 -0
- package/dist/components/pro/Sprite/shared/sculptor.js.map +1 -0
- package/dist/components/pro/Sprite/shared/speechBubble.d.ts +15 -0
- package/dist/components/pro/Sprite/shared/speechBubble.js +129 -0
- package/dist/components/pro/Sprite/shared/speechBubble.js.map +1 -0
- package/dist/components/pro/Sprite/types.d.ts +40 -0
- package/dist/contexts/AppContext.js.map +1 -1
- package/dist/contexts/authentication.js.map +1 -1
- package/dist/data-table.js +3 -3
- package/dist/data-table.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/hooks/useClickOutside.js.map +1 -1
- package/dist/hooks/useContainerElement.js.map +1 -1
- package/dist/hooks/useControllableState.js.map +1 -1
- package/dist/hooks/useCopyToClipboard.js.map +1 -1
- package/dist/hooks/useDebounce.js.map +1 -1
- package/dist/hooks/useDraggable.js.map +1 -1
- package/dist/hooks/useTableColumns.js.map +1 -1
- package/dist/hooks/useTableData.js.map +1 -1
- package/dist/index-nostyled.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +116 -115
- package/dist/layouts/MainLayout.js.map +1 -1
- package/dist/layouts/Navbar.js.map +1 -1
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/layouts/headbar/Headbar.js.map +1 -1
- package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
- package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
- package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
- package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
- package/dist/sprite.js +2 -0
- package/dist/styles/themeStyles.js.map +1 -1
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/flexLayout.js.map +1 -1
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js.map +1 -1
- package/dist/utils/rehype-code-meta.js.map +1 -1
- package/dist/utils/remark-code-meta.js.map +1 -1
- package/dist/utils/routerBuilder.js.map +1 -1
- package/dist/utils/safeStorage.js.map +1 -1
- package/dist/utils/selection.js +29 -20
- package/dist/utils/selection.js.map +1 -1
- package/dist/utils/themes.js.map +1 -1
- package/package.json +15 -11
|
@@ -11,45 +11,45 @@ import i from "./SlashMenu.js";
|
|
|
11
11
|
import a from "./BubbleToolbar.js";
|
|
12
12
|
import o from "./BlockHandle.js";
|
|
13
13
|
import { CodeBlockExtension as s } from "./extensions/CodeBlockView.js";
|
|
14
|
-
import
|
|
15
|
-
import { ResizableImage as
|
|
16
|
-
import { CommentMark as
|
|
14
|
+
import ae from "./extensions/FontSize.js";
|
|
15
|
+
import { ResizableImage as c } from "./extensions/ResizableImage.js";
|
|
16
|
+
import { CommentMark as oe } from "./extensions/CommentMark.js";
|
|
17
17
|
/* empty css */
|
|
18
|
-
import { useCallback as
|
|
19
|
-
import { jsx as
|
|
20
|
-
import { EditorContent as
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import { TextStyle as
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import
|
|
27
|
-
import
|
|
28
|
-
import { Table as
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import
|
|
32
|
-
import
|
|
33
|
-
import
|
|
34
|
-
import
|
|
35
|
-
import
|
|
36
|
-
import
|
|
37
|
-
import
|
|
38
|
-
import
|
|
18
|
+
import { useCallback as l, useEffect as u, useRef as se, useState as d } from "react";
|
|
19
|
+
import { jsx as f, jsxs as p } from "react/jsx-runtime";
|
|
20
|
+
import { EditorContent as ce, useEditor as le } from "@tiptap/react";
|
|
21
|
+
import m from "@tiptap/starter-kit";
|
|
22
|
+
import h from "@tiptap/extension-underline";
|
|
23
|
+
import { TextStyle as g } from "@tiptap/extension-text-style";
|
|
24
|
+
import ue from "@tiptap/extension-color";
|
|
25
|
+
import de from "@tiptap/extension-highlight";
|
|
26
|
+
import fe from "@tiptap/extension-text-align";
|
|
27
|
+
import pe from "@tiptap/extension-link";
|
|
28
|
+
import { Table as me } from "@tiptap/extension-table";
|
|
29
|
+
import _ from "@tiptap/extension-table-row";
|
|
30
|
+
import v from "@tiptap/extension-table-cell";
|
|
31
|
+
import y from "@tiptap/extension-table-header";
|
|
32
|
+
import b from "@tiptap/extension-placeholder";
|
|
33
|
+
import x from "@tiptap/extension-task-list";
|
|
34
|
+
import S from "@tiptap/extension-task-item";
|
|
35
|
+
import C from "@tiptap/extension-subscript";
|
|
36
|
+
import w from "@tiptap/extension-superscript";
|
|
37
|
+
import T from "@tiptap/extension-typography";
|
|
38
|
+
import E from "@tiptap/extension-font-family";
|
|
39
39
|
//#region src/components/pro/RichTextEditor/RichTextEditor.tsx
|
|
40
|
-
function
|
|
40
|
+
function D() {
|
|
41
41
|
return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
42
42
|
}
|
|
43
|
-
var
|
|
44
|
-
let [be, xe] =
|
|
43
|
+
var O = ({ content: O, value: k, onChange: A, onChangeJSON: j, placeholder: M = "Start writing...", editable: N = !0, aiConfig: P, onRequestAIConfig: F, toolbarConfig: I, aiSelectionFollowsEditor: L = !1, minHeight: R = "200px", maxHeight: z, className: he = "", autofocus: ge = !1, labels: B, editorRef: V, showComments: _e = !1, commentThreads: ve, onCommentThreadsChange: ye, currentUser: H }) => {
|
|
44
|
+
let [be, xe] = d(!1), [Se, U] = d(!1), [Ce, we] = d(""), [Te, Ee] = d({
|
|
45
45
|
from: 0,
|
|
46
46
|
to: 0
|
|
47
|
-
}), [
|
|
47
|
+
}), [W, G] = d(_e), [De, Oe] = d([]), [ke, K] = d(!1), [q, Ae] = d({
|
|
48
48
|
from: 0,
|
|
49
49
|
to: 0
|
|
50
|
-
}),
|
|
50
|
+
}), J = se(null), Y = ve ?? De, X = ye ?? Oe, Z = le({
|
|
51
51
|
extensions: [
|
|
52
|
-
|
|
52
|
+
m.configure({
|
|
53
53
|
codeBlock: !1,
|
|
54
54
|
heading: { levels: [
|
|
55
55
|
1,
|
|
@@ -62,97 +62,97 @@ var D = ({ content: D, value: O, onChange: k, onChangeJSON: A, placeholder: j =
|
|
|
62
62
|
link: !1,
|
|
63
63
|
underline: !1
|
|
64
64
|
}),
|
|
65
|
-
|
|
65
|
+
h,
|
|
66
|
+
g,
|
|
66
67
|
ue,
|
|
67
|
-
de,
|
|
68
|
-
fe.configure({
|
|
69
|
-
pe.configure({
|
|
70
|
-
me.configure({
|
|
68
|
+
de.configure({ multicolor: !0 }),
|
|
69
|
+
fe.configure({ types: ["heading", "paragraph"] }),
|
|
70
|
+
pe.configure({
|
|
71
71
|
openOnClick: !1,
|
|
72
72
|
autolink: !0,
|
|
73
73
|
HTMLAttributes: { class: "rte-link" }
|
|
74
74
|
}),
|
|
75
|
-
|
|
75
|
+
c.configure({
|
|
76
76
|
inline: !1,
|
|
77
77
|
allowBase64: !0
|
|
78
78
|
}),
|
|
79
|
-
|
|
80
|
-
g,
|
|
79
|
+
me.configure({ resizable: !0 }),
|
|
81
80
|
_,
|
|
82
81
|
v,
|
|
83
|
-
y
|
|
82
|
+
y,
|
|
83
|
+
b.configure({ placeholder: M }),
|
|
84
84
|
s,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
S,
|
|
85
|
+
x,
|
|
86
|
+
S.configure({ nested: !0 }),
|
|
88
87
|
C,
|
|
89
88
|
w,
|
|
90
89
|
T,
|
|
91
|
-
|
|
90
|
+
E,
|
|
91
|
+
ae,
|
|
92
92
|
n,
|
|
93
93
|
t,
|
|
94
|
-
|
|
94
|
+
oe
|
|
95
95
|
],
|
|
96
|
-
content:
|
|
97
|
-
editable:
|
|
96
|
+
content: k || O || "",
|
|
97
|
+
editable: N,
|
|
98
98
|
autofocus: ge ? "end" : !1,
|
|
99
99
|
onUpdate: ({ editor: e }) => {
|
|
100
|
-
|
|
100
|
+
A?.(e.getHTML()), j?.(e.getJSON());
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}, [
|
|
106
|
-
|
|
107
|
-
}, [
|
|
108
|
-
|
|
109
|
-
}, [
|
|
110
|
-
let
|
|
111
|
-
if (!
|
|
112
|
-
let { from: e, to: t } =
|
|
103
|
+
u(() => {
|
|
104
|
+
V && Z && (V.current = Z);
|
|
105
|
+
}, [Z, V]), u(() => {
|
|
106
|
+
Z && k !== void 0 && k !== Z.getHTML() && Z.commands.setContent(k, { emitUpdate: !1 });
|
|
107
|
+
}, [Z, k]), u(() => {
|
|
108
|
+
Z && Z.setEditable(N);
|
|
109
|
+
}, [Z, N]);
|
|
110
|
+
let Q = l(() => {
|
|
111
|
+
if (!Z) return;
|
|
112
|
+
let { from: e, to: t } = Z.state.selection, n = e === t ? "" : Z.state.doc.textBetween(e, t, " ");
|
|
113
113
|
we(n), Ee({
|
|
114
114
|
from: e,
|
|
115
115
|
to: t
|
|
116
|
-
}),
|
|
117
|
-
}, [
|
|
118
|
-
if (!
|
|
119
|
-
let { from: e, to: t } =
|
|
116
|
+
}), U(!0);
|
|
117
|
+
}, [Z]), $ = l(() => {
|
|
118
|
+
if (!Z) return;
|
|
119
|
+
let { from: e, to: t } = Z.state.selection;
|
|
120
120
|
e !== t && (Ae({
|
|
121
121
|
from: e,
|
|
122
122
|
to: t
|
|
123
|
-
}),
|
|
124
|
-
}, [
|
|
125
|
-
if (!
|
|
126
|
-
let t =
|
|
123
|
+
}), K(!0));
|
|
124
|
+
}, [Z]), je = l((e) => {
|
|
125
|
+
if (!Z) return;
|
|
126
|
+
let t = D(), n = {
|
|
127
127
|
id: t,
|
|
128
128
|
resolved: !1,
|
|
129
129
|
comments: [{
|
|
130
|
-
id:
|
|
131
|
-
author:
|
|
130
|
+
id: D(),
|
|
131
|
+
author: H || "User",
|
|
132
132
|
text: e,
|
|
133
133
|
createdAt: Date.now()
|
|
134
134
|
}],
|
|
135
135
|
createdAt: Date.now()
|
|
136
136
|
};
|
|
137
|
-
|
|
137
|
+
Z.chain().focus().setTextSelection(q).setComment(t).run(), X([...Y, n]), K(!1);
|
|
138
138
|
}, [
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
J,
|
|
139
|
+
Z,
|
|
140
|
+
q,
|
|
142
141
|
Y,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
X,
|
|
143
|
+
H
|
|
144
|
+
]), Me = l((e) => {
|
|
145
|
+
J.current?.scrollToThread(e);
|
|
146
146
|
}, []);
|
|
147
|
-
if (!
|
|
148
|
-
let
|
|
147
|
+
if (!Z) return null;
|
|
148
|
+
let Ne = typeof R == "number" ? `${R}px` : R, Pe = z ? typeof z == "number" ? `${z}px` : z : void 0, Fe = e("rte-container", be && "rte-container--format-painter", he), Ie = Y.filter((e) => !e.resolved).length, Le = I?.buttons?.comments ?? !0 ? /* @__PURE__ */ f("div", {
|
|
149
149
|
className: "rte-toolbar__end",
|
|
150
|
-
children: /* @__PURE__ */
|
|
150
|
+
children: /* @__PURE__ */ p("button", {
|
|
151
151
|
type: "button",
|
|
152
|
-
className: `rte-toolbar__btn rte-toolbar__comment-btn ${
|
|
153
|
-
onClick: () =>
|
|
152
|
+
className: `rte-toolbar__btn rte-toolbar__comment-btn ${W ? "rte-toolbar__btn--active" : ""}`,
|
|
153
|
+
onClick: () => G(!W),
|
|
154
154
|
title: "Toggle comments",
|
|
155
|
-
children: [/* @__PURE__ */
|
|
155
|
+
children: [/* @__PURE__ */ f("svg", {
|
|
156
156
|
width: "16",
|
|
157
157
|
height: "16",
|
|
158
158
|
viewBox: "0 0 24 24",
|
|
@@ -161,91 +161,92 @@ var D = ({ content: D, value: O, onChange: k, onChangeJSON: A, placeholder: j =
|
|
|
161
161
|
strokeWidth: "2",
|
|
162
162
|
strokeLinecap: "round",
|
|
163
163
|
strokeLinejoin: "round",
|
|
164
|
-
children: /* @__PURE__ */
|
|
165
|
-
}),
|
|
164
|
+
children: /* @__PURE__ */ f("path", { d: "M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z" })
|
|
165
|
+
}), Ie > 0 && /* @__PURE__ */ f("span", { className: "rte-toolbar__comment-badge" })]
|
|
166
166
|
})
|
|
167
167
|
}) : null;
|
|
168
|
-
return /* @__PURE__ */
|
|
169
|
-
className:
|
|
168
|
+
return /* @__PURE__ */ p("div", {
|
|
169
|
+
className: Fe,
|
|
170
170
|
style: {
|
|
171
|
-
minHeight:
|
|
172
|
-
maxHeight:
|
|
171
|
+
minHeight: Ne,
|
|
172
|
+
maxHeight: Pe
|
|
173
173
|
},
|
|
174
174
|
children: [
|
|
175
|
-
|
|
176
|
-
editor:
|
|
177
|
-
config:
|
|
178
|
-
labels:
|
|
179
|
-
hasAI: !!
|
|
180
|
-
onAIClick:
|
|
181
|
-
onRequestAIConfig:
|
|
175
|
+
N && /* @__PURE__ */ f(ee, {
|
|
176
|
+
editor: Z,
|
|
177
|
+
config: I,
|
|
178
|
+
labels: B,
|
|
179
|
+
hasAI: !!P,
|
|
180
|
+
onAIClick: Q,
|
|
181
|
+
onRequestAIConfig: F,
|
|
182
182
|
onFormatPainterChange: xe,
|
|
183
|
-
children:
|
|
183
|
+
children: Le
|
|
184
184
|
}),
|
|
185
|
-
/* @__PURE__ */
|
|
185
|
+
/* @__PURE__ */ p("div", {
|
|
186
186
|
style: {
|
|
187
187
|
display: "flex",
|
|
188
188
|
flex: 1,
|
|
189
189
|
overflow: "hidden"
|
|
190
190
|
},
|
|
191
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ p("div", {
|
|
192
192
|
className: "rte-editor-wrapper",
|
|
193
193
|
style: { flex: 1 },
|
|
194
194
|
children: [
|
|
195
|
-
/* @__PURE__ */
|
|
196
|
-
editor:
|
|
195
|
+
/* @__PURE__ */ f(ce, {
|
|
196
|
+
editor: Z,
|
|
197
197
|
className: "rte-editor-content"
|
|
198
198
|
}),
|
|
199
|
-
|
|
200
|
-
editor:
|
|
201
|
-
labels:
|
|
202
|
-
onAIClick:
|
|
199
|
+
N && /* @__PURE__ */ f(ne, {
|
|
200
|
+
editor: Z,
|
|
201
|
+
labels: B,
|
|
202
|
+
onAIClick: P ? Q : void 0
|
|
203
203
|
}),
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
editor:
|
|
207
|
-
onAddComment:
|
|
204
|
+
N && /* @__PURE__ */ f(i, { editor: Z }),
|
|
205
|
+
N && /* @__PURE__ */ f(a, {
|
|
206
|
+
editor: Z,
|
|
207
|
+
onAddComment: $
|
|
208
208
|
}),
|
|
209
|
-
|
|
210
|
-
editor:
|
|
209
|
+
N && /* @__PURE__ */ f(o, {
|
|
210
|
+
editor: Z,
|
|
211
211
|
persistent: !0
|
|
212
212
|
}),
|
|
213
|
-
/* @__PURE__ */
|
|
214
|
-
editor:
|
|
215
|
-
threads:
|
|
216
|
-
onThreadsChange:
|
|
217
|
-
showPanel:
|
|
218
|
-
onOpenPanel: () =>
|
|
219
|
-
onScrollToThread:
|
|
220
|
-
currentUser:
|
|
213
|
+
/* @__PURE__ */ f(r, {
|
|
214
|
+
editor: Z,
|
|
215
|
+
threads: Y,
|
|
216
|
+
onThreadsChange: X,
|
|
217
|
+
showPanel: W,
|
|
218
|
+
onOpenPanel: () => G(!0),
|
|
219
|
+
onScrollToThread: Me,
|
|
220
|
+
currentUser: H
|
|
221
221
|
})
|
|
222
222
|
]
|
|
223
|
-
}),
|
|
224
|
-
ref:
|
|
225
|
-
editor:
|
|
226
|
-
threads:
|
|
227
|
-
onThreadsChange:
|
|
228
|
-
onRequestAddComment:
|
|
229
|
-
currentUser:
|
|
223
|
+
}), W && /* @__PURE__ */ f(re, {
|
|
224
|
+
ref: J,
|
|
225
|
+
editor: Z,
|
|
226
|
+
threads: Y,
|
|
227
|
+
onThreadsChange: X,
|
|
228
|
+
onRequestAddComment: $,
|
|
229
|
+
currentUser: H
|
|
230
230
|
})]
|
|
231
231
|
}),
|
|
232
|
-
|
|
233
|
-
editor:
|
|
234
|
-
aiConfig:
|
|
235
|
-
labels:
|
|
232
|
+
P && Se && /* @__PURE__ */ f(te, {
|
|
233
|
+
editor: Z,
|
|
234
|
+
aiConfig: P,
|
|
235
|
+
labels: B,
|
|
236
236
|
initialSelection: Ce,
|
|
237
237
|
selectionRange: Te,
|
|
238
|
-
|
|
238
|
+
followSelection: L,
|
|
239
|
+
onClose: () => U(!1)
|
|
239
240
|
}),
|
|
240
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ f(ie, {
|
|
241
242
|
open: ke,
|
|
242
|
-
onSubmit:
|
|
243
|
-
onClose: () =>
|
|
243
|
+
onSubmit: je,
|
|
244
|
+
onClose: () => K(!1)
|
|
244
245
|
})
|
|
245
246
|
]
|
|
246
247
|
});
|
|
247
248
|
};
|
|
248
249
|
//#endregion
|
|
249
|
-
export {
|
|
250
|
+
export { O as default };
|
|
250
251
|
|
|
251
252
|
//# sourceMappingURL=RichTextEditor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichTextEditor.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RichTextEditor.js","names":["Toolbar","AIRewrite","ContextMenu","CommentPanel","CommentDialog","CommentPopover","SlashMenu","BubbleToolbar","BlockHandle","FontSize","StarterKit","Underline","Color","Highlight","TextAlign","Link","TableRow","TableCell","TableHeader","Placeholder","TaskList","TaskItem","Subscript","Superscript","Typography","FontFamily","generateId","RichTextEditor","initialShowComments","externalThreads","formatPainterActive","setFormatPainterActive","useState","showAIPanel","setShowAIPanel","aiSelection","setAiSelection","aiSelectionRange","setAiSelectionRange","showComments","setShowComments","internalThreads","setInternalThreads","commentDialogOpen","setCommentDialogOpen","commentSelectionRange","setCommentSelectionRange","commentPanelRef","useRef","threads","setThreads","onCommentThreadsChange","editor","useEditor","TextStyle","ResizableImage","Table","CodeBlockExtension","FloatingDialogExtension","MarkdownBlockExtension","CommentMark","value","content","autofocus","onChange","onChangeJSON","useEffect","editorRef","editable","handleAIClick","useCallback","text","from","to","requestAddComment","handleCommentSubmit","id","thread","currentUser","handleScrollToThread","minH","minHeight","maxH","maxHeight","containerClass","cn","className","activeCommentCount","t","toolbarEnd","toolbarConfig","aiConfig","EditorContent","aiSelectionFollowsEditor"],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n aiSelectionFollowsEditor = false,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n followSelection={aiSelectionFollowsEditor}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlashMenu.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/SlashMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { ChainedCommands } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\n\ninterface SlashMenuItem {\n label: string;\n icon: string;\n description: string;\n action: (chain: ChainedCommands) => ChainedCommands;\n keywords?: string[];\n}\n\nconst SLASH_ITEMS: SlashMenuItem[] = [\n { label: 'Text', icon: 'Aa', description: 'Plain text', keywords: ['paragraph', 'text', 'plain'],\n action: (e) => e.setParagraph() },\n { label: 'Heading 1', icon: 'H1', description: 'Large heading', keywords: ['h1', 'title'],\n action: (e) => e.setHeading({ level: 1 }) },\n { label: 'Heading 2', icon: 'H2', description: 'Medium heading', keywords: ['h2', 'subtitle'],\n action: (e) => e.setHeading({ level: 2 }) },\n { label: 'Heading 3', icon: 'H3', description: 'Small heading', keywords: ['h3'],\n action: (e) => e.setHeading({ level: 3 }) },\n { label: 'Bullet List', icon: '•', description: 'Unordered list', keywords: ['ul', 'bullet', 'unordered'],\n action: (e) => e.toggleBulletList() },\n { label: 'Numbered List', icon: '1.', description: 'Ordered list', keywords: ['ol', 'ordered', 'number'],\n action: (e) => e.toggleOrderedList() },\n { label: 'Task List', icon: '☑', description: 'To-do list', keywords: ['todo', 'checkbox', 'task'],\n action: (e) => e.toggleTaskList() },\n { label: 'Blockquote', icon: '\"', description: 'Quote block', keywords: ['quote', 'blockquote'],\n action: (e) => e.toggleBlockquote() },\n { label: 'Code Block', icon: '</>', description: 'Code snippet', keywords: ['code', 'pre', 'snippet'],\n action: (e) => e.setNode('codeBlock') },\n { label: 'Divider', icon: '—', description: 'Horizontal rule', keywords: ['hr', 'divider', 'separator', 'line'],\n action: (e) => e.setHorizontalRule() },\n { label: 'Table', icon: '⊞', description: 'Insert 3×3 table', keywords: ['table', 'grid'],\n action: (e) => e.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) },\n { label: 'Image', icon: '🖼', description: 'Insert image by URL', keywords: ['image', 'picture', 'photo'],\n action: (e) => e},\n];\n\ninterface SlashRange {\n from: number;\n to: number;\n query: string;\n}\n\ninterface SlashMenuProps {\n editor: Editor;\n}\n\nconst SlashMenu: React.FC<SlashMenuProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [renderedRange, setRenderedRange] = useState<SlashRange | null>(null);\n const query = renderedRange?.query ?? '';\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [selected, setSelected] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n const activeRange = useRef<SlashRange | null>(null);\n const dismissed = useRef<string | null>(null);\n const composing = useRef(false);\n\n const getRange = useCallback(() => {\n if (editor.isDestroyed || !editor.isEditable || editor.view.composing || composing.current) return null;\n const selection = editor.state.selection;\n if (!(selection instanceof TextSelection) || !selection.empty || selection.$from.parent.type.spec.code || selection.$from.marks().some((mark) => mark.type.spec.code)) return null;\n const { $from } = selection;\n // textContent drops inline atoms and hard breaks, so its offsets are not document offsets.\n const text = $from.parent.textBetween(0, $from.parentOffset, '\\n', (node) => node.type.name === 'hardBreak' ? '\\n' : '\\ufffc');\n const match = /(?:^|\\s)\\/([^\\s/]*)$/.exec(text);\n if (!match) return null;\n return { from: $from.pos - match[1].length - 1, to: $from.pos, query: match[1] };\n }, [editor]);\n\n const filtered = query\n ? SLASH_ITEMS.filter((item) => {\n const q = query.toLowerCase();\n return item.label.toLowerCase().includes(q)\n || item.description.toLowerCase().includes(q)\n || item.keywords?.some((k) => k.includes(q));\n })\n : SLASH_ITEMS;\n\n const close = useCallback(() => {\n setVisible(false);\n setRenderedRange(null);\n const range = activeRange.current;\n if (range) dismissed.current = `${range.from}:${range.to}:${range.query}`;\n activeRange.current = null;\n setSelected(0);\n }, []);\n\n const executeItem = useCallback((item: SlashMenuItem) => {\n const range = getRange();\n const active = activeRange.current;\n // Transactions update the ref before React commits the new menu. An old\n // rendered action must not operate on that newer trigger/selection.\n if (!range || !active || !renderedRange\n || range.from !== renderedRange.from || range.to !== renderedRange.to || range.query !== renderedRange.query\n || range.from !== active.from || range.to !== active.to || range.query !== active.query) {\n close();\n return;\n }\n const url = item.label === 'Image' ? window.prompt('Image URL:')?.trim() : undefined;\n if (item.label === 'Image' && !url) { close(); return; }\n close();\n // Delete the trigger and insert/convert in one transaction (one undo step).\n const chain = editor.chain().focus().deleteRange(range);\n (url ? chain.setImage({ src: url }) : item.action(chain)).run();\n }, [editor, getRange, close, renderedRange]);\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handleUpdate = () => {\n const range = editor.isFocused ? getRange() : null;\n if (!range) {\n activeRange.current = null;\n dismissed.current = null;\n setVisible(false);\n return;\n }\n if (dismissed.current === `${range.from}:${range.to}:${range.query}`) return;\n if (activeRange.current?.query !== range.query || activeRange.current?.from !== range.from) setSelected(0);\n activeRange.current = range;\n setRenderedRange(range);\n setVisible(true);\n };\n const start = () => { composing.current = true; close(); };\n const end = () => {\n composing.current = false;\n dismissed.current = null;\n timer = setTimeout(handleUpdate, 0);\n };\n const dom = editor.view.dom;\n editor.on('transaction', handleUpdate);\n editor.on('blur', close);\n dom.addEventListener('compositionstart', start);\n dom.addEventListener('compositionend', end);\n return () => {\n clearTimeout(timer);\n editor.off('transaction', handleUpdate);\n editor.off('blur', close);\n dom.removeEventListener('compositionstart', start);\n dom.removeEventListener('compositionend', end);\n };\n }, [editor, getRange, close]);\n\n useLayoutEffect(() => {\n if (!visible || !filtered.length) return;\n const wrapper = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n const menu = menuRef.current;\n if (!wrapper || !menu) return;\n const place = () => {\n const range = getRange();\n if (!range) { close(); return; }\n const coords = editor.view.coordsAtPos(range.to);\n const rect = wrapper.getBoundingClientRect();\n const left = Math.max(8, rect.left + wrapper.clientLeft);\n const right = Math.min(window.innerWidth - 8, rect.right);\n const top = Math.max(8, rect.top + wrapper.clientTop);\n const bottom = Math.min(window.innerHeight - 8, rect.bottom);\n // Keep partially visible edge anchors usable, but never leave an\n // offscreen menu intercepting the editor's Enter/arrow keys.\n if (right <= left || bottom <= top || coords.bottom < top || coords.top > bottom) {\n close();\n return;\n }\n const anchorTop = Math.min(Math.max(coords.top, top), bottom);\n const anchorBottom = Math.min(Math.max(coords.bottom, top), bottom);\n menu.style.boxSizing = 'border-box';\n menu.style.minWidth = '0';\n menu.style.width = `${Math.min(280, right - left)}px`;\n const below = bottom - anchorBottom - 4;\n const above = anchorTop - top - 4;\n const flip = below < Math.min(300, menu.scrollHeight) && above > below;\n const availableHeight = flip ? above : below;\n if (availableHeight <= 0) { close(); return; }\n menu.style.maxHeight = `${Math.min(300, availableHeight)}px`;\n const x = Math.max(left, Math.min(coords.left, right - menu.offsetWidth));\n const y = flip ? anchorTop - menu.offsetHeight - 4 : anchorBottom + 4;\n setPos({ x: x - rect.left - wrapper.clientLeft + wrapper.scrollLeft,\n y: y - rect.top - wrapper.clientTop + wrapper.scrollTop });\n };\n place();\n window.addEventListener('scroll', place, true);\n window.addEventListener('resize', place);\n editor.on('transaction', place);\n return () => {\n window.removeEventListener('scroll', place, true);\n window.removeEventListener('resize', place);\n editor.off('transaction', place);\n };\n }, [editor, visible, filtered.length, getRange, close]);\n\n useEffect(() => {\n if (!visible) return;\n const menu = menuRef.current;\n const item = menu?.children[selected] as HTMLElement | undefined;\n if (!menu || !item) return;\n if (item.offsetTop < menu.scrollTop) menu.scrollTop = item.offsetTop;\n else if (item.offsetTop + item.offsetHeight > menu.scrollTop + menu.clientHeight) {\n menu.scrollTop = item.offsetTop + item.offsetHeight - menu.clientHeight;\n }\n }, [selected, visible]);\n\n useEffect(() => {\n if (!visible) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!editor.view.dom.contains(e.target as Node) || !editor.isFocused || e.isComposing || e.keyCode === 229 || editor.view.composing || composing.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;\n if (!filtered.length && e.key !== 'Escape') return;\n if (['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.key)) e.stopImmediatePropagation();\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelected((s) => (s + 1) % filtered.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelected((s) => (s - 1 + filtered.length) % filtered.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filtered[selected]) executeItem(filtered[selected]);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n document.addEventListener('keydown', handleKeyDown, true);\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }, [editor, visible, filtered, selected, executeItem, close]);\n\n useEffect(() => {\n if (!visible) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) close();\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [visible, close]);\n\n if (!visible || filtered.length === 0) return null;\n\n return (\n <div ref={menuRef} className=\"rte-slash-menu\" role=\"menu\" aria-label=\"Insert block\" style={{ left: pos.x, top: pos.y }} onMouseDown={(e) => e.preventDefault()}>\n {filtered.map((item, i) => (\n <button\n key={item.label}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className={`rte-slash-menu__item ${i === selected ? 'rte-slash-menu__item--active' : ''}`}\n onClick={() => executeItem(item)}\n onMouseEnter={() => setSelected(i)}\n >\n <span className=\"rte-slash-menu__icon\">{item.icon}</span>\n <div className=\"rte-slash-menu__text\">\n <span className=\"rte-slash-menu__label\">{item.label}</span>\n <span className=\"rte-slash-menu__desc\">{item.description}</span>\n </div>\n </button>\n ))}\n </div>\n );\n};\n\nexport default SlashMenu;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SlashMenu.js","names":["SLASH_ITEMS","SlashMenu","visible","setVisible","useState","renderedRange","setRenderedRange","query","pos","setPos","selected","setSelected","menuRef","useRef","activeRange","dismissed","composing","getRange","useCallback","editor","selection","TextSelection","mark","text","$from","node","match","filtered","q","item","k","close","range","executeItem","active","url","chain","useEffect","timer","handleUpdate","start","end","dom","useLayoutEffect","wrapper","menu","place","coords","rect","left","right","top","bottom","anchorTop","anchorBottom","below","above","flip","availableHeight","x","y","handleKeyDown","s","handler","i"],"sources":["../../../../src/components/pro/RichTextEditor/SlashMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { ChainedCommands } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\n\ninterface SlashMenuItem {\n label: string;\n icon: string;\n description: string;\n action: (chain: ChainedCommands) => ChainedCommands;\n keywords?: string[];\n}\n\nconst SLASH_ITEMS: SlashMenuItem[] = [\n { label: 'Text', icon: 'Aa', description: 'Plain text', keywords: ['paragraph', 'text', 'plain'],\n action: (e) => e.setParagraph() },\n { label: 'Heading 1', icon: 'H1', description: 'Large heading', keywords: ['h1', 'title'],\n action: (e) => e.setHeading({ level: 1 }) },\n { label: 'Heading 2', icon: 'H2', description: 'Medium heading', keywords: ['h2', 'subtitle'],\n action: (e) => e.setHeading({ level: 2 }) },\n { label: 'Heading 3', icon: 'H3', description: 'Small heading', keywords: ['h3'],\n action: (e) => e.setHeading({ level: 3 }) },\n { label: 'Bullet List', icon: '•', description: 'Unordered list', keywords: ['ul', 'bullet', 'unordered'],\n action: (e) => e.toggleBulletList() },\n { label: 'Numbered List', icon: '1.', description: 'Ordered list', keywords: ['ol', 'ordered', 'number'],\n action: (e) => e.toggleOrderedList() },\n { label: 'Task List', icon: '☑', description: 'To-do list', keywords: ['todo', 'checkbox', 'task'],\n action: (e) => e.toggleTaskList() },\n { label: 'Blockquote', icon: '\"', description: 'Quote block', keywords: ['quote', 'blockquote'],\n action: (e) => e.toggleBlockquote() },\n { label: 'Code Block', icon: '</>', description: 'Code snippet', keywords: ['code', 'pre', 'snippet'],\n action: (e) => e.setNode('codeBlock') },\n { label: 'Divider', icon: '—', description: 'Horizontal rule', keywords: ['hr', 'divider', 'separator', 'line'],\n action: (e) => e.setHorizontalRule() },\n { label: 'Table', icon: '⊞', description: 'Insert 3×3 table', keywords: ['table', 'grid'],\n action: (e) => e.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) },\n { label: 'Image', icon: '🖼', description: 'Insert image by URL', keywords: ['image', 'picture', 'photo'],\n action: (e) => e},\n];\n\ninterface SlashRange {\n from: number;\n to: number;\n query: string;\n}\n\ninterface SlashMenuProps {\n editor: Editor;\n}\n\nconst SlashMenu: React.FC<SlashMenuProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [renderedRange, setRenderedRange] = useState<SlashRange | null>(null);\n const query = renderedRange?.query ?? '';\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [selected, setSelected] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n const activeRange = useRef<SlashRange | null>(null);\n const dismissed = useRef<string | null>(null);\n const composing = useRef(false);\n\n const getRange = useCallback(() => {\n if (editor.isDestroyed || !editor.isEditable || editor.view.composing || composing.current) return null;\n const selection = editor.state.selection;\n if (!(selection instanceof TextSelection) || !selection.empty || selection.$from.parent.type.spec.code || selection.$from.marks().some((mark) => mark.type.spec.code)) return null;\n const { $from } = selection;\n // textContent drops inline atoms and hard breaks, so its offsets are not document offsets.\n const text = $from.parent.textBetween(0, $from.parentOffset, '\\n', (node) => node.type.name === 'hardBreak' ? '\\n' : '\\ufffc');\n const match = /(?:^|\\s)\\/([^\\s/]*)$/.exec(text);\n if (!match) return null;\n return { from: $from.pos - match[1].length - 1, to: $from.pos, query: match[1] };\n }, [editor]);\n\n const filtered = query\n ? SLASH_ITEMS.filter((item) => {\n const q = query.toLowerCase();\n return item.label.toLowerCase().includes(q)\n || item.description.toLowerCase().includes(q)\n || item.keywords?.some((k) => k.includes(q));\n })\n : SLASH_ITEMS;\n\n const close = useCallback(() => {\n setVisible(false);\n setRenderedRange(null);\n const range = activeRange.current;\n if (range) dismissed.current = `${range.from}:${range.to}:${range.query}`;\n activeRange.current = null;\n setSelected(0);\n }, []);\n\n const executeItem = useCallback((item: SlashMenuItem) => {\n const range = getRange();\n const active = activeRange.current;\n // Transactions update the ref before React commits the new menu. An old\n // rendered action must not operate on that newer trigger/selection.\n if (!range || !active || !renderedRange\n || range.from !== renderedRange.from || range.to !== renderedRange.to || range.query !== renderedRange.query\n || range.from !== active.from || range.to !== active.to || range.query !== active.query) {\n close();\n return;\n }\n const url = item.label === 'Image' ? window.prompt('Image URL:')?.trim() : undefined;\n if (item.label === 'Image' && !url) { close(); return; }\n close();\n // Delete the trigger and insert/convert in one transaction (one undo step).\n const chain = editor.chain().focus().deleteRange(range);\n (url ? chain.setImage({ src: url }) : item.action(chain)).run();\n }, [editor, getRange, close, renderedRange]);\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handleUpdate = () => {\n const range = editor.isFocused ? getRange() : null;\n if (!range) {\n activeRange.current = null;\n dismissed.current = null;\n setVisible(false);\n return;\n }\n if (dismissed.current === `${range.from}:${range.to}:${range.query}`) return;\n if (activeRange.current?.query !== range.query || activeRange.current?.from !== range.from) setSelected(0);\n activeRange.current = range;\n setRenderedRange(range);\n setVisible(true);\n };\n const start = () => { composing.current = true; close(); };\n const end = () => {\n composing.current = false;\n dismissed.current = null;\n timer = setTimeout(handleUpdate, 0);\n };\n const dom = editor.view.dom;\n editor.on('transaction', handleUpdate);\n editor.on('blur', close);\n dom.addEventListener('compositionstart', start);\n dom.addEventListener('compositionend', end);\n return () => {\n clearTimeout(timer);\n editor.off('transaction', handleUpdate);\n editor.off('blur', close);\n dom.removeEventListener('compositionstart', start);\n dom.removeEventListener('compositionend', end);\n };\n }, [editor, getRange, close]);\n\n useLayoutEffect(() => {\n if (!visible || !filtered.length) return;\n const wrapper = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n const menu = menuRef.current;\n if (!wrapper || !menu) return;\n const place = () => {\n const range = getRange();\n if (!range) { close(); return; }\n const coords = editor.view.coordsAtPos(range.to);\n const rect = wrapper.getBoundingClientRect();\n const left = Math.max(8, rect.left + wrapper.clientLeft);\n const right = Math.min(window.innerWidth - 8, rect.right);\n const top = Math.max(8, rect.top + wrapper.clientTop);\n const bottom = Math.min(window.innerHeight - 8, rect.bottom);\n // Keep partially visible edge anchors usable, but never leave an\n // offscreen menu intercepting the editor's Enter/arrow keys.\n if (right <= left || bottom <= top || coords.bottom < top || coords.top > bottom) {\n close();\n return;\n }\n const anchorTop = Math.min(Math.max(coords.top, top), bottom);\n const anchorBottom = Math.min(Math.max(coords.bottom, top), bottom);\n menu.style.boxSizing = 'border-box';\n menu.style.minWidth = '0';\n menu.style.width = `${Math.min(280, right - left)}px`;\n const below = bottom - anchorBottom - 4;\n const above = anchorTop - top - 4;\n const flip = below < Math.min(300, menu.scrollHeight) && above > below;\n const availableHeight = flip ? above : below;\n if (availableHeight <= 0) { close(); return; }\n menu.style.maxHeight = `${Math.min(300, availableHeight)}px`;\n const x = Math.max(left, Math.min(coords.left, right - menu.offsetWidth));\n const y = flip ? anchorTop - menu.offsetHeight - 4 : anchorBottom + 4;\n setPos({ x: x - rect.left - wrapper.clientLeft + wrapper.scrollLeft,\n y: y - rect.top - wrapper.clientTop + wrapper.scrollTop });\n };\n place();\n window.addEventListener('scroll', place, true);\n window.addEventListener('resize', place);\n editor.on('transaction', place);\n return () => {\n window.removeEventListener('scroll', place, true);\n window.removeEventListener('resize', place);\n editor.off('transaction', place);\n };\n }, [editor, visible, filtered.length, getRange, close]);\n\n useEffect(() => {\n if (!visible) return;\n const menu = menuRef.current;\n const item = menu?.children[selected] as HTMLElement | undefined;\n if (!menu || !item) return;\n if (item.offsetTop < menu.scrollTop) menu.scrollTop = item.offsetTop;\n else if (item.offsetTop + item.offsetHeight > menu.scrollTop + menu.clientHeight) {\n menu.scrollTop = item.offsetTop + item.offsetHeight - menu.clientHeight;\n }\n }, [selected, visible]);\n\n useEffect(() => {\n if (!visible) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!editor.view.dom.contains(e.target as Node) || !editor.isFocused || e.isComposing || e.keyCode === 229 || editor.view.composing || composing.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;\n if (!filtered.length && e.key !== 'Escape') return;\n if (['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.key)) e.stopImmediatePropagation();\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelected((s) => (s + 1) % filtered.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelected((s) => (s - 1 + filtered.length) % filtered.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filtered[selected]) executeItem(filtered[selected]);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n document.addEventListener('keydown', handleKeyDown, true);\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }, [editor, visible, filtered, selected, executeItem, close]);\n\n useEffect(() => {\n if (!visible) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) close();\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [visible, close]);\n\n if (!visible || filtered.length === 0) return null;\n\n return (\n <div ref={menuRef} className=\"rte-slash-menu\" role=\"menu\" aria-label=\"Insert block\" style={{ left: pos.x, top: pos.y }} onMouseDown={(e) => e.preventDefault()}>\n {filtered.map((item, i) => (\n <button\n key={item.label}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className={`rte-slash-menu__item ${i === selected ? 'rte-slash-menu__item--active' : ''}`}\n onClick={() => executeItem(item)}\n onMouseEnter={() => setSelected(i)}\n >\n <span className=\"rte-slash-menu__icon\">{item.icon}</span>\n <div className=\"rte-slash-menu__text\">\n <span className=\"rte-slash-menu__label\">{item.label}</span>\n <span className=\"rte-slash-menu__desc\">{item.description}</span>\n </div>\n </button>\n ))}\n </div>\n );\n};\n\nexport default SlashMenu;\n"],"mappings":";;;;AAaA,IAAMA,IAA+B;CACnC;EAAE,OAAO;EAAQ,MAAM;EAAM,aAAa;EAAc,UAAU;GAAC;GAAa;GAAQ;EAAO;EAC7F,SAAS,MAAM,EAAE,aAAa;CAAE;CAClC;EAAE,OAAO;EAAa,MAAM;EAAM,aAAa;EAAiB,UAAU,CAAC,MAAM,OAAO;EACtF,SAAS,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;CAAE;CAC5C;EAAE,OAAO;EAAa,MAAM;EAAM,aAAa;EAAkB,UAAU,CAAC,MAAM,UAAU;EAC1F,SAAS,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;CAAE;CAC5C;EAAE,OAAO;EAAa,MAAM;EAAM,aAAa;EAAiB,UAAU,CAAC,IAAI;EAC7E,SAAS,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;CAAE;CAC5C;EAAE,OAAO;EAAe,MAAM;EAAK,aAAa;EAAkB,UAAU;GAAC;GAAM;GAAU;EAAW;EACtG,SAAS,MAAM,EAAE,iBAAiB;CAAE;CACtC;EAAE,OAAO;EAAiB,MAAM;EAAM,aAAa;EAAgB,UAAU;GAAC;GAAM;GAAW;EAAQ;EACrG,SAAS,MAAM,EAAE,kBAAkB;CAAE;CACvC;EAAE,OAAO;EAAa,MAAM;EAAK,aAAa;EAAc,UAAU;GAAC;GAAQ;GAAY;EAAM;EAC/F,SAAS,MAAM,EAAE,eAAe;CAAE;CACpC;EAAE,OAAO;EAAc,MAAM;EAAK,aAAa;EAAe,UAAU,CAAC,SAAS,YAAY;EAC5F,SAAS,MAAM,EAAE,iBAAiB;CAAE;CACtC;EAAE,OAAO;EAAc,MAAM;EAAO,aAAa;EAAgB,UAAU;GAAC;GAAQ;GAAO;EAAS;EAClG,SAAS,MAAM,EAAE,QAAQ,WAAW;CAAE;CACxC;EAAE,OAAO;EAAW,MAAM;EAAK,aAAa;EAAmB,UAAU;GAAC;GAAM;GAAW;GAAa;EAAM;EAC5G,SAAS,MAAM,EAAE,kBAAkB;CAAE;CACvC;EAAE,OAAO;EAAS,MAAM;EAAK,aAAa;EAAoB,UAAU,CAAC,SAAS,MAAM;EACtF,SAAS,MAAM,EAAE,YAAY;GAAE,MAAM;GAAG,MAAM;GAAG,eAAe;EAAK,CAAC;CAAE;CAC1E;EAAE,OAAO;EAAS,MAAM;EAAM,aAAa;EAAuB,UAAU;GAAC;GAAS;GAAW;EAAO;EACtG,SAAS,MAAM;CAAC;AACpB,GAYMC,KAAuC,EAAE,gBAAa;CAC1D,IAAM,CAACC,GAASC,KAAcC,EAAS,EAAK,GACtC,CAACC,GAAeC,KAAoBF,EAA4B,IAAI,GACpEG,IAAQF,GAAe,SAAS,IAChC,CAACG,GAAKC,KAAUL,EAAS;EAAE,GAAG;EAAG,GAAG;CAAE,CAAC,GACvC,CAACM,GAAUC,KAAeP,EAAS,CAAC,GACpCQ,IAAUC,EAAuB,IAAI,GACrCC,IAAcD,EAA0B,IAAI,GAC5CE,IAAYF,EAAsB,IAAI,GACtCG,IAAYH,EAAO,EAAK,GAExBI,IAAWC,QAAkB;EACjC,IAAIC,EAAO,eAAe,CAACA,EAAO,cAAcA,EAAO,KAAK,aAAaH,EAAU,SAAS,OAAO;EACnG,IAAMI,IAAYD,EAAO,MAAM;EAC/B,IAAI,EAAEC,aAAqBC,MAAkB,CAACD,EAAU,SAASA,EAAU,MAAM,OAAO,KAAK,KAAK,QAAQA,EAAU,MAAM,MAAM,CAAC,CAAC,MAAM,MAASE,EAAK,KAAK,KAAK,IAAI,GAAG,OAAO;EAC9K,IAAM,EAAE,aAAUF,GAEZG,IAAOC,EAAM,OAAO,YAAY,GAAGA,EAAM,cAAc,OAAO,MAASC,EAAK,KAAK,SAAS,cAAc,OAAO,GAAQ,GACvHC,IAAQ,uBAAuB,KAAKH,CAAI;EAE9C,OADKG,IACE;GAAE,MAAMF,EAAM,MAAME,EAAM,EAAE,CAAC,SAAS;GAAG,IAAIF,EAAM;GAAK,OAAOE,EAAM;EAAG,IAD5D;CAErB,GAAG,CAACP,CAAM,CAAC,GAELQ,IAAWpB,IACbP,EAAY,QAAQ,MAAS;EAC3B,IAAM4B,IAAIrB,EAAM,YAAY;EAC5B,OAAOsB,EAAK,MAAM,YAAY,CAAC,CAAC,SAASD,CAAC,KACrCC,EAAK,YAAY,YAAY,CAAC,CAAC,SAASD,CAAC,KACzCC,EAAK,UAAU,MAAM,MAAMC,EAAE,SAASF,CAAC,CAAC;CAC/C,CAAC,IACD5B,GAEE+B,IAAQb,QAAkB;EAE9B,AADAf,EAAW,EAAK,GAChBG,EAAiB,IAAI;EACrB,IAAM0B,IAAQlB,EAAY;EAG1B,AAFIkB,MAAO,EAAU,UAAU,GAAGA,EAAM,KAAK,GAAGA,EAAM,GAAG,GAAGA,EAAM,UAClE,EAAY,UAAU,MACtBrB,EAAY,CAAC;CACf,GAAG,CAAC,CAAC,GAECsB,IAAcf,GAAa,MAAwB;EACvD,IAAMc,IAAQf,EAAS,GACjBiB,IAASpB,EAAY;EAG3B,IAAI,CAACkB,KAAS,CAACE,KAAU,CAAC7B,KACrB2B,EAAM,SAAS3B,EAAc,QAAQ2B,EAAM,OAAO3B,EAAc,MAAM2B,EAAM,UAAU3B,EAAc,SACpG2B,EAAM,SAASE,EAAO,QAAQF,EAAM,OAAOE,EAAO,MAAMF,EAAM,UAAUE,EAAO,OAAO;GACzF,EAAM;GACN;EACF;EACA,IAAMC,IAAMN,EAAK,UAAU,UAAU,OAAO,OAAO,YAAY,CAAC,EAAE,KAAK,IAAI,KAAA;EAC3E,IAAIA,EAAK,UAAU,WAAW,CAACM,GAAK;GAAE,EAAM;GAAG;EAAQ;EACvD,EAAM;EAEN,IAAMC,IAAQjB,EAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,YAAYa,CAAK;EACtD,CAACG,IAAMC,EAAM,SAAS,EAAE,KAAKD,EAAI,CAAC,IAAIN,EAAK,OAAOO,CAAK,EAAA,CAAG,IAAI;CAChE,GAAG;EAACjB;EAAQF;EAAUc;EAAO1B;CAAa,CAAC;CAmI3C,OAjIAgC,QAAgB;EACd,IAAIC,GACEC,UAAqB;GACzB,IAAMP,IAAQb,EAAO,YAAYF,EAAS,IAAI;GAC9C,IAAI,CAACe,GAAO;IAGV,AAFA,EAAY,UAAU,MACtB,EAAU,UAAU,MACpB7B,EAAW,EAAK;IAChB;GACF;GACA,AAAIY,EAAU,YAAY,GAAGiB,EAAM,KAAK,GAAGA,EAAM,GAAG,GAAGA,EAAM,aACzDlB,EAAY,SAAS,UAAUkB,EAAM,SAASlB,EAAY,SAAS,SAASkB,EAAM,SAAMrB,EAAY,CAAC,GACzG,EAAY,UAAUqB,GACtB1B,EAAiB0B,CAAK,GACtB7B,EAAW,EAAI;EACjB,GACMqC,UAAc;GAA4B,AAA1B,EAAU,UAAU,IAAMT,EAAM;EAAG,GACnDU,UAAY;GAGhB,AAFA,EAAU,UAAU,IACpB,EAAU,UAAU,MACpB,IAAQ,WAAWF,GAAc,CAAC;EACpC,GACMG,IAAMvB,EAAO,KAAK;EAKxB,OAJAA,EAAO,GAAG,eAAeoB,CAAY,GACrCpB,EAAO,GAAG,QAAQY,CAAK,GACvBW,EAAI,iBAAiB,oBAAoBF,CAAK,GAC9CE,EAAI,iBAAiB,kBAAkBD,CAAG,SAC7B;GAKX,AAJA,aAAaH,CAAK,GAClBnB,EAAO,IAAI,eAAeoB,CAAY,GACtCpB,EAAO,IAAI,QAAQY,CAAK,GACxBW,EAAI,oBAAoB,oBAAoBF,CAAK,GACjDE,EAAI,oBAAoB,kBAAkBD,CAAG;EAC/C;CACF,GAAG;EAACtB;EAAQF;EAAUc;CAAK,CAAC,GAE5BY,QAAsB;EACpB,IAAI,CAACzC,KAAW,CAACyB,EAAS,QAAQ;EAClC,IAAMiB,IAAUzB,EAAO,KAAK,IAAI,QAAQ,qBAAqB,GACvD0B,IAAOjC,EAAQ;EACrB,IAAI,CAACgC,KAAW,CAACC,GAAM;EACvB,IAAMC,UAAc;GAClB,IAAMd,IAAQf,EAAS;GACvB,IAAI,CAACe,GAAO;IAAE,EAAM;IAAG;GAAQ;GAC/B,IAAMe,IAAS5B,EAAO,KAAK,YAAYa,EAAM,EAAE,GACzCgB,IAAOJ,EAAQ,sBAAsB,GACrCK,IAAO,KAAK,IAAI,GAAGD,EAAK,OAAOJ,EAAQ,UAAU,GACjDM,IAAQ,KAAK,IAAI,OAAO,aAAa,GAAGF,EAAK,KAAK,GAClDG,IAAM,KAAK,IAAI,GAAGH,EAAK,MAAMJ,EAAQ,SAAS,GAC9CQ,IAAS,KAAK,IAAI,OAAO,cAAc,GAAGJ,EAAK,MAAM;GAG3D,IAAIE,KAASD,KAAQG,KAAUD,KAAOJ,EAAO,SAASI,KAAOJ,EAAO,MAAMK,GAAQ;IAChF,EAAM;IACN;GACF;GACA,IAAMC,IAAY,KAAK,IAAI,KAAK,IAAIN,EAAO,KAAKI,CAAG,GAAGC,CAAM,GACtDE,IAAe,KAAK,IAAI,KAAK,IAAIP,EAAO,QAAQI,CAAG,GAAGC,CAAM;GAGlE,AAFA,EAAK,MAAM,YAAY,cACvB,EAAK,MAAM,WAAW,KACtB,EAAK,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAKF,IAAQD,CAAI,EAAE;GAClD,IAAMM,IAAQH,IAASE,IAAe,GAChCE,IAAQH,IAAYF,IAAM,GAC1BM,IAAOF,IAAQ,KAAK,IAAI,KAAKV,EAAK,YAAY,KAAKW,IAAQD,GAC3DG,IAAkBD,IAAOD,IAAQD;GACvC,IAAIG,KAAmB,GAAG;IAAE,EAAM;IAAG;GAAQ;GAC7C,EAAK,MAAM,YAAY,GAAG,KAAK,IAAI,KAAKA,CAAe,EAAE;GACzD,IAAMC,IAAI,KAAK,IAAIV,GAAM,KAAK,IAAIF,EAAO,MAAMG,IAAQL,EAAK,WAAW,CAAC,GAClEe,IAAIH,IAAOJ,IAAYR,EAAK,eAAe,IAAIS,IAAe;GACpE,EAAO;IAAE,GAAGK,IAAIX,EAAK,OAAOJ,EAAQ,aAAaA,EAAQ;IACvD,GAAGgB,IAAIZ,EAAK,MAAMJ,EAAQ,YAAYA,EAAQ;GAAU,CAAC;EAC7D;EAKA,OAJAE,EAAM,GACN,OAAO,iBAAiB,UAAUA,GAAO,EAAI,GAC7C,OAAO,iBAAiB,UAAUA,CAAK,GACvC3B,EAAO,GAAG,eAAe2B,CAAK,SACjB;GAGX,AAFA,OAAO,oBAAoB,UAAUA,GAAO,EAAI,GAChD,OAAO,oBAAoB,UAAUA,CAAK,GAC1C3B,EAAO,IAAI,eAAe2B,CAAK;EACjC;CACF,GAAG;EAAC3B;EAAQjB;EAASyB,EAAS;EAAQV;EAAUc;CAAK,CAAC,GAEtDM,QAAgB;EACd,IAAI,CAACnC,GAAS;EACd,IAAM2C,IAAOjC,EAAQ,SACfiB,IAAOgB,GAAM,SAASnC;EAC5B,AAAKmC,KAAShB,MACVA,EAAK,YAAYgB,EAAK,YAAW,EAAK,YAAYhB,EAAK,YAClDA,EAAK,YAAYA,EAAK,eAAegB,EAAK,YAAYA,EAAK,iBAClE,EAAK,YAAYhB,EAAK,YAAYA,EAAK,eAAegB,EAAK;CAE/D,GAAG,CAACnC,GAAUR,CAAO,CAAC,GAEtBmC,QAAgB;EACd,IAAI,CAACnC,GAAS;EACd,IAAM2D,KAAiB,MAAqB;GAC1C,AAAI,CAAC1C,EAAO,KAAK,IAAI,SAAS,EAAE,MAAc,KAAK,CAACA,EAAO,aAAa,EAAE,eAAe,EAAE,YAAY,OAAOA,EAAO,KAAK,aAAaH,EAAU,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,aAC/LW,EAAS,UAAU,EAAE,QAAQ,cAC9B;IAAC;IAAa;IAAW;IAAS;GAAQ,CAAC,CAAC,SAAS,EAAE,GAAG,KAAG,EAAE,yBAAyB,GACxF,EAAE,QAAQ,eACZ,EAAE,eAAe,GACjBhB,GAAa,OAAOmD,IAAI,KAAKnC,EAAS,MAAM,KACnC,EAAE,QAAQ,aACnB,EAAE,eAAe,GACjBhB,GAAa,OAAOmD,IAAI,IAAInC,EAAS,UAAUA,EAAS,MAAM,KACrD,EAAE,QAAQ,WACnB,EAAE,eAAe,GACbA,EAASjB,MAAWuB,EAAYN,EAASjB,EAAS,KAC7C,EAAE,QAAQ,aACnB,EAAE,eAAe,GACjBqB,EAAM;EAEV;EAEA,OADA,SAAS,iBAAiB,WAAW8B,GAAe,EAAI,SAC3C,SAAS,oBAAoB,WAAWA,GAAe,EAAI;CAC1E,GAAG;EAAC1C;EAAQjB;EAASyB;EAAUjB;EAAUuB;EAAaF;CAAK,CAAC,GAE5DM,QAAgB;EACd,IAAI,CAACnC,GAAS;EACd,IAAM6D,KAAW,MAAkB;GACjC,AAAInD,EAAQ,WAAW,CAACA,EAAQ,QAAQ,SAAS,EAAE,MAAc,KAAGmB,EAAM;EAC5E;EAEA,OADA,SAAS,iBAAiB,aAAagC,CAAO,SACjC,SAAS,oBAAoB,aAAaA,CAAO;CAChE,GAAG,CAAC7D,GAAS6B,CAAK,CAAC,GAEf,CAAC7B,KAAWyB,EAAS,WAAW,IAAU,OAG5C,kBAAC,OAAD;EAAK,KAAKf;EAAS,WAAU;EAAiB,MAAK;EAAO,cAAW;EAAe,OAAO;GAAE,MAAMJ,EAAI;GAAG,KAAKA,EAAI;EAAE;EAAG,cAAc,MAAM,EAAE,eAAe;EAC1J,UAAAmB,EAAS,KAAK,GAAM,MACnB,kBAAC,UAAD;GAEE,MAAK;GACL,MAAK;GACL,UAAU;GACV,WAAW,wBAAwBqC,MAAMtD,IAAW,iCAAiC;GACrF,eAAeuB,EAAYJ,CAAI;GAC/B,oBAAoBlB,EAAYqD,CAAC;GAPnC,UAAA,CASE,kBAAC,QAAD;IAAM,WAAU;IAAwB,UAAAnC,EAAK;GAAW,CAAA,GACxD,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,QAAD;KAAM,WAAU;KAAyB,UAAAA,EAAK;IAAY,CAAA,GAC1D,kBAAC,QAAD;KAAM,WAAU;KAAwB,UAAAA,EAAK;IAAkB,CAAA,CAC5D;GACC,CAAA,CAAA;EAbD,GAAAA,EAAK,KAaJ,CACT;CACE,CAAA;AAET"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPicker.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon?: React.ReactNode;\n kind?: 'text' | 'highlight';\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n /** Portals the palette outside scroll-clipped bubble toolbars. */\n portalOwner?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, kind = 'text', buttonClassName = 'rte-toolbar__btn', portalOwner }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [paletteTheme, setPaletteTheme] = useState<React.CSSProperties>({});\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const paletteRef = useRef<HTMLDivElement>(null);\n const paletteId = useId();\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, paletteRef);\n const label = title || (kind === 'text' ? 'Text color' : 'Highlight color');\n const description = `${label}: ${value || (kind === 'text' ? 'Default' : 'None')}`;\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node) && !paletteRef.current?.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [ref, paletteRef]);\n\n const palette = isOpen && (\n <div ref={paletteRef} id={paletteId} data-rte-palette-owner={portalOwner}\n className=\"rte-toolbar__color-dropdown\" role=\"group\" aria-label={label}\n style={{ ...dropdownStyle, ...paletteTheme }}>\n {COLORS.map((color) => (\n <button key={color} type=\"button\"\n className={`rte-toolbar__color-swatch ${color === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: color }}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(color); setIsOpen(false); }}\n title={`${label}: ${color}`} aria-label={`${label}: ${color}`}\n aria-pressed={color.toLowerCase() === value.toLowerCase()} />\n ))}\n <button type=\"button\" className=\"rte-toolbar__color-clear\"\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(''); setIsOpen(false); }}\n title={`Clear ${label}`} aria-label={`Clear ${label}`} aria-pressed={!value}>Clear</button>\n </div>\n );\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !paletteRef.current?.contains(event.relatedTarget)) setIsOpen(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault();\n event.stopPropagation();\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`${buttonClassName} rte-toolbar__color-trigger`}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={event => {\n if (portalOwner && !isOpen) {\n const computed = getComputedStyle(event.currentTarget);\n const variables: Record<string, string> = {};\n for (const name of ['--rte-bg', '--rte-text', '--rte-border', '--rte-placeholder', '--rte-active-color', '--rte-toolbar-btn-hover']) {\n variables[name] = computed.getPropertyValue(name);\n }\n setPaletteTheme(variables);\n }\n setIsOpen(!isOpen);\n }}\n title={description}\n aria-label={description}\n aria-expanded={isOpen}\n aria-controls={isOpen ? paletteId : undefined}\n >\n <span className={`rte-toolbar__color-icon rte-toolbar__color-icon--${kind}`} aria-hidden=\"true\">\n {icon || (kind === 'text' ? <span className=\"rte-toolbar__color-letter\">A</span> : (\n <svg width=\"18\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6\" />\n </svg>\n ))}\n <span\n className={`rte-toolbar__color-indicator${value ? '' : ' rte-toolbar__color-indicator--empty'}`}\n style={{ backgroundColor: value || undefined }}\n />\n </span>\n </button>\n {portalOwner && typeof document !== 'undefined' ? createPortal(palette, document.body) : palette}\n </div>\n );\n};\n"],"mappings":";;;;;AAgBA,
|
|
1
|
+
{"version":3,"file":"ColorPicker.js","names":["COLORS","ColorPicker","isOpen","setIsOpen","useState","paletteTheme","setPaletteTheme","ref","useRef","triggerRef","paletteRef","paletteId","useId","dropdownStyle","useAnchoredDropdown","label","title","kind","description","value","handler","palette","portalOwner","color","event","onChange","buttonClassName","computed","variables","name","icon","createPortal"],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon?: React.ReactNode;\n kind?: 'text' | 'highlight';\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n /** Portals the palette outside scroll-clipped bubble toolbars. */\n portalOwner?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, kind = 'text', buttonClassName = 'rte-toolbar__btn', portalOwner }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [paletteTheme, setPaletteTheme] = useState<React.CSSProperties>({});\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const paletteRef = useRef<HTMLDivElement>(null);\n const paletteId = useId();\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, paletteRef);\n const label = title || (kind === 'text' ? 'Text color' : 'Highlight color');\n const description = `${label}: ${value || (kind === 'text' ? 'Default' : 'None')}`;\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node) && !paletteRef.current?.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [ref, paletteRef]);\n\n const palette = isOpen && (\n <div ref={paletteRef} id={paletteId} data-rte-palette-owner={portalOwner}\n className=\"rte-toolbar__color-dropdown\" role=\"group\" aria-label={label}\n style={{ ...dropdownStyle, ...paletteTheme }}>\n {COLORS.map((color) => (\n <button key={color} type=\"button\"\n className={`rte-toolbar__color-swatch ${color === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: color }}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(color); setIsOpen(false); }}\n title={`${label}: ${color}`} aria-label={`${label}: ${color}`}\n aria-pressed={color.toLowerCase() === value.toLowerCase()} />\n ))}\n <button type=\"button\" className=\"rte-toolbar__color-clear\"\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(''); setIsOpen(false); }}\n title={`Clear ${label}`} aria-label={`Clear ${label}`} aria-pressed={!value}>Clear</button>\n </div>\n );\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !paletteRef.current?.contains(event.relatedTarget)) setIsOpen(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault();\n event.stopPropagation();\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`${buttonClassName} rte-toolbar__color-trigger`}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={event => {\n if (portalOwner && !isOpen) {\n const computed = getComputedStyle(event.currentTarget);\n const variables: Record<string, string> = {};\n for (const name of ['--rte-bg', '--rte-text', '--rte-border', '--rte-placeholder', '--rte-active-color', '--rte-toolbar-btn-hover']) {\n variables[name] = computed.getPropertyValue(name);\n }\n setPaletteTheme(variables);\n }\n setIsOpen(!isOpen);\n }}\n title={description}\n aria-label={description}\n aria-expanded={isOpen}\n aria-controls={isOpen ? paletteId : undefined}\n >\n <span className={`rte-toolbar__color-icon rte-toolbar__color-icon--${kind}`} aria-hidden=\"true\">\n {icon || (kind === 'text' ? <span className=\"rte-toolbar__color-letter\">A</span> : (\n <svg width=\"18\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6\" />\n </svg>\n ))}\n <span\n className={`rte-toolbar__color-indicator${value ? '' : ' rte-toolbar__color-indicator--empty'}`}\n style={{ backgroundColor: value || undefined }}\n />\n </span>\n </button>\n {portalOwner && typeof document !== 'undefined' ? createPortal(palette, document.body) : palette}\n </div>\n );\n};\n"],"mappings":"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"}
|