UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

110 lines (109 loc) • 5.57 kB
/*! All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://github.com/Esri/calcite-design-system/blob/dev/LICENSE.md for details. v3.2.1 */ import { c as customElement } from "../../chunks/runtime.js"; import { ref } from "lit-html/directives/ref.js"; import { html } from "lit"; import { LitElement, safeClassMap } from "@arcgis/lumina"; import { s as slotChangeGetAssignedElements, e as getSlotAssignedElements } from "../../chunks/dom.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { section: "section" }; const SLOTS = { titleGroup: "title-group" }; const styles = css`:host{display:flex;flex-direction:column}: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.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(); let tabIds; let titleIds; const tabs = getSlotAssignedElements(this.slotEl, "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; }); } setDefaultSlotRef(el) { this.slotEl = el; } render() { return html`<slot name=${SLOTS.titleGroup}></slot><section class=${safeClassMap(CSS.section)}><slot @slotchange=${this.defaultSlotChangeHandler} ${ref(this.setDefaultSlotRef)}></slot></section>`; } } customElement("calcite-tabs", Tabs); export { Tabs };