Skip to content

Commit f83bfc2

Browse files
authored
fix: resize only on direction of drag move (#8222)
* fix: resize only on direction of drag move * test: skip test for safari
1 parent 748501e commit f83bfc2

File tree

3 files changed

+127
-5
lines changed

3 files changed

+127
-5
lines changed

packages/dashboard/src/widget-resize-controller.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,10 @@ export class WidgetResizeController {
8989

9090
const currentElementHeight = itemWrapper.firstElementChild.offsetHeight;
9191
const rowMinHeight = Math.min(...gridStyle.gridTemplateRows.split(' ').map((height) => parseFloat(height)));
92-
if (this.__resizeHeight > currentElementHeight + gapSize + rowMinHeight / 2) {
92+
if (e.detail.ddy > 0 && this.__resizeHeight > currentElementHeight + gapSize + rowMinHeight / 2) {
9393
// Resized vertically above the half of the next row, increase rowspan
9494
this.__updateResizedItem(0, 1);
95-
} else if (this.__resizeHeight < currentElementHeight - rowMinHeight / 2) {
95+
} else if (e.detail.ddy < 0 && this.__resizeHeight < currentElementHeight - rowMinHeight / 2) {
9696
// Resized vertically below the half of the current row, decrease rowspan
9797
this.__updateResizedItem(0, -1);
9898
}

packages/dashboard/test/dashboard-widget-resizing.test.ts

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect } from '@vaadin/chai-plugins';
2-
import { fixtureSync, nextFrame } from '@vaadin/testing-helpers';
2+
import { fire, fixtureSync, nextFrame } from '@vaadin/testing-helpers';
33
import sinon from 'sinon';
44
import '../vaadin-dashboard.js';
55
import { isSafari } from '@vaadin/component-base/src/browser-utils.js';
@@ -11,6 +11,8 @@ import {
1111
fireResizeOver,
1212
fireResizeStart,
1313
getElementFromCell,
14+
getEventCoordinates,
15+
getResizeHandle,
1416
onceResized,
1517
setMaximumColumnWidth,
1618
setMinimumColumnWidth,
@@ -201,10 +203,34 @@ describe('dashboard - widget resizing', () => {
201203
[0, 2],
202204
]);
203205

206+
const resizeHandle = getResizeHandle(getElementFromCell(dashboard, 1, 0)!);
207+
const { x: initialX, y: initialY } = getEventCoordinates(resizeHandle, 'bottom');
208+
204209
fireResizeStart(getElementFromCell(dashboard, 1, 0)!);
205210
await nextFrame();
206211

207-
fireResizeOver(getElementFromCell(dashboard, 0, 0)!, 'top');
212+
const targetElement = getElementFromCell(dashboard, 0, 0)!;
213+
fireResizeOver(targetElement, 'top');
214+
await nextFrame();
215+
216+
const { x: targetX, y: targetY } = getEventCoordinates(targetElement, 'top');
217+
const event = new MouseEvent('mousemove', {
218+
bubbles: true,
219+
composed: true,
220+
clientX: targetX,
221+
clientY: targetY,
222+
buttons: 1,
223+
});
224+
targetElement.dispatchEvent(event);
225+
fire(resizeHandle, 'track', {
226+
state: 'track',
227+
x: targetX,
228+
y: targetY - 1,
229+
dx: targetX - initialX,
230+
dy: targetY - initialY - 1,
231+
ddx: 0,
232+
ddy: -1,
233+
});
208234
await nextFrame();
209235

210236
fireResizeEnd(dashboard);
@@ -323,6 +349,99 @@ describe('dashboard - widget resizing', () => {
323349
]);
324350
});
325351

352+
(isSafari ? it.skip : it)('should resize only when dragged in the same direction (top -> bottom)', async () => {
353+
setMinimumRowHeight(dashboard, 50);
354+
dashboard.items = [{ id: 0, rowspan: 2 }, { id: 1 }, { id: 2 }];
355+
await nextFrame();
356+
357+
// prettier-ignore
358+
expectLayout(dashboard, [
359+
[0, 1],
360+
[0, 2],
361+
]);
362+
363+
const widget = getElementFromCell(dashboard, 0, 1)!;
364+
const initialHeight = widget.offsetHeight;
365+
fireResizeStart(widget);
366+
await nextFrame();
367+
368+
const targetElement = getElementFromCell(dashboard, 1, 1)!;
369+
const { x, y } = getEventCoordinates(targetElement, 'top');
370+
const minSizeIncreaseDelta = initialHeight / 2 + 1;
371+
const minSizeIncreaseY = y + minSizeIncreaseDelta;
372+
const event = new MouseEvent('mousemove', {
373+
bubbles: true,
374+
composed: true,
375+
clientX: x,
376+
clientY: minSizeIncreaseY,
377+
buttons: 1,
378+
});
379+
targetElement.dispatchEvent(event);
380+
await nextFrame();
381+
382+
let previousHeight = initialHeight;
383+
const resizeHandle = getResizeHandle(widget);
384+
for (let i = 1; i < 5; i++) {
385+
fire(resizeHandle, 'track', {
386+
state: 'track',
387+
x,
388+
y: minSizeIncreaseY + i,
389+
dx: 0,
390+
dy: minSizeIncreaseDelta + i,
391+
ddx: 0,
392+
ddy: 1,
393+
});
394+
await nextFrame();
395+
const newHeight = getElementFromCell(dashboard, 0, 1)!.offsetHeight;
396+
expect(newHeight >= previousHeight).to.be.true;
397+
previousHeight = newHeight;
398+
}
399+
});
400+
401+
it('should resize only when dragged in the same direction (bottom -> top)', async () => {
402+
setMinimumRowHeight(dashboard, 50);
403+
dashboard.items = [{ id: 0, rowspan: 2 }, { id: 1 }, { id: 2, rowspan: 3 }];
404+
await nextFrame();
405+
406+
const widget = getElementFromCell(dashboard, 2, 1)!;
407+
const initialHeight = widget.offsetHeight;
408+
fireResizeStart(widget);
409+
await nextFrame();
410+
411+
const targetElement = getElementFromCell(dashboard, 1, 1)!;
412+
const { x, y } = getEventCoordinates(targetElement, 'top');
413+
const minSizeDecreaseDelta = initialHeight / 3 + 1;
414+
const minSizeDecreaseY = y - minSizeDecreaseDelta;
415+
const event = new MouseEvent('mousemove', {
416+
bubbles: true,
417+
composed: true,
418+
clientX: x,
419+
clientY: minSizeDecreaseY,
420+
buttons: 1,
421+
});
422+
targetElement.dispatchEvent(event);
423+
await nextFrame();
424+
425+
let previousHeight = initialHeight;
426+
const resizeHandle = getResizeHandle(widget);
427+
428+
for (let i = 1; i < 5; i++) {
429+
fire(resizeHandle, 'track', {
430+
state: 'track',
431+
x,
432+
y: minSizeDecreaseY - i,
433+
dx: 0,
434+
dy: minSizeDecreaseDelta - i,
435+
ddx: 0,
436+
ddy: -1,
437+
});
438+
await nextFrame();
439+
const newHeight = getElementFromCell(dashboard, 1, 1)!.offsetHeight;
440+
expect(newHeight <= previousHeight).to.be.true;
441+
previousHeight = newHeight;
442+
}
443+
});
444+
326445
it('should dispatch an item resized event', async () => {
327446
const resizeEndSpy = sinon.spy();
328447
dashboard.addEventListener('dashboard-item-resized', resizeEndSpy);

packages/dashboard/test/helpers.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,10 @@ export function createDragEvent(type: string, { x, y }: { x: number; y: number }
229229
return event;
230230
}
231231

232-
function getEventCoordinates(relativeElement: Element, location: 'top' | 'bottom' | 'start' | 'end') {
232+
export function getEventCoordinates(
233+
relativeElement: Element,
234+
location: 'top' | 'bottom' | 'start' | 'end',
235+
): { x: number; y: number } {
233236
const { top, bottom, left, right } = relativeElement.getBoundingClientRect();
234237
const y = location === 'top' ? top : bottom;
235238
const dir = document.dir;

0 commit comments

Comments
 (0)