@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
251 lines (247 loc) • 8.3 kB
JavaScript
import { h, H as Host } from './index-8fd57462.js';
import { f as focusElement, c as getSlotted, g as getElementDir, a as getElementTheme } from './dom-d9ba1da4.js';
import { d as debounce } from './debounce-4dee3b1c.js';
import { g as getRoundRobinIndex } from './array-af19adb2.js';
import { C as CSS } from './resources-e06851d2.js';
function mutationObserverCallback() {
this.setUpItems();
this.setUpFilter();
}
const SUPPORTED_ARROW_KEYS = ["ArrowUp", "ArrowDown"];
// --------------------------------------------------------------------------
//
// Lifecycle
//
// --------------------------------------------------------------------------
function initialize() {
this.setUpItems();
this.setUpFilter();
this.emitCalciteListChange = debounce(internalCalciteListChangeEvent.bind(this), 0);
}
function initializeObserver() {
this.observer.observe(this.el, { childList: true, subtree: true });
}
function cleanUpObserver() {
this.observer.disconnect();
}
// --------------------------------------------------------------------------
//
// Listeners
//
// --------------------------------------------------------------------------
function calciteListItemChangeHandler(event) {
const { selectedValues } = this;
const { item, value, selected, shiftPressed } = event.detail;
if (selected) {
if (!this.multiple) {
this.deselectSiblingItems(item);
}
if (this.multiple && shiftPressed) {
this.selectSiblings(item);
}
selectedValues.set(value, item);
}
else {
selectedValues.delete(value);
if (this.multiple && shiftPressed) {
this.selectSiblings(item, true);
}
}
if (!this.multiple) {
toggleSingleSelectItemTabbing(item, selected);
}
this.lastSelectedItem = item;
this.emitCalciteListChange();
}
function calciteListItemValueChangeHandler(event) {
event.stopPropagation();
const oldValue = event.detail.oldValue;
const selectedValues = this.selectedValues;
if (selectedValues.has(oldValue)) {
const item = selectedValues.get(oldValue);
selectedValues.delete(oldValue);
selectedValues.set(event.detail.newValue, item);
}
}
// --------------------------------------------------------------------------
//
// Private Methods
//
// --------------------------------------------------------------------------
function isValidNavigationKey(key) {
return !!SUPPORTED_ARROW_KEYS.find((k) => k === key);
}
function keyDownHandler(event) {
const { key, target } = event;
if (!isValidNavigationKey(key)) {
return;
}
const { items, multiple } = this;
const { length: totalItems } = items;
const currentIndex = items.indexOf(target);
if (!totalItems || currentIndex === -1) {
return;
}
event.preventDefault();
const index = getRoundRobinIndex(currentIndex + (key === "ArrowUp" ? -1 : 1), totalItems);
const item = items[index];
toggleSingleSelectItemTabbing(item, true);
focusElement(item);
if (!multiple) {
item.selected = true;
}
}
function internalCalciteListChangeEvent() {
this.calciteListChange.emit(this.selectedValues);
}
function removeItem(event) {
if (event.defaultPrevented) {
return;
}
const item = event.target;
const selectedValues = this.selectedValues;
if (item.parentElement.tagName === "CALCITE-PICK-LIST-GROUP") {
item.parentElement.remove();
Array.from(item.parentElement.children).forEach((item) => selectedValues.delete(item.value));
}
else {
item.remove();
selectedValues.delete(item.value);
}
this.emitCalciteListChange();
}
function toggleSingleSelectItemTabbing(item, selectable) {
// using attribute intentionally
if (selectable) {
item.removeAttribute("tabindex");
}
else {
item.setAttribute("tabindex", "-1");
}
}
function setFocus() {
const { multiple, items } = this;
if (items.length === 0) {
return;
}
if (multiple) {
return items[0].setFocus();
}
const selected = items.find((item) => item.selected);
return (selected ? selected : items[0]).setFocus();
}
function setUpItems(tagName) {
this.items = Array.from(this.el.querySelectorAll(tagName));
let hasSelected = false;
const { items } = this;
items.forEach((item) => {
item.icon = this.getIconType();
if (!this.multiple) {
item.disableDeselect = true;
toggleSingleSelectItemTabbing(item, false);
}
if (item.selected) {
hasSelected = true;
toggleSingleSelectItemTabbing(item, true);
this.selectedValues.set(item.value, item);
}
});
const [first] = items;
if (!hasSelected && first) {
toggleSingleSelectItemTabbing(first, true);
}
}
function deselectSiblingItems(item) {
this.items.forEach((currentItem) => {
if (currentItem.value !== item.value) {
currentItem.toggleSelected(false);
if (this.selectedValues.has(currentItem.value)) {
this.selectedValues.delete(currentItem.value);
}
}
});
}
function selectSiblings(item, deselect = false) {
if (!this.lastSelectedItem) {
return;
}
const { items } = this;
const start = items.findIndex((currentItem) => {
return currentItem.value === this.lastSelectedItem.value;
});
const end = items.findIndex((currentItem) => {
return currentItem.value === item.value;
});
items.slice(Math.min(start, end), Math.max(start, end)).forEach((currentItem) => {
currentItem.toggleSelected(!deselect);
if (!deselect) {
this.selectedValues.set(currentItem.value, currentItem);
}
else {
this.selectedValues.delete(currentItem.value);
}
});
}
let groups;
function handleFilter(event) {
const filteredData = event.detail;
const values = filteredData.map((item) => item.value);
if (!groups) {
groups = new Set();
}
const matchedItems = this.items.filter((item) => {
const parent = item.parentElement;
const grouped = parent.matches("calcite-pick-list-group");
if (grouped) {
groups.add(parent);
}
const matches = values.includes(item.value);
item.hidden = !matches;
return matches;
});
groups.forEach((group) => {
const hasAtLeastOneMatch = matchedItems.some((item) => group.contains(item));
group.hidden = !hasAtLeastOneMatch;
if (!hasAtLeastOneMatch) {
return;
}
const parentItem = getSlotted(group, "parent-item");
if (parentItem) {
parentItem.hidden = false;
if (matchedItems.includes(parentItem)) {
Array.from(group.children).forEach((child) => (child.hidden = false));
}
}
});
groups.clear();
}
function getItemData() {
return this.items.map((item) => ({
label: item.label,
description: item.description,
metadata: item.metadata,
value: item.value
}));
}
var __rest = (undefined && undefined.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
const List = (_a) => {
var { props: { disabled, loading, filterEnabled, dataForFilter, handleFilter, filterPlaceholder, el } } = _a, rest = __rest(_a, ["props"]);
const defaultSlot = h("slot", null);
return (h(Host, Object.assign({ "aria-busy": loading.toString(), "aria-disabled": disabled.toString(), role: "menu" }, rest),
h("section", null,
h("header", { class: { [CSS.sticky]: true } },
filterEnabled ? (h("calcite-filter", { "aria-label": filterPlaceholder, data: dataForFilter, dir: getElementDir(el), onCalciteFilterChange: handleFilter, placeholder: filterPlaceholder })) : null,
h("slot", { name: "menu-actions" })),
loading || disabled ? (h("calcite-scrim", { loading: loading, theme: getElementTheme(el) }, defaultSlot)) : (defaultSlot))));
};
export { List as L, initializeObserver as a, calciteListItemChangeHandler as b, cleanUpObserver as c, deselectSiblingItems as d, calciteListItemValueChangeHandler as e, setUpItems as f, getItemData as g, handleFilter as h, initialize as i, setFocus as j, keyDownHandler as k, mutationObserverCallback as m, removeItem as r, selectSiblings as s };