diff --git a/spec/dd-simple-integration-spec.ts b/spec/dd-simple-integration-spec.ts index 3e506dc35..16a7d2380 100644 --- a/spec/dd-simple-integration-spec.ts +++ b/spec/dd-simple-integration-spec.ts @@ -351,6 +351,35 @@ describe('DD Integration Tests', () => { resizable.destroy(); }); + it('should keep peer resize handles hidden during an active resize', () => { + const peer = document.createElement('div') as GridItemHTMLElement; + document.body.appendChild(peer); + const resizable = new DDResizable(element, {handles: 'se', autoHide: true}); + const peerResizable = new DDResizable(peer, {handles: 'se', autoHide: true}); + const handle = element.querySelector('.ui-resizable-se')!; + + try { + mouse('mouseover', 100, 100, element); + mouse('mousedown', 100, 100, handle); + mouse('mousemove', 120, 120); + expect(element.classList.contains('ui-resizable-resizing')).toBe(true); + + mouse('mouseout', 120, 120, element); + mouse('mouseover', 120, 120, peer); + + expect(peer.classList.contains('ui-resizable-autohide')).toBe(true); + + mouse('mouseup', 120, 120); + expect(peer.classList.contains('ui-resizable-autohide')).toBe(false); + expect(DDManager.resizeElement).toBeUndefined(); + } finally { + mouse('mouseup', 120, 120); + resizable.destroy(); + peerResizable.destroy(); + peer.remove(); + } + }); + it('should cancel the resize on Escape', () => { const stop = vi.fn(); const resizable = new DDResizable(element, {handles: 'se', stop}); @@ -361,6 +390,7 @@ describe('DD Integration Tests', () => { document.dispatchEvent(new KeyboardEvent('keydown', {key: 'Escape', bubbles: true})); expect(stop).toHaveBeenCalled(); + expect(DDManager.resizeElement).toBeUndefined(); resizable.destroy(); }); }); diff --git a/src/dd-manager.ts b/src/dd-manager.ts index a390b20f6..ae51f7b60 100644 --- a/src/dd-manager.ts +++ b/src/dd-manager.ts @@ -49,9 +49,12 @@ export class DDManager { public static dropElement?: DDDroppable; /** - * Reference to the element currently being resized. - * Helps ignore nested grid resize handles during resize operations. + * Reference to the resizable element currently under the pointer. + * Helps ignore nested grid resize handles during hover operations. */ public static overResizeElement?: DDResizable; + /** @internal element with an active resize operation, used to keep peer handles hidden */ + public static resizeElement?: DDResizable; + } diff --git a/src/dd-resizable.ts b/src/dd-resizable.ts index 157ff3494..013bfddf6 100644 --- a/src/dd-resizable.ts +++ b/src/dd-resizable.ts @@ -143,7 +143,7 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt if (DDManager.overResizeElement || DDManager.dragElement) return; DDManager.overResizeElement = this; // console.log(`${count++} enter ${(this.el as GridItemHTMLElement).gridstackNode._id}`) - this.el.classList.remove('ui-resizable-autohide'); + if (!DDManager.resizeElement) this.el.classList.remove('ui-resizable-autohide'); } /** @internal */ @@ -181,6 +181,7 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt this._setupHelper(); this._applyChange(); const ev = Utils.initEvent(event, { type: 'resizestart', target: this.el }); + DDManager.resizeElement = this; if (this.option.start) { this.option.start(ev, this._ui()); } @@ -215,6 +216,10 @@ export class DDResizable extends DDBaseImplement implements HTMLElementExtendOpt this.option.stop(ev); // Note: ui() not used by gridstack so don't pass } this.el.classList.remove('ui-resizable-resizing'); + if (DDManager.resizeElement === this) delete DDManager.resizeElement; + if (!DDManager.resizeElement && DDManager.overResizeElement) { + DDManager.overResizeElement.el.classList.remove('ui-resizable-autohide'); + } this.triggerEvent('resizestop', ev); delete this.startEvent; delete this.originalRect;