mirror of
https://github.com/mathuo/dockview
synced 2025-10-02 14:08:07 +00:00
bug: popup within floating panel
This commit is contained in:
parent
22deb851dc
commit
d1239a5ee5
@ -1,3 +1,4 @@
|
|||||||
|
import { shiftAbsoluteElementIntoView } from '../../dom';
|
||||||
import { addDisposableListener } from '../../events';
|
import { addDisposableListener } from '../../events';
|
||||||
import {
|
import {
|
||||||
CompositeDisposable,
|
CompositeDisposable,
|
||||||
@ -5,48 +6,6 @@ import {
|
|||||||
MutableDisposable,
|
MutableDisposable,
|
||||||
} from '../../lifecycle';
|
} from '../../lifecycle';
|
||||||
|
|
||||||
function shiftAbsoluteElementIntoView(element: HTMLElement, root: HTMLElement) {
|
|
||||||
const rect = element.getBoundingClientRect();
|
|
||||||
const rootRect = element.getBoundingClientRect();
|
|
||||||
|
|
||||||
const viewportWidth = root.clientWidth;
|
|
||||||
const viewportHeight = root.clientHeight;
|
|
||||||
|
|
||||||
// const viewportWidth =
|
|
||||||
// window.innerWidth || document.documentElement.clientWidth;
|
|
||||||
// const viewportHeight =
|
|
||||||
// window.innerHeight || document.documentElement.clientHeight;
|
|
||||||
|
|
||||||
const buffer = 10; // 10px buffer
|
|
||||||
|
|
||||||
let translateX = 0;
|
|
||||||
let translateY = 0;
|
|
||||||
|
|
||||||
const left = rect.left - rootRect.left;
|
|
||||||
const top = rect.top - rootRect.top;
|
|
||||||
const bottom = rect.bottom - rootRect.bottom;
|
|
||||||
const right = rect.right - rootRect.right;
|
|
||||||
|
|
||||||
// Check horizontal overflow
|
|
||||||
if (left < buffer) {
|
|
||||||
translateX = buffer - left;
|
|
||||||
} else if (right > viewportWidth - buffer) {
|
|
||||||
translateX = viewportWidth - right - buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check vertical overflow
|
|
||||||
if (top < buffer) {
|
|
||||||
translateY = buffer - top;
|
|
||||||
} else if (bottom > viewportHeight - buffer) {
|
|
||||||
translateY = viewportHeight - bottom - buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the translation if needed
|
|
||||||
if (translateX !== 0 || translateY !== 0) {
|
|
||||||
element.style.transform = `translate(${translateX}px, ${translateY}px)`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class PopupService extends CompositeDisposable {
|
export class PopupService extends CompositeDisposable {
|
||||||
private readonly _element: HTMLElement;
|
private readonly _element: HTMLElement;
|
||||||
private _active: HTMLElement | null = null;
|
private _active: HTMLElement | null = null;
|
||||||
@ -71,13 +30,13 @@ export class PopupService extends CompositeDisposable {
|
|||||||
|
|
||||||
openPopover(
|
openPopover(
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
position: { x: number; y: number }
|
position: { x: number; y: number; zIndex?: string }
|
||||||
): void {
|
): void {
|
||||||
this.close();
|
this.close();
|
||||||
|
|
||||||
const wrapper = document.createElement('div');
|
const wrapper = document.createElement('div');
|
||||||
wrapper.style.position = 'absolute';
|
wrapper.style.position = 'absolute';
|
||||||
wrapper.style.zIndex = '99';
|
wrapper.style.zIndex = position.zIndex ?? 'var(--dv-overlay-z-index)';
|
||||||
wrapper.appendChild(element);
|
wrapper.appendChild(element);
|
||||||
|
|
||||||
const anchorBox = this._element.getBoundingClientRect();
|
const anchorBox = this._element.getBoundingClientRect();
|
||||||
@ -92,7 +51,7 @@ export class PopupService extends CompositeDisposable {
|
|||||||
this._active = wrapper;
|
this._active = wrapper;
|
||||||
|
|
||||||
this._activeDisposable.value = new CompositeDisposable(
|
this._activeDisposable.value = new CompositeDisposable(
|
||||||
addDisposableListener(window, 'pointerdown', (event) => {
|
addDisposableListener(window, 'pointerdown', (event) => {
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
|
|
||||||
if (!(target instanceof HTMLElement)) {
|
if (!(target instanceof HTMLElement)) {
|
||||||
|
@ -8,7 +8,7 @@ import { addDisposableListener, Emitter, Event } from '../../../events';
|
|||||||
import { Tab } from '../tab/tab';
|
import { Tab } from '../tab/tab';
|
||||||
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
|
import { DockviewGroupPanel } from '../../dockviewGroupPanel';
|
||||||
import { VoidContainer } from './voidContainer';
|
import { VoidContainer } from './voidContainer';
|
||||||
import { toggleClass } from '../../../dom';
|
import { findRelativeZIndexParent, toggleClass } from '../../../dom';
|
||||||
import { IDockviewPanel } from '../../dockviewPanel';
|
import { IDockviewPanel } from '../../dockviewPanel';
|
||||||
import { DockviewComponent } from '../../dockviewComponent';
|
import { DockviewComponent } from '../../dockviewComponent';
|
||||||
import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
|
import { WillShowOverlayLocationEvent } from '../../dockviewGroupPanelModel';
|
||||||
@ -378,7 +378,7 @@ export class TabsContainer
|
|||||||
!panelObject.api.isActive
|
!panelObject.api.isActive
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.addEventListener('mousedown', () => {
|
wrapper.addEventListener('pointerdown', () => {
|
||||||
this.accessor.popupService.close();
|
this.accessor.popupService.close();
|
||||||
tab.element.scrollIntoView();
|
tab.element.scrollIntoView();
|
||||||
tab.panel.api.setActive();
|
tab.panel.api.setActive();
|
||||||
@ -388,9 +388,14 @@ export class TabsContainer
|
|||||||
el.appendChild(wrapper);
|
el.appendChild(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const relativeParent = findRelativeZIndexParent(root);
|
||||||
|
|
||||||
this.accessor.popupService.openPopover(el, {
|
this.accessor.popupService.openPopover(el, {
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
y: event.clientY,
|
y: event.clientY,
|
||||||
|
zIndex: relativeParent?.style.zIndex
|
||||||
|
? `calc(${relativeParent.style.zIndex} * 2)`
|
||||||
|
: undefined,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -451,3 +451,53 @@ export function onDidWindowResizeEnd(element: Window, cb: () => void) {
|
|||||||
|
|
||||||
return disposable;
|
return disposable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function shiftAbsoluteElementIntoView(
|
||||||
|
element: HTMLElement,
|
||||||
|
root: HTMLElement,
|
||||||
|
options: { buffer: number } = { buffer: 10 }
|
||||||
|
) {
|
||||||
|
const buffer = options.buffer;
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const rootRect = element.getBoundingClientRect();
|
||||||
|
|
||||||
|
const viewportWidth = root.clientWidth;
|
||||||
|
const viewportHeight = root.clientHeight;
|
||||||
|
|
||||||
|
let translateX = 0;
|
||||||
|
let translateY = 0;
|
||||||
|
|
||||||
|
const left = rect.left - rootRect.left;
|
||||||
|
const top = rect.top - rootRect.top;
|
||||||
|
const bottom = rect.bottom - rootRect.bottom;
|
||||||
|
const right = rect.right - rootRect.right;
|
||||||
|
|
||||||
|
// Check horizontal overflow
|
||||||
|
if (left < buffer) {
|
||||||
|
translateX = buffer - left;
|
||||||
|
} else if (right > viewportWidth - buffer) {
|
||||||
|
translateX = viewportWidth - right - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check vertical overflow
|
||||||
|
if (top < buffer) {
|
||||||
|
translateY = buffer - top;
|
||||||
|
} else if (bottom > viewportHeight - buffer) {
|
||||||
|
translateY = viewportHeight - bottom - buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the translation if needed
|
||||||
|
if (translateX !== 0 || translateY !== 0) {
|
||||||
|
element.style.transform = `translate(${translateX}px, ${translateY}px)`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findRelativeZIndexParent(el: HTMLElement): HTMLElement | null {
|
||||||
|
let tmp: HTMLElement | null = el;
|
||||||
|
|
||||||
|
while (tmp && (tmp.style.zIndex === 'auto' || tmp.style.zIndex === '')) {
|
||||||
|
tmp = tmp.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user