UNPKG

@postnord/web-components

Version:
134 lines (129 loc) 7.62 kB
/*! * Built with Stencil * By PostNord. */ 'use strict'; var index = require('./index-CfUQZtlH.js'); var index$1 = require('./index.cjs.js'); const pnTabCss = () => `${index.transformTag("pn-tab")}{position:relative;overflow:hidden;flex-shrink:0;scroll-snap-align:center;display:inline-block;border-radius:0.5em}${index.transformTag("pn-tab")} .pn-tab{position:relative;cursor:pointer;margin:1em 0.25em;padding:0 0.25em;border:none;border-radius:0.5em;color:#2d2013;background-color:transparent;font-family:inherit;font-size:1em;font-weight:500;text-decoration:none;display:flex;gap:0.5em;align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent}${index.transformTag("pn-tab")} .pn-tab .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}}${index.transformTag("pn-tab")} .pn-tab{transition-property:color, outline-color, background-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){${index.transformTag("pn-tab")} .pn-tab{transition-duration:0s;transition-delay:0s}}${index.transformTag("pn-tab")} .pn-tab{outline:0.2rem solid transparent;outline-offset:0.2rem}${index.transformTag("pn-tab")} .pn-tab-label{line-height:1.5em}${index.transformTag("pn-tab")} .pn-tab:focus-visible{overflow:hidden;outline-color:#005d92;background-color:#ffffff}${index.transformTag("pn-tab")} .pn-tab[aria-selected=true],${index.transformTag("pn-tab")} .pn-tab[aria-current=page]{color:#005d92}${index.transformTag("pn-tab")} .pn-tab[aria-selected=true]:focus,${index.transformTag("pn-tab")} .pn-tab[aria-current=page]:focus{color:#0d234b}${index.transformTag("pn-tab")} .pn-tab[aria-selected=true]:focus ${index.transformTag("pn-icon")}>.pn-icon-svg path,${index.transformTag("pn-tab")} .pn-tab[aria-selected=true]:focus ${index.transformTag("pn-icon")}>.pn-icon-svg polygon,${index.transformTag("pn-tab")} .pn-tab[aria-current=page]:focus ${index.transformTag("pn-icon")}>.pn-icon-svg path,${index.transformTag("pn-tab")} .pn-tab[aria-current=page]:focus ${index.transformTag("pn-icon")}>.pn-icon-svg polygon{fill:#0d234b}`; const PnTab = class { constructor(hostRef) { index.registerInstance(this, hostRef); this.setActiveTab = index.createEvent(this, "setActiveTab"); this.tabEnter = index.createEvent(this, "tabEnter"); this.tabLeave = index.createEvent(this, "tabLeave"); } mo; tag = 'button'; get hostElement() { return index.getElement(this); } /** Set a label for the tab. */ label; /** This is the value that will be matched with `pn-tablist` value. (required) */ value; /** Turns the tab from a `button` to an `a` element, but only if the `pn-tablist` is inside a `pn-header`. */ href; /** The SVG content of the icon you want to display */ icon; /** Use the ID of the container that this tab controls. */ ariacontrols; /** Tab ID, use if you want to have the tab container be `aria-labelledby` by this tab. */ tabid; /** Is set by `pn-tablist`, don't use this prop. @hide true */ activeTab; /** Used by `pn-tab` to communicate with `pn-tablist`. Emits the selected tab value and element. */ setActiveTab; setActiveTabHandler({ click = false, element } = {}) { if (click || this.isActive()) { const val = element?.value || this.value; const el = ((element?.value && element) || this.hostElement); this.setActiveTab.emit({ val, el, }); } } /** Used by `pn-tab` to communicate with `pn-tablist`. Emits when the tab gets focus. */ tabEnter; triggerEnter(event) { this.tabEnter.emit(event); } /** Used by `pn-tab` to communicate with `pn-tablist`. Emits when the tab is blured. */ tabLeave; triggerLeave(event) { this.tabLeave.emit(event); } connectedCallback() { this.mo = new MutationObserver(() => index.forceUpdate(this.hostElement)); this.mo.observe(this.hostElement, { subtree: true, childList: true }); } disconnectedCallback() { this.mo?.disconnect(); } componentWillLoad() { this.tabTag(); } componentDidUpdate() { this.setActiveTabHandler(); } componentDidLoad() { this.setActiveTabHandler(); } arrowKeyNav(event) { if (!/^(ArrowRight|ArrowLeft|Home|End)$/.test(event.key)) return; event.preventDefault(); // Get tablist parent const parent = event.target.closest(`${index.transformTag("pn-tablist")}`); const list = Array.from(parent.querySelectorAll(`${index.transformTag("pn-tab")}`)); const first = list[0]; const last = list[list.length - 1]; const nextElement = this.hostElement.nextElementSibling; const previousElement = this.hostElement.previousElementSibling; if (event.key === 'Home') this.setActiveTabHandler({ element: first }); if (event.key === 'End') this.setActiveTabHandler({ element: last }); if (event.key === 'ArrowRight') { // Check the next element value. We do this because the last element i a DIV element. If no value, go to the first element. this.setActiveTabHandler({ element: nextElement?.value ? nextElement : first }); } if (event.key === 'ArrowLeft') { // Go to the last element if there is no element to your left. this.setActiveTabHandler({ element: previousElement?.value ? previousElement : last }); } } isActive() { return this.activeTab === this.value; } tabTag() { const isMenu = this.hostElement.closest(`${index.transformTag("pn-tablist")}`); this.tag = isMenu.slot === 'menu' ? 'a' : 'button'; } renderProperties() { return this.tag === 'a' ? { 'href': this.href, 'aria-current': this.isActive() ? 'page' : 'false', } : { 'tabindex': this.isActive() ? 0 : -1, 'type': 'button', 'role': 'tab', 'aria-selected': this.isActive().toString(), 'aria-controls': this.ariacontrols, }; } iconColor() { return this.isActive() ? 'blue700' : 'gray900'; } handleClick(e) { this.setActiveTabHandler({ click: true }); index$1.ripple(e, this.hostElement, '.pn-tab'); } render() { const Tag = this.tag; return (index.h(index.Host, { key: 'a3d1810848574a33819d13fa281d85eb08f1ce80' }, index.h(Tag, { key: '08548598375643778185f9ea3900b6b16e079c23', id: this.tabid, class: "pn-tab", ...this.renderProperties(), onClick: (e) => this.handleClick(e), onMouseEnter: (e) => this.triggerEnter(e), onFocus: (e) => this.triggerEnter(e), onMouseLeave: (e) => this.triggerLeave(e), onBlur: (e) => this.triggerLeave(e), onKeyDown: (e) => this.arrowKeyNav(e) }, !!this.icon && index.h("pn-icon", { key: 'ed1076eaf2ea4fc6f56ae86e2947b656808d1c02', icon: this.icon, color: this.iconColor() }), index.h("slot", { key: '48a7a902e8e2712b0595ac88f3b906149703f92c' }), index.h("span", { key: 'cde1646f13a5fe4f553dcfa919268f62286d3f5c', class: "pn-tab-label" }, this.label)))); } }; PnTab.style = pnTabCss(); exports.pn_tab = PnTab;