UNPKG

@postnord/web-components

Version:
155 lines (150 loc) 8.09 kB
/*! * Built with Stencil * By PostNord. */ import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client'; import { u as uuidv4 } from './helpers.js'; import { d as defineCustomElement$4 } from './pn-button2.js'; import { d as defineCustomElement$3 } from './pn-icon2.js'; import { d as defineCustomElement$2 } from './pn-spinner2.js'; const pnButtonDropdownCss = "pn-button-dropdown{display:inline-block;position:relative}pn-button-dropdown .pn-button-dropdown-container{z-index:10;position:absolute;top:130%;left:0;background-color:#ffffff;border-radius:1em;box-shadow:0 0.125em 1em rgba(0, 0, 0, 0.2);overflow-y:auto;max-width:95vw;max-width:min(95vw, 40em);max-height:80vh;transform:scale(0);transform-origin:top left;transition-property:transform;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-button-dropdown .pn-button-dropdown-container{transition-duration:0s;transition-delay:0s}}pn-button-dropdown .pn-button-dropdown-container{transition-delay:0.2s}pn-button-dropdown .pn-button-dropdown-container[data-right]{left:unset;right:0;transform-origin:top right}pn-button-dropdown .pn-button-dropdown-container[data-top]{top:unset;bottom:130%;transform-origin:bottom left}pn-button-dropdown .pn-button-dropdown-content{position:relative;padding:1em;opacity:0;width:max-content;max-width:100%;visibility:hidden;transition-property:opacity, visibility;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-button-dropdown .pn-button-dropdown-content{transition-duration:0s;transition-delay:0s}}pn-button-dropdown .pn-button-dropdown-content{transition-delay:0s, 0.2s}pn-button-dropdown .pn-button-dropdown[data-open=true] .pn-button-dropdown-container{transition-delay:0s}pn-button-dropdown .pn-button-dropdown[data-open=true] .pn-button-dropdown-content{opacity:1;visibility:visible}"; const PnButtonDropdown$1 = /*@__PURE__*/ proxyCustomElement(class PnButtonDropdown extends HTMLElement { constructor(registerHost) { super(); if (registerHost !== false) { this.__registerHost(); } } id = `pn-button-${uuidv4()}`; focusableElements; container; dropdownButtonId = `${this.id}-dropdown`; dropdownContentId = `${this.id}-content`; get hostElement() { return this; } right = false; top = false; /** The required label on the button. */ label; /** The optional SVG content of the icon you want. */ icon; /** Select between `light` and `warning`. */ appearance = ''; /** Select between `outlined` and `borderless`. */ variant = ''; /** Smaller button. */ small = false; /** Tooltip (required for Icon Only). */ tooltip; /** Open/close the dropdown without user interaction. */ open = false; openHandler() { this.toggleDropdown(); if (this.open) { document.addEventListener('click', this.globalHandler); document.addEventListener('keyup', this.globalHandler); } else { document.removeEventListener('click', this.globalHandler); document.removeEventListener('keyup', this.globalHandler); } } componentDidLoad() { if (this.open) this.openHandler(); } getRect(element) { return element.getBoundingClientRect(); } globalHandler = (e) => { // global events that we want to track to close the select, like "click outside" or tab out if (!this.hostElement.contains(e.target) || e?.key === 'Escape') { this.open = false; } }; toggleDropdown() { this.right = this.hostElement.offsetLeft > window.innerWidth / 2; requestAnimationFrame(() => { if (this.open) { this.container.style.transition = 'none'; this.container.style.transform = 'none'; } const containerRect = this.getRect(this.container); const hostElementRect = this.getRect(this.hostElement); // Calculate if dropdown should open upwards // if there is enough space above button const enoughSpaceAbove = hostElementRect.top > containerRect.height + window.innerWidth * 0.025; this.top = enoughSpaceAbove && hostElementRect.top + hostElementRect.height + containerRect.height > window.innerHeight - window.innerWidth * 0.025; let xAxis = 0; if (containerRect.right > window.innerWidth || containerRect.x < 0) { // 0.025 because the max width of the element is 95vw and we want the same margin on both sides xAxis = containerRect.x + containerRect.width + window.innerWidth * 0.025 - window.innerWidth; } this.container.style.transform = ''; requestAnimationFrame(() => { this.container.style.transition = ''; this.container.style.transform = this.open ? `scale(1) translateX(-${xAxis}px)` : ''; requestAnimationFrame(() => { this.hostElement.querySelector('.pn-button-dropdown').dataset.open = `${this.open}`; }); }); }); } toggle = () => { this.open = !this.open; }; render() { return (h(Host, { key: '0b6deb752a9f01bea9571627205b5cd3efbc1c66' }, h("div", { key: 'c7833d539d682a980bb7cc529f17d9942ffd7eb2', class: "pn-button-dropdown" }, h("pn-button", { key: '42d252b99f98b0c3f51795c894e899c6489839c2', label: this.label, buttonId: this.dropdownButtonId, class: "pn-button-dropdown-label", appearance: this.appearance, variant: this.variant, small: this.small, icon: this.icon, iconOnly: !!this.tooltip && !!this.icon && !this.label, ariacontrols: this.dropdownContentId, ariahaspopup: "true", ariaexpanded: this.open.toString(), tooltip: this.tooltip, tooltipUp: !this.top, onPnClick: this.toggle }), h("div", { key: 'dd494c992ef2b51f31ed5c48d87fb3044ed40009', ref: el => (this.container = el), id: this.dropdownContentId, class: "pn-button-dropdown-container", role: "region", "aria-labelledby": this.dropdownButtonId, "data-right": this.right, "data-top": this.top }, h("div", { key: 'e217ae843fa641335ce0714272f68f9a080afe7d', class: "pn-button-dropdown-content" }, h("slot", { key: 'f52ad763a52e9ee17d9a95a1e3a959d61fae2fe1' })))))); } static get watchers() { return { "open": ["openHandler"] }; } static get style() { return pnButtonDropdownCss; } }, [260, "pn-button-dropdown", { "label": [1], "icon": [1], "appearance": [1], "variant": [1], "small": [4], "tooltip": [1], "open": [1540], "right": [32], "top": [32] }, undefined, { "open": ["openHandler"] }]); function defineCustomElement$1() { if (typeof customElements === "undefined") { return; } const components = ["pn-button-dropdown", "pn-button", "pn-icon", "pn-spinner"]; components.forEach(tagName => { switch (tagName) { case "pn-button-dropdown": if (!customElements.get(tagName)) { customElements.define(tagName, PnButtonDropdown$1); } break; case "pn-button": if (!customElements.get(tagName)) { defineCustomElement$4(); } break; case "pn-icon": if (!customElements.get(tagName)) { defineCustomElement$3(); } break; case "pn-spinner": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; } }); } const PnButtonDropdown = PnButtonDropdown$1; const defineCustomElement = defineCustomElement$1; export { PnButtonDropdown, defineCustomElement }; //# sourceMappingURL=pn-button-dropdown.js.map //# sourceMappingURL=pn-button-dropdown.js.map