UNPKG

@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

411 lines (403 loc) 12.8 kB
import { drawer_custom_styles_default } from "./chunk.I4FIU7FA.js"; import { drawer_styles_default } from "./chunk.N7QJ54ZM.js"; import { Modal } from "./chunk.AYAX7BG7.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/drawer/drawer.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, state } from "lit/decorators.js"; // src/internal/string.ts function uppercaseFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } // src/components/drawer/drawer.component.ts var SynDrawer = class extends SynergyElement { constructor() { super(...arguments); this.hasSlotController = new HasSlotController(this, "footer"); this.localize = new LocalizeController(this); this.modal = new Modal(this); this.isVisible = false; this.open = false; this.label = ""; this.placement = "end"; this.contained = false; this.noHeader = false; this.handleDocumentKeyDown = (event) => { if (this.contained) { return; } if (event.key === "Escape" && this.modal.isActive() && this.open) { event.stopImmediatePropagation(); this.requestClose("keyboard"); } }; } firstUpdated() { this.drawer.hidden = this.isVisible ? false : !this.open; if (this.open) { this.addOpenListeners(); if (!this.contained) { this.modal.activate(); lockBodyScrolling(this); } } } disconnectedCallback() { super.disconnectedCallback(); unlockBodyScrolling(this); this.removeOpenListeners(); } requestClose(source) { const slRequestClose = this.emit("syn-request-close", { cancelable: true, detail: { source } }); if (slRequestClose.defaultPrevented) { const animation = getAnimation(this, "drawer.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(); if (!this.contained) { this.closeWatcher = new CloseWatcher(); this.closeWatcher.onclose = () => this.requestClose("keyboard"); } } else { document.addEventListener("keydown", this.handleDocumentKeyDown); } } removeOpenListeners() { var _a; document.removeEventListener("keydown", this.handleDocumentKeyDown); (_a = this.closeWatcher) == null ? void 0 : _a.destroy(); } async handleOpenChange() { if (this.open) { this.emit("syn-show"); this.addOpenListeners(); this.originalTrigger = document.activeElement; if (!this.contained) { this.modal.activate(); lockBodyScrolling(this); } const autoFocusTarget = this.querySelector("[autofocus]"); if (autoFocusTarget) { autoFocusTarget.removeAttribute("autofocus"); } await Promise.all([stopAnimations(this.drawer), stopAnimations(this.overlay)]); this.drawer.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, `drawer.show${uppercaseFirstLetter(this.placement)}`, { dir: this.localize.dir() }); const overlayAnimation = getAnimation(this, "drawer.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(); if (!this.contained) { this.modal.deactivate(); unlockBodyScrolling(this); } await Promise.all([stopAnimations(this.drawer), stopAnimations(this.overlay)]); const panelAnimation = getAnimation(this, `drawer.hide${uppercaseFirstLetter(this.placement)}`, { dir: this.localize.dir() }); const overlayAnimation = getAnimation(this, "drawer.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.drawer.hidden = !this.isVisible; this.overlay.hidden = false; this.panel.hidden = false; const trigger = this.originalTrigger; if (typeof (trigger == null ? void 0 : trigger.focus) === "function") { setTimeout(() => trigger.focus()); } this.emit("syn-after-hide"); } } handleNoModalChange() { if (this.open && !this.contained) { this.modal.activate(); lockBodyScrolling(this); } if (this.open && this.contained) { this.modal.deactivate(); unlockBodyScrolling(this); } } /** Shows the drawer. */ async show() { if (this.open) { return void 0; } this.open = true; return waitForEvent(this, "syn-after-show"); } /** Hides the drawer */ async hide() { if (!this.open) { return void 0; } this.open = false; return waitForEvent(this, "syn-after-hide"); } // Forces the visibility of the drawer even with `open` set to false. This is needed for the `rail` and `sticky` variant of the syn-side-nav forceVisibility(isVisible) { this.isVisible = isVisible; this.drawer.hidden = isVisible ? false : !this.open; } render() { return html` <div part="base" class=${classMap({ drawer: true, "drawer--open": this.open, "drawer--top": this.placement === "top", "drawer--end": this.placement === "end", "drawer--bottom": this.placement === "bottom", "drawer--start": this.placement === "start", "drawer--contained": this.contained, "drawer--fixed": !this.contained, "drawer--rtl": this.localize.dir() === "rtl", "drawer--has-footer": this.hasSlotController.test("footer") })} > <div part="overlay" class="drawer__overlay" @click=${() => this.requestClose("overlay")} tabindex="-1"></div> <div part="panel" class="drawer__panel" role="dialog" aria-modal="true" aria-hidden=${this.isVisible ? "false" : this.open ? "false" : "true"} aria-label=${ifDefined(this.noHeader ? this.label : void 0)} aria-labelledby=${ifDefined(!this.noHeader ? "title" : void 0)} tabindex="0" > ${!this.noHeader ? html` <header part="header" class="drawer__header"> <h2 part="title" class="drawer__title" id="title"> <!-- If there's no label, use an invisible character to prevent the header from collapsing --> <slot name="label"> ${this.label.length > 0 ? this.label : String.fromCharCode(65279)} </slot> </h2> <div part="header-actions" class="drawer__header-actions"> <slot name="header-actions"></slot> <syn-icon-button part="close-button" exportparts="base:close-button__base" class="drawer__close" name="x-lg" label=${this.localize.term("close")} library="system" @click=${() => this.requestClose("close-button")} ></syn-icon-button> </div> </header> ` : ""} <slot part="body" class="drawer__body"></slot> <footer part="footer" class="drawer__footer"> <slot name="footer"></slot> </footer> </div> </div> `; } }; SynDrawer.styles = [component_styles_default, drawer_styles_default, drawer_custom_styles_default]; SynDrawer.dependencies = { "syn-icon-button": SynIconButton }; __decorateClass([ state() ], SynDrawer.prototype, "isVisible", 2); __decorateClass([ query(".drawer") ], SynDrawer.prototype, "drawer", 2); __decorateClass([ query(".drawer__panel") ], SynDrawer.prototype, "panel", 2); __decorateClass([ query(".drawer__overlay") ], SynDrawer.prototype, "overlay", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynDrawer.prototype, "open", 2); __decorateClass([ property({ reflect: true }) ], SynDrawer.prototype, "label", 2); __decorateClass([ property({ reflect: true }) ], SynDrawer.prototype, "placement", 2); __decorateClass([ property({ type: Boolean, reflect: true }) ], SynDrawer.prototype, "contained", 2); __decorateClass([ property({ attribute: "no-header", type: Boolean, reflect: true }) ], SynDrawer.prototype, "noHeader", 2); __decorateClass([ watch("open", { waitUntilFirstUpdate: true }) ], SynDrawer.prototype, "handleOpenChange", 1); __decorateClass([ watch("contained", { waitUntilFirstUpdate: true }) ], SynDrawer.prototype, "handleNoModalChange", 1); setDefaultAnimation("drawer.showTop", { keyframes: [ { opacity: 0, translate: "0 -100%" }, { opacity: 1, translate: "0 0" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.hideTop", { keyframes: [ { opacity: 1, translate: "0 0" }, { opacity: 0, translate: "0 -100%" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.showEnd", { keyframes: [ { opacity: 0, translate: "100%" }, { opacity: 1, translate: "0" } ], rtlKeyframes: [ { opacity: 0, translate: "-100%" }, { opacity: 1, translate: "0" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.hideEnd", { keyframes: [ { opacity: 1, translate: "0" }, { opacity: 0, translate: "100%" } ], rtlKeyframes: [ { opacity: 1, translate: "0" }, { opacity: 0, translate: "-100%" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.showBottom", { keyframes: [ { opacity: 0, translate: "0 100%" }, { opacity: 1, translate: "0 0" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.hideBottom", { keyframes: [ { opacity: 1, translate: "0 0" }, { opacity: 0, translate: "0 100%" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.showStart", { keyframes: [ { opacity: 0, translate: "-100%" }, { opacity: 1, translate: "0" } ], rtlKeyframes: [ { opacity: 0, translate: "100%" }, { opacity: 1, translate: "0" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.hideStart", { keyframes: [ { opacity: 1, translate: "0" }, { opacity: 0, translate: "-100%" } ], rtlKeyframes: [ { opacity: 1, translate: "0" }, { opacity: 0, translate: "100%" } ], options: { duration: 250, easing: "ease" } }); setDefaultAnimation("drawer.denyClose", { keyframes: [{ scale: 1 }, { scale: 1.01 }, { scale: 1 }], options: { duration: 250 } }); setDefaultAnimation("drawer.overlay.show", { keyframes: [{ opacity: 0 }, { opacity: 1 }], options: { duration: 250 } }); setDefaultAnimation("drawer.overlay.hide", { keyframes: [{ opacity: 1 }, { opacity: 0 }], options: { duration: 250 } }); export { SynDrawer }; //# sourceMappingURL=chunk.RN7MBD4H.js.map