mirror of
https://github.com/mathuo/dockview
synced 2025-09-07 09:56:40 +00:00
bug: always rendered floating groups z-index
This commit is contained in:
parent
6bf0263797
commit
1efa5c0ef6
@ -29,10 +29,6 @@
|
||||
position: absolute;
|
||||
z-index: 997;
|
||||
|
||||
&.dv-bring-to-front {
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
border: 1px solid var(--dv-tab-divider-color);
|
||||
box-shadow: var(--dv-floating-box-shadow);
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
import {
|
||||
applyOnlyToThisElement,
|
||||
disableIframePointEvents,
|
||||
getElementsByTagName,
|
||||
quasiDefaultPrevented,
|
||||
toggleClass,
|
||||
} from '../dom';
|
||||
@ -15,7 +13,36 @@ import { CompositeDisposable, MutableDisposable } from '../lifecycle';
|
||||
import { clamp } from '../math';
|
||||
import { AnchoredBox } from '../types';
|
||||
|
||||
const bringElementToFront = applyOnlyToThisElement('dv-bring-to-front');
|
||||
export const DEFAULT_OVERLAY_Z_INDEX = 999;
|
||||
|
||||
class AriaLevelTracker {
|
||||
private _orderedList: HTMLElement[] = [];
|
||||
|
||||
push(element: HTMLElement): void {
|
||||
this._orderedList = [
|
||||
...this._orderedList.filter((item) => item !== element),
|
||||
element,
|
||||
];
|
||||
|
||||
this.update();
|
||||
}
|
||||
|
||||
destroy(element: HTMLElement): void {
|
||||
this._orderedList = this._orderedList.filter(
|
||||
(item) => item !== element
|
||||
);
|
||||
this.update();
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
for (let i = 0; i < this._orderedList.length; i++) {
|
||||
this._orderedList[i].setAttribute('aria-level', `${i}`);
|
||||
this._orderedList[i].style.zIndex = `${DEFAULT_OVERLAY_Z_INDEX + i * 2}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const arialLevelTracker = new AriaLevelTracker();
|
||||
|
||||
export class Overlay extends CompositeDisposable {
|
||||
private _element: HTMLElement = document.createElement('div');
|
||||
@ -40,6 +67,10 @@ export class Overlay extends CompositeDisposable {
|
||||
this.options.minimumInViewportHeight = value;
|
||||
}
|
||||
|
||||
get element(): HTMLElement {
|
||||
return this._element;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly options: AnchoredBox & {
|
||||
container: HTMLElement;
|
||||
@ -75,10 +106,12 @@ export class Overlay extends CompositeDisposable {
|
||||
...('left' in this.options && { left: this.options.left }),
|
||||
...('right' in this.options && { right: this.options.right }),
|
||||
});
|
||||
|
||||
arialLevelTracker.push(this._element);
|
||||
}
|
||||
|
||||
bringToFront(): void {
|
||||
bringElementToFront.update(this._element);
|
||||
arialLevelTracker.push(this._element);
|
||||
}
|
||||
|
||||
setBounds(bounds: Partial<AnchoredBox> = {}): void {
|
||||
@ -346,14 +379,12 @@ export class Overlay extends CompositeDisposable {
|
||||
this.options.content,
|
||||
'mousedown',
|
||||
() => {
|
||||
bringElementToFront.update(this._element);
|
||||
arialLevelTracker.push(this._element);
|
||||
},
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
bringElementToFront.update(this._element);
|
||||
|
||||
if (options.inDragMode) {
|
||||
track();
|
||||
}
|
||||
@ -586,6 +617,7 @@ export class Overlay extends CompositeDisposable {
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
arialLevelTracker.destroy(this._element);
|
||||
this._element.remove();
|
||||
super.dispose();
|
||||
}
|
||||
|
@ -357,6 +357,10 @@ export class DockviewComponent
|
||||
return this.gridview.margin;
|
||||
}
|
||||
|
||||
get floatingGroups(): DockviewFloatingGroupPanel[] {
|
||||
return this._floatingGroups;
|
||||
}
|
||||
|
||||
constructor(parentElement: HTMLElement, options: DockviewComponentOptions) {
|
||||
super({
|
||||
proportionalLayout: true,
|
||||
@ -371,11 +375,14 @@ export class DockviewComponent
|
||||
className: options.className,
|
||||
});
|
||||
|
||||
const gready = document.createElement('div');
|
||||
gready.className = 'dv-overlay-render-container';
|
||||
this.gridview.element.appendChild(gready);
|
||||
// const gready = document.createElement('div');
|
||||
// gready.className = 'dv-overlay-render-container';
|
||||
// this.gridview.element.appendChild(gready);
|
||||
|
||||
this.overlayRenderContainer = new OverlayRenderContainer(gready);
|
||||
this.overlayRenderContainer = new OverlayRenderContainer(
|
||||
this.gridview.element,
|
||||
this
|
||||
);
|
||||
|
||||
toggleClass(this.gridview.element, 'dv-dockview', true);
|
||||
toggleClass(this.element, 'dv-debug', !!options.debug);
|
||||
@ -639,7 +646,8 @@ export class DockviewComponent
|
||||
gready.className = 'dv-overlay-render-container';
|
||||
|
||||
const overlayRenderContainer = new OverlayRenderContainer(
|
||||
gready
|
||||
gready,
|
||||
this
|
||||
);
|
||||
|
||||
const referenceGroup =
|
||||
|
@ -964,7 +964,7 @@ export class DockviewGroupPanelModel
|
||||
});
|
||||
this.watermark = watermark;
|
||||
|
||||
addDisposableListener(this.watermark.element, 'click', () => {
|
||||
addDisposableListener(this.watermark.element, 'pointerdown', () => {
|
||||
if (!this.isActive) {
|
||||
this.accessor.doSetGroupActive(this.groupPanel);
|
||||
}
|
||||
|
@ -278,21 +278,3 @@ export function disableIframePointEvents() {
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyOnlyToThisElement(className: string): {
|
||||
update: (element: HTMLElement) => void;
|
||||
} {
|
||||
let previous: WeakRef<HTMLElement> | null;
|
||||
|
||||
return {
|
||||
update: (element: HTMLElement): void => {
|
||||
const ref = previous?.deref();
|
||||
if (ref !== element && ref !== undefined) {
|
||||
toggleClass(ref, className, false);
|
||||
}
|
||||
|
||||
toggleClass(element, className, true);
|
||||
previous = new WeakRef(element);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
z-index: 998;
|
||||
|
||||
&.dv-render-overlay-active {
|
||||
z-index: 1000;
|
||||
// z-index: 1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
import { DragAndDropObserver } from './dnd/dnd';
|
||||
import { Droptarget } from './dnd/droptarget';
|
||||
import { getDomNodePagePosition, toggleClass } from './dom';
|
||||
import {
|
||||
applyOnlyToThisElement,
|
||||
getDomNodePagePosition,
|
||||
toggleClass,
|
||||
} from './dom';
|
||||
import { CompositeDisposable, Disposable, IDisposable } from './lifecycle';
|
||||
CompositeDisposable,
|
||||
Disposable,
|
||||
IDisposable,
|
||||
MutableDisposable,
|
||||
} from './lifecycle';
|
||||
import { IDockviewPanel } from './dockview/dockviewPanel';
|
||||
import { DockviewComponent } from './dockview/dockviewComponent';
|
||||
import { DEFAULT_OVERLAY_Z_INDEX } from './dnd/overlay';
|
||||
|
||||
export type DockviewPanelRenderer = 'onlyWhenVisible' | 'always';
|
||||
|
||||
@ -21,8 +24,6 @@ function createFocusableElement(): HTMLDivElement {
|
||||
return element;
|
||||
}
|
||||
|
||||
const bringElementToFront = applyOnlyToThisElement('dv-active');
|
||||
|
||||
export class OverlayRenderContainer extends CompositeDisposable {
|
||||
private readonly map: Record<
|
||||
string,
|
||||
@ -36,7 +37,10 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
|
||||
private _disposed = false;
|
||||
|
||||
constructor(private readonly element: HTMLElement) {
|
||||
constructor(
|
||||
readonly element: HTMLElement,
|
||||
readonly accessor: DockviewComponent
|
||||
) {
|
||||
super();
|
||||
|
||||
this.addDisposables(
|
||||
@ -114,7 +118,10 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
focusContainer.style.display = panel.api.isVisible ? '' : 'none';
|
||||
};
|
||||
|
||||
const observerDisposable = new MutableDisposable();
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
observerDisposable,
|
||||
/**
|
||||
* since container is positioned absoutely we must explicitly forward
|
||||
* the dnd events for the expect behaviours to continue to occur in terms of dnd
|
||||
@ -155,14 +162,52 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
|
||||
resize();
|
||||
}),
|
||||
panel.api.onDidActiveGroupChange(() => {
|
||||
// toggleClass(
|
||||
// focusContainer,
|
||||
// 'dv-active',
|
||||
// panel.api.isGroupActive
|
||||
// );
|
||||
if (panel.api.isGroupActive) {
|
||||
bringElementToFront.update(focusContainer);
|
||||
panel.api.onDidLocationChange((event) => {
|
||||
const isFloating = event.location.type === 'floating';
|
||||
|
||||
/**
|
||||
* Whilst floating the z-index must sync with the floating
|
||||
* groups z-index
|
||||
*/
|
||||
|
||||
if (isFloating) {
|
||||
queueMicrotask(() => {
|
||||
const floatingGroup = this.accessor.floatingGroups.find(
|
||||
(group) => group.group === panel.api.group
|
||||
);
|
||||
|
||||
if (!floatingGroup) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = floatingGroup.overlay.element;
|
||||
|
||||
const update = () => {
|
||||
const level = Number(
|
||||
element.getAttribute('aria-level')
|
||||
);
|
||||
focusContainer.style.zIndex = `${
|
||||
DEFAULT_OVERLAY_Z_INDEX + level * 2 + 1
|
||||
}`;
|
||||
};
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
update();
|
||||
});
|
||||
|
||||
observerDisposable.value = Disposable.from(() =>
|
||||
observer.disconnect()
|
||||
);
|
||||
|
||||
observer.observe(element, {
|
||||
attributeFilter: ['aria-level'],
|
||||
attributes: true,
|
||||
});
|
||||
|
||||
update();
|
||||
});
|
||||
} else {
|
||||
focusContainer.style.zIndex = ''; // reset the z-index, perhaps CSS will take over here
|
||||
}
|
||||
})
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user