From 0b1a09d910ad5a6c357e2ab49475c4ded9e3ba05 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:13:44 +0000 Subject: [PATCH] feat: replace transform with top,left,width,height --- .../src/__tests__/dnd/droptarget.spec.ts | 88 +++++++++++++------ packages/dockview-core/src/dnd/droptarget.ts | 41 ++++++--- 2 files changed, 89 insertions(+), 40 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dnd/droptarget.spec.ts b/packages/dockview-core/src/__tests__/dnd/droptarget.spec.ts index 517fa40aa..3f04a800e 100644 --- a/packages/dockview-core/src/__tests__/dnd/droptarget.spec.ts +++ b/packages/dockview-core/src/__tests__/dnd/droptarget.spec.ts @@ -171,18 +171,37 @@ describe('droptarget', () => { createOffsetDragOverEvent({ clientX: 19, clientY: 0 }) ); + function check( + element: HTMLElement, + box: { + left: string; + top: string; + width: string; + height: string; + } + ) { + expect(element.style.top).toBe(box.top); + expect(element.style.left).toBe(box.left); + expect(element.style.width).toBe(box.width); + expect(element.style.height).toBe(box.height); + } + viewQuery = element.querySelectorAll( '.drop-target > .drop-target-dropzone > .drop-target-selection' ); expect(viewQuery.length).toBe(1); expect(droptarget.state).toBe('left'); - expect( - ( - element - .getElementsByClassName('drop-target-selection') - .item(0) as HTMLDivElement - ).style.transform - ).toBe('translateX(-25%) scaleX(0.5)'); + check( + element + .getElementsByClassName('drop-target-selection') + .item(0) as HTMLDivElement, + { + top: '0px', + left: '0px', + width: '50%', + height: '100%', + } + ); fireEvent( target, @@ -194,13 +213,17 @@ describe('droptarget', () => { ); expect(viewQuery.length).toBe(1); expect(droptarget.state).toBe('top'); - expect( - ( - element - .getElementsByClassName('drop-target-selection') - .item(0) as HTMLDivElement - ).style.transform - ).toBe('translateY(-25%) scaleY(0.5)'); + check( + element + .getElementsByClassName('drop-target-selection') + .item(0) as HTMLDivElement, + { + top: '0px', + left: '0px', + width: '100%', + height: '50%', + } + ); fireEvent( target, @@ -212,13 +235,17 @@ describe('droptarget', () => { ); expect(viewQuery.length).toBe(1); expect(droptarget.state).toBe('bottom'); - expect( - ( - element - .getElementsByClassName('drop-target-selection') - .item(0) as HTMLDivElement - ).style.transform - ).toBe('translateY(25%) scaleY(0.5)'); + check( + element + .getElementsByClassName('drop-target-selection') + .item(0) as HTMLDivElement, + { + top: '50%', + left: '0px', + width: '100%', + height: '50%', + } + ); fireEvent( target, @@ -230,14 +257,17 @@ describe('droptarget', () => { ); expect(viewQuery.length).toBe(1); expect(droptarget.state).toBe('right'); - expect( - ( - element - .getElementsByClassName('drop-target-selection') - .item(0) as HTMLDivElement - ).style.transform - ).toBe('translateX(25%) scaleX(0.5)'); - + check( + element + .getElementsByClassName('drop-target-selection') + .item(0) as HTMLDivElement, + { + top: '0px', + left: '50%', + width: '50%', + height: '100%', + } + ); fireEvent( target, createOffsetDragOverEvent({ clientX: 100, clientY: 50 }) diff --git a/packages/dockview-core/src/dnd/droptarget.ts b/packages/dockview-core/src/dnd/droptarget.ts index d5c7e290c..2f2868fbc 100644 --- a/packages/dockview-core/src/dnd/droptarget.ts +++ b/packages/dockview-core/src/dnd/droptarget.ts @@ -304,24 +304,43 @@ export class Droptarget extends CompositeDisposable { } } - const translate = (1 - size) / 2; - const scale = size; - - let transform: string; + const box = { top: '0px', left: '0px', width: '100%', height: '100%' }; + /** + * You can also achieve the overlay placement using the transform CSS property + * to translate and scale the element however this has the undesired effect of + * 'skewing' the element. Comment left here for anybody that ever revisits this. + * + * @see https://developer.mozilla.org/en-US/docs/Web/CSS/transform + * + * right + * translateX(${100 * (1 - size) / 2}%) scaleX(${scale}) + * + * left + * translateX(-${100 * (1 - size) / 2}%) scaleX(${scale}) + * + * top + * translateY(-${100 * (1 - size) / 2}%) scaleY(${scale}) + * + * bottom + * translateY(${100 * (1 - size) / 2}%) scaleY(${scale}) + */ if (rightClass) { - transform = `translateX(${100 * translate}%) scaleX(${scale})`; + box.left = `${100 * (1 - size)}%`; + box.width = `${100 * size}%`; } else if (leftClass) { - transform = `translateX(-${100 * translate}%) scaleX(${scale})`; + box.width = `${100 * size}%`; } else if (topClass) { - transform = `translateY(-${100 * translate}%) scaleY(${scale})`; + box.height = `${100 * size}%`; } else if (bottomClass) { - transform = `translateY(${100 * translate}%) scaleY(${scale})`; - } else { - transform = ''; + box.top = `${100 * size}%`; + box.height = `${100 * size}%`; } - this.overlayElement.style.transform = transform; + this.overlayElement.style.top = box.top; + this.overlayElement.style.left = box.left; + this.overlayElement.style.width = box.width; + this.overlayElement.style.height = box.height; toggleClass( this.overlayElement,