Skip to content

Commit 1450ef8

Browse files
committed
[6027] Improve visual feedback for diagram DnD
Bug: #6027 Signed-off-by: Pierre-Charles David <pierre-charles.david@obeo.fr>
1 parent 453eedb commit 1450ef8

File tree

3 files changed

+29
-16
lines changed

3 files changed

+29
-16
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,7 @@ Downstream applications can now implement `IProxyRemovalServiceDelegate` to cust
250250
The node action icons are now a little smaller and only appear after the node has been hovered for 0.5s.
251251
- https://github.com/eclipse-sirius/sirius-web/issues/6022[#6022] [sirius-web] Rename the "Representations" workbench view to "Related Views"
252252
- https://github.com/eclipse-sirius/sirius-web/issues/6041[#6041] [sirius-web] Provide access to the `editingContextId`, for migration participants during the loading of the resources, thanks to an adapter on the resource set named `EditingContextAdapter`.
253-
254-
253+
- https://github.com/eclipse-sirius/sirius-web/issues/6027[#6027] [diagram] Improve visual feedback when dragging a node to show which targets are compatible/valid/invalid for a drop
255254

256255
== 2025.12.0
257256

integration-tests-playwright/playwright/e2e/diagrams/dnd.spec.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2025 Obeo.
2+
* Copyright (c) 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -141,9 +141,7 @@ test.describe('diagram - drag and drop', () => {
141141
() => {
142142
const node = document.querySelector(`[data-testid="FreeForm - Entity1"]`);
143143
// We need to check for the normalized box-shadow value, which is different from what we set in the code, but equivalent
144-
return (
145-
node && window.getComputedStyle(node).getPropertyValue('box-shadow') === 'rgb(67, 160, 71) 0px 0px 2px 2px'
146-
);
144+
return node && window.getComputedStyle(node).getPropertyValue('box-shadow').match('oklab\\(');
147145
},
148146
{ timeout: 2000 }
149147
);

packages/diagrams/frontend/sirius-components-diagrams/src/renderer/dropNode/useDropNodeStyle.ts

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023, 2025 Obeo.
2+
* Copyright (c) 2023, 2026 Obeo.
33
* This program and the accompanying materials
44
* are made available under the terms of the Eclipse Public License v2.0
55
* which accompanies this distribution, and is available at
@@ -17,23 +17,39 @@ import { DiagramContext } from '../../contexts/DiagramContext';
1717
import { DiagramContextValue } from '../../contexts/DiagramContext.types';
1818
import { useDropNodeStyleValue } from './useDropNodeStyle.types';
1919

20+
/**
21+
* Computes the CSS style customization to apply to a given node during a DnD operation.
22+
*
23+
* @param isDropNodeTarget whether the node to style is currently targeted by the drop
24+
* (i.e. the mouse is on top of it, and releasing the mousing
25+
* button would trigger the drop on this node)
26+
* @param isDropNodeCandidate whether the node to style is a compatible drop candidate
27+
* for the dragged element(s)
28+
* @param isDragging whether the node is (one of) the node(s) being moved/dragged.
29+
* @returns CSS properties to apply to the node to give feedback to the user.
30+
*/
2031
export const useDropNodeStyle = (
2132
isDropNodeTarget: boolean,
22-
isDropNodeCandidate,
33+
isDropNodeCandidate: boolean,
2334
isDragging: boolean
2435
): useDropNodeStyleValue => {
2536
const { readOnly } = useContext<DiagramContextValue>(DiagramContext);
26-
2737
const theme = useTheme();
28-
const style: React.CSSProperties = {};
38+
const dropPossible = `rgb(from ${theme.palette.success.main} r g b / 0.5)`;
39+
const dropValid = theme.palette.success.main;
40+
const dropInvalid = `rgb(from ${theme.palette.error.main} r g b / 0.5)`;
2941

30-
if (!readOnly) {
31-
if (!isDragging && isDropNodeCandidate) {
32-
style.boxShadow = `0px 0px 2px 2px ${theme.palette.success.main}`;
33-
style.transition = `box-shadow 0.3s ease-in-out`;
42+
const style: React.CSSProperties = {};
43+
if (!readOnly && !isDragging) {
44+
let highlightColor: string | null = null;
45+
if (isDropNodeCandidate) {
46+
highlightColor = isDropNodeTarget ? dropValid : dropPossible;
47+
} else if (isDropNodeTarget) {
48+
highlightColor = dropInvalid;
3449
}
35-
if (isDropNodeTarget) {
36-
style.boxShadow = `0px 0px 2px 2px ${theme.palette.primary.main}`;
50+
if (highlightColor) {
51+
style.boxShadow = `0px 0px 2px 2px ${highlightColor}`;
52+
style.transition = `box-shadow 0.3s ease-in-out`;
3753
}
3854
}
3955

0 commit comments

Comments
 (0)