UNPKG

@dsb.dk/designsystem

Version:

Development environment for creating components to the DSB Designsystem.

152 lines (123 loc) 4.97 kB
import { h, T } from '../lit-element-a21c046d.js'; import { r as randomId } from '../id-839a82d1.js'; import { f as flip } from '../flip-60377d92.js'; var css_248z = ":host{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}aside{-webkit-transition:var(--flyout-transition);transition:var(--flyout-transition);position:fixed;left:0;top:0;width:100vw;min-height:50vh;z-index:13;background-color:var(--color-red);color:var(--color-white);-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}aside,aside[hidden]{display:-webkit-box;display:-ms-flexbox;display:flex}aside[hidden]{-webkit-transform:translateY(-100%);transform:translateY(-100%)}aside[hidden]+.backdrop{opacity:0}.backdrop{-webkit-transition:opacity .6s var(--ease-in-out-quint);transition:opacity .6s var(--ease-in-out-quint);position:fixed;top:0;right:0;bottom:0;left:0;background:rgba(0,0,0,.6);z-index:-1;pointer-events:none}.close-button{--icon-size:var(--units-2);position:absolute;right:0;top:0;padding:var(--icon-size)}"; const FLYOUT_WAS_TOGGLED = 'flyout-toggled'; const FLYOUT_DOM_TREE_CHANGED = 'flyout-changed'; class Flyout extends h { static get styles() { return [css_248z]; } static get properties() { return { isOpen: { state: true }, id: { state: true }, }; } constructor() { super(); this.isOpen = false; this.id = randomId(); this.activeElementBeforeOpening = null; this.observer = null; this.contentSize = null; } connectedCallback() { super.connectedCallback(); // TODO: can't find element directly? why? setTimeout(() => { this.content = this.renderRoot.querySelector('aside'); this.initMutationObserver(); this.contentSize = flip.getState(this.content); window.addEventListener('resize', this.animateSize.bind(this)); }, 10); window.addEventListener('keydown', this.closeOnEsc.bind(this)); window.addEventListener('click', this.closeOnBodyClick.bind(this)); } disconnectedCallback() { super.disconnectedCallback(); window.removeEventListener('keydown', this.closeOnEsc.bind(this)); window.removeEventListener('resize', this.animateSize.bind(this)); window.removeEventListener('click', this.closeOnBodyClick.bind(this)); this.observer && this.observer.disconnect(); } closeOnEsc(event) { if (!this.isOpen) return; if (event.key === 'Escape') this.toggle(false); } closeOnBodyClick(event) { if (!this.isOpen) return; if (event.clientY > this.content.getBoundingClientRect().height) { this.toggle(false); } } toggle(shouldOpen) { this.isOpen = shouldOpen !== undefined ? shouldOpen : !this.isOpen; if (this.isOpen && document.activeElement) { this.activeElementBeforeOpening = document.activeElement; } if (!this.isOpen && this.activeElementBeforeOpening) { this.activeElementBeforeOpening.focus(); } this.fireCustomEvent(); } animateSize() { flip.expand(this.contentSize); this.contentSize = flip.getState(this.content); } initMutationObserver() { const config = { attributes: true, childList: true, subtree: true }; const callback = (mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === 'childList') { this.fireCustomEvent(); this.animateSize(); } } }; this.observer = new MutationObserver(callback); this.observer.observe(this, config); } fireCustomEvent() { this.dispatchEvent( new CustomEvent(FLYOUT_WAS_TOGGLED, { bubbles: true, detail: { message: `<dsb-flyout> with id ${this.id} was toggled`, isOpen: this.isOpen, contentSize: this.content.getBoundingClientRect(), }, }) ); } render() { return T` <slot name="openButton" @click=${() => this.toggle()} aria-expanded=${this.isOpen} aria-controls=${this.id} ></slot> <aside class="content ${this.isOpen ? 'is-open' : ''}" .hidden=${!this.isOpen} aria-hidden=${!this.isOpen} id=${this.id} role="dialog" > <div class="close-button"> <dsb-icon-button icon="cross" @click=${() => this.toggle(false)} aria-expanded=${this.isOpen} aria-controls=${this.id} ></dsb-icon-button> </div> <slot></slot> </aside> <div class="backdrop"></div> `; } } customElements.define('dsb-flyout', Flyout); export { FLYOUT_DOM_TREE_CHANGED, FLYOUT_WAS_TOGGLED, Flyout };