@postnord/web-components
Version:
PostNord Web Components
122 lines (118 loc) • 7.6 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { r as registerInstance, c as createEvent, g as getElement, h, a as Host } from './index-C247oTEA.js';
import { c as chevron_down } from './chevron_down-DrYFvs2M.js';
import { ripple, reduceMotion } from './index.js';
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}pn-accordion-row .pn-accordion-row-text[data-transparent]{background-color:transparent}pn-accordion-row .pn-accordion-row-text{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)}@media (prefers-reduced-motion: reduce){pn-accordion-row .pn-accordion-row-text{transition-duration:0s;transition-delay:0s}}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)}@media (prefers-reduced-motion: reduce){pn-accordion-row .pn-accordion-row-icon{transition-duration:0s;transition-delay:0s}}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 PnAccordionRow = class {
constructor(hostRef) {
registerInstance(this, hostRef);
this.togglerow = createEvent(this, "togglerow");
}
details;
summary;
content;
animation;
defaultAnimationDuration = 400;
animationDuration = this.defaultAnimationDuration;
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;
/** Optional prop that removes the default white background on the accordion row. @since v7.10.0 */
transparent = false;
/** 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);
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) {
if (reduceMotion())
this.animationDuration = 0;
else
this.animationDuration = this.defaultAnimationDuration;
this.animation = this.details.animate({
height: [startHeight, endHeight],
}, {
duration: this.animationDuration,
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: '2b50f9026275b623128e0a441ec4434c50a54338' }, h("details", { key: 'd60df44b58cd5c27306ec97dd42750bf1f01486c', class: "pn-accordion-row", open: this.state, ref: (el) => (this.details = el) }, h("summary", { key: '448587e8102df440a0d633702ea4af8cfe1d9da3', id: this.buttonid, class: "pn-accordion-row-summary", onClick: e => this.clickHandler(e), ref: el => (this.summary = el) }, h("div", { key: 'bef1fa9595b890919445a6631742c03fd7e18f3f', class: "pn-accordion-row-text", "data-transparent": this.transparent }, this.label ? this.label : '', h("slot", { key: '30742c10f2f557f39f80e97ec3e1c5473400d128', name: "label" }), h("pn-icon", { key: 'cfde3e68aab8348a0773c7aa41e02bb905a47e07', class: "pn-accordion-row-icon", icon: chevron_down }))), h("div", { key: '054aae1bcf9fb3bf9a050c9fdf7cefef38f164d0', id: this.contentid, class: "pn-accordion-row-content", ref: (el) => (this.content = el) }, h("slot", { key: '69378af205ca6c4c159c718f497a2ecf319be959' })))));
}
};
PnAccordionRow.style = pnAccordionRowCss;
export { PnAccordionRow as pn_accordion_row };
//# sourceMappingURL=pn-accordion-row.entry.js.map