diff --git a/packages/base/src/util/dragAndDrop/GlobalDragDropManager.ts b/packages/base/src/util/dragAndDrop/GlobalDragDropManager.ts new file mode 100644 index 000000000000..f41a3e9fa0cc --- /dev/null +++ b/packages/base/src/util/dragAndDrop/GlobalDragDropManager.ts @@ -0,0 +1,62 @@ +import type UI5Element from "../../UI5Element.js"; +import DragRegistry from "./DragRegistry.js"; + +let globalHandlersAttached = false; +const subscribers = new Set(); + +const ondragstart = (e: DragEvent) => { + if (!e.dataTransfer) { + return; + } + + const draggedElement = e.composedPath().find(el => (el as any).movable) as HTMLElement; + + if (!subscribers.has(draggedElement.parentElement as UI5Element)) { + return; + } + + DragRegistry.setDraggedElement(draggedElement); +}; + +const ondragend = () => { + DragRegistry.clearDraggedElement(); +}; + +const attachGlobalHandlers = () => { + if (globalHandlersAttached) { + return; + } + + document.body.addEventListener("dragstart", ondragstart); + document.body.addEventListener("dragend", ondragend); + globalHandlersAttached = true; +}; + +const detachGlobalHandlers = () => { + document.body.removeEventListener("dragstart", ondragstart); + document.body.removeEventListener("dragend", ondragend); + globalHandlersAttached = false; +}; + +const subscribe = (subscriber: UI5Element) => { + subscribers.add(subscriber); + + if (!globalHandlersAttached) { + attachGlobalHandlers(); + } +}; + +const unsubscribe = (subscriber: UI5Element) => { + subscribers.delete(subscriber); + + if (subscribers.size === 0 && globalHandlersAttached) { + detachGlobalHandlers(); + } +}; + +const GlobalDragDropManager = { + subscribe, + unsubscribe, +}; + +export default GlobalDragDropManager; diff --git a/packages/main/src/Table.ts b/packages/main/src/Table.ts index 639178f8c095..f5d0b22bc1c1 100644 --- a/packages/main/src/Table.ts +++ b/packages/main/src/Table.ts @@ -9,6 +9,7 @@ import TableStyles from "./generated/themes/Table.css.js"; import TableExtension from "./TableExtension.js"; import TableNavigation from "./TableNavigation.js"; import TableOverflowMode from "./types/TableOverflowMode.js"; +import GlobalDragDropManager from "@ui5/webcomponents-base/dist/util/dragAndDrop/GlobalDragDropManager.js"; import TableDragAndDrop from "./TableDragAndDrop.js"; import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; import { @@ -404,7 +405,7 @@ class Table extends UI5Element { @i18n("@ui5/webcomponents") static i18nBundle: I18nBundle; - _events = ["keydown", "keyup", "click", "focusin", "focusout", "dragstart", "dragenter", "dragleave", "dragover", "drop", "dragend"]; + _events = ["keydown", "keyup", "click", "focusin", "focusout", "dragenter", "dragleave", "dragover", "drop"]; _onEventBound: (e: Event) => void; _onResizeBound: ResizeObserverCallback; _tableNavigation?: TableNavigation; @@ -423,12 +424,14 @@ class Table extends UI5Element { this.features.forEach(feature => feature.onTableActivate?.(this)); this._tableNavigation = new TableNavigation(this); this._tableDragAndDrop = new TableDragAndDrop(this); + GlobalDragDropManager.subscribe(this); } onExitDOM() { this._tableNavigation = undefined; this._tableDragAndDrop = undefined; this._events.forEach(eventType => this.removeEventListener(eventType, this._onEventBound)); + GlobalDragDropManager.unsubscribe(this); } onBeforeRendering(): void { diff --git a/packages/main/src/TableDragAndDrop.ts b/packages/main/src/TableDragAndDrop.ts index 17bfe155e3a8..79ebb459f038 100644 --- a/packages/main/src/TableDragAndDrop.ts +++ b/packages/main/src/TableDragAndDrop.ts @@ -1,4 +1,3 @@ -import DragRegistry from "@ui5/webcomponents-base/dist/util/dragAndDrop/DragRegistry.js"; import { findClosestPosition } from "@ui5/webcomponents-base/dist/util/dragAndDrop/findClosestPosition.js"; import Orientation from "@ui5/webcomponents-base/dist/types/Orientation.js"; import handleDragOver from "@ui5/webcomponents-base/dist/util/dragAndDrop/handleDragOver.js"; @@ -14,14 +13,6 @@ export default class TableDragAndDrop extends TableExtension { this._table = table; } - _ondragstart(e: DragEvent) { - DragRegistry.setDraggedElement(e.target as HTMLElement); - } - - _ondragend() { - DragRegistry.clearDraggedElement(); - } - _ondragenter(e: DragEvent) { e.preventDefault(); } diff --git a/packages/main/test/pages/ListDragAndDrop.html b/packages/main/test/pages/ListDragAndDrop.html index c038f99ff314..b33c35f4600b 100644 --- a/packages/main/test/pages/ListDragAndDrop.html +++ b/packages/main/test/pages/ListDragAndDrop.html @@ -17,9 +17,9 @@

Drag and drop

- 1. Bulgaria - 1. Germany - 1. Spain + Item 1sap + Item 2 + Item 3
diff --git a/packages/main/test/pages/TableDragAndDropShadowDom.html b/packages/main/test/pages/TableDragAndDropShadowDom.html new file mode 100644 index 000000000000..64e7e24e9a62 --- /dev/null +++ b/packages/main/test/pages/TableDragAndDropShadowDom.html @@ -0,0 +1,145 @@ + + + + + + + Table (in development) + + + + + + + + + + + Item 1 + Item 2 + Item 3 + Item 4 + Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + +