Skip to content

fix(DnD): fix drag and drop in Shadow DOM #11975

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

Open
wants to merge 42 commits into
base: main
Choose a base branch
from

Conversation

TeodorTaushanov
Copy link
Member

@TeodorTaushanov TeodorTaushanov commented Jul 22, 2025

  • DragRegistry no longer handles global drag-related event listeners.
  • setDraggedElement and clearDraggedElement methods are added. subscribe/unsubscribe are removed.
  • The startMultipleDrag function now requires a DragEvent argument.
  • Automatic drag-and-drop from links or other elements has been removed.

Jira: BGSOFUIRODOPI-3442
fixes #11185

@TeodorTaushanov TeodorTaushanov changed the title fix(DnD): fix drag and drop in Shadow DOM wip(DnD): fix drag and drop in Shadow DOM Jul 29, 2025
@TeodorTaushanov TeodorTaushanov changed the title wip(DnD): fix drag and drop in Shadow DOM fix(DnD): fix drag and drop in Shadow DOM Jul 31, 2025
@dimovpetar dimovpetar force-pushed the drag_drop_shadow_dom branch from f18cca0 to ce1dc89 Compare August 6, 2025 10:06
@@ -404,7 +404,7 @@ class Table extends UI5Element {
@i18n("@ui5/webcomponents")
static i18nBundle: I18nBundle;

_events = ["keydown", "keyup", "click", "focusin", "focusout", "dragenter", "dragleave", "dragover", "drop"];
_events = ["keydown", "keyup", "click", "focusin", "focusout", "dragstart", "dragenter", "dragleave", "dragover", "drop", "dragend"];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

event order 👌 ❤️

DragRegistry.subscribe(this._table); // TODO: Where unsubscribe?
}

_ondragstart(e: DragEvent) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if there's a technical reason for it, but it feels really wrong: does every component that might become movable have to handle those things itself

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, now interested components need to call setDraggedElement/clearDraggedElement. The alternative approach to overcome shadow DOMs is to keep the global document handler in the DragRegistry and apply heuristic search using the event's composedPath(). This approach was discussed and rejected.
Another pro of setDraggedElement/clearDraggedElement is that it is more obvious to component developers as no logic happens behind the scenes. In the future, we might improve it even further by introducing a DragDropDelegate, similar to the ItemNavigation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the reasoning here. Why can't these lines be implemented within the DragRegistry? Since the table elements are in the light DOM, there should be no difference between registering this event on document.body or handling it directly in the Table.

You mentioned that this approach was discussed and rejected, but the reasons for that decision have not been shared. Also, the "pro" you mentioned is from my perspective a "contra".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only functional difference I can see between handling dragstart/dragend in the Table versus the DragRegistry would be in scenarios where the Table is used inside the shadow root of another Web Component with movable rows enabled( lets name it a SmartTable)

In your current approach, the source parameter of the dragstart event would be the TableRow inside the Table's shadow DOM (if this is desired from the SmartTable perspective is discussable). If handled via DragRegistry, the source would instead be the SmartTable. I don’t see this as a problem, this is consistent with how Web Components behave. The target parameter of any event never points to an element inside a shadow DOM. If you've discussed this internally and disagree, I'd recommend inspecting composedPath() to find the first UI5 element that is movable.

PS: In the current implementation, because the table elements reside in the light DOM, dragging a link or text within a row results in the dragged element being registered in the DragRegistry instead of the row itself. I believe this is incorrect. This suggests there may need to be adjustments in the TableRow implementation.

@dimovpetar dimovpetar requested a review from aborjinik August 8, 2025 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Tree/DragDrop] Shadow DOM usage breaks DragDrop behaviour
3 participants