From ea861725e93894763b5c63d76d59ba6e55406444 Mon Sep 17 00:00:00 2001 From: Tomi Virkki Date: Wed, 11 Sep 2024 12:54:06 +0300 Subject: [PATCH] document and fixes --- .../dashboard/src/vaadin-dashboard-widget.js | 4 ++++ .../dashboard/src/widget-resize-controller.js | 13 +++++++++++ .../test/dashboard-widget-resizing.test.ts | 23 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/packages/dashboard/src/vaadin-dashboard-widget.js b/packages/dashboard/src/vaadin-dashboard-widget.js index 52a8f38c4a..c853ac406f 100644 --- a/packages/dashboard/src/vaadin-dashboard-widget.js +++ b/packages/dashboard/src/vaadin-dashboard-widget.js @@ -49,6 +49,10 @@ class DashboardWidget extends ControllerMixin(ElementMixin(PolylitMixin(LitEleme flex: 1; } + #resize-handle { + display: var(--_vaadin-dashboard-widget-actions-display, none); + } + #resize-handle::before { position: absolute; bottom: 0; diff --git a/packages/dashboard/src/widget-resize-controller.js b/packages/dashboard/src/widget-resize-controller.js index df864bd488..33037890f4 100644 --- a/packages/dashboard/src/widget-resize-controller.js +++ b/packages/dashboard/src/widget-resize-controller.js @@ -49,8 +49,10 @@ export class WidgetResizeController extends EventTarget { this.host.dispatchEvent(new CustomEvent('dashboard-item-resize-start')); this.__resizedElement = e.target; + // Observe the removal of the resized element from the DOM this.__resizedElementRemoveObserver.observe(this.host, { childList: true, subtree: true }); + // Prevent scrolling on touch devices while resizing document.addEventListener('touchmove', this.__touchMoveCancelListener, { passive: false }); } @@ -76,16 +78,24 @@ export class WidgetResizeController extends EventTarget { const columns = gridStyle.gridTemplateColumns.split(' '); const columnWidth = parseFloat(columns[0]); if (this.__resizeWidth > currentElementWidth + gapSize + columnWidth / 2) { + // Resized horizontally above the half of the next column, increase colspan this.__updateResizedItem(Math.min((this.resizedItem.colspan || 1) + 1, columns.length), this.resizedItem.rowspan); } else if (this.__resizeWidth < currentElementWidth - columnWidth / 2) { + // Resized horizontally below the half of the current column, decrease colspan this.__updateResizedItem(Math.max((this.resizedItem.colspan || 1) - 1, 1), this.resizedItem.rowspan); } + if (!gridStyle.getPropertyValue('--vaadin-dashboard-row-min-height')) { + return; + } + const currentElementHeight = itemWrapper.firstElementChild.offsetHeight; const rowMinHeight = Math.min(...gridStyle.gridTemplateRows.split(' ').map((height) => parseFloat(height))); if (this.__resizeHeight > currentElementHeight + gapSize + rowMinHeight / 2) { + // Resized vertically above the half of the next row, increase rowspan this.__updateResizedItem(this.resizedItem.colspan, (this.resizedItem.rowspan || 1) + 1); } else if (this.__resizeHeight < currentElementHeight - rowMinHeight / 2) { + // Resized vertically below the half of the current row, decrease rowspan this.__updateResizedItem(this.resizedItem.colspan, Math.max((this.resizedItem.rowspan || 1) - 1, 1)); } } @@ -108,9 +118,12 @@ export class WidgetResizeController extends EventTarget { this.host.$.grid.toggleAttribute('resizing', false); + // Disconnect the observer for the resized element removal this.__resizedElementRemoveObserver.disconnect(); + // Cleanup the touchmove listener this.cleanup(); + // Dispatch the resize end event this.host.dispatchEvent( new CustomEvent('dashboard-item-resize-end', { detail: { item: this.resizedItem }, diff --git a/packages/dashboard/test/dashboard-widget-resizing.test.ts b/packages/dashboard/test/dashboard-widget-resizing.test.ts index be19b8e987..cb2b5d6dd0 100644 --- a/packages/dashboard/test/dashboard-widget-resizing.test.ts +++ b/packages/dashboard/test/dashboard-widget-resizing.test.ts @@ -211,6 +211,29 @@ describe('dashboard - widget resizing', () => { ]); }); + it('should not resize vertically if minimum row height is not defined', async () => { + setMinimumRowHeight(dashboard, undefined); + dashboard.items = [{ id: 0 }, { id: 1 }, { id: 2 }]; + await nextFrame(); + // prettier-ignore + expectLayout(dashboard, [ + [0, 1], + [2], + ]); + + fireResizeStart(getElementFromCell(dashboard, 0, 0)!); + await nextFrame(); + + fireResizeOver(getElementFromCell(dashboard, 1, 0)!, 'bottom'); + await nextFrame(); + + // prettier-ignore + expectLayout(dashboard, [ + [0, 1], + [2], + ]); + }); + it('should not resize a widget if not dragging by the resize handle', async () => { const widget = getElementFromCell(dashboard, 0, 0)!; widget.shadowRoot?.querySelector('.resize-handle')?.remove();