mirror of
https://github.com/mathuo/dockview
synced 2025-02-08 17:35:44 +00:00
Merge pull request #683 from mathuo/656-renderer-always-causes-floating-group-z-index-bug
feat: correct z-index level for floating always rendered panel
This commit is contained in:
commit
520aa39724
@ -8,11 +8,11 @@ import {
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { Writable, exhaustMicrotaskQueue } from '../__test_utils__/utils';
|
||||
import { DockviewComponent } from '../../dockview/dockviewComponent';
|
||||
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
|
||||
|
||||
describe('overlayRenderContainer', () => {
|
||||
let referenceContainer: IRenderable;
|
||||
let parentContainer: HTMLElement;
|
||||
let cut: OverlayRenderContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
parentContainer = document.createElement('div');
|
||||
@ -21,14 +21,14 @@ describe('overlayRenderContainer', () => {
|
||||
element: document.createElement('div'),
|
||||
dropTarget: fromPartial<Droptarget>({}),
|
||||
};
|
||||
|
||||
cut = new OverlayRenderContainer(
|
||||
parentContainer,
|
||||
fromPartial<DockviewComponent>({})
|
||||
);
|
||||
});
|
||||
|
||||
test('that attach(...) and detach(...) mutate the DOM as expected', () => {
|
||||
const cut = new OverlayRenderContainer(
|
||||
parentContainer,
|
||||
fromPartial<DockviewComponent>({})
|
||||
);
|
||||
|
||||
const panelContentEl = document.createElement('div');
|
||||
|
||||
const onDidVisibilityChange = new Emitter<any>();
|
||||
@ -42,6 +42,7 @@ describe('overlayRenderContainer', () => {
|
||||
onDidDimensionsChange: onDidDimensionsChange.event,
|
||||
onDidLocationChange: onDidLocationChange.event,
|
||||
isVisible: true,
|
||||
location: { type: 'grid' },
|
||||
},
|
||||
view: {
|
||||
content: {
|
||||
@ -67,6 +68,11 @@ describe('overlayRenderContainer', () => {
|
||||
});
|
||||
|
||||
test('add a view that is not currently in the DOM', async () => {
|
||||
const cut = new OverlayRenderContainer(
|
||||
parentContainer,
|
||||
fromPartial<DockviewComponent>({})
|
||||
);
|
||||
|
||||
const panelContentEl = document.createElement('div');
|
||||
|
||||
const onDidVisibilityChange = new Emitter<any>();
|
||||
@ -80,6 +86,7 @@ describe('overlayRenderContainer', () => {
|
||||
onDidDimensionsChange: onDidDimensionsChange.event,
|
||||
onDidLocationChange: onDidLocationChange.event,
|
||||
isVisible: true,
|
||||
location: { type: 'grid' },
|
||||
},
|
||||
view: {
|
||||
content: {
|
||||
@ -197,4 +204,60 @@ describe('overlayRenderContainer', () => {
|
||||
referenceContainer.element.getBoundingClientRect
|
||||
).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
test('related z-index from `aria-level` set on floating panels', async () => {
|
||||
const group = fromPartial<DockviewGroupPanel>({});
|
||||
|
||||
const element = document.createElement('div');
|
||||
element.setAttribute('aria-level', '2');
|
||||
const spy = jest.spyOn(element, 'getAttribute');
|
||||
|
||||
const accessor = fromPartial<DockviewComponent>({
|
||||
floatingGroups: [
|
||||
{
|
||||
group,
|
||||
overlay: {
|
||||
element,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const cut = new OverlayRenderContainer(parentContainer, accessor);
|
||||
|
||||
const panelContentEl = document.createElement('div');
|
||||
|
||||
const onDidVisibilityChange = new Emitter<any>();
|
||||
const onDidDimensionsChange = new Emitter<any>();
|
||||
const onDidLocationChange = new Emitter<any>();
|
||||
|
||||
const panel = fromPartial<IDockviewPanel>({
|
||||
api: {
|
||||
id: 'test_panel_id',
|
||||
onDidVisibilityChange: onDidVisibilityChange.event,
|
||||
onDidDimensionsChange: onDidDimensionsChange.event,
|
||||
onDidLocationChange: onDidLocationChange.event,
|
||||
isVisible: true,
|
||||
group,
|
||||
location: { type: 'floating' },
|
||||
},
|
||||
view: {
|
||||
content: {
|
||||
element: panelContentEl,
|
||||
},
|
||||
},
|
||||
group: {
|
||||
api: {
|
||||
location: { type: 'floating' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
cut.attach({ panel, referenceContainer });
|
||||
|
||||
await exhaustMicrotaskQueue();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith('aria-level');
|
||||
expect(panelContentEl.parentElement!.style.zIndex).toBe('1004');
|
||||
});
|
||||
});
|
||||
|
@ -87,7 +87,7 @@ export class DockviewPanel
|
||||
// you are actually just resizing the panels parent which is the group
|
||||
this.group.api.setSize(event);
|
||||
}),
|
||||
this.api.onDidRendererChange((event) => {
|
||||
this.api.onDidRendererChange(() => {
|
||||
this.group.model.rerender(this);
|
||||
})
|
||||
);
|
||||
|
@ -120,6 +120,48 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
|
||||
const observerDisposable = new MutableDisposable();
|
||||
|
||||
const correctLayerPosition = () => {
|
||||
if (panel.api.location.type === 'floating') {
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
observerDisposable,
|
||||
/**
|
||||
@ -147,7 +189,7 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
},
|
||||
}),
|
||||
|
||||
panel.api.onDidVisibilityChange((event) => {
|
||||
panel.api.onDidVisibilityChange(() => {
|
||||
/**
|
||||
* Control the visibility of the content, however even when not visible (display: none)
|
||||
* the content is still maintained within the DOM hence DOM specific attributes
|
||||
@ -162,48 +204,8 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
|
||||
resize();
|
||||
}),
|
||||
panel.api.onDidLocationChange((event) => {
|
||||
const isFloating = event.location.type === 'floating';
|
||||
|
||||
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
|
||||
}
|
||||
panel.api.onDidLocationChange(() => {
|
||||
correctLayerPosition();
|
||||
})
|
||||
);
|
||||
|
||||
@ -215,6 +217,8 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
focusContainer.parentElement?.removeChild(focusContainer);
|
||||
});
|
||||
|
||||
correctLayerPosition();
|
||||
|
||||
queueMicrotask(() => {
|
||||
if (this.isDisposed) {
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user