From b7ceaf513382403a503f748d4bbe0e79c0109bd4 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:53:54 +0100 Subject: [PATCH] experiments --- .../dockview-core/src/api/component.api.ts | 4 ++ .../src/dockview/dockviewComponent.ts | 12 +++-- .../dockview-core/src/dockview/options.ts | 4 +- packages/dockview-core/src/overlay/overlay.ts | 48 ++++++++++++------- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/packages/dockview-core/src/api/component.api.ts b/packages/dockview-core/src/api/component.api.ts index 6978df401..b48897fb5 100644 --- a/packages/dockview-core/src/api/component.api.ts +++ b/packages/dockview-core/src/api/component.api.ts @@ -931,4 +931,8 @@ export class DockviewApi implements CommonApi { dispose(): void { this.component.dispose(); } + + anchor(): HTMLElement { + return this.component.anchor; + } } diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 2a72db7fe..b95ad3f49 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -168,6 +168,7 @@ export interface IDockviewComponent extends IBaseGrid { readonly panels: IDockviewPanel[]; readonly orientation: Orientation; readonly gap: number; + readonly anchor: HTMLElement; readonly onDidDrop: Event; readonly onWillDrop: Event; readonly onWillShowOverlay: Event; @@ -339,6 +340,10 @@ export class DockviewComponent return this._floatingGroups; } + get anchor(): HTMLElement { + return this.options.anchor ?? this.gridview.element; + } + constructor(parentElement: HTMLElement, options: DockviewComponentOptions) { super(parentElement, { proportionalLayout: true, @@ -352,8 +357,10 @@ export class DockviewComponent className: options.className, }); + this._options = options; + this.overlayRenderContainer = new OverlayRenderContainer( - this.gridview.element, + this.anchor, this ); @@ -423,8 +430,6 @@ export class DockviewComponent }) ); - this._options = options; - this._rootDropTarget = new Droptarget(this.element, { canDisplayOverlay: (event, position) => { const data = getPanelData(); @@ -873,6 +878,7 @@ export class DockviewComponent const overlay = new Overlay({ container: this.gridview.element, + anchor: this.anchor, content: group.element, ...anchoredBox, minimumInViewportWidth: diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 5fce93ebf..d0c8c2ea5 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -39,6 +39,7 @@ export interface DockviewOptions { * Call `.layout(width, height)` to manually resize the container. */ disableAutoResizing?: boolean; + anchor?: HTMLElement; hideBorders?: boolean; singleTabMode?: 'fullwidth' | 'default'; disableFloatingGroups?: boolean; @@ -94,11 +95,12 @@ export class DockviewUnhandledDragOverEvent implements DockviewDndOverlayEvent { export const PROPERTY_KEYS: (keyof DockviewOptions)[] = (() => { /** - * by readong the keys from an empty value object TypeScript will error + * by reading the keys from an empty value object TypeScript will error * when we add or remove new properties to `DockviewOptions` */ const properties: Record = { disableAutoResizing: undefined, + anchor: undefined, hideBorders: undefined, singleTabMode: undefined, disableFloatingGroups: undefined, diff --git a/packages/dockview-core/src/overlay/overlay.ts b/packages/dockview-core/src/overlay/overlay.ts index 0f39961ce..f186eef4f 100644 --- a/packages/dockview-core/src/overlay/overlay.ts +++ b/packages/dockview-core/src/overlay/overlay.ts @@ -74,6 +74,7 @@ export class Overlay extends CompositeDisposable { constructor( private readonly options: AnchoredBox & { container: HTMLElement; + anchor: HTMLElement; content: HTMLElement; minimumInViewportWidth?: number; minimumInViewportHeight?: number; @@ -95,7 +96,7 @@ export class Overlay extends CompositeDisposable { this.setupResize('bottomright'); this._element.appendChild(this.options.content); - this.options.container.appendChild(this._element); + this.options.anchor.appendChild(this._element); // if input bad resize within acceptable boundaries this.setBounds({ @@ -115,6 +116,12 @@ export class Overlay extends CompositeDisposable { } setBounds(bounds: Partial = {}): void { + const containerRect = this.options.anchor.getBoundingClientRect(); + const anchorRect = this.options.anchor.getBoundingClientRect(); + + const dy = 0; //containerRect.top - anchorRect.top; + const dx = 0; // containerRect.left - anchorRect.left; + if (typeof bounds.height === 'number') { this._element.style.height = `${bounds.height}px`; } @@ -122,27 +129,26 @@ export class Overlay extends CompositeDisposable { this._element.style.width = `${bounds.width}px`; } if ('top' in bounds && typeof bounds.top === 'number') { - this._element.style.top = `${bounds.top}px`; + this._element.style.top = `${bounds.top + dy}px`; this._element.style.bottom = 'auto'; this.verticalAlignment = 'top'; } if ('bottom' in bounds && typeof bounds.bottom === 'number') { - this._element.style.bottom = `${bounds.bottom}px`; + this._element.style.bottom = `${bounds.bottom + dy}px`; this._element.style.top = 'auto'; this.verticalAlignment = 'bottom'; } if ('left' in bounds && typeof bounds.left === 'number') { - this._element.style.left = `${bounds.left}px`; + this._element.style.left = `${bounds.left + dx}px`; this._element.style.right = 'auto'; this.horiziontalAlignment = 'left'; } if ('right' in bounds && typeof bounds.right === 'number') { - this._element.style.right = `${bounds.right}px`; + this._element.style.right = `${bounds.right + dx}px`; this._element.style.left = 'auto'; this.horiziontalAlignment = 'right'; } - const containerRect = this.options.container.getBoundingClientRect(); const overlayRect = this._element.getBoundingClientRect(); // region: ensure bounds within allowable limits @@ -156,10 +162,14 @@ export class Overlay extends CompositeDisposable { if (this.verticalAlignment === 'top') { const top = clamp( overlayRect.top - containerRect.top, - -yOffset, - Math.max(0, containerRect.height - overlayRect.height + yOffset) + dy + -yOffset, + dy + + Math.max( + 0, + anchorRect.height - overlayRect.height + yOffset + ) ); - this._element.style.top = `${top}px`; + this._element.style.top = `${top + dy}px`; this._element.style.bottom = 'auto'; } @@ -167,9 +177,9 @@ export class Overlay extends CompositeDisposable { const bottom = clamp( containerRect.bottom - overlayRect.bottom, -yOffset, - Math.max(0, containerRect.height - overlayRect.height + yOffset) + Math.max(0, anchorRect.height - overlayRect.height + yOffset) ); - this._element.style.bottom = `${bottom}px`; + this._element.style.bottom = `${bottom + dy}px`; this._element.style.top = 'auto'; } @@ -177,9 +187,9 @@ export class Overlay extends CompositeDisposable { const left = clamp( overlayRect.left - containerRect.left, -xOffset, - Math.max(0, containerRect.width - overlayRect.width + xOffset) + Math.max(0, anchorRect.width - overlayRect.width + xOffset) ); - this._element.style.left = `${left}px`; + this._element.style.left = `${left + dx}px`; this._element.style.right = 'auto'; } @@ -187,9 +197,9 @@ export class Overlay extends CompositeDisposable { const right = clamp( containerRect.right - overlayRect.right, -xOffset, - Math.max(0, containerRect.width - overlayRect.width + xOffset) + Math.max(0, anchorRect.width - overlayRect.width + xOffset) ); - this._element.style.right = `${right}px`; + this._element.style.right = `${right + dx}px`; this._element.style.left = 'auto'; } @@ -243,7 +253,13 @@ export class Overlay extends CompositeDisposable { }, addDisposableWindowListener(window, 'mousemove', (e) => { const containerRect = - this.options.container.getBoundingClientRect(); + this.options.anchor.getBoundingClientRect(); + const anchorRect = + this.options.anchor.getBoundingClientRect(); + + const dy = containerRect.top - anchorRect.top; + const dx = containerRect.left - anchorRect.left; + const x = e.clientX - containerRect.left; const y = e.clientY - containerRect.top;