mirror of
https://github.com/mathuo/dockview
synced 2025-02-13 03:45:47 +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,52 +120,8 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
|
||||
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
|
||||
*
|
||||
* the dnd observer does not need to be conditional on whether the panel is visible since
|
||||
* non-visible panels are 'display: none' and in such case the dnd observer will not fire.
|
||||
*/
|
||||
new DragAndDropObserver(focusContainer, {
|
||||
onDragEnd: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragEnd(e);
|
||||
},
|
||||
onDragEnter: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragEnter(e);
|
||||
},
|
||||
onDragLeave: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragLeave(e);
|
||||
},
|
||||
onDrop: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDrop(e);
|
||||
},
|
||||
onDragOver: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragOver(e);
|
||||
},
|
||||
}),
|
||||
|
||||
panel.api.onDidVisibilityChange((event) => {
|
||||
/**
|
||||
* 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
|
||||
* such as scroll position are maintained when next made visible.
|
||||
*/
|
||||
visibilityChanged();
|
||||
}),
|
||||
panel.api.onDidDimensionsChange(() => {
|
||||
if (!panel.api.isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
resize();
|
||||
}),
|
||||
panel.api.onDidLocationChange((event) => {
|
||||
const isFloating = event.location.type === 'floating';
|
||||
|
||||
if (isFloating) {
|
||||
const correctLayerPosition = () => {
|
||||
if (panel.api.location.type === 'floating') {
|
||||
queueMicrotask(() => {
|
||||
const floatingGroup = this.accessor.floatingGroups.find(
|
||||
(group) => group.group === panel.api.group
|
||||
@ -204,6 +160,52 @@ export class OverlayRenderContainer extends CompositeDisposable {
|
||||
} else {
|
||||
focusContainer.style.zIndex = ''; // reset the z-index, perhaps CSS will take over here
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
*
|
||||
* the dnd observer does not need to be conditional on whether the panel is visible since
|
||||
* non-visible panels are 'display: none' and in such case the dnd observer will not fire.
|
||||
*/
|
||||
new DragAndDropObserver(focusContainer, {
|
||||
onDragEnd: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragEnd(e);
|
||||
},
|
||||
onDragEnter: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragEnter(e);
|
||||
},
|
||||
onDragLeave: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragLeave(e);
|
||||
},
|
||||
onDrop: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDrop(e);
|
||||
},
|
||||
onDragOver: (e) => {
|
||||
referenceContainer.dropTarget.dnd.onDragOver(e);
|
||||
},
|
||||
}),
|
||||
|
||||
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
|
||||
* such as scroll position are maintained when next made visible.
|
||||
*/
|
||||
visibilityChanged();
|
||||
}),
|
||||
panel.api.onDidDimensionsChange(() => {
|
||||
if (!panel.api.isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
resize();
|
||||
}),
|
||||
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