UNPKG

@postnord/web-components

Version:
172 lines (167 loc) 10.9 kB
/*! * Built with Stencil * By PostNord. */ import { proxyCustomElement, HTMLElement, forceUpdate, h, Host } from '@stencil/core/internal/client'; import { a as arrow_left } from './arrow_left.js'; import { a as arrow_right } from './arrow_right.js'; import { d as defineCustomElement$2 } from './pn-icon2.js'; const pnSegmentedControlCss = "pn-segmented-control{position:relative;display:inline-block;max-width:100%;overflow:hidden;border-radius:3em;transform:translateZ(0);transition-property:outline-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-segmented-control{transition-duration:0s;transition-delay:0s}}pn-segmented-control{outline:0.2rem solid transparent;outline-offset:0.2rem}pn-segmented-control:focus-within,pn-segmented-control:active{outline-color:#005d92}pn-segmented-control .pn-segmented-control{display:flex;align-items:center;border-radius:3em;min-height:3em;padding:0.25em;background:#f3f2f2;position:relative;overflow-x:auto;scroll-snap-type:x mandatory}pn-segmented-control .pn-segmented-control:hover .pn-sc-bg[data-hover]{opacity:1}pn-segmented-control .pn-segmented-control::-webkit-scrollbar{display:none}pn-segmented-control .pn-segmented-control .pn-sc-bg{position:absolute;top:50%;transform:translateY(-50%);will-change:transform;left:0;border-radius:inherit;transition-property:width, transform, background-color, opacity, box-shadow;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-segmented-control .pn-segmented-control .pn-sc-bg{transition-duration:0s;transition-delay:0s}}pn-segmented-control .pn-segmented-control .pn-sc-bg[data-active]{box-shadow:0px 0.3px 0.9px rgba(0, 0, 0, 0.1), 0px 1.6px 3.6px rgba(0, 0, 0, 0.13);border:0.0625em solid #005d92;background-color:#ffffff;z-index:1}pn-segmented-control .pn-segmented-control .pn-sc-bg[data-hover]{background-color:#e0f8ff;opacity:0;border:0.25em solid transparent;z-index:0}pn-segmented-control .pn-segmented-control .pn-sc-bg[data-hover][data-disabled]{border-color:#e9e6e5;background-color:#e9e6e5}pn-segmented-control .pn-segmented-control .pn-sc-bg[data-disabled]{border-color:#e9e6e5;background-color:#e9e6e5}pn-segmented-control .pn-sc-arrows{position:absolute;top:50%;transform:translateY(-50%);left:0;height:100%;width:100%;z-index:3;display:flex;justify-content:space-between;align-items:center;pointer-events:none}pn-segmented-control .pn-sc-arrows svg{width:1.5em}pn-segmented-control .pn-sc-arrows svg.pn-icon-svg path{fill:#005d92}pn-segmented-control .pn-sc-arrows>.pn-sc-arrow{cursor:pointer;pointer-events:all;width:2.5em;height:2.5em;background:#ffffff;border:none;outline:none;display:flex;align-items:center;justify-content:center;opacity:0;will-change:transform;-webkit-tap-highlight-color:transparent;transition-property:transform, opacity, background-color, box-shadow;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.7, 0, 0.3, 1)}@media (prefers-reduced-motion: reduce){pn-segmented-control .pn-sc-arrows>.pn-sc-arrow{transition-duration:0s;transition-delay:0s}}pn-segmented-control .pn-sc-arrows>.pn-sc-arrow.pn-sc-arrow-left{transform:translateX(-100%);border-radius:0 50% 50% 0;padding:0 0.3em 0 0;box-shadow:0.2rem 0.3rem 0.2rem rgba(0, 0, 0, 0.4)}pn-segmented-control .pn-sc-arrows>.pn-sc-arrow.pn-sc-arrow-right{transform:translateX(100%);border-radius:50% 0 0 50%;box-shadow:-0.2rem 0.3rem 0.2rem rgba(0, 0, 0, 0.4)}pn-segmented-control .pn-sc-arrows.pn-sc-left-visible .pn-sc-arrow-left,pn-segmented-control .pn-sc-arrows.pn-sc-right-visible .pn-sc-arrow-right{opacity:1;transform:translateX(0)}"; const PnSegmentedControl$1 = /*@__PURE__*/ proxyCustomElement(class PnSegmentedControl extends HTMLElement { constructor(registerHost) { super(); if (registerHost !== false) { this.__registerHost(); } } mo; segmentContainer; segments = []; activeBg; hoverBg; scrollRegistered = false; get hostElement() { return this; } showScrollArrows = false; showLeftArrow = false; showRightArrow = false; /** This is the name of the radio buttons inside the controller. @deprecated Set the name in the nested `pn-segment` components. */ name; /** Currently active segment value. */ value; valueHandler() { this.setActiveSegment(); } changeHandler(event) { const target = event.target; this.value = target.value; this.setActiveSegment(); } handleResize() { this.rerender(); } handleHover(event) { const { target } = event.detail; this.calcHighlight(target, true); } componentDidLoad() { if (this.mo) this.mo.disconnect(); this.mo = new MutationObserver(() => { forceUpdate(this.hostElement); this.setSegments(); }); this.mo.observe(this.hostElement, { childList: true }); this.setSegments(); } setSegments() { this.segments = Array.from(this.hostElement.querySelectorAll('pn-segment')); this.setActiveSegment(); } setActiveSegment() { this.segments.forEach(segmentEl => { if (this.value === segmentEl.value) segmentEl.setAttribute('selected', 'true'); else segmentEl.removeAttribute('selected'); }); this.rerender(); } rerender() { requestAnimationFrame(() => { this.calcHighlight(); this.scrollArrowRender(); }); } /*---------------------------------------HIGHLIGHT LOGIC-------------------------------------------*/ calcHighlight(element, hover) { const chip = hover ? this.hoverBg : this.activeBg; requestAnimationFrame(() => { const el = element || this.segments.find(({ value }) => value === this.value); const elSegment = el?.closest('pn-segment'); if (!elSegment) return; const elRect = elSegment.getBoundingClientRect(); const { left: hostLeft } = this.segmentContainer.getBoundingClientRect(); const { left: segmentLeft, height: segmentHeight, width: segmentWidth } = elRect; const offset = segmentLeft - hostLeft + this.segmentContainer.scrollLeft; chip.style.setProperty('transform', `translate(${offset}px, -50%`); chip.style.setProperty('width', `${segmentWidth}px`); chip.style.setProperty('height', `${segmentHeight}px`); el.disabled ? (chip.dataset.disabled = '') : delete chip.dataset.disabled; }); } /*---------------------------------------/HIGHLIGHT LOGIC-------------------------------------------*/ /*---------------------------------------SCROLL ARROW LOGIC-------------------------------------------*/ scrollArrowRender() { if (this.segmentContainer.scrollWidth > this.segmentContainer.clientWidth) { this.showScrollArrows = true; if (!this.scrollRegistered) { this.segmentContainer.addEventListener('scroll', this.scrollArrowRender.bind(this)); this.scrollRegistered = true; } const amountScrolled = Math.round(this.segmentContainer.scrollWidth - this.segmentContainer.scrollLeft); const distanceToEnd = amountScrolled - this.segmentContainer.clientWidth; const distanceToStart = this.segmentContainer.scrollLeft; this.showLeftArrow = distanceToStart > 0; this.showRightArrow = distanceToEnd > 0; return; } this.showLeftArrow = false; this.showRightArrow = false; this.showScrollArrows = false; } scroll(val) { let amount = this.segmentContainer.scrollLeft + val; this.segmentContainer.scroll({ left: amount, behavior: 'smooth', }); } scrollArrowClasses() { const list = ['pn-sc-arrows']; if (this.showLeftArrow) list.push('pn-sc-left-visible'); if (this.showRightArrow) list.push('pn-sc-right-visible'); return list.join(' '); } /*---------------------------------------/SCROLL ARROW LOGIC-------------------------------------------*/ render() { return (h(Host, { key: '9b89bf1fa5f6aa9f8c8f6c454a746a9e8565a134' }, h("div", { key: '25f7b91df0de018a553d31f17ba5a6edb64be829', class: "pn-segmented-control", ref: el => (this.segmentContainer = el) }, h("slot", { key: '7a279cce34babc5212e308c732d3f0aad33462fe' }), h("div", { key: '9491ee41db640152a109fa6a83619314a060aaa3', class: "pn-sc-bg", "data-active": true, ref: el => (this.activeBg = el) }), h("div", { key: '2f84544d72147c7f004e890fd9e08cb25e204c16', class: "pn-sc-bg", "data-hover": true, ref: el => (this.hoverBg = el) })), h("div", { key: '880804e74824b71eee88e274b8e44537a5e9a6f8', class: this.scrollArrowClasses(), hidden: !this.showScrollArrows }, h("button", { key: 'adebbaadaeb4c1064ad053e523a4d35f07b6908c', "aria-label": "Left", class: "pn-sc-arrow pn-sc-arrow-left", onClick: () => this.scroll(-120), tabindex: "-1" }, h("pn-icon", { key: '652cd5b07b1657d32c9a7c2d75d77d36e995f1ca', icon: arrow_left })), h("button", { key: 'e4235b21c3cd40a276dcd0feea50d1ac322ea36d', "aria-label": "Right", class: "pn-sc-arrow pn-sc-arrow-right", onClick: () => this.scroll(120), tabindex: "-1" }, h("pn-icon", { key: '5c3b343f962b22f9e9fc3df1eaf98785d8197415', icon: arrow_right }))))); } static get watchers() { return { "value": ["valueHandler"] }; } static get style() { return pnSegmentedControlCss; } }, [260, "pn-segmented-control", { "name": [1], "value": [1025], "showScrollArrows": [32], "showLeftArrow": [32], "showRightArrow": [32] }, [[0, "change", "changeHandler"], [9, "resize", "handleResize"], [0, "segmentHover", "handleHover"]], { "value": ["valueHandler"] }]); function defineCustomElement$1() { if (typeof customElements === "undefined") { return; } const components = ["pn-segmented-control", "pn-icon"]; components.forEach(tagName => { switch (tagName) { case "pn-segmented-control": if (!customElements.get(tagName)) { customElements.define(tagName, PnSegmentedControl$1); } break; case "pn-icon": if (!customElements.get(tagName)) { defineCustomElement$2(); } break; } }); } const PnSegmentedControl = PnSegmentedControl$1; const defineCustomElement = defineCustomElement$1; export { PnSegmentedControl, defineCustomElement }; //# sourceMappingURL=pn-segmented-control.js.map //# sourceMappingURL=pn-segmented-control.js.map