From deaf865a20674cc5811e18345bd1ebb88154abda Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Mon, 18 Nov 2024 10:56:13 +0200 Subject: [PATCH 1/3] fix: attach element when used in drag source Attach elemnt to dom and move it outside of the viewport to have it visible as a drag image. Image can be used without attaching to dom. Hidden elements are also not shown so throw exception when using one as dragImage. Fixes #20426 --- .../vaadin/flow/component/dnd/DragSource.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java index 7e799cef943..1d3fe5c451e 100644 --- a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java +++ b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java @@ -17,6 +17,8 @@ import java.util.Locale; +import org.slf4j.LoggerFactory; + import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEventListener; import com.vaadin.flow.component.ComponentUtil; @@ -25,6 +27,7 @@ import com.vaadin.flow.component.dependency.JsModule; import com.vaadin.flow.component.dnd.internal.DndUtil; import com.vaadin.flow.dom.Element; +import com.vaadin.flow.dom.Style; import com.vaadin.flow.internal.nodefeature.VirtualChildrenList; import com.vaadin.flow.shared.Registration; @@ -344,6 +347,10 @@ default void setDragImage(Component dragImage) { * the y-offset of the drag image */ default void setDragImage(Component dragImage, int offsetX, int offsetY) { + if (dragImage != null && !dragImage.isVisible()) { + throw new IllegalStateException( + "Drag image element is not visible and will not show.\nMake element visible to use as drag image!"); + } if (getDragImage() != null && getDragImage() != dragImage) { // Remove drag image from the virtual children list if it's there. if (getDraggableElement().getNode() @@ -362,14 +369,12 @@ default void setDragImage(Component dragImage, int offsetX, int offsetY) { getDragSourceComponent().addAttachListener(event -> { if (!dragImage.isAttached() && dragImage.getParent().isEmpty()) { - getDraggableElement() - .appendVirtualChild(dragImage.getElement()); + appendDragElement(dragImage.getElement()); } event.unregisterListener(); }); } else { - getDraggableElement() - .appendVirtualChild(dragImage.getElement()); + appendDragElement(dragImage.getElement()); } } ComponentUtil.setData(getDragSourceComponent(), @@ -380,6 +385,20 @@ default void setDragImage(Component dragImage, int offsetX, int offsetY) { (dragImage == null ? 0 : offsetY), getDraggableElement()); } + private void appendDragElement(Element dragElement) { + if (dragElement.getTag().equals("img")) { + getDraggableElement().appendVirtualChild(dragElement); + } else { + LoggerFactory.getLogger(DragSource.class).info( + "Attaching child to dom in position -100,-100. Consider adding the component manually to not get overlapping components on drag for element."); + getDraggableElement().appendChild(dragElement); + Style style = dragElement.getStyle(); + style.set("position", "absolute"); + style.set("top", "-100px"); + style.set("left", "-100px"); + } + } + /** * Get server side drag image. This image is applied automatically in the * next drag start event in the browser. From 151349aa6d7885c1d7ebd5eabc79e221268b4b98 Mon Sep 17 00:00:00 2001 From: Mikael Grankvist Date: Mon, 18 Nov 2024 15:04:58 +0200 Subject: [PATCH 2/3] Use display none for added element --- .../java/com/vaadin/flow/component/dnd/DragSource.java | 1 + .../resources/META-INF/resources/frontend/dndConnector.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java index 1d3fe5c451e..fbb90037ac9 100644 --- a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java +++ b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java @@ -396,6 +396,7 @@ private void appendDragElement(Element dragElement) { style.set("position", "absolute"); style.set("top", "-100px"); style.set("left", "-100px"); + style.set("display", "none"); } } diff --git a/flow-dnd/src/main/resources/META-INF/resources/frontend/dndConnector.js b/flow-dnd/src/main/resources/META-INF/resources/frontend/dndConnector.js index 853dec45483..5450db3083b 100644 --- a/flow-dnd/src/main/resources/META-INF/resources/frontend/dndConnector.js +++ b/flow-dnd/src/main/resources/META-INF/resources/frontend/dndConnector.js @@ -93,6 +93,10 @@ window.Vaadin.Flow.dndConnector = { event.currentTarget.classList.add('v-dragged'); } if(event.currentTarget.__dragImage) { + if(event.currentTarget.__dragImage.style.display === "none") { + event.currentTarget.__dragImage.style.display = "block"; + event.currentTarget.classList.add('shown'); + } event.dataTransfer.setDragImage( event.currentTarget.__dragImage, event.currentTarget.__dragImageOffsetX, @@ -102,6 +106,10 @@ window.Vaadin.Flow.dndConnector = { __dragendListener: function (event) { event.currentTarget.classList.remove('v-dragged'); + if(event.currentTarget.classList.contains('shown')) { + event.currentTarget.classList.remove('shown'); + event.currentTarget.__dragImage.style.display = "none"; + } }, updateDragSource: function (element) { From e3a4042a27ada363b692bcb308b95d6ff4b9f8b8 Mon Sep 17 00:00:00 2001 From: caalador Date: Tue, 19 Nov 2024 06:42:23 +0200 Subject: [PATCH 3/3] Log as debug Log attach as debug now that the Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com> --- .../src/main/java/com/vaadin/flow/component/dnd/DragSource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java index fbb90037ac9..b3fa8e28227 100644 --- a/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java +++ b/flow-dnd/src/main/java/com/vaadin/flow/component/dnd/DragSource.java @@ -389,7 +389,7 @@ private void appendDragElement(Element dragElement) { if (dragElement.getTag().equals("img")) { getDraggableElement().appendVirtualChild(dragElement); } else { - LoggerFactory.getLogger(DragSource.class).info( + LoggerFactory.getLogger(DragSource.class).debug( "Attaching child to dom in position -100,-100. Consider adding the component manually to not get overlapping components on drag for element."); getDraggableElement().appendChild(dragElement); Style style = dragElement.getStyle();