From 5cd7f2b56386c51d4f13c1c39aae0b9580824eb4 Mon Sep 17 00:00:00 2001 From: Jamie Linskell Date: Wed, 12 Mar 2025 13:08:24 +0000 Subject: [PATCH] #2667 Fixed sidebar items not honouring gs-w and gs-h when dragging between multiple grids. Fixed gs-w and gs-h attributes being written back to original sidebar item --- src/gridstack.ts | 18 ++++++++++++++++-- src/types.ts | 2 ++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gridstack.ts b/src/gridstack.ts index cc873eda3..1f589e387 100644 --- a/src/gridstack.ts +++ b/src/gridstack.ts @@ -2215,6 +2215,12 @@ export class GridStack { return false; // prevent parent from receiving msg (which may be a grid as well) } + // If sidebar item, restore the sidebar node size to ensure consistent behavior when dragging between grids + if (node?._sidebarOrig) { + node.w = node._sidebarOrig.w; + node.h = node._sidebarOrig.h; + } + // fix #1578 when dragging fast, we may not get a leave on the previous grid so force one now if (node?.grid && node.grid !== this && !node._temporaryRemoved) { // console.log('dropover without leave'); // TEST @@ -2227,7 +2233,7 @@ export class GridStack { cellWidth = this.cellWidth(); cellHeight = this.getCellHeight(true); - // sidebar items: load any element attributes if we don't have a node + // sidebar items: load any element attributes if we don't have a node on first enter from the sidebar if (!node) { const attr = helper.getAttribute('data-gs-widget') || helper.getAttribute('gridstacknode'); // TBD: temp support for old V11.0.0 attribute if (attr) { @@ -2240,6 +2246,8 @@ export class GridStack { helper.removeAttribute('gridstacknode'); } if (!node) node = this._readAttr(helper); // used to pass false for #2354, but now we clone top level node + // On first grid enter from sidebar, set the initial sidebar item size properties for the node + node._sidebarOrig = { w: node.w, h: node.h } } if (!node.grid) { // sidebar item if (!node.el) node = {...node}; // clone first time we're coming from sidebar (since 'clone' doesn't copy vars) @@ -2661,7 +2669,10 @@ export class GridStack { this._updateContainerHeight(); const target = event.target as GridItemHTMLElement;// @ts-ignore - this._writePosAttr(target, node); + // Do not write sidebar item attributes back to the original sidebar el + if (!node._sidebarOrig) { + this._writePosAttr(target, node); + } if (this._gsEventHandler[event.type]) { this._gsEventHandler[event.type](event, target); } @@ -2687,7 +2698,10 @@ export class GridStack { this.engine.removeNode(node); // remove placeholder as well, otherwise it's a sign node is not in our list, which is a bigger issue node.el = node._isExternal && helper ? helper : el; // point back to real item being dragged + const sidebarOrig = node._sidebarOrig; if (node._isExternal) this.engine.cleanupNode(node); + // Restore sidebar item initial size info to stay consistent when dragging between multiple grids + node._sidebarOrig = sidebarOrig; if (this.opts.removable === true) { // boolean vs a class string // item leaving us and we are supposed to remove on leave (no need to drag onto trash) mark it so diff --git a/src/types.ts b/src/types.ts index fcf985567..05283a5cb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -456,6 +456,8 @@ export interface GridStackNode extends GridStackWidget { _temporaryRemoved?: boolean; /** @internal true if we should remove DOM element on _notify() rather than clearing _id (old way) */ _removeDOM?: boolean; + /** @internal original position/size of item if dragged from sidebar */ + _sidebarOrig?: GridStackPosition; /** @internal had drag&drop been initialized */ _initDD?: boolean; }