From 70e9cca4d45c5b2b2df52d9ffbe2b77224383a2f Mon Sep 17 00:00:00 2001
From: Quinton Jason
Date: Thu, 27 Aug 2026 15:48:19 -0500
Subject: [PATCH 1/8] feat(pds-modal): add disableTopLayer to opt out of the
browser top layer
---
libs/core/src/components.d.ts | 11 +++
.../src/components/pds-modal/pds-modal.tsx | 24 +++++-
libs/core/src/components/pds-modal/readme.md | 15 ++--
.../pds-modal/stories/pds-modal.stories.js | 77 +++++++++++++++++++
.../pds-modal/test/pds-modal.spec.tsx | 61 +++++++++++++++
5 files changed, 178 insertions(+), 10 deletions(-)
diff --git a/libs/core/src/components.d.ts b/libs/core/src/components.d.ts
index c0eddce4f..195f14d75 100644
--- a/libs/core/src/components.d.ts
+++ b/libs/core/src/components.d.ts
@@ -1476,6 +1476,11 @@ export namespace Components {
* A unique identifier used for the underlying component `id` attribute.
*/
"componentId": string;
+ /**
+ * When `true`, the modal opens as a non-modal dialog (`dialog.show()`) in the normal stacking context instead of the browser top layer (`dialog.showModal()`). This lets overlays rendered elsewhere in the DOM — e.g. file pickers, rich-text editor menus — display above the modal via `z-index`, which is impossible while the modal sits in the top layer. Note that the rest of the page is not made inert in this mode.
+ * @default false
+ */
+ "disableTopLayer": boolean;
/**
* Closes the modal
*/
@@ -4783,6 +4788,11 @@ declare namespace LocalJSX {
* A unique identifier used for the underlying component `id` attribute.
*/
"componentId"?: string;
+ /**
+ * When `true`, the modal opens as a non-modal dialog (`dialog.show()`) in the normal stacking context instead of the browser top layer (`dialog.showModal()`). This lets overlays rendered elsewhere in the DOM — e.g. file pickers, rich-text editor menus — display above the modal via `z-index`, which is impossible while the modal sits in the top layer. Note that the rest of the page is not made inert in this mode.
+ * @default false
+ */
+ "disableTopLayer"?: boolean;
/**
* Emitted when the modal is closed
*/
@@ -6233,6 +6243,7 @@ declare namespace LocalJSX {
"open": boolean;
"size": 'sm' | 'md' | 'lg' | 'fullscreen';
"scrollable": boolean;
+ "disableTopLayer": boolean;
}
interface PdsModalContentAttributes {
"border": 'none' | 'both' | 'top' | 'bottom';
diff --git a/libs/core/src/components/pds-modal/pds-modal.tsx b/libs/core/src/components/pds-modal/pds-modal.tsx
index 21c91b2d9..cde5b6164 100644
--- a/libs/core/src/components/pds-modal/pds-modal.tsx
+++ b/libs/core/src/components/pds-modal/pds-modal.tsx
@@ -41,6 +41,17 @@ export class PdsModal {
*/
@Prop() scrollable = true;
+ /**
+ * When `true`, the modal opens as a non-modal dialog (`dialog.show()`) in the
+ * normal stacking context instead of the browser top layer
+ * (`dialog.showModal()`). This lets overlays rendered elsewhere in the DOM —
+ * e.g. file pickers, rich-text editor menus — display above the modal via
+ * `z-index`, which is impossible while the modal sits in the top layer. Note
+ * that the rest of the page is not made inert in this mode.
+ * @default false
+ */
+ @Prop() disableTopLayer = false;
+
/**
* Emitted when the modal is opened
*/
@@ -163,8 +174,15 @@ export class PdsModal {
// Store the currently focused element to restore focus when modal closes
this.previousActiveElement = document.activeElement as HTMLElement;
- // Use native dialog showModal method which makes the rest of the page inert
- this.modalRef.showModal();
+ // showModal() promotes the dialog to the browser top layer (and makes the
+ // rest of the page inert), which prevents any overlay outside the dialog
+ // from ever painting above it. show() opens a non-modal dialog that stays
+ // in the normal stacking context so those overlays can stack above it.
+ if (this.disableTopLayer) {
+ this.modalRef.show();
+ } else {
+ this.modalRef.showModal();
+ }
this.open = true;
// Update focusable elements and set initial focus
@@ -303,7 +321,7 @@ export class PdsModal {
'pds-modal__backdrop': true,
'open': this.open
}}
- aria-modal="true"
+ aria-modal={this.disableTopLayer ? 'false' : 'true'}
aria-labelledby={`${this.componentId}-heading`}
onClick={this.handleBackdropClick}
>
diff --git a/libs/core/src/components/pds-modal/readme.md b/libs/core/src/components/pds-modal/readme.md
index eb23c6f0b..7a6693c37 100644
--- a/libs/core/src/components/pds-modal/readme.md
+++ b/libs/core/src/components/pds-modal/readme.md
@@ -7,13 +7,14 @@
## Properties
-| Property | Attribute | Description | Type | Default |
-| ----------------- | ------------------ | --------------------------------------------------------------------- | -------------------------------------- | ----------- |
-| `backdropDismiss` | `backdrop-dismiss` | Whether the modal can be dismissed by clicking the backdrop | `boolean` | `true` |
-| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
-| `open` | `open` | Whether the modal is open | `boolean` | `false` |
-| `scrollable` | `scrollable` | Whether the modal content should be scrollable | `boolean` | `true` |
-| `size` | `size` | The size of the modal | `"fullscreen" \| "lg" \| "md" \| "sm"` | `'md'` |
+| Property | Attribute | Description | Type | Default |
+| ----------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------- |
+| `backdropDismiss` | `backdrop-dismiss` | Whether the modal can be dismissed by clicking the backdrop | `boolean` | `true` |
+| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
+| `disableTopLayer` | `disable-top-layer` | When `true`, the modal opens as a non-modal dialog (`dialog.show()`) in the normal stacking context instead of the browser top layer (`dialog.showModal()`). This lets overlays rendered elsewhere in the DOM — e.g. file pickers, rich-text editor menus — display above the modal via `z-index`, which is impossible while the modal sits in the top layer. Note that the rest of the page is not made inert in this mode. | `boolean` | `false` |
+| `open` | `open` | Whether the modal is open | `boolean` | `false` |
+| `scrollable` | `scrollable` | Whether the modal content should be scrollable | `boolean` | `true` |
+| `size` | `size` | The size of the modal | `"fullscreen" \| "lg" \| "md" \| "sm"` | `'md'` |
## Events
diff --git a/libs/core/src/components/pds-modal/stories/pds-modal.stories.js b/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
index 332e0ddbb..034077621 100644
--- a/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
+++ b/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
@@ -8,6 +8,7 @@ export default {
args: {
backdropDismiss: true,
componentId: 'modal-demo',
+ disableTopLayer: false,
open: false,
scrollable: true,
size: 'md',
@@ -26,6 +27,7 @@ const BaseTemplate = (args) => html`
component-id="${args.componentId}"
size="${args.size}"
?backdrop-dismiss=${args.backdropDismiss}
+ ?disable-top-layer=${args.disableTopLayer}
scrollable="${args.scrollable}"
?open=${args.open}
key="${args.scrollable ? 'scrollable' : 'non-scrollable'}"
@@ -652,3 +654,78 @@ export const CustomBorders = CustomBordersTemplate.bind({});
CustomBorders.args = {
componentId: 'custom-borders-modal',
};
+
+// Demonstrates `disable-top-layer`: the modal opens as a non-modal dialog
+// (dialog.show()) so an overlay appended to document.body can display above it.
+// With the default top-layer behavior the same overlay would render behind the
+// modal and be unreachable.
+const DisableTopLayerTemplate = (args) => html`
+
+
+ Open Modal (disable-top-layer)
+
+
+
+
+
+
+ Modal Title
+
+
+
+
+
+
+
+
+
+
+ This modal uses disable-top-layer, so it renders in the normal stacking
+ context instead of the browser top layer.
+
+
+ An overlay appended to document.body with a higher z-index can
+ therefore display above it — useful for file pickers, rich-text editor menus, and
+ other body-mounted overlays that would otherwise be trapped behind a top-layer dialog.
+
+
+ Show overlay above modal
+
+
+
+
+
+
+
+ Close
+
+
+
+
+
+`;
+
+export const DisableTopLayer = DisableTopLayerTemplate.bind({});
+DisableTopLayer.args = {
+ componentId: 'disable-top-layer-modal',
+ disableTopLayer: true,
+ size: 'md',
+ open: false,
+};
diff --git a/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx b/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
index 9f1774f7b..4e9536160 100644
--- a/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
+++ b/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
@@ -1,5 +1,6 @@
import { newSpecPage } from '@stencil/core/testing';
import { MockPdsModal } from './mock-pds-modal';
+import { PdsModal } from '../pds-modal';
// Test the modal component using our mock implementation
describe('pds-modal', () => {
@@ -192,4 +193,64 @@ describe('pds-modal', () => {
// Modal should still be open
expect(page.rootInstance.open).toBe(true);
});
+
+ // disableTopLayer — exercises the real component (the mock does not touch the
+ //
Show overlay above modal
From 1d43a1566775ef008180a3acd38d26ea0de1db17 Mon Sep 17 00:00:00 2001
From: Quinton Jason
Date: Thu, 27 Aug 2026 16:32:29 -0500
Subject: [PATCH 6/8] fix(pds-modal): leave Escape to overlays that own focus
in non-top-layer mode
---
libs/core/src/components.d.ts | 4 ++--
libs/core/src/components/pds-modal/pds-modal.tsx | 10 +++++++++-
libs/core/src/components/pds-modal/readme.md | 16 ++++++++--------
3 files changed, 19 insertions(+), 11 deletions(-)
diff --git a/libs/core/src/components.d.ts b/libs/core/src/components.d.ts
index 99442184e..37777adde 100644
--- a/libs/core/src/components.d.ts
+++ b/libs/core/src/components.d.ts
@@ -1477,7 +1477,7 @@ export namespace Components {
*/
"componentId": string;
/**
- * Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode.
+ * Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode. Read when the modal opens; changing it while the modal is open is not supported.
* @default false
*/
"disableTopLayer": boolean;
@@ -4789,7 +4789,7 @@ declare namespace LocalJSX {
*/
"componentId"?: string;
/**
- * Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode.
+ * Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode. Read when the modal opens; changing it while the modal is open is not supported.
* @default false
*/
"disableTopLayer"?: boolean;
diff --git a/libs/core/src/components/pds-modal/pds-modal.tsx b/libs/core/src/components/pds-modal/pds-modal.tsx
index 6eb37d449..9535a5f32 100644
--- a/libs/core/src/components/pds-modal/pds-modal.tsx
+++ b/libs/core/src/components/pds-modal/pds-modal.tsx
@@ -46,7 +46,8 @@ export class PdsModal {
* When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so
* overlays rendered elsewhere in the DOM (file pickers, editor menus) can display
* above it via `z-index`. The page is not made inert and focus is not trapped in
- * this mode.
+ * this mode. Read when the modal opens; changing it while the modal is open is
+ * not supported.
* @default false
*/
@Prop() disableTopLayer = false;
@@ -272,6 +273,13 @@ export class PdsModal {
// Handle Escape key to close the modal
if (e.key === 'Escape') {
+ // In non-top-layer mode, focus can move into an overlay stacked above the
+ // modal (the reason disableTopLayer exists). If that overlay owns focus,
+ // leave Escape to it rather than dismissing this modal out from under it.
+ const active = document.activeElement;
+ if (this.disableTopLayer && active && active !== document.body && !this.el.contains(active)) {
+ return;
+ }
// Always prevent native dialog close behavior
e.preventDefault();
// Only close if backdropDismiss is enabled and this is the innermost modal
diff --git a/libs/core/src/components/pds-modal/readme.md b/libs/core/src/components/pds-modal/readme.md
index 1793f15c9..f6ab2b235 100644
--- a/libs/core/src/components/pds-modal/readme.md
+++ b/libs/core/src/components/pds-modal/readme.md
@@ -7,14 +7,14 @@
## Properties
-| Property | Attribute | Description | Type | Default |
-| ----------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | ----------- |
-| `backdropDismiss` | `backdrop-dismiss` | Whether the modal can be dismissed by clicking the backdrop | `boolean` | `true` |
-| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
-| `disableTopLayer` | `disable-top-layer` | Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode. | `boolean` | `false` |
-| `open` | `open` | Whether the modal is open | `boolean` | `false` |
-| `scrollable` | `scrollable` | Whether the modal content should be scrollable | `boolean` | `true` |
-| `size` | `size` | The size of the modal | `"fullscreen" \| "lg" \| "md" \| "sm"` | `'md'` |
+| Property | Attribute | Description | Type | Default |
+| ----------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ----------- |
+| `backdropDismiss` | `backdrop-dismiss` | Whether the modal can be dismissed by clicking the backdrop | `boolean` | `true` |
+| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
+| `disableTopLayer` | `disable-top-layer` | Whether the modal opens outside the browser top layer as a non-modal dialog. When `true` it opens with `dialog.show()` instead of `dialog.showModal()`, so overlays rendered elsewhere in the DOM (file pickers, editor menus) can display above it via `z-index`. The page is not made inert and focus is not trapped in this mode. Read when the modal opens; changing it while the modal is open is not supported. | `boolean` | `false` |
+| `open` | `open` | Whether the modal is open | `boolean` | `false` |
+| `scrollable` | `scrollable` | Whether the modal content should be scrollable | `boolean` | `true` |
+| `size` | `size` | The size of the modal | `"fullscreen" \| "lg" \| "md" \| "sm"` | `'md'` |
## Events
From 2ef45d4efdd45dfd4f9a051a758dfec8b384e616 Mon Sep 17 00:00:00 2001
From: Quinton Jason
Date: Thu, 27 Aug 2026 16:32:49 -0500
Subject: [PATCH 7/8] test(pds-modal): cover Escape ownership for non-top-layer
overlays in e2e
---
.../pds-modal/test/pds-modal.e2e.ts | 33 +++++++++++++++++++
.../pds-modal/test/pds-modal.spec.tsx | 5 +++
2 files changed, 38 insertions(+)
diff --git a/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts b/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts
index cf1c976d8..a36f708c7 100644
--- a/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts
+++ b/libs/core/src/components/pds-modal/test/pds-modal.e2e.ts
@@ -137,6 +137,39 @@ describe('pds-modal', () => {
expect(state.ariaModal).toBe('false');
});
+ it('leaves Escape to an overlay above it and closes normally when focus is inside', async () => {
+ const page = await newE2EPage();
+ await page.setContent(
+ `Content
`,
+ );
+
+ const modal = await page.find('pds-modal');
+ await modal.callMethod('showModal');
+ await page.waitForChanges();
+ expect(await modal.getProperty('open')).toBe(true);
+
+ // An overlay mounted on the body owns focus — Escape should not dismiss the modal.
+ await page.evaluate(() => {
+ const o = document.createElement('button');
+ o.id = 'probe-overlay';
+ o.textContent = 'Overlay';
+ document.body.appendChild(o);
+ o.focus();
+ });
+ await page.keyboard.press('Escape');
+ await page.waitForChanges();
+ expect(await modal.getProperty('open')).toBe(true);
+
+ // Remove the overlay so focus is no longer held outside the modal — Escape
+ // now dismisses the modal as usual.
+ await page.evaluate(() => {
+ (document.getElementById('probe-overlay') as HTMLElement)?.remove();
+ });
+ await page.keyboard.press('Escape');
+ await page.waitForChanges();
+ expect(await modal.getProperty('open')).toBe(false);
+ });
+
it('lets a higher z-index overlay paint above the non-modal dialog', async () => {
const page = await newE2EPage();
await page.setContent(
diff --git a/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx b/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
index 4e9536160..0276bffc5 100644
--- a/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
+++ b/libs/core/src/components/pds-modal/test/pds-modal.spec.tsx
@@ -252,5 +252,10 @@ describe('pds-modal', () => {
});
expect(nonModal.root?.querySelector('dialog')?.getAttribute('aria-modal')).toBe('false');
});
+
+ // The Escape-ownership behavior (leave Escape to an overlay that holds focus,
+ // close otherwise) depends on document.activeElement and dialog.close(), which
+ // the spec mock-doc environment does not implement — it is covered in the e2e
+ // suite where a real browser exercises focus and key events.
});
});
From c16b5acddeb00301981a728d530c72084e82fee9 Mon Sep 17 00:00:00 2001
From: Quinton Jason
Date: Thu, 27 Aug 2026 16:33:03 -0500
Subject: [PATCH 8/8] docs(pds-modal): fix heading parse, clarify Escape
behavior, auto-remove demo overlay
---
.../src/components/pds-modal/docs/pds-modal.mdx | 13 +++++++++----
.../pds-modal/stories/pds-modal.stories.js | 2 +-
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/libs/core/src/components/pds-modal/docs/pds-modal.mdx b/libs/core/src/components/pds-modal/docs/pds-modal.mdx
index 84b346ec1..fc511ecbb 100644
--- a/libs/core/src/components/pds-modal/docs/pds-modal.mdx
+++ b/libs/core/src/components/pds-modal/docs/pds-modal.mdx
@@ -1318,13 +1318,14 @@ Modals can be nested, with only the topmost modal responding to escape key and b
+
### Overlays Above the Modal
By default a modal opens with the native `dialog.showModal()`, which promotes it to the browser [top layer](https://developer.mozilla.org/en-US/docs/Glossary/Top_layer). Nothing outside the dialog can paint above the top layer — not even with a higher `z-index` — so an overlay mounted elsewhere in the DOM (a file picker, a rich-text editor menu, a third-party widget appended to `document.body`) renders _behind_ the modal and becomes unreachable.
Set `disable-top-layer` to open the modal as a non-modal dialog (`dialog.show()`) in the normal stacking context instead. Overlays with a higher `z-index` can then display above it.
-> **Note:** This mode is for letting a higher-`z-index` overlay (a file picker, an editor menu) appear _above_ the modal — not for making the modal itself non-blocking. The dimming backdrop still covers the page and an outside click still dismisses it (unless `backdrop-dismiss="false"`), and Escape still closes it. What changes: the page is **not** made `inert` and **focus is not trapped**, so controls in an overlay stacked above the modal stay reachable by keyboard and assistive tech (which is why `aria-modal` is `false` in this mode). Two caveats: because the dialog now participates in normal stacking, a page element with its own higher stacking context can overlap it; and avoid mixing a `disable-top-layer` modal with a default (top-layer) modal in the same stack, since backdrop/Escape dismiss targeting is resolved by `z-index`.
+> **Note:** This mode is for letting a higher-`z-index` overlay (a file picker, an editor menu) appear _above_ the modal — not for making the modal itself non-blocking. The dimming backdrop still covers the page and an outside click still dismisses it (unless `backdrop-dismiss="false"`). What changes: the page is **not** made `inert` and **focus is not trapped**, so controls in an overlay stacked above the modal stay reachable by keyboard and assistive tech (which is why `aria-modal` is `false` in this mode). Escape closes the modal while focus is inside it; when an overlay above the modal owns focus, Escape is left to that overlay so it can close itself. Two caveats: because the dialog now participates in normal stacking, a page element with its own higher stacking context can overlap it; and avoid mixing a `disable-top-layer` modal with a default (top-layer) modal in the same stack, since backdrop/Escape dismiss targeting is resolved by `z-index`.
o.remove();
+ const modal = document.querySelector('#top-layer-modal');
+ const remove = () => o.remove();
+ o.onclick = remove;
+ o.addEventListener('keydown', (e) => { if (e.key === 'Escape') remove(); });
+ if (modal) modal.addEventListener('pdsModalClose', remove, { once: true });
document.body.appendChild(o);
o.focus();
}}>Show overlay above modal
@@ -1401,7 +1406,7 @@ Set `disable-top-layer` to open the modal as a non-modal dialog (`dialog.show()`
This modal uses disable-top-layer, so an overlay appended to document.body can display above it.
- Show overlay above modal
+ Show overlay above modal
@@ -1455,7 +1460,7 @@ Set `disable-top-layer` to open the modal as a non-modal dialog (`dialog.show()`
## Technical Notes
- The component renders a native `` and automatically sets `aria-labelledby` based on the slotted heading content (`${componentId}-heading`). Ensure your modal header contains a semantic heading (``) so assistive technologies announce it. `aria-modal` is `true` by default and `false` when `disable-top-layer` is set (a non-modal dialog).
-- Focus trapping is managed internally. When `open` becomes `true`, the component stores the previously focused element, queries for focusable nodes inside the modal, and moves focus to the first match. When `hideModal()` is called (directly or indirectly), focus is restored to the element that opened the modal.
+- Focus trapping is managed internally. When `open` becomes `true`, the component stores the previously focused element, queries for focusable nodes inside the modal, and moves focus to the first match. When `hideModal()` is called (directly or indirectly), focus is restored to the element that opened the modal. In `disable-top-layer` mode focus is still placed on open but **not** trapped, so it can move to overlays stacked above the modal.
- Nested modals respect z-index order: backdrop clicks and Escape close only the top-most modal. Use this when stacking wizard dialogs or confirm prompts.
diff --git a/libs/core/src/components/pds-modal/stories/pds-modal.stories.js b/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
index e97636220..d2dc2fe17 100644
--- a/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
+++ b/libs/core/src/components/pds-modal/stories/pds-modal.stories.js
@@ -704,7 +704,7 @@ const DisableTopLayerTemplate = (args) => html`
Show overlay above modal