-
Notifications
You must be signed in to change notification settings - Fork 860
[Pattern] Nested drag and drop #9270
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
base: main
Are you sure you want to change the base?
[Pattern] Nested drag and drop #9270
Conversation
47c0c58 to
fcad1c5
Compare
26e1bb8 to
4d1b4c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is some opinionated formatting in this diff so I'll highlight the most important changes with comments 👇🏻
| :::accessibility Consider your users and use case | ||
|
|
||
| :::warning Consider your users and use case | ||
| Drag and drop is often less suitable than standard form inputs. It relies on spatial orientation, which can be difficult for screen reader users. Keyboard navigation typically does not afford the same nuanced manipulation as a mouse. EUI maintains accessibility support but carefully consider your users' context when choosing this pattern. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opinionated rewrite of the previous admonition that was long, used some hefty words and, in my opinion, didn't get the point across effectively. I can drop if someone disagrees.
| :::warning Limitations | ||
|
|
||
| EUI (largely due to the great work already in @hello-pangea/dnd) has and will continue to ensure accessibility where possible. With that in mind, keep your users' working context in mind. | ||
| One of the limitations of <EuiLink href="https://github.com/hello-pangea/dnd" target="_blank">@hello-pangea/dnd</EuiLink> is **nested drag and drop** (dragging elements between nesting levels). For this use case, we recommend using <EuiLink href="https://atlassian.design/components/pragmatic-drag-and-drop/about" target="_blank">Pragmatic drag and drop</EuiLink>. Check out our [Nested drag and drop pattern](../../patterns/nested-drag-and-drop/index.mdx) for a simplified example of how to implement it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an admonition to warn users about the limitations of our drag and drop components and redirect them to the "Nested drag and drop" pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to separate the code source into this file.
💡 We can reuse this pattern for other "examples" that are a tad more complex and might benefit from the static code analysis and syntax highlighting that a separate file like this provides.
| "compilerOptions": { | ||
| "baseUrl": ".", | ||
| "jsxImportSource": "@emotion/react", | ||
| "module": "nodenext", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this because I got a TS failure. I noticed this specifically when working in example.tsx and TS wasn't complaining.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did this because otherwise TS complains about the css prop not existing. Not sure why this didn't surface before, maybe we do not use css prop in *.ts(x) files in the website project.
💚 Build Succeeded
History
|
💚 Build SucceededHistory
|
Summary
Note
I do not recommend going commit by commit. I went through several rewrites and refactors, adding and removing a bunch of code. There are not a lot of files changed so I can recommend simply using the regular diff.
This PR adds the Nested drag and drop pattern documentation.
Huge thanks to @acstll for working on the initial PoC to test the feasibility and for providing amazing feedback! 💚 👏🏻
Design
It is inspired by the Atlassian Tree example and the Streams designs. The result was consulted on and approved by the Streams designers (@boriskirov, @patpascal) and the EUI designers (@ek-so, @JoseLuisGJ).
Accessibility
Semantically speaking, it is a tree but it doesn't fully fit the definition of the Tree view pattern. It is a nested, draggable composition of
EuiPanelandEuiAccordion(Disclosure pattern). Similarly, Atlassian doesn't userole="tree"in their example.Furthermore, unlike our simple drag and drop components, we cannot handle reordering and nesting with keyboard both due to technical feasibility and UX. From accessibility standpoint, it's better to provide separate actions that can be applied to the specific element: "Move Up", "Move Down", "Outdent", "Indent".
I considered "Nest" and "Unnest" but the behavior is it nests under the previous sibling so the above-mentioned terminology makes this more intuitive.
The motivation behind adding the roving tabindex (which can always be changed by the consumers depending on their context) is that for large trees tabbing through all of the nodes would result in an annoying experience. A possible alternative is a skip link but that's very use case specific.
Styles
I tried reusing the styles in the drag and drop components, which is easy for the group indicator. It's much more complex for the reorder indicator. I even prepared the component to be exposed as
EuiLineIndicator.Our drag and drop components bring the complexity of horizontal and vertical axis support and the displacement animation which rewriting would significantly enlarge the scope of the task. We would have to test it thoroughly both in Kibana and Cloud, and run by additional Solution teams.
@ek-so also has another idea for how the drag and drop should look, and it slightly diverges from what's presented in this pattern.
So we agreed to move it to another time. Once we have the design ready, we can create an appropriate task and figure out how we can reuse the styles with this pattern as well. For now, I don't see the reason to move the styles anywhere else than the source code if we don't know if and how they will be reused.
Documentation
I decided to put this pattern in the "Patterns" page but leave the other pages alone for now. We can decide what exactly to do with them later, after a team discussion.
I also decided to add comments to the code wherever necessary, prioritizing linking to the documentation. Instead of verbose paragraphs repeating what Atlassian writes. I don't think it makes sense for the 3rd party library.
I tried adding headers but the page content is so simple, the headers bring more noise than order. We can always revisit this later with more complex patterns that require more text content.
Why are we making this change?
Resolves #9138
There is an internal ask to showcase how EUI components can be used specifically for the nested drag and drop pattern. We have decided to use Pragmatic library.
Screenshots #
Kapture.2025-12-19.at.17.31.48.mp4
Impact to users
🟢 This is a pattern that builds on top of existing EUI state. There are no changes to the EUI library source.
QA
General checklist
@defaultif default values are missing) and playground toggles