From 30b68123246ae49c3f582dcd45606a3d62c91dec Mon Sep 17 00:00:00 2001 From: zbeyens Date: Fri, 20 Dec 2024 01:28:25 +0100 Subject: [PATCH] docs --- .../(app)/_components/installation-tab.tsx | 5 +- apps/www/src/config/customizer-items.ts | 20 +-- .../components/editor/use-create-editor.ts | 95 +++++----- .../components/editor/plugins/dnd-plugins.tsx | 5 + .../default/components/editor/transforms.ts | 6 +- .../editor/use-create-editor-list.ts | 93 +++++----- .../components/editor/use-create-editor.ts | 5 +- .../default/plate-ui/column-element.tsx | 24 +-- .../default/plate-ui/column-group-element.tsx | 55 ++++-- .../default/plate-ui/date-element.tsx | 9 +- .../registry/default/plate-ui/draggable.tsx | 165 +++++++++++++----- .../default/plate-ui/image-element.tsx | 15 +- .../default/plate-ui/media-video-element.tsx | 8 +- .../plate-ui/table-cell-element-static.tsx | 2 +- .../default/plate-ui/table-cell-element.tsx | 2 +- .../default/plate-ui/with-draggables.tsx | 148 ---------------- apps/www/src/registry/registry-ui.ts | 8 +- 17 files changed, 295 insertions(+), 370 deletions(-) delete mode 100644 apps/www/src/registry/default/plate-ui/with-draggables.tsx diff --git a/apps/www/src/app/(app)/_components/installation-tab.tsx b/apps/www/src/app/(app)/_components/installation-tab.tsx index f4e22a5853..be1bbd2137 100644 --- a/apps/www/src/app/(app)/_components/installation-tab.tsx +++ b/apps/www/src/app/(app)/_components/installation-tab.tsx @@ -309,7 +309,6 @@ export default function InstallationTab() { pluginsCode.push(formattedPlugin + ','); }); - const hasDraggable = components.some((comp) => comp.id === 'draggable'); const hasPlaceholder = components.some((comp) => comp.id === 'placeholder'); const usageCode = [ @@ -318,11 +317,11 @@ export default function InstallationTab() { pluginsCode.join('\n'), ' ],', ' override: {', - ` components: ${hasDraggable ? 'withDraggables(' : ''}${hasPlaceholder ? 'withPlaceholders(' : ''}({`, + ` components: ${hasPlaceholder ? 'withPlaceholders(' : ''}({`, ...componentsWithPluginKey.map( ({ pluginKey, usage }) => ` [${pluginKey}]: ${usage},` ), - ` })${hasPlaceholder ? ')' : ''}${hasDraggable ? ')' : ''},`, + ` })${hasPlaceholder ? ')' : ''},`, ' },', ' value: [', ' {', diff --git a/apps/www/src/config/customizer-items.ts b/apps/www/src/config/customizer-items.ts index b1d23434a4..aaf77be80d 100644 --- a/apps/www/src/config/customizer-items.ts +++ b/apps/www/src/config/customizer-items.ts @@ -417,16 +417,16 @@ export const customizerItems: Record = { [DndPlugin.key]: { id: DndPlugin.key, badges: [customizerBadges.handler, customizerBadges.ui], - components: [ - { - id: 'draggable', - filename: 'with-draggables', - label: 'Draggable', - registry: 'draggable', - route: getComponentNavItem('draggable').href, - usage: 'withDraggables', - }, - ], + // components: [ + // { + // id: 'draggable', + // filename: 'with-draggables', + // label: 'Draggable', + // registry: 'draggable', + // route: getComponentNavItem('draggable').href, + // usage: 'withDraggables', + // }, + // ], customImports: [ `import { DndProvider } from 'react-dnd';`, `import { HTML5Backend } from 'react-dnd-html5-backend';`, diff --git a/apps/www/src/registry/default/block/editor-ai/components/editor/use-create-editor.ts b/apps/www/src/registry/default/block/editor-ai/components/editor/use-create-editor.ts index 95cf5f8276..441b42ddd1 100644 --- a/apps/www/src/registry/default/block/editor-ai/components/editor/use-create-editor.ts +++ b/apps/www/src/registry/default/block/editor-ai/components/editor/use-create-editor.ts @@ -92,59 +92,56 @@ import { TableElement } from '@/registry/default/plate-ui/table-element'; import { TableRowElement } from '@/registry/default/plate-ui/table-row-element'; import { TocElement } from '@/registry/default/plate-ui/toc-element'; import { ToggleElement } from '@/registry/default/plate-ui/toggle-element'; -import { withDraggables } from '@/registry/default/plate-ui/with-draggables'; export const useCreateEditor = () => { return usePlateEditor({ override: { - components: withDraggables( - withPlaceholders({ - [AIPlugin.key]: AILeaf, - [AudioPlugin.key]: MediaAudioElement, - [BlockquotePlugin.key]: BlockquoteElement, - [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }), - [CodeBlockPlugin.key]: CodeBlockElement, - [CodeLinePlugin.key]: CodeLineElement, - [CodePlugin.key]: CodeLeaf, - [CodeSyntaxPlugin.key]: CodeSyntaxLeaf, - [ColumnItemPlugin.key]: ColumnElement, - [ColumnPlugin.key]: ColumnGroupElement, - [CommentsPlugin.key]: CommentLeaf, - [DatePlugin.key]: DateElement, - [EmojiInputPlugin.key]: EmojiInputElement, - [ExcalidrawPlugin.key]: ExcalidrawElement, - [FilePlugin.key]: MediaFileElement, - [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }), - [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }), - [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }), - [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }), - [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }), - [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }), - [HighlightPlugin.key]: HighlightLeaf, - [HorizontalRulePlugin.key]: HrElement, - [ImagePlugin.key]: ImageElement, - [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }), - [KbdPlugin.key]: KbdLeaf, - [LinkPlugin.key]: LinkElement, - [MediaEmbedPlugin.key]: MediaEmbedElement, - [MentionInputPlugin.key]: MentionInputElement, - [MentionPlugin.key]: MentionElement, - [ParagraphPlugin.key]: ParagraphElement, - [PlaceholderPlugin.key]: MediaPlaceholderElement, - [SlashInputPlugin.key]: SlashInputElement, - [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }), - [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }), - [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }), - [TableCellHeaderPlugin.key]: TableCellHeaderElement, - [TableCellPlugin.key]: TableCellElement, - [TablePlugin.key]: TableElement, - [TableRowPlugin.key]: TableRowElement, - [TocPlugin.key]: TocElement, - [TogglePlugin.key]: ToggleElement, - [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }), - [VideoPlugin.key]: MediaVideoElement, - }) - ), + components: withPlaceholders({ + [AIPlugin.key]: AILeaf, + [AudioPlugin.key]: MediaAudioElement, + [BlockquotePlugin.key]: BlockquoteElement, + [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }), + [CodeBlockPlugin.key]: CodeBlockElement, + [CodeLinePlugin.key]: CodeLineElement, + [CodePlugin.key]: CodeLeaf, + [CodeSyntaxPlugin.key]: CodeSyntaxLeaf, + [ColumnItemPlugin.key]: ColumnElement, + [ColumnPlugin.key]: ColumnGroupElement, + [CommentsPlugin.key]: CommentLeaf, + [DatePlugin.key]: DateElement, + [EmojiInputPlugin.key]: EmojiInputElement, + [ExcalidrawPlugin.key]: ExcalidrawElement, + [FilePlugin.key]: MediaFileElement, + [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }), + [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }), + [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }), + [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }), + [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }), + [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }), + [HighlightPlugin.key]: HighlightLeaf, + [HorizontalRulePlugin.key]: HrElement, + [ImagePlugin.key]: ImageElement, + [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }), + [KbdPlugin.key]: KbdLeaf, + [LinkPlugin.key]: LinkElement, + [MediaEmbedPlugin.key]: MediaEmbedElement, + [MentionInputPlugin.key]: MentionInputElement, + [MentionPlugin.key]: MentionElement, + [ParagraphPlugin.key]: ParagraphElement, + [PlaceholderPlugin.key]: MediaPlaceholderElement, + [SlashInputPlugin.key]: SlashInputElement, + [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }), + [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }), + [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }), + [TableCellHeaderPlugin.key]: TableCellHeaderElement, + [TableCellPlugin.key]: TableCellElement, + [TablePlugin.key]: TableElement, + [TableRowPlugin.key]: TableRowElement, + [TocPlugin.key]: TocElement, + [TogglePlugin.key]: ToggleElement, + [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }), + [VideoPlugin.key]: MediaVideoElement, + }), }, plugins: [ ...copilotPlugins, diff --git a/apps/www/src/registry/default/components/editor/plugins/dnd-plugins.tsx b/apps/www/src/registry/default/components/editor/plugins/dnd-plugins.tsx index f5569c0f58..48a405835b 100644 --- a/apps/www/src/registry/default/components/editor/plugins/dnd-plugins.tsx +++ b/apps/www/src/registry/default/components/editor/plugins/dnd-plugins.tsx @@ -4,6 +4,8 @@ import { DndPlugin } from '@udecode/plate-dnd'; import { PlaceholderPlugin } from '@udecode/plate-media/react'; import { NodeIdPlugin } from '@udecode/plate-node-id'; +import { DraggableAboveNodes } from '@/registry/default/plate-ui/draggable'; + export const dndPlugins = [ NodeIdPlugin, DndPlugin.configure({ @@ -15,5 +17,8 @@ export const dndPlugins = [ .insert.media(dragItem.files, { at: target, nextBlock: false }); }, }, + render: { + aboveNodes: DraggableAboveNodes, + }, }), ] as const; diff --git a/apps/www/src/registry/default/components/editor/transforms.ts b/apps/www/src/registry/default/components/editor/transforms.ts index 26d7431155..bd1448eca8 100644 --- a/apps/www/src/registry/default/components/editor/transforms.ts +++ b/apps/www/src/registry/default/components/editor/transforms.ts @@ -53,7 +53,7 @@ import { } from '@udecode/plate-table/react'; import { Path } from 'slate'; -export const STRUCTURAL_TYPES = [ +export const STRUCTURAL_TYPES: string[] = [ ColumnPlugin.key, ColumnItemPlugin.key, TablePlugin.key, @@ -79,7 +79,7 @@ const insertBlockMap: Record< (editor: PlateEditor, type: string) => void > = { [ACTION_THREE_COLUMNS]: (editor) => - insertColumnGroup(editor, { layout: 3, select: true }), + insertColumnGroup(editor, { columns: 3, select: true }), [AudioPlugin.key]: (editor) => insertAudioPlaceholder(editor, { select: true }), [CalloutPlugin.key]: (editor) => insertCallout(editor, { select: true }), @@ -163,7 +163,7 @@ const setBlockMap: Record< string, (editor: PlateEditor, type: string, entry: TNodeEntry) => void > = { - [ACTION_THREE_COLUMNS]: (editor) => toggleColumnGroup(editor, { layout: 3 }), + [ACTION_THREE_COLUMNS]: (editor) => toggleColumnGroup(editor, { columns: 3 }), [INDENT_LIST_KEYS.todo]: setList, [ListStyleType.Decimal]: setList, [ListStyleType.Disc]: setList, diff --git a/apps/www/src/registry/default/components/editor/use-create-editor-list.ts b/apps/www/src/registry/default/components/editor/use-create-editor-list.ts index 1b90c14313..acacdacadc 100644 --- a/apps/www/src/registry/default/components/editor/use-create-editor-list.ts +++ b/apps/www/src/registry/default/components/editor/use-create-editor-list.ts @@ -88,58 +88,55 @@ import { TableElement } from '@/registry/default/plate-ui/table-element'; import { TableRowElement } from '@/registry/default/plate-ui/table-row-element'; import { TocElement } from '@/registry/default/plate-ui/toc-element'; import { ToggleElement } from '@/registry/default/plate-ui/toggle-element'; -import { withDraggables } from '@/registry/default/plate-ui/with-draggables'; export const useCreateEditor = () => { return usePlateEditor({ override: { - components: withDraggables( - withPlaceholders({ - [AIPlugin.key]: AILeaf, - [BlockquotePlugin.key]: BlockquoteElement, - [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }), - [BulletedListPlugin.key]: withProps(ListElement, { variant: 'ul' }), - [CodeBlockPlugin.key]: CodeBlockElement, - [CodeLinePlugin.key]: CodeLineElement, - [CodePlugin.key]: CodeLeaf, - [CodeSyntaxPlugin.key]: CodeSyntaxLeaf, - [ColumnItemPlugin.key]: ColumnElement, - [ColumnPlugin.key]: ColumnGroupElement, - [CommentsPlugin.key]: CommentLeaf, - [DatePlugin.key]: DateElement, - [EmojiInputPlugin.key]: EmojiInputElement, - [ExcalidrawPlugin.key]: ExcalidrawElement, - [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }), - [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }), - [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }), - [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }), - [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }), - [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }), - [HighlightPlugin.key]: HighlightLeaf, - [HorizontalRulePlugin.key]: HrElement, - [ImagePlugin.key]: ImageElement, - [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }), - [KbdPlugin.key]: KbdLeaf, - [LinkPlugin.key]: LinkElement, - [ListItemPlugin.key]: withProps(PlateElement, { as: 'li' }), - [MediaEmbedPlugin.key]: MediaEmbedElement, - [MentionInputPlugin.key]: MentionInputElement, - [MentionPlugin.key]: MentionElement, - [NumberedListPlugin.key]: withProps(ListElement, { variant: 'ol' }), - [ParagraphPlugin.key]: ParagraphElement, - [SlashInputPlugin.key]: SlashInputElement, - [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }), - [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }), - [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }), - [TableCellHeaderPlugin.key]: TableCellHeaderElement, - [TableCellPlugin.key]: TableCellElement, - [TablePlugin.key]: TableElement, - [TableRowPlugin.key]: TableRowElement, - [TocPlugin.key]: TocElement, - [TogglePlugin.key]: ToggleElement, - [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }), - }) - ), + components: withPlaceholders({ + [AIPlugin.key]: AILeaf, + [BlockquotePlugin.key]: BlockquoteElement, + [BoldPlugin.key]: withProps(PlateLeaf, { as: 'strong' }), + [BulletedListPlugin.key]: withProps(ListElement, { variant: 'ul' }), + [CodeBlockPlugin.key]: CodeBlockElement, + [CodeLinePlugin.key]: CodeLineElement, + [CodePlugin.key]: CodeLeaf, + [CodeSyntaxPlugin.key]: CodeSyntaxLeaf, + [ColumnItemPlugin.key]: ColumnElement, + [ColumnPlugin.key]: ColumnGroupElement, + [CommentsPlugin.key]: CommentLeaf, + [DatePlugin.key]: DateElement, + [EmojiInputPlugin.key]: EmojiInputElement, + [ExcalidrawPlugin.key]: ExcalidrawElement, + [HEADING_KEYS.h1]: withProps(HeadingElement, { variant: 'h1' }), + [HEADING_KEYS.h2]: withProps(HeadingElement, { variant: 'h2' }), + [HEADING_KEYS.h3]: withProps(HeadingElement, { variant: 'h3' }), + [HEADING_KEYS.h4]: withProps(HeadingElement, { variant: 'h4' }), + [HEADING_KEYS.h5]: withProps(HeadingElement, { variant: 'h5' }), + [HEADING_KEYS.h6]: withProps(HeadingElement, { variant: 'h6' }), + [HighlightPlugin.key]: HighlightLeaf, + [HorizontalRulePlugin.key]: HrElement, + [ImagePlugin.key]: ImageElement, + [ItalicPlugin.key]: withProps(PlateLeaf, { as: 'em' }), + [KbdPlugin.key]: KbdLeaf, + [LinkPlugin.key]: LinkElement, + [ListItemPlugin.key]: withProps(PlateElement, { as: 'li' }), + [MediaEmbedPlugin.key]: MediaEmbedElement, + [MentionInputPlugin.key]: MentionInputElement, + [MentionPlugin.key]: MentionElement, + [NumberedListPlugin.key]: withProps(ListElement, { variant: 'ol' }), + [ParagraphPlugin.key]: ParagraphElement, + [SlashInputPlugin.key]: SlashInputElement, + [StrikethroughPlugin.key]: withProps(PlateLeaf, { as: 's' }), + [SubscriptPlugin.key]: withProps(PlateLeaf, { as: 'sub' }), + [SuperscriptPlugin.key]: withProps(PlateLeaf, { as: 'sup' }), + [TableCellHeaderPlugin.key]: TableCellHeaderElement, + [TableCellPlugin.key]: TableCellElement, + [TablePlugin.key]: TableElement, + [TableRowPlugin.key]: TableRowElement, + [TocPlugin.key]: TocElement, + [TogglePlugin.key]: ToggleElement, + [UnderlinePlugin.key]: withProps(PlateLeaf, { as: 'u' }), + }), }, plugins: [ ...copilotPlugins, diff --git a/apps/www/src/registry/default/components/editor/use-create-editor.ts b/apps/www/src/registry/default/components/editor/use-create-editor.ts index d452926a5c..f3820bcff5 100644 --- a/apps/www/src/registry/default/components/editor/use-create-editor.ts +++ b/apps/www/src/registry/default/components/editor/use-create-editor.ts @@ -91,7 +91,6 @@ import { TableElement } from '@/registry/default/plate-ui/table-element'; import { TableRowElement } from '@/registry/default/plate-ui/table-row-element'; import { TocElement } from '@/registry/default/plate-ui/toc-element'; import { ToggleElement } from '@/registry/default/plate-ui/toggle-element'; -import { withDraggables } from '@/registry/default/plate-ui/with-draggables'; import { editorPlugins, viewPlugins } from './plugins/editor-plugins'; @@ -162,9 +161,7 @@ export const useCreateEditor = ( { override: { components: { - ...(readOnly - ? viewComponents - : withPlaceholders(withDraggables(editorComponents))), + ...(readOnly ? viewComponents : withPlaceholders(editorComponents)), ...components, }, ...override, diff --git a/apps/www/src/registry/default/plate-ui/column-element.tsx b/apps/www/src/registry/default/plate-ui/column-element.tsx index 1e5caf7369..271aac256a 100644 --- a/apps/www/src/registry/default/plate-ui/column-element.tsx +++ b/apps/www/src/registry/default/plate-ui/column-element.tsx @@ -6,11 +6,7 @@ import type { TColumnElement } from '@udecode/plate-layout'; import { cn, useComposedRef, withRef } from '@udecode/cn'; import { useElement, withHOC } from '@udecode/plate-common/react'; -import { - useDraggable, - useDraggableState, - useDropLine, -} from '@udecode/plate-dnd'; +import { useDraggable, useDropLine } from '@udecode/plate-dnd'; import { ResizableProvider } from '@udecode/plate-resizable'; import { GripHorizontal } from 'lucide-react'; import { Path } from 'slate'; @@ -26,24 +22,20 @@ import { TooltipTrigger, } from './tooltip'; -const DRAG_ITEM_COLUMN = 'column'; - export const ColumnElement = withHOC( ResizableProvider, withRef(({ children, className, ...props }, ref) => { const readOnly = useReadOnly(); const { width } = useElement(); - const state = useDraggableState({ + const { isDragging, previewRef, handleRef } = useDraggable({ canDropNode: ({ dragEntry, dropEntry }) => Path.equals(Path.parent(dragEntry[1]), Path.parent(dropEntry[1])), element: props.element, orientation: 'horizontal', - type: DRAG_ITEM_COLUMN, + type: 'column', }); - const { previewRef, handleRef } = useDraggable(state); - return (
{children} @@ -108,9 +100,9 @@ const DropLine = React.forwardRef< HTMLDivElement, React.HTMLAttributes >(({ className, ...props }, ref) => { - const state = useDropLine({ orientation: 'horizontal' }); + const { dropLine } = useDropLine({ orientation: 'horizontal' }); - if (!state.dropLine) return null; + if (!dropLine) return null; return (
( ); export function ColumnFloatingToolbar({ children }: React.PropsWithChildren) { + const editor = useEditorRef(); const readOnly = useReadOnly(); - const { - setDoubleColumn, - setDoubleSideDoubleColumn, - setLeftSideDoubleColumn, - setRightSideDoubleColumn, - setThreeColumn, - } = useColumnState(); - const element = useElement(ColumnItemPlugin.key); + const columnGroupElement = useElement(ColumnPlugin.key); const { props: buttonProps } = useRemoveNodeButton({ element }); const isOpen = useDebouncePopoverOpen(); + const onColumnChange = (widths: string[]) => { + setColumns(editor, { + at: findNodePath(editor, columnGroupElement), + widths, + }); + }; + if (readOnly) return <>{children}; return ( @@ -61,26 +70,38 @@ export function ColumnFloatingToolbar({ children }: React.PropsWithChildren) { sideOffset={10} >
- - - diff --git a/apps/www/src/registry/default/plate-ui/date-element.tsx b/apps/www/src/registry/default/plate-ui/date-element.tsx index f914ec68b7..f9f90708db 100644 --- a/apps/www/src/registry/default/plate-ui/date-element.tsx +++ b/apps/www/src/registry/default/plate-ui/date-element.tsx @@ -1,8 +1,7 @@ 'use client'; import { cn, withRef } from '@udecode/cn'; -import { setNodes } from '@udecode/plate-common'; -import { findPath } from '@udecode/plate-common/react'; +import { setNode } from '@udecode/plate-common/react'; import { useReadOnly } from 'slate-react'; import { Calendar } from './calendar'; @@ -74,11 +73,7 @@ export const DateElement = withRef( onSelect={(date) => { if (!date) return; - setNodes( - editor, - { date: date.toDateString() }, - { at: findPath(editor, element) } - ); + setNode(editor, element, { date: date.toDateString() }); }} mode="single" initialFocus diff --git a/apps/www/src/registry/default/plate-ui/draggable.tsx b/apps/www/src/registry/default/plate-ui/draggable.tsx index ec514ce65c..96951824bd 100644 --- a/apps/www/src/registry/default/plate-ui/draggable.tsx +++ b/apps/www/src/registry/default/plate-ui/draggable.tsx @@ -1,28 +1,41 @@ /* eslint-disable tailwindcss/no-custom-classname */ 'use client'; -import React from 'react'; - -import type { TEditor } from '@udecode/plate-common'; -import type { DropTargetMonitor } from 'react-dnd'; +import React, { useMemo } from 'react'; import { cn, withRef } from '@udecode/cn'; +import { BlockquotePlugin } from '@udecode/plate-block-quote/react'; +import { CodeBlockPlugin } from '@udecode/plate-code-block/react'; +import { isType, someNode } from '@udecode/plate-common'; import { - type PlateElementProps, + type NodeWrapperComponent, + type PlateRenderElementProps, MemoizedChildren, + ParagraphPlugin, useEditorPlugin, useEditorRef, + useElement, } from '@udecode/plate-common/react'; +import { useDraggable, useDropLine } from '@udecode/plate-dnd'; +import { ExcalidrawPlugin } from '@udecode/plate-excalidraw/react'; +import { HEADING_KEYS } from '@udecode/plate-heading'; +import { ColumnItemPlugin, ColumnPlugin } from '@udecode/plate-layout/react'; import { - type DragItemNode, - useDraggable, - useDraggableGutter, - useDraggableState, - useDropLine, -} from '@udecode/plate-dnd'; + ImagePlugin, + MediaEmbedPlugin, + PlaceholderPlugin, +} from '@udecode/plate-media/react'; import { BlockSelectionPlugin } from '@udecode/plate-selection/react'; +import { + TableCellPlugin, + TablePlugin, + TableRowPlugin, +} from '@udecode/plate-table/react'; +import { TogglePlugin } from '@udecode/plate-toggle/react'; import { GripVertical } from 'lucide-react'; -import { useSelected } from 'slate-react'; +import { useReadOnly, useSelected } from 'slate-react'; + +import { STRUCTURAL_TYPES } from '@/registry/default/components/editor/transforms'; import { Tooltip, @@ -32,30 +45,58 @@ import { TooltipTrigger, } from './tooltip'; -export interface DraggableProps extends PlateElementProps { - /** - * Intercepts the drop handling. If `false` is returned, the default drop - * behavior is called after. If `true` is returned, the default behavior is - * not called. - */ - onDropHandler?: ( - editor: TEditor, - props: { - id: string; - dragItem: DragItemNode; - monitor: DropTargetMonitor; - nodeRef: any; +const UNDRAGGABLE_KEYS = [ + ColumnItemPlugin.key, + TableRowPlugin.key, + TableCellPlugin.key, +]; + +export const DraggableAboveNodes: NodeWrapperComponent = (props) => { + const { editor, element, path } = props; + const readOnly = useReadOnly(); + + const enabled = useMemo(() => { + if (readOnly) return false; + if (path.length === 1 && !isType(editor, element, UNDRAGGABLE_KEYS)) { + return true; } - ) => boolean; -} + if (path.length === 3 && !isType(editor, element, UNDRAGGABLE_KEYS)) { + const block = someNode(editor, { + at: path, + match: { + type: editor.getType(ColumnPlugin), + }, + }); + + if (block) { + return true; + } + } + if (path.length === 4 && !isType(editor, element, UNDRAGGABLE_KEYS)) { + const block = someNode(editor, { + at: path, + match: { + type: editor.getType(TablePlugin), + }, + }); + + if (block) { + return true; + } + } + + return false; + }, [editor, element, path, readOnly]); -export const Draggable = withRef<'div', DraggableProps>( - ({ className, onDropHandler, ...props }, ref) => { - const { children, element } = props; + if (!enabled) return; - const state = useDraggableState({ element, onDropHandler }); - const { isDragging } = state; - const { previewRef, handleRef } = useDraggable(state); + return (props) => ; +}; + +export const Draggable = withRef<'div', PlateRenderElementProps>( + ({ className, ...props }, ref) => { + const { children, editor, element } = props; + const { isDragging, previewRef, handleRef } = useDraggable({ element }); return (
( className={cn( 'relative', isDragging && 'opacity-50', - 'group', + STRUCTURAL_TYPES.includes(element.type) + ? 'group/structural' + : 'group', className )} > -
+
>(({ children, className, ...props }, ref) => { - const { useOption } = useEditorPlugin(BlockSelectionPlugin); + const { editor, useOption } = useEditorPlugin(BlockSelectionPlugin); + const element = useElement(); const isSelectionAreaVisible = useOption('isSelectionAreaVisible'); - const gutter = useDraggableGutter(); const selected = useSelected(); + const isNodeType = (keys: string[] | string) => isType(editor, element, keys); + return (
{children}
@@ -150,21 +228,20 @@ const DragHandle = React.memo(() => { const DropLine = React.memo( React.forwardRef>( ({ className, ...props }, ref) => { - const state = useDropLine(); + const { dropLine } = useDropLine(); - if (!state.dropLine) return null; + if (!dropLine) return null; return (
diff --git a/apps/www/src/registry/default/plate-ui/image-element.tsx b/apps/www/src/registry/default/plate-ui/image-element.tsx index e05ea38aa3..337ae132ae 100644 --- a/apps/www/src/registry/default/plate-ui/image-element.tsx +++ b/apps/www/src/registry/default/plate-ui/image-element.tsx @@ -3,8 +3,8 @@ import React from 'react'; import { cn, withRef } from '@udecode/cn'; -import { useEditorRef, withHOC } from '@udecode/plate-common/react'; -import { useDraggable, useDraggableState } from '@udecode/plate-dnd'; +import { withHOC } from '@udecode/plate-common/react'; +import { useDraggable } from '@udecode/plate-dnd'; import { Image, ImagePlugin, useMediaState } from '@udecode/plate-media/react'; import { ResizableProvider, useResizableStore } from '@udecode/plate-resizable'; @@ -21,18 +21,13 @@ export const ImageElement = withHOC( ResizableProvider, withRef( ({ children, className, nodeProps, ...props }, ref) => { - const editor = useEditorRef(); - const { align = 'center', focused, readOnly, selected } = useMediaState(); const width = useResizableStore().get.width(); - const state = editor.plugins.dnd - ? useDraggableState({ element: props.element }) - : ({} as any); - - const { isDragging } = state; - const { handleRef } = useDraggable(state); + const { isDragging, handleRef } = useDraggable({ + element: props.element, + }); return ( diff --git a/apps/www/src/registry/default/plate-ui/media-video-element.tsx b/apps/www/src/registry/default/plate-ui/media-video-element.tsx index 571da9a527..2140e048c2 100644 --- a/apps/www/src/registry/default/plate-ui/media-video-element.tsx +++ b/apps/www/src/registry/default/plate-ui/media-video-element.tsx @@ -6,7 +6,7 @@ import ReactPlayer from 'react-player'; import { cn, withRef } from '@udecode/cn'; import { useEditorMounted, withHOC } from '@udecode/plate-common/react'; -import { useDraggable, useDraggableState } from '@udecode/plate-dnd'; +import { useDraggable } from '@udecode/plate-dnd'; import { parseTwitterUrl, parseVideoUrl } from '@udecode/plate-media'; import { useMediaState } from '@udecode/plate-media/react'; import { ResizableProvider, useResizableStore } from '@udecode/plate-resizable'; @@ -39,9 +39,9 @@ export const MediaVideoElement = withHOC( const isTweet = true; - const state = useDraggableState({ element: props.element }); - const { isDragging } = state; - const { handleRef } = useDraggable(state); + const { isDragging, handleRef } = useDraggable({ + element: props.element, + }); return ( -
+
{children}
diff --git a/apps/www/src/registry/default/plate-ui/table-cell-element.tsx b/apps/www/src/registry/default/plate-ui/table-cell-element.tsx index b0bacd0987..abd0f7e7a3 100644 --- a/apps/www/src/registry/default/plate-ui/table-cell-element.tsx +++ b/apps/www/src/registry/default/plate-ui/table-cell-element.tsx @@ -86,7 +86,7 @@ export const TableCellElement = withRef< } >
> - > -) => - withDraggablePrimitive(Draggable, Component, options as any); - -export const withDraggablesPrimitive = createNodesWithHOC(withDraggable); - -export const withDraggables = (components: any) => { - return withDraggablesPrimitive(components, [ - { - keys: [ParagraphPlugin.key, 'ul', 'ol'], - level: 0, - }, - { - key: HEADING_KEYS.h1, - draggableProps: { - className: - '[&_.slate-blockToolbarWrapper]:h-[1.3em] [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-1 [&_.slate-gutterLeft]:text-[1.875em]', - }, - }, - { - key: HEADING_KEYS.h2, - draggableProps: { - className: - '[&_.slate-blockToolbarWrapper]:h-[1.3em] [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-1 [&_.slate-gutterLeft]:text-[1.5em]', - }, - }, - { - key: HEADING_KEYS.h3, - draggableProps: { - className: - '[&_.slate-blockToolbarWrapper]:h-[1.3em] [&_.slate-gutterLeft]:pt-[2px] [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-1 [&_.slate-gutterLeft]:text-[1.25em]', - }, - }, - { - keys: [HEADING_KEYS.h4, HEADING_KEYS.h5], - draggableProps: { - className: - '[&_.slate-blockToolbarWrapper]:h-[1.3em] [&_.slate-gutterLeft]:pt-[3px] [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0 [&_.slate-gutterLeft]:text-[1.1em]', - }, - }, - { - keys: [ParagraphPlugin.key], - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-[3px] [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - keys: [HEADING_KEYS.h6, 'ul', 'ol'], - draggableProps: { - className: '[&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: BlockquotePlugin.key, - draggableProps: { - className: '[&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: CodeBlockPlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-6 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: ImagePlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-0 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: MediaEmbedPlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-0 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: ExcalidrawPlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-0 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: TogglePlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-0 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: ColumnPlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-0 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: PlaceholderPlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-3 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - { - key: TablePlugin.key, - draggableProps: { - className: - '[&_.slate-gutterLeft]:pt-3 [&_.slate-gutterLeft]:px-0 [&_.slate-gutterLeft]:pb-0', - }, - }, - ]); -}; diff --git a/apps/www/src/registry/registry-ui.ts b/apps/www/src/registry/registry-ui.ts index edbbbbd9b1..4052c3ef38 100644 --- a/apps/www/src/registry/registry-ui.ts +++ b/apps/www/src/registry/registry-ui.ts @@ -250,9 +250,7 @@ export const uiComponents: Registry = [ `import { DndPlugin } from '@udecode/plate-dnd'; import { NodeIdPlugin } from '@udecode/plate-node-id'; import { DndProvider } from 'react-dnd'; -import { HTML5Backend } from 'react-dnd-html5-backend'; - -import { withDraggables } from './withDraggables';`, +import { HTML5Backend } from 'react-dnd-html5-backend';`, `export function MyEditor() { const editor = usePlateEditor({ plugins: [ @@ -261,9 +259,9 @@ import { withDraggables } from './withDraggables';`, DndPlugin.configure({ options: { enableScroller: true } }), ], override: { - components: withDraggables({ + components: { // ...components - }), + }, } });