UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

108 lines (107 loc) • 5.53 kB
/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */ import { c as customElement } from "../../chunks/runtime.js"; import { css, html } from "lit"; import { LitElement, safeClassMap } from "@arcgis/lumina"; import { createRef, ref } from "lit/directives/ref.js"; import { b as slotChangeGetAssignedElements, C as getSlotAssignedElements } from "../../chunks/dom.js"; const CSS = { section: "section" }; const SLOTS = { titleGroup: "title-group" }; const styles = css`:host{display:flex;flex-direction:column;background-color:var(--calcite-tab-background-color, var(--calcite-color-transparent))}:host([bordered]){box-shadow:inset 0 1px 0 var(--calcite-tab-border-color, var(--calcite-color-border-1));background-color:var(--calcite-tab-background-color, var(--calcite-color-foreground-1))}:host([bordered]) section{border-color:var(--calcite-tab-border-color, var(--calcite-color-border-1));border-style:solid}section{display:flex;flex-grow:1;overflow:hidden;border-width:1px;border-block-start-style:solid;border-block-start-color:var(--calcite-tab-border-color, var(--calcite-color-border-1))}:host([bordered][position=bottom]){box-shadow:inset 0 1px 0 var(--calcite-tab-border-color, var(--calcite-color-border-1)),inset 0 -1px 0 var(--calcite-tab-border-color, var(--calcite-color-border-1))}:host([bordered]:not([position=bottom])) ::slotted(calcite-tab-nav){margin-block-end:-1px}:host([position=bottom]){flex-direction:column-reverse}:host([position=bottom]) section{flex-direction:column-reverse;border-block-start-width:0px;border-block-end-width:1px}:host([bordered][scale=s]) section{padding:.75rem}:host([bordered][scale=m]) section{padding:.5rem}:host([bordered][scale=l]) section{padding:1rem}:host([position=bottom]:not([bordered])) section{border-block-end-style:solid;border-block-end-color:var(--calcite-tab-border-color, var(--calcite-color-border-1))}@media(forced-colors:active){:host([bordered]) section{border-block-start-width:0px;border-block-end-width:1px}:host([position=bottom][bordered]) section{border-block-start-width:1px;border-block-end-width:0px}}:host([hidden]){display:none}[hidden]{display:none}`; class Tabs extends LitElement { constructor() { super(); this.slotRef = createRef(); this.tabs = []; this.titles = []; this.bordered = false; this.layout = "inline"; this.position = "top"; this.scale = "m"; this.listen("calciteInternalTabNavSlotChange", this.calciteInternalTabNavSlotChangeHandler); } static { this.properties = { tabs: [16, {}, { state: true }], titles: [16, {}, { state: true }], bordered: [5, {}, { type: Boolean }], layout: [3, {}, { reflect: true }], position: [3, {}, { reflect: true }], scale: [3, {}, { reflect: true }] }; } static { this.styles = styles; } connectedCallback() { super.connectedCallback(); this.updateItems(); } load() { this.updateItems(); } willUpdate(changes) { if (changes.has("position") && (this.hasUpdated || this.position !== "top") || changes.has("scale") && (this.hasUpdated || this.scale !== "m")) { this.updateItems(); } if ((changes.has("titles") || changes.has("tabs")) && this.hasUpdated && this.titles?.length > 0 && this.tabs?.length > 0) { this.updateAriaSettings(); this.updateItems(); } } calciteInternalTabNavSlotChangeHandler(event) { event.stopPropagation(); if (event.detail.length !== this.titles.length) { this.titles = event.detail; } } defaultSlotChangeHandler(event) { this.tabs = slotChangeGetAssignedElements(event, "calcite-tab"); } async updateAriaSettings() { await this.componentOnReady(); if (!this.slotRef.value) { return; } let tabIds; let titleIds; const tabs = getSlotAssignedElements(this.slotRef.value, "calcite-tab"); if (tabs.some((el) => el.tab) || this.titles.some((el) => el.tab)) { tabIds = tabs.sort((a, b) => a.tab.localeCompare(b.tab)).map((el) => el.id); titleIds = this.titles.sort((a, b) => a.tab.localeCompare(b.tab)).map((el) => el.id); } else { const tabDomIndexes = await Promise.all(tabs.map((el) => el.getTabIndex())); const titleDomIndexes = await Promise.all(this.titles.map((el) => el.getTabIndex())); tabIds = tabDomIndexes.reduce((ids, indexInDOM, registryIndex) => { ids[indexInDOM] = tabs[registryIndex].id; return ids; }, []); titleIds = titleDomIndexes.reduce((ids, indexInDOM, registryIndex) => { ids[indexInDOM] = this.titles[registryIndex].id; return ids; }, []); } tabs.forEach((el) => el._updateAriaInfo(tabIds, titleIds)); this.titles.forEach((el) => el._updateAriaInfo(tabIds, titleIds)); } updateItems() { const { position, scale } = this; const nav = this.el.querySelector("calcite-tab-nav"); if (nav) { nav.position = position; nav.scale = scale; } Array.from(this.el.querySelectorAll("calcite-tab")).forEach((tab) => { if (tab.parentElement === this.el) { tab.scale = scale; } }); Array.from(this.el.querySelectorAll("calcite-tab-nav > calcite-tab-title")).forEach((title) => { title.position = position; title.scale = scale; }); } render() { return html`<slot name=${SLOTS.titleGroup}></slot><section class=${safeClassMap(CSS.section)}><slot @slotchange=${this.defaultSlotChangeHandler} ${ref(this.slotRef)}></slot></section>`; } } customElement("calcite-tabs", Tabs); export { Tabs };