@postnord/web-components
Version:
PostNord Web Components
99 lines (95 loc) • 5.79 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { r as registerInstance, g as getElement, h, a as Host } from './index-5606614b.js';
import { u as uuidv4 } from './helpers-88f72b54.js';
const pnButtonDropdownCss = "pn-button-dropdown{display:inline-block;position:relative}pn-button-dropdown .pn-button-dropdown-container{position:absolute;top:130%;left:0;border-radius:1em;box-shadow:0 0.125em 1em rgba(0, 0, 0, 0.2);transform-origin:top left;transition:transform 0.2s cubic-bezier(0.7, 0, 0.3, 1) 0.15s;transform:scale(0);overflow-y:auto;max-width:95vw;max-width:min(95vw, 40em);max-height:80vh;z-index:10;background:#ffffff}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{padding:1em;opacity:0;transition:opacity 0.2s cubic-bezier(0.7, 0, 0.3, 1), visibility 0.2s;transition-delay:0s;position:relative;width:max-content;max-width:100%;visibility:hidden}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 PnButtonDropdownStyle0 = pnButtonDropdownCss;
const PnButtonDropdown = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.right = false;
this.top = false;
this.label = undefined;
this.icon = undefined;
this.appearance = '';
this.variant = '';
this.small = false;
this.tooltip = undefined;
this.open = false;
}
id = `pn-button-${uuidv4()}`;
focusableElements;
container;
dropdownButtonId = `${this.id}-dropdown`;
dropdownContentId = `${this.id}-content`;
get hostElement() { return getElement(this); }
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: '7398ec85382fc0abe7b81849e739a7bc26bdd084' }, h("div", { key: '6ca6e2a0f28ce2fb03e0a2eca02309dbc50cbabb', class: "pn-button-dropdown" }, h("pn-button", { key: '629cec46e4cdf9cd346ff4160596cf255dea6187', label: this.label, buttonId: this.dropdownButtonId, class: "pn-button-dropdown-label", appearance: this.appearance, variant: this.variant, small: this.small, icon: this.icon, ariacontrols: this.dropdownContentId, ariahaspopup: "true", ariaexpanded: this.open.toString(), onPnClick: this.toggle, tooltip: this.tooltip, tooltipUp: !this.top, iconOnly: !!this.tooltip && !!this.icon && !this.label }), h("div", { key: '51c980101ab122802f27634488b2ae6ef6c59ced', 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: 'e6d703cfcc8e123b4e84e98fb4e7471911bc28bb', class: "pn-button-dropdown-content" }, h("slot", { key: 'ee5450952fb2c7df077cb56debcd7873cfc86739' }))))));
}
static get watchers() { return {
"open": ["openHandler"]
}; }
};
PnButtonDropdown.style = PnButtonDropdownStyle0;
export { PnButtonDropdown as pn_button_dropdown };
//# sourceMappingURL=pn-button-dropdown.entry.js.map