UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

155 lines (154 loc) 6.22 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 { html } from "lit"; import { createRef, ref } from "lit-html/directives/ref.js"; import { LitElement, createEvent } from "@arcgis/lumina"; import { d as focusElementInGroup, s as slotChangeGetAssignedElements } from "../../chunks/dom.js"; import { u as updateHostInteraction, I as InteractiveContainer } from "../../chunks/interactive.js"; import { c as componentFocusable } from "../../chunks/component.js"; import { css } from "@lit/reactive-element/css-tag.js"; const styles = css`:host([disabled]){cursor:default;-webkit-user-select:none;user-select:none;opacity:var(--calcite-opacity-disabled)}:host([disabled]) *,:host([disabled]) ::slotted(*){pointer-events:none}:host{display:flex}.container{display:flex;inline-size:100%;flex-wrap:wrap;gap:.5rem}::slotted(calcite-chip){flex:none}:host([scale=s]) .container{gap:.25rem}:host([scale=l]) .container{gap:.75rem}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}:host([hidden]){display:none}[hidden]{display:none}`; class ChipGroup extends LitElement { constructor() { super(); this.items = []; this.slotRefEl = createRef(); this.disabled = false; this.scale = "m"; this.selectedItems = []; this.selectionMode = "none"; this.calciteChipGroupSelect = createEvent({ cancelable: false }); this.listen("calciteInternalChipKeyEvent", this.calciteInternalChipKeyEventListener); this.listen("calciteChipClose", this.calciteChipCloseListener); this.listen("calciteChipSelect", this.calciteChipSelectListener); this.listen("calciteInternalChipSelect", this.calciteInternalChipSelectListener); this.listen("calciteInternalSyncSelectedChips", this.calciteInternalSyncSelectedChips); } static { this.properties = { disabled: [7, {}, { reflect: true, type: Boolean }], label: 1, scale: [3, {}, { reflect: true }], selectedItems: [0, {}, { attribute: false }], selectionMode: [3, {}, { reflect: true }] }; } static { this.styles = styles; } async setFocus() { await componentFocusable(this); if (!this.disabled) { return (this.selectedItems[0] || this.items[0])?.setFocus(); } } willUpdate(changes) { if (changes.has("selectionMode") && (this.hasUpdated || this.selectionMode !== "none")) { this.updateItems(); } } updated() { updateHostInteraction(this); } calciteInternalChipKeyEventListener(event) { if (event.composedPath().includes(this.el)) { const interactiveItems = this.items?.filter((el) => !el.disabled); switch (event.detail.key) { case "ArrowRight": focusElementInGroup(interactiveItems, event.detail.target, "next"); break; case "ArrowLeft": focusElementInGroup(interactiveItems, event.detail.target, "previous"); break; case "Home": focusElementInGroup(interactiveItems, event.detail.target, "first"); break; case "End": focusElementInGroup(interactiveItems, event.detail.target, "last"); break; } } event.stopPropagation(); } calciteChipCloseListener(event) { const item = event.target; if (this.items?.includes(item)) { if (this.items?.indexOf(item) > 0) { focusElementInGroup(this.items, item, "previous"); } else if (this.items?.indexOf(item) === 0) { focusElementInGroup(this.items, item, "next"); } else { focusElementInGroup(this.items, item, "first"); } } this.items = this.items?.filter((el) => el !== item); event.stopPropagation(); } calciteChipSelectListener(event) { if (event.composedPath().includes(this.el)) { this.setSelectedItems(true, event.target); } event.stopPropagation(); } calciteInternalChipSelectListener(event) { if (event.composedPath().includes(this.el)) { this.setSelectedItems(false, event.target); } event.stopPropagation(); } calciteInternalSyncSelectedChips(event) { if (event.composedPath().includes(this.el)) { this.updateSelectedItems(); if (this.selectionMode === "single" && this.selectedItems.length > 1) { this.setSelectedItems(false, event.target); } } event.stopPropagation(); } updateItems(event) { const itemsFromSlot = this.slotRefEl.value?.assignedElements({ flatten: true }).filter((el) => el?.matches("calcite-chip")); this.items = !event ? itemsFromSlot : slotChangeGetAssignedElements(event); if (this.items?.length < 1) { return; } this.items?.forEach((el) => { el.interactive = true; el.scale = this.scale; el.selectionMode = this.selectionMode; el.parentChipGroup = this.el; }); this.setSelectedItems(false); } updateSelectedItems() { this.selectedItems = this.items?.filter((el) => el.selected); } setSelectedItems(emit, elToMatch) { if (elToMatch) { this.items?.forEach((el) => { const matchingEl = elToMatch === el; switch (this.selectionMode) { case "multiple": if (matchingEl) { el.selected = !el.selected; } break; case "single": el.selected = matchingEl ? !el.selected : false; break; case "single-persist": el.selected = !!matchingEl; break; } }); } this.updateSelectedItems(); if (emit) { this.calciteChipGroupSelect.emit(); } } render() { const role = this.selectionMode === "none" || this.selectionMode === "multiple" ? "group" : "radiogroup"; const { disabled } = this; return InteractiveContainer({ disabled, children: html`<div .ariaLabel=${this.label} class="container" .role=${role}><slot @slotchange=${this.updateItems} ${ref(this.slotRefEl)}></slot></div>` }); } } customElement("calcite-chip-group", ChipGroup); export { ChipGroup };