UNPKG

@cbpds/web-components

Version:
184 lines (183 loc) 8.17 kB
/*! * CPB Design System web components - built with Stencil */ import { Host, h } from "@stencil/core"; import { setCSSProps } from "../../utils/utils"; export class CbpTabs { constructor() { this.tabs = []; this.selectedIndex = 0; this.focusIndex = 0; this.accessibilityText = undefined; this.context = undefined; this.sx = {}; } initTabset() { let activeTab = this.tabs[0]; this.tabs.forEach(tab => { if (tab.selected === true) activeTab = tab; }); this.setActiveTab(activeTab); } setActiveTab(activatedTab) { this.tabs.forEach((tab, index) => { let button = tab.querySelector('button'); let panelid = tab.name; let panel = document.querySelector(`#${panelid}`); if (!panel) { console === null || console === void 0 ? void 0 : console.warn(`Warning: cbp-tab does not reference valid tab panel with id ${panelid}`); return; } if (activatedTab == tab) { tab.selected = true; this.selectedIndex = this.focusIndex = index; panel.selected = true; button === null || button === void 0 ? void 0 : button.scrollIntoView({ behavior: "smooth", inline: 'start' }); } else { tab.selected = false; panel.selected = false; } }); } keyboardNav(key) { const l = this.tabs.length - 1; const n = { Home: 0, ArrowLeft: -1 < this.focusIndex + -1 ? this.focusIndex + -1 : l, ArrowRight: l + 1 > this.focusIndex + 1 ? this.focusIndex + 1 : 0, End: l, Tab: this.focusIndex = this.selectedIndex, }[key]; const d = (key == 'ArrowLeft') ? 'end' : 'start'; if (n !== undefined && key !== 'Tab') { this.tabs[n].scrollIntoView({ behavior: "smooth", inline: d }); setTimeout(() => { this.tabs[n].querySelector('button').focus(); }, 20); this.focusIndex = n; } } responsiveNav(direction) { const l = this.tabs.length - 1; if (direction == 'next') { this.focusIndex = l + 1 > this.focusIndex + 1 ? this.focusIndex + 1 : 0; this.tabs[this.focusIndex].scrollIntoView({ behavior: "smooth", inline: "start" }); setTimeout(() => { this.tabs[this.focusIndex].querySelector('button').focus(); }, 20); } if (direction == 'previous') { this.focusIndex = -1 < this.focusIndex + -1 ? this.focusIndex + -1 : l; this.tabs[this.focusIndex].scrollIntoView({ behavior: "smooth", inline: "end" }); setTimeout(() => { this.tabs[this.focusIndex].querySelector('button').focus(); }, 20); } } componentWillLoad() { this.tabs = Array.from(this.host.querySelectorAll('cbp-tab')).filter(tab => tab.closest('cbp-tabs') == this.host); this.tabs.forEach(tab => { tab.addEventListener('tabClicked', e => this.setActiveTab(e.detail.host)); }); if (typeof this.sx == 'string') { this.sx = JSON.parse(this.sx) || {}; } setCSSProps(this.host, Object.assign({}, this.sx)); } componentDidLoad() { this.initTabset(); this.observer = new ResizeObserver(([{ contentRect: { width } }]) => { if (width + 1 > this.wrapper.scrollWidth) { this.previousControl.setAttribute('hidden', ''); this.nextControl.setAttribute('hidden', ''); } else { this.previousControl.removeAttribute('hidden'); this.nextControl.removeAttribute('hidden'); } }); this.observedEl = this.host; this.observer.observe(this.observedEl); } disconnectedCallback() { if (this.observer) { this.observer.unobserve(this.observedEl); } } render() { return (h(Host, { key: 'ef0c56b13ebee3d1408c9833169f32960284e858', role: "tablist", "aria-label": this.accessibilityText, onKeydown: ({ key }) => { this.keyboardNav(key); } }, h("cbp-button", { key: '1aab46c48d75518fcd6217c5d8c0c8bab0a786d3', color: "secondary", fill: "outline", variant: "square", width: "3.5rem", height: "3.5rem", context: this.context, onClick: () => this.responsiveNav('previous'), ref: el => (this.previousControl = el) }, h("button", { key: '49b7315b357a1bd88e922d59391ae2d4cdbaa8bf', type: "button", tabindex: "-1", "aria-label": "Previous Tab", slot: "cbp-button-custom" }, h("cbp-icon", { key: '04d80acd6a3f17185aa984d6f5d2b9d55c38d8bd', name: "chevron-right", size: "var(--cbp-space-5x)", rotate: 180 }))), h("div", { key: 'a2a5fa29eebe9952f2e06c6a0e3f49c1aea6c21e', class: "cbp-tabs-wrapper", ref: el => (this.wrapper = el) }, h("slot", { key: '083455cee91429c49fcbdd95d7be96c91f54d55f' })), h("cbp-button", { key: '99b3836706561b19aa9759956e8c2193b6c0852f', color: "secondary", fill: "outline", variant: "square", width: "3.5rem", height: "3.5rem", context: this.context, onClick: () => this.responsiveNav('next'), ref: el => (this.nextControl = el) }, h("button", { key: '662c0e5cef69da94c660a7996cb833dba6c52c52', type: "button", tabindex: "-1", "aria-label": "Next Tab", slot: "cbp-button-custom" }, h("cbp-icon", { key: '0d78c62da25adf5313769b9df885ea2982c3ecfc', name: "chevron-right", size: "var(--cbp-space-5x)" }))))); } static get is() { return "cbp-tabs"; } static get originalStyleUrls() { return { "$": ["cbp-tabs.scss"] }; } static get styleUrls() { return { "$": ["cbp-tabs.css"] }; } static get properties() { return { "accessibilityText": { "type": "string", "mutable": false, "complexType": { "original": "string", "resolved": "string", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "The accessible label of the tablist. Required unless `aria-labelledby` is specified on the host tag directly." }, "attribute": "accessibility-text", "reflect": false }, "context": { "type": "string", "mutable": false, "complexType": { "original": "'light-inverts' | 'light-always' | 'dark-inverts' | 'dark-always'", "resolved": "\"dark-always\" | \"dark-inverts\" | \"light-always\" | \"light-inverts\"", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Specifies the context of the component as it applies to the visual design and whether it inverts when light/dark mode is toggled. Default behavior is \"light-inverts\" and does not have to be specified." }, "attribute": "context", "reflect": true }, "sx": { "type": "any", "mutable": false, "complexType": { "original": "any", "resolved": "any", "references": {} }, "required": false, "optional": false, "docs": { "tags": [], "text": "Supports adding inline styles as an object" }, "attribute": "sx", "reflect": false, "defaultValue": "{}" } }; } static get elementRef() { return "host"; } } //# sourceMappingURL=cbp-tabs.js.map