From d6df3d2c7242e6db20bd7a54c16b9a55edec028e Mon Sep 17 00:00:00 2001 From: Alain Dumesny Date: Wed, 22 Dec 2021 18:49:49 -0800 Subject: [PATCH] dragging nested items no longer clipp * fix to make #992 better going forward as I'm focusing on nested grids again * dragging sub item between grids no longer get clipped by parent * removed basePosition.aboslute option as I'm not sure how we can make it work (parent has position.relative which will clip us otherwise) * nested.html you can drag pink items between grids (h5 case, JQ still clipps) --- doc/CHANGES.md | 1 + src/h5/dd-draggable.ts | 25 +++++++++++++++---------- src/h5/dd-resizable.ts | 4 +--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 7e5d9bfbe..186e63724 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -67,6 +67,7 @@ Change log ## 4.4.0-dev TBD * fix [#1901](https://github.com/gridstack/gridstack.js/pull/1901) error introduced for #1785 when re-loading with fewer objects +* fix [#1902](https://github.com/gridstack/gridstack.js/pull/1902) nested.html: dragging between sub-grids show items clipped ## 4.4.0 (2021-12-21) * add [#1887](https://github.com/gridstack/gridstack.js/pull/1887) support for IE (new es5 folder) by [@SmileLifeIven](https://github.com/SmileLifeIven) diff --git a/src/h5/dd-draggable.ts b/src/h5/dd-draggable.ts index f6c5714ad..db5721f51 100644 --- a/src/h5/dd-draggable.ts +++ b/src/h5/dd-draggable.ts @@ -16,7 +16,6 @@ export interface DDDraggableOpt { revert?: string | boolean | unknown; // TODO: not implemented yet scroll?: boolean; // nature support by HTML5 drag drop, can't be switch to off actually helper?: string | HTMLElement | ((event: Event) => HTMLElement); - basePosition?: 'fixed' | 'absolute'; start?: (event: Event, ui: DDUIData) => void; stop?: (event: Event) => void; drag?: (event: Event, ui: DDUIData) => void; @@ -52,13 +51,11 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt private parentOriginStylePosition: string; /** @internal */ private helperContainment: HTMLElement; - /** @internal */ - private static basePosition: 'fixed' | 'absolute' = 'absolute'; /** @internal #1541 can't have {passive: true} on Safari as otherwise it reverts animate back to old location on drop */ private static dragEventListenerOption = true; // DDUtils.isEventSupportPassiveOption ? { capture: true, passive: true } : true; /** @internal */ private static originStyleProp = ['transition', 'pointerEvents', 'position', - 'left', 'top', 'opacity', 'zIndex', 'width', 'height', 'willChange']; + 'left', 'top', 'opacity', 'zIndex', 'width', 'height', 'willChange', 'min-width']; constructor(el: HTMLElement, option: DDDraggableOpt = {}) { super(); @@ -213,13 +210,14 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt /** @internal */ private _setupHelperStyle(): DDDraggable { + // TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593 this.helper.style.pointerEvents = 'none'; this.helper.style.width = this.dragOffset.width + 'px'; this.helper.style.height = this.dragOffset.height + 'px'; this.helper.style.willChange = 'left, top'; this.helper.style.transition = 'none'; // show up instantly - this.helper.style.position = this.option.basePosition || DDDraggable.basePosition; - this.helper.style.zIndex = '1000'; + this.helper.style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative' + this.helper.style['min-width'] = 0; // since we no longer relative to our parent and we don't resize anyway (normally 100/#column %) setTimeout(() => { if (this.helper) { this.helper.style.transition = null; // recover animation @@ -232,10 +230,17 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt private _removeHelperStyle(): DDDraggable { // don't bother restoring styles if we're gonna remove anyway... let node = this.helper ? (this.helper as GridItemHTMLElement).gridstackNode : undefined; - if (!node || !node._isAboutToRemove) { + if (this.dragElementOriginStyle && (!node || !node._isAboutToRemove)) { DDDraggable.originStyleProp.forEach(prop => { this.helper.style[prop] = this.dragElementOriginStyle[prop] || null; }); + // show up instantly otherwise we animate to off the grid when switching back to 'absolute' from 'fixed' + this.helper.style.transition = 'none'; + setTimeout(() => { + if (this.helper) { + this.helper.style.transition = this.dragElementOriginStyle['transition']; // recover animation + } + }, 0); } delete this.dragElementOriginStyle; return this; @@ -262,7 +267,7 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt /** @internal */ private _setupHelperContainmentStyle(): DDDraggable { this.helperContainment = this.helper.parentElement; - if (this.option.basePosition !== 'fixed') { + if (this.helper.style.position !== 'fixed') { this.parentOriginStylePosition = this.helperContainment.style.position; if (window.getComputedStyle(this.helperContainment).position.match(/static/)) { this.helperContainment.style.position = 'relative'; @@ -271,10 +276,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt return this; } - /** @internal prevent the default gost image to be created (which has wrongas we move the helper/element instead + /** @internal prevent the default ghost image to be created (which has wrong as we move the helper/element instead * (legacy jquery UI code updates the top/left of the item). * TODO: maybe use mouse event instead of HTML5 drag as we have to work around it anyway, or change code to not update - * the actual grid-item but move the gost image around (and special case jq version) ? + * the actual grid-item but move the ghost image around (and special case jq version) ? **/ private _cancelDragGhost(e: DragEvent): DDDraggable { /* doesn't seem to do anything... diff --git a/src/h5/dd-resizable.ts b/src/h5/dd-resizable.ts index 6719d2e21..cfd759533 100644 --- a/src/h5/dd-resizable.ts +++ b/src/h5/dd-resizable.ts @@ -17,7 +17,6 @@ export interface DDResizableOpt { maxWidth?: number; minHeight?: number; minWidth?: number; - basePosition?: 'fixed' | 'absolute'; start?: (event: Event, ui: DDUIData) => void; stop?: (event: Event) => void; resize?: (event: Event, ui: DDUIData) => void; @@ -206,9 +205,8 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt if (window.getComputedStyle(this.el.parentElement).position.match(/static/)) { this.el.parentElement.style.position = 'relative'; } - this.el.style.position = this.option.basePosition || 'absolute'; // or 'fixed' + this.el.style.position = 'absolute'; this.el.style.opacity = '0.8'; - this.el.style.zIndex = '1000'; return this; }