Hello! You can close this notification here:
diff --git a/packages/overlays/docs/40-system-configuration.md b/packages/overlays/docs/40-system-configuration.md
index 17efe6209..4df796fef 100644
--- a/packages/overlays/docs/40-system-configuration.md
+++ b/packages/overlays/docs/40-system-configuration.md
@@ -203,8 +203,8 @@ Boolean property. When true, will add a backdrop when the overlay is opened.
The backdrop styling can be configured by targeting the `.global-overlays .global-overlays__backdrop` css selector.
The backdrop animation can be configured by targeting the
-`.global-overlays .global-overlays__backdrop--fade-in` and
-`.global-overlays .global-overlays__backdrop--fade-out` css selector.
+`.global-overlays .global-overlays__backdrop--animation-in` and
+`.global-overlays .global-overlays__backdrop--animation-out` css selector.
This currently only supports CSS Animations, because it relies on the `animationend` event to add/remove classes.
```js preview-story
@@ -235,8 +235,8 @@ Boolean property. When true, will add a backdrop when the overlay is opened.
The backdrop styling can be configured by targeting the `.global-overlays .global-overlays__backdrop` css selector.
The backdrop animation can be configured by targeting the
-`.global-overlays .global-overlays__backdrop--fade-in` and
-`.global-overlays .global-overlays__backdrop--fade-out` css selector.
+`.global-overlays .global-overlays__backdrop--animation-in` and
+`.global-overlays .global-overlays__backdrop--animation-out` css selector.
This currently only supports CSS Animations, because it relies on the `animationend` event to add/remove classes.
```js preview-story
diff --git a/packages/overlays/docs/demo-overlay-backdrop.js b/packages/overlays/docs/demo-overlay-backdrop.js
new file mode 100644
index 000000000..3aa56e3b4
--- /dev/null
+++ b/packages/overlays/docs/demo-overlay-backdrop.js
@@ -0,0 +1,48 @@
+import { css, LitElement } from '@lion/core';
+
+/**
+ * @typedef {import('../types/OverlayConfig').OverlayConfig} OverlayConfig
+ */
+class DemoOverlayBackdrop extends LitElement {
+ static get styles() {
+ return css`
+ :host {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 1;
+ background-color: red;
+ opacity: 0.3;
+ display: none;
+ }
+
+ :host(.local-overlays__backdrop--visible) {
+ display: block;
+ }
+
+ :host(.local-overlays__backdrop--animation-in) {
+ animation: local-overlays-backdrop-fade-in 300ms;
+ }
+
+ :host(.local-overlays__backdrop--animation-out) {
+ animation: local-overlays-backdrop-fade-out 300ms;
+ opacity: 0;
+ }
+
+ @keyframes local-overlays-backdrop-fade-in {
+ from {
+ opacity: 0;
+ }
+ }
+
+ @keyframes local-overlays-backdrop-fade-out {
+ from {
+ opacity: 0.3;
+ }
+ }
+ `;
+ }
+}
+customElements.define('demo-overlay-backdrop', DemoOverlayBackdrop);
diff --git a/packages/overlays/docs/demo-overlay-system.js b/packages/overlays/docs/demo-overlay-system.js
index 4bcbfa85f..d94ae5499 100644
--- a/packages/overlays/docs/demo-overlay-system.js
+++ b/packages/overlays/docs/demo-overlay-system.js
@@ -40,7 +40,7 @@ class DemoOverlaySystem extends OverlayMixin(LitElement) {
render() {
return html`
-
+
diff --git a/packages/overlays/src/OverlayController.js b/packages/overlays/src/OverlayController.js
index 9eca844a1..22f69a2f5 100644
--- a/packages/overlays/src/OverlayController.js
+++ b/packages/overlays/src/OverlayController.js
@@ -251,7 +251,7 @@ export class OverlayController extends EventTargetShim {
* @type {boolean}
*/
get hasBackdrop() {
- return /** @type {boolean} */ (this.config?.hasBackdrop);
+ return /** @type {boolean} */ (!!this.backdropNode || this.config?.hasBackdrop);
}
/**
@@ -618,7 +618,7 @@ export class OverlayController extends EventTargetShim {
}
}
} else if (phase === 'teardown') {
- this.__restorOriginalAttrs();
+ this.__restoreOriginalAttrs();
}
}
@@ -634,7 +634,7 @@ export class OverlayController extends EventTargetShim {
this.__originalAttrs.set(node, attrMap);
}
- __restorOriginalAttrs() {
+ __restoreOriginalAttrs() {
for (const [node, attrMap] of this.__originalAttrs) {
Object.entries(attrMap).forEach(([attrName, value]) => {
if (value !== null) {
@@ -798,16 +798,49 @@ export class OverlayController extends EventTargetShim {
}
/**
- * @param {{backdropNode:HTMLElement, contentNode:HTMLElement}} config
+ * @param {{backdropNode:HTMLElement, contentNode:HTMLElement}} hideConfig
*/
// eslint-disable-next-line class-methods-use-this, no-empty-function, no-unused-vars
- async transitionHide(config) {}
+ async transitionHide(hideConfig) {
+ if (hideConfig.backdropNode) {
+ hideConfig.backdropNode.classList.remove(
+ `${this.placementMode}-overlays__backdrop--animation-in`,
+ );
+ /** @type {(ev:AnimationEvent) => void} */
+ let afterFadeOut;
+ hideConfig.backdropNode.classList.add(
+ `${this.placementMode}-overlays__backdrop--animation-out`,
+ );
+ this.__backdropAnimation = new Promise(resolve => {
+ afterFadeOut = () => {
+ if (hideConfig.backdropNode) {
+ hideConfig.backdropNode.classList.remove(
+ `${this.placementMode}-overlays__backdrop--animation-out`,
+ );
+ hideConfig.backdropNode.classList.remove(
+ `${this.placementMode}-overlays__backdrop--visible`,
+ );
+ hideConfig.backdropNode.removeEventListener('animationend', afterFadeOut);
+ }
+ resolve();
+ };
+ });
+ // @ts-expect-error
+ hideConfig.backdropNode.addEventListener('animationend', afterFadeOut);
+ }
+ }
/**
- * @param {{backdropNode:HTMLElement, contentNode:HTMLElement}} config
+ * @param {{backdropNode:HTMLElement, contentNode:HTMLElement}} showConfig
*/
// eslint-disable-next-line class-methods-use-this, no-empty-function, no-unused-vars
- async transitionShow(config) {}
+ async transitionShow(showConfig) {
+ if (showConfig.backdropNode) {
+ showConfig.backdropNode.classList.add(
+ `${this.placementMode}-overlays__backdrop--animation-in`,
+ );
+ }
+ }
_restoreFocus() {
// We only are allowed to move focus if we (still) 'own' it.
@@ -893,19 +926,20 @@ export class OverlayController extends EventTargetShim {
/**
* Sets up backdrop on the given overlay. If there was a backdrop on another element
- * it is removed. Otherwise this is the first time displaying a backdrop, so a fade-in
+ * it is removed. Otherwise this is the first time displaying a backdrop, so a animation-in
* animation is played.
* @param {{ animation?: boolean, phase: OverlayPhase }} config
*/
- _handleBackdrop({ animation = true, phase }) {
+ _handleBackdrop({ phase }) {
switch (phase) {
case 'init': {
if (!this.backdropNode) {
this.__backdropNode = document.createElement('div');
/** @type {HTMLElement} */
+ (this.backdropNode).slot = 'backdrop';
+ /** @type {HTMLElement} */
(this.backdropNode).classList.add(`${this.placementMode}-overlays__backdrop`);
}
- this.backdropNode.slot = '_overlay-shadow-outlet';
let insertionAnchor = /** @type {HTMLElement} */ (this.contentNode.parentNode);
let insertionBefore = this.contentNode;
@@ -917,12 +951,7 @@ export class OverlayController extends EventTargetShim {
break;
}
case 'show':
- if (this.placementMode === 'global') {
- this.backdropNode.classList.add('global-overlays__backdrop--visible');
- if (animation === true) {
- this.backdropNode.classList.add('global-overlays__backdrop--fade-in');
- }
- }
+ this.backdropNode.classList.add(`${this.placementMode}-overlays__backdrop--visible`);
this.__hasActiveBackdrop = true;
break;
case 'hide':
@@ -930,39 +959,15 @@ export class OverlayController extends EventTargetShim {
return;
}
this.__hasActiveBackdrop = false;
-
- if (this.placementMode === 'global') {
- this.backdropNode.classList.remove('global-overlays__backdrop--fade-in');
- if (animation) {
- /** @type {(ev:AnimationEvent) => void} */
- let afterFadeOut;
- this.backdropNode.classList.add('global-overlays__backdrop--fade-out');
- this.__backDropAnimation = new Promise(resolve => {
- afterFadeOut = () => {
- if (this.backdropNode) {
- this.backdropNode.classList.remove('global-overlays__backdrop--fade-out');
- this.backdropNode.classList.remove('global-overlays__backdrop--visible');
- this.backdropNode.removeEventListener('animationend', afterFadeOut);
- }
- resolve();
- };
- });
- // @ts-expect-error
- this.backdropNode.addEventListener('animationend', afterFadeOut);
- } else {
- this.backdropNode.classList.remove('global-overlays__backdrop--visible');
- }
- }
-
break;
case 'teardown':
if (!this.backdropNode || !this.backdropNode.parentNode) {
return;
}
- if (animation && this.__backDropAnimation) {
+ if (this.__backdropAnimation) {
this.__backdropNodeToBeTornDown = this.backdropNode;
- this.__backDropAnimation.then(() => {
+ this.__backdropAnimation.then(() => {
if (this.__backdropNodeToBeTornDown) {
/** @type {HTMLElement} */ (this.__backdropNodeToBeTornDown.parentNode).removeChild(
this.__backdropNodeToBeTornDown,
diff --git a/packages/overlays/src/globalOverlaysStyle.js b/packages/overlays/src/globalOverlaysStyle.js
index d112f77fb..7325d1305 100644
--- a/packages/overlays/src/globalOverlaysStyle.js
+++ b/packages/overlays/src/globalOverlaysStyle.js
@@ -85,11 +85,11 @@ export const globalOverlaysStyle = css`
display: block;
}
- .global-overlays .global-overlays__backdrop--fade-in {
+ .global-overlays .global-overlays__backdrop--animation-in {
animation: global-overlays-backdrop-fade-in 300ms;
}
- .global-overlays .global-overlays__backdrop--fade-out {
+ .global-overlays .global-overlays__backdrop--animation-out {
animation: global-overlays-backdrop-fade-out 300ms;
opacity: 0;
}