@synergy-design-system/components
Version:
This package provides the base of the Synergy Design System as native web components. It uses [lit](https://www.lit.dev) and parts of [shoelace](https://shoelace.style/). Synergy officially supports the latest two versions of all major browsers (as define
296 lines (291 loc) • 9.28 kB
JavaScript
import {
Modal
} from "./chunk.AYAX7BG7.js";
import {
dialog_custom_styles_default
} from "./chunk.IU3SSJZE.js";
import {
dialog_styles_default
} from "./chunk.MU43DZ7W.js";
import {
lockBodyScrolling,
unlockBodyScrolling
} from "./chunk.5732DMBC.js";
import {
blurActiveElement
} from "./chunk.WXVOTRW5.js";
import {
SynIconButton
} from "./chunk.BANJ5DAQ.js";
import {
waitForEvent
} from "./chunk.C2ENQBPM.js";
import {
animateTo,
stopAnimations
} from "./chunk.G6ITZTTW.js";
import {
getAnimation,
setDefaultAnimation
} from "./chunk.7JGKUB4A.js";
import {
LocalizeController
} from "./chunk.OAQRCZOO.js";
import {
HasSlotController
} from "./chunk.WVVQK5TE.js";
import {
watch
} from "./chunk.BVZQ6QSY.js";
import {
component_styles_default
} from "./chunk.NLYVOJGK.js";
import {
SynergyElement
} from "./chunk.3AZFEB6D.js";
import {
__decorateClass
} from "./chunk.Z4XV3SMG.js";
// src/components/dialog/dialog.component.ts
import { classMap } from "lit/directives/class-map.js";
import { html } from "lit";
import { ifDefined } from "lit/directives/if-defined.js";
import { property, query } from "lit/decorators.js";
var SynDialog = class extends SynergyElement {
constructor() {
super(...arguments);
this.hasSlotController = new HasSlotController(this, "footer");
this.localize = new LocalizeController(this);
this.modal = new Modal(this);
this.open = false;
this.label = "";
this.noHeader = false;
this.handleDocumentKeyDown = (event) => {
if (event.key === "Escape" && this.modal.isActive() && this.open) {
event.stopPropagation();
this.requestClose("keyboard");
}
};
}
firstUpdated() {
this.dialog.hidden = !this.open;
if (this.open) {
this.addOpenListeners();
this.modal.activate();
lockBodyScrolling(this);
}
}
disconnectedCallback() {
super.disconnectedCallback();
this.modal.deactivate();
unlockBodyScrolling(this);
this.removeOpenListeners();
}
requestClose(source) {
const slRequestClose = this.emit("syn-request-close", {
cancelable: true,
detail: { source }
});
if (slRequestClose.defaultPrevented) {
const animation = getAnimation(this, "dialog.denyClose", { dir: this.localize.dir() });
animateTo(this.panel, animation.keyframes, animation.options);
return;
}
this.hide();
}
addOpenListeners() {
var _a;
if ("CloseWatcher" in window) {
(_a = this.closeWatcher) == null ? void 0 : _a.destroy();
this.closeWatcher = new CloseWatcher();
this.closeWatcher.onclose = () => this.requestClose("keyboard");
} else {
document.addEventListener("keydown", this.handleDocumentKeyDown);
}
}
removeOpenListeners() {
var _a;
(_a = this.closeWatcher) == null ? void 0 : _a.destroy();
document.removeEventListener("keydown", this.handleDocumentKeyDown);
}
async handleOpenChange() {
if (this.open) {
this.emit("syn-show");
this.addOpenListeners();
this.originalTrigger = document.activeElement;
this.modal.activate();
lockBodyScrolling(this);
const autoFocusTarget = this.querySelector("[autofocus]");
if (autoFocusTarget) {
autoFocusTarget.removeAttribute("autofocus");
}
await Promise.all([stopAnimations(this.dialog), stopAnimations(this.overlay)]);
this.dialog.hidden = false;
requestAnimationFrame(() => {
const slInitialFocus = this.emit("syn-initial-focus", { cancelable: true });
if (!slInitialFocus.defaultPrevented) {
if (autoFocusTarget) {
autoFocusTarget.focus({ preventScroll: true });
} else {
this.panel.focus({ preventScroll: true });
}
}
if (autoFocusTarget) {
autoFocusTarget.setAttribute("autofocus", "");
}
});
const panelAnimation = getAnimation(this, "dialog.show", { dir: this.localize.dir() });
const overlayAnimation = getAnimation(this, "dialog.overlay.show", { dir: this.localize.dir() });
await Promise.all([
animateTo(this.panel, panelAnimation.keyframes, panelAnimation.options),
animateTo(this.overlay, overlayAnimation.keyframes, overlayAnimation.options)
]);
this.emit("syn-after-show");
} else {
blurActiveElement(this);
this.emit("syn-hide");
this.removeOpenListeners();
this.modal.deactivate();
await Promise.all([stopAnimations(this.dialog), stopAnimations(this.overlay)]);
const panelAnimation = getAnimation(this, "dialog.hide", { dir: this.localize.dir() });
const overlayAnimation = getAnimation(this, "dialog.overlay.hide", { dir: this.localize.dir() });
await Promise.all([
animateTo(this.overlay, overlayAnimation.keyframes, overlayAnimation.options).then(() => {
this.overlay.hidden = true;
}),
animateTo(this.panel, panelAnimation.keyframes, panelAnimation.options).then(() => {
this.panel.hidden = true;
})
]);
this.dialog.hidden = true;
this.overlay.hidden = false;
this.panel.hidden = false;
unlockBodyScrolling(this);
const trigger = this.originalTrigger;
if (typeof (trigger == null ? void 0 : trigger.focus) === "function") {
setTimeout(() => trigger.focus());
}
this.emit("syn-after-hide");
}
}
/** Shows the dialog. */
async show() {
if (this.open) {
return void 0;
}
this.open = true;
return waitForEvent(this, "syn-after-show");
}
/** Hides the dialog */
async hide() {
if (!this.open) {
return void 0;
}
this.open = false;
return waitForEvent(this, "syn-after-hide");
}
render() {
return html`
<div
part="base"
class=${classMap({
dialog: true,
"dialog--open": this.open,
"dialog--has-footer": this.hasSlotController.test("footer")
})}
>
<div part="overlay" class="dialog__overlay" =${() => this.requestClose("overlay")} tabindex="-1"></div>
<div
part="panel"
class="dialog__panel"
role="dialog"
aria-modal="true"
aria-hidden=${this.open ? "false" : "true"}
aria-label=${ifDefined(this.noHeader ? this.label : void 0)}
aria-labelledby=${ifDefined(!this.noHeader ? "title" : void 0)}
tabindex="-1"
>
${!this.noHeader ? html`
<header part="header" class="dialog__header">
<h2 part="title" class="dialog__title" id="title">
<slot name="label"> ${this.label.length > 0 ? this.label : String.fromCharCode(65279)} </slot>
</h2>
<div part="header-actions" class="dialog__header-actions">
<slot name="header-actions"></slot>
<syn-icon-button
part="close-button"
exportparts="base:close-button__base"
class="dialog__close"
name="x-lg"
label=${this.localize.term("close")}
library="system"
="${() => this.requestClose("close-button")}"
></syn-icon-button>
</div>
</header>
` : ""}
${""}
<div part="body" class="dialog__body" tabindex="-1"><slot></slot></div>
<footer part="footer" class="dialog__footer">
<slot name="footer"></slot>
</footer>
</div>
</div>
`;
}
};
SynDialog.styles = [component_styles_default, dialog_styles_default, dialog_custom_styles_default];
SynDialog.dependencies = {
"syn-icon-button": SynIconButton
};
__decorateClass([
query(".dialog")
], SynDialog.prototype, "dialog", 2);
__decorateClass([
query(".dialog__panel")
], SynDialog.prototype, "panel", 2);
__decorateClass([
query(".dialog__overlay")
], SynDialog.prototype, "overlay", 2);
__decorateClass([
property({ type: Boolean, reflect: true })
], SynDialog.prototype, "open", 2);
__decorateClass([
property({ reflect: true })
], SynDialog.prototype, "label", 2);
__decorateClass([
property({ attribute: "no-header", type: Boolean, reflect: true })
], SynDialog.prototype, "noHeader", 2);
__decorateClass([
watch("open", { waitUntilFirstUpdate: true })
], SynDialog.prototype, "handleOpenChange", 1);
setDefaultAnimation("dialog.show", {
keyframes: [
{ opacity: 0, scale: 0.8 },
{ opacity: 1, scale: 1 }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("dialog.hide", {
keyframes: [
{ opacity: 1, scale: 1 },
{ opacity: 0, scale: 0.8 }
],
options: { duration: 250, easing: "ease" }
});
setDefaultAnimation("dialog.denyClose", {
keyframes: [{ scale: 1 }, { scale: 1.02 }, { scale: 1 }],
options: { duration: 250 }
});
setDefaultAnimation("dialog.overlay.show", {
keyframes: [{ opacity: 0 }, { opacity: 1 }],
options: { duration: 250 }
});
setDefaultAnimation("dialog.overlay.hide", {
keyframes: [{ opacity: 1 }, { opacity: 0 }],
options: { duration: 250 }
});
export {
SynDialog
};
//# sourceMappingURL=chunk.FCSIWF7F.js.map