Skip to content

Commit

Permalink
feat: add internal API for nested overlays to bringToFront
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Feb 17, 2025
1 parent 4f4c7da commit e2e8240
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 0 deletions.
22 changes: 22 additions & 0 deletions packages/overlay/src/vaadin-overlay-stack-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ const getOverlayInstances = () => getAttachedInstances().filter((el) => el.$.ove
*/
export const isLastOverlay = (overlay) => overlay === getOverlayInstances().pop();

const overlayMap = new WeakMap();

/**
* Stores the reference to the nested overlay for given parent,
* or removes it when the nested overlay is null.
* @param {HTMLElement} parent
* @param {HTMLElement} nested
* @protected
*/
export const setNestedOverlay = (parent, nested) => {
if (nested != null) {
overlayMap.set(parent, nested);
} else {
overlayMap.delete(nested);
}
};

/**
* @polymerMixin
*/
Expand Down Expand Up @@ -63,6 +80,11 @@ export const OverlayStackMixin = (superClass) =>
}
this.style.zIndex = zIndex;
this.__zIndex = zIndex || parseFloat(getComputedStyle(this).zIndex);

// If there is a nested overlay, call `bringToFront()` for it as well.
if (overlayMap.has(this)) {
overlayMap.get.bringToFront();
}
}

/** @protected */
Expand Down
52 changes: 52 additions & 0 deletions packages/overlay/test/multiple.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { expect } from '@vaadin/chai-plugins';
import { click, escKeyDown, fixtureSync, nextRender } from '@vaadin/testing-helpers';
import sinon from 'sinon';
import '../vaadin-overlay.js';
import { setNestedOverlay } from '@vaadin/overlay/src/vaadin-overlay-stack-mixin.js';
import { createOverlay } from './helpers.js';

describe('multiple overlays', () => {
Expand Down Expand Up @@ -317,4 +318,55 @@ describe('multiple overlays', () => {
expect(spy.called).to.be.false;
});
});

describe('setNestedOverlay', () => {
let overlays;

beforeEach(() => {
overlays = Array.from(
fixtureSync(`
<div id="parent">
<vaadin-overlay modeless></vaadin-overlay>
<vaadin-overlay modeless></vaadin-overlay>
<vaadin-overlay modeless></vaadin-overlay>
</div>
`).children,
);
overlays.forEach((el, idx) => {
el.renderer = (root) => {
if (!root.firstChild) {
const btn = document.createElement('button');
btn.textContent = `Overlay ${idx}`;
root.appendChild(btn);
}
};
});
});

it('should bring nested overlays to front recursively', () => {
setNestedOverlay(overlays[0], overlays[1]);
setNestedOverlay(overlays[1], overlays[2]);

const bringToFrontSpy1 = sinon.spy(overlays[1], 'bringToFront');
const bringToFrontSpy2 = sinon.spy(overlays[2], 'bringToFront');

overlays[0].bringToFront();

expect(bringToFrontSpy1).to.be.calledOnce;
expect(bringToFrontSpy2).to.be.calledOnce;
expect(bringToFrontSpy2).to.be.calledAfter(bringToFrontSpy1);
});

it('should not bring nested overlay to front when resetting', () => {
setNestedOverlay(overlays[0], overlays[1]);

setNestedOverlay(overlays[0], null);

const bringToFrontSpy = sinon.spy(overlays[1], 'bringToFront');

overlays[0].bringToFront();

expect(bringToFrontSpy).to.be.not.called;
});
});
});

0 comments on commit e2e8240

Please # to comment.