UNPKG

@postnord/web-components

Version:

PostNord Web Components

148 lines (142 loc) 8.4 kB
/*! * Built with Stencil * By PostNord. */ import { r as registerInstance, g as getElement, f as forceUpdate, h, a as Host, c as createEvent } from './index-dc6e40e7.js'; import { a as angle_down } from './angle_down-d788f691.js'; import { r as ripple } from './helpers-88f72b54.js'; const pnAccordionCss = "pn-accordion{position:relative;background-color:#ffffff;display:flex;align-items:stretch;flex-direction:column;gap:0.25em}pn-accordion>pn-accordion-row+pn-accordion-row:after{content:\"\";position:absolute;top:-0.125em;left:0.25em;width:calc(100% - 0.5em);height:0;border-top:0.0625em solid #d3cecb}"; const PnAccordionStyle0 = pnAccordionCss; const PnAccordion = class { constructor(hostRef) { registerInstance(this, hostRef); } mo; closeEvent = new CustomEvent('rowstate', { detail: false }); get hostElement() { return getElement(this); } /** Only allow a single row to be open at once. */ single = false; connectedCallback() { this.mo = new MutationObserver(() => forceUpdate(this.hostElement)); this.mo.observe(this.hostElement, { childList: true, subtree: true }); } disconnectedCallback() { this.mo.disconnect(); } handleSingleRow({ detail }) { if (!this.single) return; const element = detail.element; const activeRow = element.closest('pn-accordion-row'); const rows = Array.from(this.hostElement.querySelectorAll('pn-accordion-row')); rows.forEach(row => !row.isSameNode(activeRow) && row.dispatchEvent(this.closeEvent)); } render() { return (h(Host, { key: '800bf9af052f84af2f2fa3ec4e2351e8fd54da89' }, h("slot", { key: '53c8eac1eda11eda881f50b37476f3600ea3897b' }))); } }; PnAccordion.style = PnAccordionStyle0; const pnAccordionRowCss = "pn-accordion-row{position:relative;margin:0 -0.25em 0}pn-accordion-row .pn-accordion-row{width:100%;display:flex;flex-direction:column}pn-accordion-row .pn-accordion-row-summary{color:#2d2013;position:relative;border:none;outline:0;cursor:pointer;-webkit-tap-highlight-color:transparent;width:100%;padding:0.25em;font-size:1em;font-weight:400;border-radius:0.5em;list-style:none}pn-accordion-row .pn-accordion-row-summary:hover>.pn-accordion-row-text{background-color:#e0f8ff}pn-accordion-row .pn-accordion-row-summary:focus-visible>.pn-accordion-row-text{outline-color:#005d92}pn-accordion-row .pn-accordion-row-summary::-webkit-details-marker{display:none}pn-accordion-row .pn-accordion-row-text{position:relative;overflow:hidden;display:flex;align-items:center;padding:0.75em;background-color:#ffffff;border-radius:0.5em;-webkit-tap-highlight-color:transparent;outline:0.2rem solid transparent;outline-offset:0.2rem;transition-property:background-color, outline-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}pn-accordion-row .pn-accordion-row-text .pn-ripple{animation:ripple 0.4s cubic-bezier(0.7, 0, 0.3, 1);position:absolute;border-radius:50%;background-color:#005d92;transform:translate(-50%, -50%) scale(0);opacity:0.1;pointer-events:none;z-index:3}@keyframes ripple{to{transform:translate(-50%, -50%) scale(1);opacity:0}}pn-accordion-row .pn-accordion-row-icon{margin-left:auto;flex-shrink:0;transition-property:transform;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}pn-accordion-row .pn-accordion-row-icon path{fill:#005d92}pn-accordion-row .pn-accordion-row[open] .pn-accordion-row-icon{transform:rotate(-180deg)}pn-accordion-row .pn-accordion-row-content{color:#2d2013;display:block;padding:1em}"; const PnAccordionRowStyle0 = pnAccordionRowCss; const PnAccordionRow = class { constructor(hostRef) { registerInstance(this, hostRef); this.togglerow = createEvent(this, "togglerow", 7); } details; summary; content; animation; get hostElement() { return getElement(this); } isClosing = false; isExpanding = false; /** The label/title of the accordion row, you can also pass a slot with the name "label" if you want to put custom HTML content in there. */ label; /** The open/close status of the accordion row. */ state = false; /** Optional unique id for the `summary` element. @category ID */ buttonid; /** Optional unique id for the `div` element containing the content. @category ID */ contentid; /** Dispatched every time the row is toggled. Includes the row element and the boolean `state` prop. */ togglerow; /** Internal function for closing rows when using the `single` prop on the `pn-accordion`. */ handleRowState(event) { if (event.detail !== this.state) { this.details.style.overflow = 'hidden'; this.closeAccordion(); } } componentWillLoad() { const slottedLabel = !!this.hostElement.querySelector('[slot="label"]'); this.label = slottedLabel ? null : this.label; } toggleOpen(open) { const state = open ?? !this.state; if (this.state !== open) this.togglerow.emit({ element: this.details, state }); this.state = state; } clickHandler(e) { e.preventDefault(); this.details.style.overflow = 'hidden'; if (this.isClosing || !this.state) this.openAccordion(); else if (this.isClosing || this.state) this.closeAccordion(); const { x, width, y, top } = this.hostElement.getBoundingClientRect(); const clientCor = e.clientX === 0 && e.clientY === 0 ? { clientX: x + width - 24, clientY: y - top } : e; ripple(clientCor, this.hostElement, '.pn-accordion-row-text'); } openAccordion() { this.details.style.height = `${this.details.offsetHeight}px`; this.toggleOpen(true); window.requestAnimationFrame(() => { this.isExpanding = true; const startHeight = `${this.details.offsetHeight}px`; const endHeight = `${this.summary.offsetHeight + this.content.offsetHeight}px`; this.cancelAnimations(); this.animate(true, startHeight, endHeight); }); } closeAccordion() { this.isClosing = true; const startHeight = `${this.details.offsetHeight}px`; const endHeight = `${this.summary.offsetHeight}px`; this.cancelAnimations(); this.animate(false, startHeight, endHeight); } animate(open, startHeight, endHeight) { this.animation = this.details.animate({ height: [startHeight, endHeight], }, { duration: 400, easing: 'cubic-bezier(0.6, 0, 0.2, 1)', }); this.animation.onfinish = () => this.animationFinish(open); this.animation.oncancel = () => { if (open) this.isExpanding = false; else this.isClosing = false; }; } animationFinish(open) { this.toggleOpen(open); this.cancelAnimations(); this.isClosing = false; this.isExpanding = false; this.details.style.height = ''; this.details.style.overflow = ''; } cancelAnimations() { if (this.animation) this.animation.cancel(); } render() { return (h(Host, { key: 'e98e506637a1303e493b529928435dceb965bc35' }, h("details", { key: '34fec5b0c944442f48e8c6d23ef7756366906023', class: "pn-accordion-row", open: this.state, ref: (el) => (this.details = el) }, h("summary", { key: '9f2359b4aa9c3e894a5b436968e1783ac3361c65', id: this.buttonid, class: "pn-accordion-row-summary", onClick: e => this.clickHandler(e), ref: el => (this.summary = el) }, h("div", { key: '261f053b904d2f6f50ea90a610176829cfc2bf89', class: "pn-accordion-row-text" }, this.label ? this.label : '', h("slot", { key: 'ba20d07bfa5af6b771b98b407b7688b65339f341', name: "label" }), h("pn-icon", { key: 'fea80322eb33a895fc5fce7a9245de98e9f28e2a', class: "pn-accordion-row-icon", icon: angle_down }))), h("div", { key: 'f3bf848e95eb68e3bcb268f3a35924709df0823e', id: this.contentid, class: "pn-accordion-row-content", ref: (el) => (this.content = el) }, h("slot", { key: 'd7c939e3ca67e430906c655b347c08c236f528fa' }))))); } }; PnAccordionRow.style = PnAccordionRowStyle0; export { PnAccordion as pn_accordion, PnAccordionRow as pn_accordion_row }; //# sourceMappingURL=pn-accordion_2.entry.js.map