Drag list item #1491
Replies: 5 comments 11 replies
-
Simply delete {
keys: [ELEMENT_PARAGRAPH, ELEMENT_UL, ELEMENT_OL],
level: 0,
}, This limits it only show handle on level 0. And replace it with: {
// only element that registered keys here will have dnd grabber
keys: [ELEMENT_LI],
}, |
Beta Was this translation helpful? Give feedback.
-
But this will generate tree like this: bare li on the root We need a normalization to recreate its parent, and may need li contain information about its parent. @zbeyens do you think there is a better solution? I'm working on this. I'm very curious about how Notion handles this. |
Beta Was this translation helpful? Give feedback.
-
my attempt:
{
key: ELEMENT_LI,
},
export const useDragBlock = <V extends Value>(editor: TEditor<V>, element: EElement<V>, path: Path) => {
return useDrag(
() => ({
type: 'block',
item(): DragItemWithParent {
editor.isDragging = true;
document.body.classList.add('dragging');
const parentNode = Editor.above(editor as Editor, { at: path })?.[0] as EElement<V> | undefined;
return { id: element.id as string, type: element.type, parentType: parentNode?.type };
},
return useDrop({
accept: 'block',
drop: (dragItem: DragItemBlock, monitor: DropTargetMonitor) => {
...
const to = before ? dropPath : Path.next(dropPath);
withoutNormalizing(editor, () => {
Transforms.moveNodes(editor as ReactEditor, {
at: dragPath,
to,
});
postDropNormalize(editor, dragItem, to);
});
import { DragItemBlock, TReactEditor, Value } from '@udecode/plate';
import { Path, Transforms } from 'slate';
import { ReactEditor } from 'slate-react';
import type { DragItemWithParent } from './useDragBlock';
export function postDropNormalize<V extends Value>(editor: TReactEditor<V>, dragItem: DragItemBlock, path: Path): void {
if ('parentType' in dragItem) {
const dragItemWithParent = dragItem as DragItemWithParent;
if (dragItemWithParent.type === 'li' && (dragItemWithParent.parentType === 'ol' || dragItemWithParent.parentType === 'ul')) {
Transforms.wrapNodes(editor as ReactEditor, { type: dragItemWithParent.parentType }, { at: path });
}
}
} |
Beta Was this translation helpful? Give feedback.
-
In
This solve the drag handle invisible bug on list item, but still need to solve wrap parent issue: |
Beta Was this translation helpful? Give feedback.
-
My serialization target (wikitext) don't have indent support, so I won't be able to use indent-list, I will still use normal list plugin instead. So I may need an API to allow passing in a An example normalization function is as simple as import { DragItemNode } from '@udecode/plate-dnd';
import type { Value } from '@udecode/slate';
import type { TReactEditor } from '@udecode/slate-react';
import { Path, Transforms } from 'slate';
import type { ReactEditor } from 'slate-react';
export function postDropNormalize<V extends Value>(editor: TReactEditor<V>, dragItem: DragItemNode, path: Path): void {
if ('parentType' in dragItem) {
const dragItemWithParent = dragItem;
if (dragItemWithParent.type === 'li' && (dragItemWithParent.parentType === 'ol' || dragItemWithParent.parentType === 'ul')) {
// @ts-expect-error Object literal may only specify known properties, and 'type' does not exist in type 'BaseElement'.ts(2345)
Transforms.wrapNodes(editor as ReactEditor, { type: dragItemWithParent.parentType }, { at: path });
}
}
} I just need an API to pass it in (instead of fork & modify the dnd plugin), thanks. Or can I PR to add this function to this codebase? |
Beta Was this translation helpful? Give feedback.
-
List level dragging and drop to reorder list items.
Currently, the list item can't be dragged. How to modify the list plugin or dnd plugin to enable this?
2022-04-13.22.57.31.mov
Beta Was this translation helpful? Give feedback.
All reactions