@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
118 lines (117 loc) • 4.75 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { css, html } from "lit";
import { createRef, ref } from "lit/directives/ref.js";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { f as focusElementInGroup } from "../../chunks/dom.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
import { u as useInteractive } from "../../chunks/useInteractive.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:block}.container{display:flex;flex-wrap:wrap;gap:var(--calcite-card-group-space, var(--calcite-card-group-gap, var(--calcite-spacing-md)))}:host([hidden]){display:none}[hidden]{display:none}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}`;
const CSS = {
container: "container"
};
class CardGroup extends LitElement {
constructor() {
super();
this.items = [];
this.slotRef = createRef();
this.focusSetter = useSetFocus()(this);
this.interactiveContainer = useInteractive(this);
this.disabled = false;
this.selectedItems = [];
this.selectionMode = "none";
this.calciteCardGroupSelect = createEvent({ cancelable: false });
this.listen("calciteInternalCardKeyEvent", this.calciteInternalCardKeyEventListener);
this.listen("calciteCardSelect", this.calciteCardSelectListener);
}
static {
this.properties = { disabled: [7, {}, { reflect: true, type: Boolean }], label: 1, selectedItems: [0, {}, { attribute: false }], selectionMode: [3, {}, { reflect: true }] };
}
static {
this.styles = styles;
}
async setFocus(options) {
return this.focusSetter(() => this.items[0], options);
}
willUpdate(changes) {
if (changes.has("selectionMode") && this.hasUpdated) {
this.updateItemsOnSelectionModeChange();
}
}
loaded() {
this.updateSelectedItems();
}
calciteInternalCardKeyEventListener(event) {
if (event.composedPath().includes(this.el)) {
const interactiveItems = this.items.filter((el) => !el.disabled);
switch (event.detail["key"]) {
case "ArrowRight":
focusElementInGroup(interactiveItems, event.target, "next", true, false);
break;
case "ArrowLeft":
focusElementInGroup(interactiveItems, event.target, "previous", true, false);
break;
case "Home":
focusElementInGroup(interactiveItems, event.target, "first", true, false);
break;
case "End":
focusElementInGroup(interactiveItems, event.target, "last", true, false);
break;
}
}
}
calciteCardSelectListener(event) {
if (event.composedPath().includes(this.el) && !event.target.selectable) {
this.setSelectedItems(true, event.target);
}
}
updateItemsOnSelectionModeChange() {
this.updateSlottedItems(this.slotRef.value);
this.updateSelectedItems();
}
updateItemsOnSlotChange(event) {
this.updateSlottedItems(event.target);
this.updateSelectedItems();
}
updateSlottedItems(target) {
this.items = target?.assignedElements({ flatten: true }).filter((el) => el?.matches("calcite-card")) || [];
}
updateSelectedItems() {
this.items.forEach((el) => {
el.selectionMode = this.selectionMode;
});
this.setSelectedItems(false);
}
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.selectedItems = this.items.filter((el) => el.selected);
if (emit && this.selectionMode !== "none" && !this.disabled) {
this.calciteCardGroupSelect.emit();
}
}
render() {
const role = this.selectionMode === "none" || this.selectionMode === "multiple" ? "group" : "radiogroup";
return this.interactiveContainer({ disabled: this.disabled, children: html`<div .ariaLabel=${this.label} class=${safeClassMap(CSS.container)} .role=${role}><slot @slotchange=${this.updateItemsOnSlotChange} ${ref(this.slotRef)}></slot></div>` });
}
}
customElement("calcite-card-group", CardGroup);
export {
CardGroup
};