Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: draggable block #2115

Closed
echarles opened this issue May 9, 2022 · 8 comments · Fixed by #2860
Closed

Feature: draggable block #2115

echarles opened this issue May 9, 2022 · 8 comments · Fixed by #2860
Labels
enhancement Improvement over existing feature

Comments

@echarles
Copy link
Contributor

echarles commented May 9, 2022

It would be great to have draggable blocks ready to be used (in core or as an example), see the notion like experience.

Untitled5

@echarles echarles added the enhancement Improvement over existing feature label May 9, 2022
@echarles
Copy link
Contributor Author

Work is being done in #2027 that could help to get the block drag/drop feature alive.

@oskar-szwajkowski
Copy link

oskar-szwajkowski commented Jul 26, 2022

Could you share your opinions about how could it be achieved in lexical?

Up to this point I was using Draft.js, and there I implemented drag & drop by wrapping each block inside draggablewrapper, then saving blockkey on drag event, and when dropping, changing order of blocks array to reflect drag & drop behavior

Should implementing custom drag & drop in lexical works similarly? However I cannot figure out the way to create general 'wrapper' around every non-inline element
(Other use case of such wrapper might be counting up amount of open comments in this paragraph/block)

Looking into the code and given that only DecoratorNode can return custom React component, I would have to redo every standard node as custom decorator node, wrapped in f.e. react-beautiful-dnd's , is that correct?
Maybe @LuciNyan have any idea how thos could be made, as I saw some commits regarding dragging images in #2027

EDIT:
I cannot create wrappers for standard notes, as f.e. ParagraphNode cannot be replace by your custom ones, as they will have same type, and editor is complaining about it having same type with classes not matching.

So I don't see any way of being able to wrap each non inline element with some draggable block, which could be later intercepted in drop event

Trying to do some decorator which will be there before every paragraph node as first child always, and it being dragable handler, saving node key on drag and reading node key that was dropped onto, but it seems a bit hacky as we are in fact not dragging whole block, but just single wrapper, so dragging clone can not reflect text/content

@DaniGuardiola
Copy link

Bumping this as we also need this feature really badly. What @oskar-szwajkowski shared is quite similar to our thinking. Two main challenges stand out:

  • Overriding the nodes to wrap them with a drag and drop handle. Ideally, in a universal way (wrap all block nodes without duplicating too much code) and with the possibility of using react elements. Thinking that Decoupling plugin and nodes #1262 will be a step forward here.
  • Showing drop targets in the right places to visually indicate where the block would land if dropped.

Would really love to learn how to implement something like this.

@hustlefueled
Copy link

+1 to @DaniGuardiola and @oskar-szwajkowski .

Being able to readjust content blocks will be super helpful. Currently, you need to cut and paste elements to realign and this creates formatting issues.

Would love to see this come to Lexical.

@acywatson
Copy link
Contributor

Acknowledging this thread - thanks for the feedback and thoughts here! Will try to follow up with some ideas on how we might be able to achieve something like this.

@LuciNyan
Copy link
Contributor

Hi @oskar-szwajkowski.

I'm sorry for missing your mention. For this feature, I tried a few different implementations. In my opinion the drag and drop implementation should not be intrusive to any other code. The user is free to choose whether or not to add this plugin, so I think the best implementation would be to add a draggable menu. When dragging happens it's essentially just dragging an icon, and we can customize the content displayed by way of setDragImage.

@songispm
Copy link

anything new?

@echarles
Copy link
Contributor Author

@songispm A draft PR is being worked out by @LuciNyan. You can try the playground on https://lexical-playground-nzep8plck-fbopensource.vercel.app I find the implemented feature appealing and meeting the requirements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement over existing feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants