[lexical-react] Feat: add draggable block support to individual list items#8178
[lexical-react] Feat: add draggable block support to individual list items#8178Sa-Te wants to merge 1 commit intofacebook:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
f6ebca4 to
0acaab5
Compare
etrepum
left a comment
There was a problem hiding this comment.
The UX here is a bit weird, since it adds new target locations between lists but they don't actually work unless the dragged node is a list. The lines should only show up when the dragged node can be dropped there, so either code should be added to split lists if a paragraph is dragged into it, or the targeting code should be aware of the dragged node's type.
Screen.Recording.2026-02-26.at.13.19.36.mov
|
The nested list case is also unintuitive, it seems that you can only reorder the top-level |
0acaab5 to
9facfe1
Compare
I've just pushed an update that addresses both points: Note on the horizontal "indent" drag behavior: I noticed in testing that if you drag a nested item vertically below its parent's bounding box, it natively drops into the outer list (due to Lexical's Y-axis targeting). Implementing X-axis drag-to-indent tracking would require a rewrite of the core coordinate engine, so I kept this PR strictly scoped to enabling the vertical reordering of list items. |
|
I think if we're trying to re-implement something like Notion's list support for draggable block reordering, why not rewrite any necessary code required to make that happen? There isn't really any API surface here to worry about preserving compatibility. The way Notion shows you where the node will land is much more intuitive |
|
Allow me to share my thoughts on this In fact, it is not necessary to use drag'n'drop only for nested list items. It can be enabled for any nested items inside containers. For example, in lexical-playground, these are Collapsible Container and Columns Layout/Item. I think it's a good idea, at least so that the plugin doesn't depend on specific nodes. If you look at Notion, there is also a Callout container from which and into which you can drag and drop any elements, while still being able to use drag on the Callout itself. Notion.s.nested.drag.movBy the way, I forked the DraggableBlockPlugin to add a nested drag feature to it, but I disabled the ability to drag individual list items because, as Bob said, there is a problem with new fake target locations, as well as the problem that it is impossible to move the entire list at once. The last problem in Notion is solved by selecting several blocks at once and then using the drag icon, but this is a much more complicated feature than simple nested drag. Notion.s.entire.or.partial.list.drag.mov |
Description
This PR addresses #7630 by enhancing the
DraggableBlockPluginto support dragging individualListItemNodes independently of their parentListNode.Previously, hovering over a list would only target the top-level
<ul>or<ol>, making it impossible to restructure individual items via drag-and-drop.Key Changes:
getBlockElementto check if a top-level block is a List. If so, it searches its children to attach the drag handle to the specific<li>being hovered.calculateZoomLevellogic.$onDropto handle cross-node drops. If an<li>is dragged out of a list and dropped onto a<p>, it automatically wraps the item in a newListNodematching the original list type (bullet, number, etc.) to prevent orphaned nodes and aggressive normalization errors.Impact
Brings the Lexical Playground's restructuring UX to parity with editors like Notion and PlateJS, allowing users to easily reorder list items or break them out into new lists.
Testing
List item one can be successfully dragged below list item twoList item can be dragged out of a list and dropped below a paragraphCloses #7630