@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
465 lines (464 loc) • 33.2 kB
JavaScript
/*! 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 { keyed } from "lit-html/directives/keyed.js";
import { html, nothing } from "lit";
import { createRef, ref } from "lit-html/directives/ref.js";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { a as slotChangeHasAssignedElement, x as getFirstTabbable, g as getElementDir } from "../../chunks/dom.js";
import { u as updateHostInteraction, I as InteractiveContainer } from "../../chunks/interactive.js";
import { c as componentFocusable, g as getIconScale } from "../../chunks/component.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { l as logger } from "../../chunks/logger.js";
import { s as styles$1 } from "../../chunks/_sortable.js";
import { l as listSelector, g as getDepth, a as getListItemChildren } from "../../chunks/utils.js";
import { a as activeCellTestAttribute, I as ICONS, C as CSS, S as SLOTS } from "../../chunks/resources5.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;flex-direction:column}:host([filter-hidden]),:host([closed]){display:none}.wrapper--bordered{border-block-end:1px solid var(--calcite-list-border-color, var(--calcite-color-border-3))}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}.container{box-sizing:border-box;display:flex;flex:1 1 0%;overflow:hidden;background-color:var(--calcite-list-background-color, var(--calcite-color-foreground-1))}.container *{box-sizing:border-box}.container--hover:hover{cursor:pointer;background-color:var(--calcite-list-background-color-hover, var(--calcite-color-foreground-2))}.container:active{background-color:var(--calcite-list-background-color-press, var(--calcite-color-foreground-3))}.container--border{position:relative}.container--border:before{position:absolute;inline-size:var(--calcite-border-width-lg);inset-block:0;inset-inline-start:0;background-color:transparent;content:""}.container--border-selected:before{background-color:var(--calcite-list-selection-border-color, var(--calcite-color-brand))}.container--border-selected:focus{box-shadow:inset var(--calcite-border-width-lg) 0 0 0 var(--calcite-list-selection-border-color, var(--calcite-color-brand))}.nested-container{display:none;flex-direction:column;border-width:0px;border-style:solid;border-color:1px solid var(--calcite-list-border-color, var(--calcite-color-border-3));margin-inline-start:var(--calcite-list-spacing-indent, 1.5rem)}.nested-container--expanded{display:flex}.selection-container{display:flex;padding-block:0px;color:var(--calcite-list-icon-color, var(--calcite-color-border-input))}:host(:not([disabled]):not([selected])) .container:hover .selection-container--single{color:var(--calcite-list-icon-color, var(--calcite-color-border-input))}:host([selected]:hover) .selection-container,:host([selected]:hover) .selection-container--single,:host([selected]) .selection-container{color:var(--calcite-list-icon-color, var(--calcite-color-brand))}.content-container-wrapper{display:flex;flex:1 1 auto}.content-container-wrapper--bordered{border-block-end:1px solid var(--calcite-list-border-color, var(--calcite-color-border-3))}.content-container{display:flex;flex:1 1 auto;-webkit-user-select:none;user-select:none;align-items:stretch;font-weight:var(--calcite-font-weight-normal);color:var(--calcite-list-content-text-color, var(--calcite-color-text-2))}.content-container--unavailable{opacity:var(--calcite-opacity-disabled)}.row,.grid-cell{outline-color:transparent}.row{position:relative}.row:focus,.grid-cell:focus{outline:2px solid var(--calcite-color-focus, var(--calcite-ui-focus-color, var(--calcite-color-brand)));outline-offset:calc(-2px*(1 - (2*clamp(0,var(--calcite-offset-invert-focus),1))))}.content,.custom-content{display:flex;flex:1 1 auto;flex-direction:column;justify-content:center;line-height:var(--calcite-font-line-height-relative-snug)}.label{color:var(--calcite-list-label-text-color, var(--calcite-color-text-1))}.description{color:var(--calcite-list-description-text-color, var(--calcite-color-text-3))}.icon{align-self:center;color:var(--calcite-list-icon-color, var(--calcite-color-text-3))}.icon:hover,.icon:active{color:var(--calcite-color-text-1)}:host([display-mode=flat][drag-handle]:is([selection-mode=none],[selection-appearance=border])) .drag-container{padding-inline-end:var(--calcite-spacing-xxs)}:host([scale=s]) .actions-start{padding-inline-end:var(--calcite-spacing-sm)}:host([scale=s]) .content-container{gap:var(--calcite-spacing-sm);min-block-size:32px;padding-block:var(--calcite-spacing-xxs);padding-inline-end:var(--calcite-spacing-sm)}:host([scale=s]) .content,:host([scale=s]) .custom-content,:host([scale=s]) .label{font-size:var(--calcite-font-size--2)}:host([scale=s]) .description{font-size:var(--calcite-font-size--3)}:host([scale=s][display-mode=flat]:not([drag-handle])) .container{padding-inline-start:var(--calcite-spacing-sm)}:host([scale=s][display-mode=flat]:not([drag-handle])) .selection-container{padding-inline-end:var(--calcite-spacing-sm)}:host([scale=s][display-mode=flat][drag-handle]) .selection-container{padding-inline:var(--calcite-spacing-xxs) var(--calcite-spacing-sm)}:host([scale=s][display-mode=nested]) .selection-container{padding-inline-end:var(--calcite-spacing-xxs)}:host([scale=s][display-mode=nested][selection-appearance=icon]:not([selection-mode=none]):not([drag-handle])) .container{padding-inline-start:var(--calcite-spacing-sm)}:host([scale=s][display-mode=nested][selection-appearance=icon]:not([selection-mode=none]):not([drag-handle])) .selection-container{padding-inline-end:var(--calcite-spacing-xxs)}:host([scale=s][display-mode=nested][drag-handle]) .selection-container{padding-inline:var(--calcite-spacing-xxs)}:host([scale=m]) .actions-start{padding-inline-end:var(--calcite-spacing-sm)}:host([scale=m]) .content-container{gap:var(--calcite-spacing-sm);min-block-size:40px;padding-block:var(--calcite-spacing-sm);padding-inline-end:var(--calcite-spacing-md)}:host([scale=m]) .content,:host([scale=m]) .custom-content{font-size:var(--calcite-font-size--2)}:host([scale=m]) .label{font-size:var(--calcite-font-size--1)}:host([scale=m]) .description{font-size:var(--calcite-font-size--2)}:host([scale=m][display-mode=flat]) .container{padding-inline-start:var(--calcite-spacing-md)}:host([scale=m][display-mode=flat]) .selection-container{padding-inline-end:var(--calcite-spacing-sm)}:host([scale=m][display-mode=flat][drag-handle]) .container{padding-inline-start:0}:host([scale=m][display-mode=flat][drag-handle]) .selection-container{padding-inline:var(--calcite-spacing-xxs) var(--calcite-spacing-sm)}:host([scale=m][display-mode=nested]) .container{padding-inline-start:var(--calcite-spacing-xxs)}:host([scale=m][display-mode=nested]) .selection-container{padding-inline-end:var(--calcite-spacing-xxs)}:host([scale=m][display-mode=nested][selection-appearance=icon]:not([selection-mode=none]):not([drag-handle])) .container{padding-inline-start:var(--calcite-spacing-md)}:host([scale=m][display-mode=nested][drag-handle]) .container{padding-inline-start:0}:host([scale=m][display-mode=nested][drag-handle]) .selection-container{padding-inline:var(--calcite-spacing-xxs)}:host([scale=l]) .actions-start{padding-inline-end:var(--calcite-spacing-md)}:host([scale=l]) .content-container{gap:var(--calcite-spacing-md);min-block-size:56px;padding-block:.625rem;padding-inline-end:var(--calcite-spacing-lg)}:host([scale=l]) .content,:host([scale=l]) .custom-content,:host([scale=l]) .label{font-size:var(--calcite-font-size-0)}:host([scale=l]) .description{font-size:var(--calcite-font-size--1)}:host([scale=l]) .nested-container{margin-inline-start:1.75rem}:host([scale=l][display-mode=flat]) .container{padding-inline-start:var(--calcite-spacing-lg)}:host([scale=l][display-mode=flat]) .selection-container{padding-inline-end:var(--calcite-spacing-md)}:host([scale=l][display-mode=flat][drag-handle]) .container{padding-inline-start:0}:host([scale=l][display-mode=flat][drag-handle]) .selection-container{padding-inline-end:var(--calcite-spacing-md)}:host([scale=l][display-mode=nested]) .container{padding-inline-start:var(--calcite-spacing-xxs)}:host([scale=l][display-mode=nested][drag-handle]) .container{padding-inline-start:0}:host([scale=l][display-mode=nested][selection-appearance=icon]:not([selection-mode=none]):not([drag-handle])) .container{padding-inline-start:var(--calcite-spacing-lg)}.label,.description,.content-bottom{font-family:var(--calcite-font-family);font-weight:var(--calcite-font-weight-normal);word-wrap:break-word;word-break:break-word}:host([selected]) .label{font-weight:var(--calcite-font-weight-medium)}:host([selected]) .icon{color:var(--calcite-list-icon-color, var(--calcite-color-text-1))}:host([selected]) .description{color:var(--calcite-list-description-text-color, var(--calcite-color-text-2))}.content-start{justify-content:flex-start}.content-end{justify-content:flex-end}.content-start,.content-end{flex:1 1 auto}.content-start ::slotted(calcite-icon),.content-end ::slotted(calcite-icon){align-self:center}.content-bottom{display:flex;flex-direction:column}.content-container--has-center-content .content-start,.content-container--has-center-content .content-end{flex:0 1 auto}.expanded-container{color:var(--calcite-list-icon-color, var(--calcite-color-text-3));padding-inline:var(--calcite-spacing-xxs)}:host(:not([disabled])) .expanded-container:hover{color:var(--calcite-list-icon-color, var(--calcite-color-text-1))}.actions-start,.actions-end,.content-start,.content-end,.selection-container,.drag-container,.expanded-container{display:flex;align-items:center}.actions-start calcite-action,.actions-start calcite-sort-handle,.actions-end calcite-action,.actions-end calcite-sort-handle,.content-start calcite-action,.content-start calcite-sort-handle,.content-end calcite-action,.content-end calcite-sort-handle,.selection-container calcite-action,.selection-container calcite-sort-handle,.drag-container calcite-action,.drag-container calcite-sort-handle,.expanded-container calcite-action,.expanded-container calcite-sort-handle{align-self:stretch}.drag-container,.selection-container,.expanded-container{padding-block-end:var(--calcite-spacing-px)}.expanded-container,.selection-container{cursor:pointer}.actions-start,.actions-end{position:relative;padding:0}.actions-start ::slotted(calcite-action),.actions-start ::slotted(calcite-action-menu),.actions-start ::slotted(calcite-sort-handle),.actions-start ::slotted(calcite-dropdown),.actions-end ::slotted(calcite-action),.actions-end ::slotted(calcite-action-menu),.actions-end ::slotted(calcite-sort-handle),.actions-end ::slotted(calcite-dropdown){align-self:stretch;color:inherit}.row:focus .actions-start,.row:focus .actions-end{inset-block:.125rem}.row:focus .actions-start .close,.row:focus .actions-start ::slotted(calcite-action),.row:focus .actions-start ::slotted(calcite-action-menu),.row:focus .actions-start ::slotted(calcite-sort-handle),.row:focus .actions-start ::slotted(calcite-dropdown),.row:focus .actions-end .close,.row:focus .actions-end ::slotted(calcite-action),.row:focus .actions-end ::slotted(calcite-action-menu),.row:focus .actions-end ::slotted(calcite-sort-handle),.row:focus .actions-end ::slotted(calcite-dropdown){block-size:calc(100% - .25rem)}.row:focus:after,.row:focus:before{position:absolute;content:"";inline-size:.125rem;z-index:var(--calcite-z-index-header);background-color:var(--calcite-color-focus, var(--calcite-ui-focus-color, var(--calcite-color-brand)));inset-block:0}.row:focus:before{inset-inline-start:0}.row:focus:after{inset-inline-end:0}.container--border:focus:before{display:none}::slotted(calcite-list:empty){border-block-start-width:0px}:host([hidden]){display:none}[hidden]{display:none}`;
const focusMap = /* @__PURE__ */ new Map();
class ListItem extends LitElement {
constructor() {
super();
this.actionsEndEl = createRef();
this.actionsStartEl = createRef();
this.containerEl = createRef();
this.contentEl = createRef();
this.defaultSlotEl = createRef();
this.handleGridEl = createRef();
this.messages = useT9n();
this.hasActionsEnd = false;
this.hasActionsStart = false;
this.hasContentBottom = false;
this.hasContentEnd = false;
this.hasContentStart = false;
this.hasCustomContent = false;
this.level = null;
this.expandable = false;
this.active = false;
this.bordered = false;
this.closable = false;
this.closed = false;
this.disabled = false;
this.dragDisabled = false;
this.dragHandle = false;
this.expanded = false;
this.filterHidden = false;
this.interactionMode = null;
this.displayMode = "flat";
this.moveToItems = [];
this.scale = "m";
this.selected = false;
this.selectionAppearance = null;
this.selectionMode = null;
this.sortHandleOpen = false;
this.unavailable = false;
this.calciteInternalFocusPreviousItem = createEvent({ cancelable: false });
this.calciteInternalListItemActive = createEvent({ cancelable: false });
this.calciteInternalListItemChange = createEvent({ cancelable: false });
this.calciteInternalListItemSelect = createEvent({ cancelable: false });
this.calciteInternalListItemSelectMultiple = createEvent({ cancelable: false });
this.calciteInternalListItemToggle = createEvent({ cancelable: false });
this.calciteListItemClose = createEvent({ cancelable: false });
this.calciteListItemSelect = createEvent({ cancelable: false });
this.calciteListItemSortHandleBeforeClose = createEvent({ cancelable: false });
this.calciteListItemSortHandleBeforeOpen = createEvent({ cancelable: false });
this.calciteListItemSortHandleClose = createEvent({ cancelable: false });
this.calciteListItemSortHandleOpen = createEvent({ cancelable: false });
this.calciteListItemToggle = createEvent({ cancelable: false });
this.listen("calciteInternalListItemGroupDefaultSlotChange", this.handleCalciteInternalListDefaultSlotChanges);
this.listen("calciteInternalListDefaultSlotChange", this.handleCalciteInternalListDefaultSlotChanges);
}
static {
this.properties = { hasActionsEnd: [16, {}, { state: true }], hasActionsStart: [16, {}, { state: true }], hasContentBottom: [16, {}, { state: true }], hasContentEnd: [16, {}, { state: true }], hasContentStart: [16, {}, { state: true }], hasCustomContent: [16, {}, { state: true }], level: [16, {}, { state: true }], expandable: [16, {}, { state: true }], parentListEl: [16, {}, { state: true }], active: [5, {}, { type: Boolean }], bordered: [5, {}, { type: Boolean }], closable: [7, {}, { reflect: true, type: Boolean }], closed: [7, {}, { reflect: true, type: Boolean }], description: 1, disabled: [7, {}, { reflect: true, type: Boolean }], dragDisabled: [7, {}, { reflect: true, type: Boolean }], dragHandle: [7, {}, { reflect: true, type: Boolean }], expanded: [7, {}, { reflect: true, type: Boolean }], filterHidden: [7, {}, { reflect: true, type: Boolean }], interactionMode: 1, label: 1, messageOverrides: [0, {}, { attribute: false }], metadata: [0, {}, { attribute: false }], displayMode: [3, {}, { reflect: true }], moveToItems: [0, {}, { attribute: false }], open: [7, {}, { reflect: true, type: Boolean }], scale: [3, {}, { reflect: true }], selected: [7, {}, { reflect: true, type: Boolean }], selectionAppearance: [3, {}, { reflect: true }], selectionMode: [3, {}, { reflect: true }], setPosition: [9, {}, { type: Number }], setSize: [9, {}, { type: Number }], sortHandleOpen: [7, {}, { reflect: true, type: Boolean }], unavailable: [7, {}, { reflect: true, type: Boolean }], value: 1, iconStart: [3, {}, { reflect: true }], iconEnd: [3, {}, { reflect: true }], iconFlipRtl: [3, {}, { reflect: true }] };
}
static {
this.styles = [styles, styles$1];
}
get open() {
return this.expanded;
}
set open(value) {
logger.deprecated("property", {
name: "open",
removalVersion: 4,
suggested: "expanded"
});
this.expanded = value;
}
async setFocus() {
await componentFocusable(this);
const { containerEl: { value: containerEl }, parentListEl } = this;
const focusIndex = focusMap.get(parentListEl);
if (typeof focusIndex === "number") {
const cells = this.getGridCells();
if (cells[focusIndex]) {
this.focusCell(cells[focusIndex]);
} else {
containerEl?.focus();
}
return;
}
containerEl?.focus();
}
connectedCallback() {
super.connectedCallback();
const { el } = this;
this.parentListEl = el.closest(listSelector);
this.level = getDepth(el) + 1;
this.setSelectionDefaults();
}
willUpdate(changes) {
if (changes.has("active") && (this.hasUpdated || this.active !== false)) {
this.activeHandler(this.active);
}
if (changes.has("closed") && (this.hasUpdated || this.closed !== false)) {
this.handleClosedChange();
}
if (changes.has("disabled") && (this.hasUpdated || this.disabled !== false)) {
this.handleDisabledChange();
}
if (changes.has("expanded") && (this.hasUpdated || this.expanded !== false)) {
this.handleExpandedChange();
}
if (changes.has("selected") && (this.hasUpdated || this.selected !== false)) {
this.handleSelectedChange();
}
if (changes.has("sortHandleOpen") && (this.hasUpdated || this.sortHandleOpen !== false)) {
this.sortHandleOpenHandler();
}
if (changes.has("displayMode") && this.hasUpdated) {
this.handleExpandableChange(this.defaultSlotEl.value);
}
}
updated() {
updateHostInteraction(this);
}
activeHandler(active) {
if (!active) {
this.focusCell(null, false);
}
}
handleClosedChange() {
this.emitCalciteInternalListItemChange();
}
handleDisabledChange() {
this.emitCalciteInternalListItemChange();
}
handleExpandedChange() {
this.emitCalciteInternalListItemToggle();
}
handleSelectedChange() {
this.calciteInternalListItemSelect.emit();
}
sortHandleOpenHandler() {
if (!this.sortHandleEl) {
return;
}
this.sortHandleEl.open = this.sortHandleOpen;
}
handleCalciteInternalListDefaultSlotChanges(event) {
event.stopPropagation();
this.handleExpandableChange(this.defaultSlotEl.value);
}
setSortHandleEl(el) {
this.sortHandleEl = el;
this.sortHandleOpenHandler();
}
handleSortHandleBeforeOpen(event) {
event.stopPropagation();
this.calciteListItemSortHandleBeforeOpen.emit();
}
handleSortHandleBeforeClose(event) {
event.stopPropagation();
this.calciteListItemSortHandleBeforeClose.emit();
}
handleSortHandleClose(event) {
event.stopPropagation();
this.sortHandleOpen = false;
this.calciteListItemSortHandleClose.emit();
}
handleSortHandleOpen(event) {
event.stopPropagation();
this.sortHandleOpen = true;
this.calciteListItemSortHandleOpen.emit();
}
emitInternalListItemActive() {
this.calciteInternalListItemActive.emit();
}
emitCalciteInternalListItemToggle() {
this.calciteInternalListItemToggle.emit();
}
emitCalciteInternalListItemChange() {
this.calciteInternalListItemChange.emit();
}
handleCloseClick() {
this.closed = true;
this.calciteListItemClose.emit();
}
handleContentSlotChange(event) {
this.hasCustomContent = slotChangeHasAssignedElement(event);
}
handleActionsStartSlotChange(event) {
this.hasActionsStart = slotChangeHasAssignedElement(event);
}
handleActionsEndSlotChange(event) {
this.hasActionsEnd = slotChangeHasAssignedElement(event);
}
handleContentStartSlotChange(event) {
this.hasContentStart = slotChangeHasAssignedElement(event);
}
handleContentEndSlotChange(event) {
this.hasContentEnd = slotChangeHasAssignedElement(event);
}
handleContentBottomSlotChange(event) {
this.hasContentBottom = slotChangeHasAssignedElement(event);
}
setSelectionDefaults() {
const { parentListEl, selectionMode, selectionAppearance } = this;
if (!parentListEl) {
return;
}
if (!selectionMode) {
this.selectionMode = parentListEl.selectionMode;
}
if (!selectionAppearance) {
this.selectionAppearance = parentListEl.selectionAppearance;
}
}
handleExpandableChange(slotEl) {
if (!slotEl) {
return;
}
const children = getListItemChildren(slotEl);
children.lists.forEach((list) => {
list.displayMode = this.displayMode;
});
this.expandable = this.displayMode === "nested" && (children.lists.length > 0 || children.items.length > 0);
}
handleDefaultSlotChange(event) {
this.handleExpandableChange(event.target);
}
handleToggleClick() {
this.toggle();
}
toggle(value = !this.expanded) {
this.expanded = value;
this.calciteListItemToggle.emit();
}
handleItemClick(event) {
if (event.defaultPrevented) {
return;
}
this.toggleSelected(event.shiftKey);
}
async toggleSelected(shiftKey) {
const { selectionMode, selected } = this;
if (this.disabled) {
return;
}
if (selectionMode === "multiple" || selectionMode === "single") {
this.selected = !selected;
} else if (selectionMode === "single-persist") {
this.selected = true;
}
this.calciteInternalListItemSelectMultiple.emit({
selectMultiple: shiftKey && selectionMode === "multiple"
});
await this.updateComplete;
this.calciteListItemSelect.emit();
}
getGridCells() {
return [
this.handleGridEl.value,
this.actionsStartEl.value,
this.contentEl.value,
this.actionsEndEl.value
].filter((el) => el && !el.hidden);
}
handleItemKeyDown(event) {
if (event.defaultPrevented) {
return;
}
const { key } = event;
const composedPath = event.composedPath();
const { containerEl: { value: containerEl }, actionsStartEl: { value: actionsStartEl }, actionsEndEl: { value: actionsEndEl }, expanded, expandable } = this;
const cells = this.getGridCells();
const currentIndex = cells.findIndex((cell) => composedPath.includes(cell));
if (key === "Enter" && !composedPath.includes(actionsStartEl) && !composedPath.includes(actionsEndEl)) {
event.preventDefault();
this.toggleSelected(event.shiftKey);
} else if (key === "ArrowRight") {
event.preventDefault();
const nextIndex = currentIndex + 1;
if (currentIndex === -1) {
if (!expanded && expandable) {
this.toggle(true);
this.focusCell(null);
} else if (cells[0]) {
this.focusCell(cells[0]);
}
} else if (cells[currentIndex] && cells[nextIndex]) {
this.focusCell(cells[nextIndex]);
}
} else if (key === "ArrowLeft") {
event.preventDefault();
const prevIndex = currentIndex - 1;
if (currentIndex === -1) {
this.focusCell(null);
if (expanded && expandable) {
this.toggle(false);
} else {
this.calciteInternalFocusPreviousItem.emit();
}
} else if (currentIndex === 0) {
this.focusCell(null);
containerEl.focus();
} else if (cells[currentIndex] && cells[prevIndex]) {
this.focusCell(cells[prevIndex]);
}
}
}
focusCellNull() {
this.focusCell(null);
}
setFocusCell(focusEl, focusedEl, saveFocusIndex) {
const { parentListEl } = this;
if (saveFocusIndex) {
focusMap.set(parentListEl, null);
}
const gridCells = this.getGridCells();
gridCells.forEach((tableCell) => {
tableCell.removeAttribute("tabindex");
tableCell.removeAttribute(activeCellTestAttribute);
});
if (!focusEl) {
return;
}
if (focusEl === focusedEl) {
focusEl.tabIndex = 0;
} else {
focusEl.removeAttribute("tabindex");
}
focusEl.setAttribute(activeCellTestAttribute, "");
if (saveFocusIndex) {
focusMap.set(parentListEl, gridCells.indexOf(focusEl));
}
}
focusCell(focusEl, saveFocusIndex = true) {
const focusedEl = getFirstTabbable(focusEl);
this.setFocusCell(focusEl, focusedEl, saveFocusIndex);
focusedEl?.focus();
}
renderSelected() {
const { selected, selectionMode, selectionAppearance } = this;
if (selectionMode === "none" || selectionAppearance === "border") {
return null;
}
return keyed("selection-container", html`<div class=${safeClassMap({
[CSS.selectionContainer]: true,
[CSS.selectionContainerSingle]: selectionMode === "single" || selectionMode === "single-persist"
})} @click=${this.handleItemClick}><calcite-icon .icon=${selected ? selectionMode === "multiple" ? ICONS.selectedMultiple : ICONS.selectedSingle : selectionMode === "multiple" ? ICONS.unselectedMultiple : ICONS.unselectedSingle} .scale=${getIconScale(this.scale)}></calcite-icon></div>`);
}
renderDragHandle() {
const { label, dragHandle, dragDisabled, setPosition, setSize, moveToItems } = this;
return dragHandle ? keyed("drag-handle-container", html`<div .ariaLabel=${label} class=${safeClassMap({ [CSS.dragContainer]: true, [CSS.gridCell]: true })} role=gridcell ${ref(this.handleGridEl)}><calcite-sort-handle .disabled=${dragDisabled} .label=${label} .moveToItems=${moveToItems} @calciteSortHandleBeforeClose=${this.handleSortHandleBeforeClose} @calciteSortHandleBeforeOpen=${this.handleSortHandleBeforeOpen} @calciteSortHandleClose=${this.handleSortHandleClose} @calciteSortHandleOpen=${this.handleSortHandleOpen} overlay-positioning=fixed .scale=${this.scale} .setPosition=${setPosition} .setSize=${setSize} ${ref(this.setSortHandleEl)}></calcite-sort-handle></div>`) : null;
}
renderExpanded() {
const { el, expanded, expandable, messages, displayMode, scale } = this;
if (displayMode !== "nested") {
return null;
}
const dir = getElementDir(el);
const icon = expandable ? expanded ? ICONS.open : dir === "rtl" ? ICONS.collapsedRTL : ICONS.collapsedLTR : ICONS.blank;
const iconScale = getIconScale(scale);
const tooltip = expandable ? expanded ? messages.collapse : messages.expand : void 0;
const expandedClickHandler = expandable ? this.handleToggleClick : void 0;
return keyed("expanded-container", html`<div class=${safeClassMap(CSS.expandedContainer)} @click=${expandedClickHandler} title=${tooltip ?? nothing}>${keyed(icon, html`<calcite-icon .icon=${icon} .scale=${iconScale}></calcite-icon>`)}</div>`);
}
renderActionsStart() {
const { label, hasActionsStart } = this;
return keyed("actions-start-container", html`<div .ariaLabel=${label} class=${safeClassMap({ [CSS.actionsStart]: true, [CSS.gridCell]: true })} .hidden=${!hasActionsStart} role=gridcell ${ref(this.actionsStartEl)}><slot name=${SLOTS.actionsStart} @slotchange=${this.handleActionsStartSlotChange}></slot></div>`);
}
renderActionsEnd() {
const { label, hasActionsEnd, closable, messages } = this;
return keyed("actions-end-container", html`<div .ariaLabel=${label} class=${safeClassMap({ [CSS.actionsEnd]: true, [CSS.gridCell]: true })} .hidden=${!(hasActionsEnd || closable)} role=gridcell ${ref(this.actionsEndEl)}><slot name=${SLOTS.actionsEnd} @slotchange=${this.handleActionsEndSlotChange}></slot>${closable ? keyed("close-action", html`<calcite-action appearance=transparent class=${safeClassMap(CSS.close)} .icon=${ICONS.close} .label=${messages.close} @click=${this.handleCloseClick} .scale=${this.scale} .text=${messages.close}></calcite-action>`) : null}</div>`);
}
renderContentStart() {
const { hasContentStart } = this;
return html`<div class=${safeClassMap(CSS.contentStart)} .hidden=${!hasContentStart}><slot name=${SLOTS.contentStart} @slotchange=${this.handleContentStartSlotChange}></slot></div>`;
}
renderCustomContent() {
const { hasCustomContent } = this;
return html`<div class=${safeClassMap(CSS.customContent)} .hidden=${!hasCustomContent}><slot name=${SLOTS.content} @slotchange=${this.handleContentSlotChange}></slot></div>`;
}
renderIconStart() {
const { iconStart, iconFlipRtl, scale } = this;
return iconStart ? keyed("icon-start", html`<calcite-icon class=${safeClassMap(CSS.icon)} .flipRtl=${iconFlipRtl === "both" || iconFlipRtl === "start"} .icon=${iconStart} .scale=${getIconScale(scale)}></calcite-icon>`) : null;
}
renderIconEnd() {
const { iconEnd, iconFlipRtl, scale } = this;
return iconEnd ? keyed("icon-end", html`<calcite-icon class=${safeClassMap(CSS.icon)} .flipRtl=${iconFlipRtl === "both" || iconFlipRtl === "end"} .icon=${iconEnd} .scale=${getIconScale(scale)}></calcite-icon>`) : null;
}
renderContentEnd() {
const { hasContentEnd } = this;
return html`<div class=${safeClassMap(CSS.contentEnd)} .hidden=${!hasContentEnd}><slot name=${SLOTS.contentEnd} @slotchange=${this.handleContentEndSlotChange}></slot></div>`;
}
renderContentBottom() {
const { hasContentBottom } = this;
return html`<div class=${safeClassMap(CSS.contentBottom)} .hidden=${!hasContentBottom}><slot name=${SLOTS.contentBottom} @slotchange=${this.handleContentBottomSlotChange}></slot></div>`;
}
renderDefaultContainer() {
return html`<div class=${safeClassMap({
[CSS.nestedContainer]: true,
[CSS.nestedContainerExpanded]: this.expandable && this.expanded
})}><slot @slotchange=${this.handleDefaultSlotChange} ${ref(this.defaultSlotEl)}></slot></div>`;
}
renderContentProperties() {
const { label, description, hasCustomContent } = this;
return !hasCustomContent && (!!label || !!description) ? keyed("content", html`<div class=${safeClassMap(CSS.content)}>${label ? keyed("label", html`<div class=${safeClassMap(CSS.label)}>${label}</div>`) : null}${description ? keyed("description", html`<div class=${safeClassMap(CSS.description)}>${description}</div>`) : null}</div>`) : null;
}
renderContentContainer() {
const { description, label, selectionMode, hasCustomContent, unavailable } = this;
const hasCenterContent = hasCustomContent || !!label || !!description;
const content = [
this.renderContentStart(),
this.renderCustomContent(),
this.renderIconStart(),
this.renderContentProperties(),
this.renderIconEnd(),
this.renderContentEnd()
];
return keyed("content-container", html`<div .ariaLabel=${label} class=${safeClassMap({
[CSS.gridCell]: true,
[CSS.contentContainer]: true,
[CSS.contentContainerUnavailable]: unavailable,
[CSS.contentContainerSelectable]: selectionMode !== "none",
[CSS.contentContainerHasCenterContent]: hasCenterContent
})} @click=${this.handleItemClick} role=gridcell ${ref(this.contentEl)}>${content}</div>`);
}
render() {
const { expandable, expanded, level, active, label, selected, selectionAppearance, selectionMode, interactionMode, closed, filterHidden, bordered, disabled, hasContentBottom } = this;
const wrapperBordered = bordered && hasContentBottom;
const contentContainerWrapperBordered = bordered && !hasContentBottom;
const showSelectionBorder = selectionMode !== "none" && selectionAppearance === "border";
const selectionBorderSelected = showSelectionBorder && selected;
const selectionBorderUnselected = showSelectionBorder && !selected;
const containerInteractive = interactionMode === "interactive" || interactionMode === "static" && selectionMode !== "none" && selectionAppearance === "border";
return InteractiveContainer({ disabled, children: html`<div class=${safeClassMap({ [CSS.wrapper]: true, [CSS.wrapperBordered]: wrapperBordered })}><div .ariaExpanded=${expandable ? expanded : null} .ariaLabel=${label} .ariaLevel=${level} .ariaSelected=${selected} class=${safeClassMap({
[CSS.row]: true,
[CSS.container]: true,
[CSS.containerHover]: containerInteractive,
[CSS.containerBorder]: showSelectionBorder,
[CSS.containerBorderSelected]: selectionBorderSelected,
[CSS.containerBorderUnselected]: selectionBorderUnselected
})} .hidden=${closed || filterHidden} @focus=${this.focusCellNull} @focusin=${this.emitInternalListItemActive} @keydown=${this.handleItemKeyDown} role=row .tabIndex=${active ? 0 : -1} ${ref(this.containerEl)}>${this.renderDragHandle()}${this.renderSelected()}${this.renderExpanded()}<div class=${safeClassMap({
[CSS.contentContainerWrapper]: true,
[CSS.contentContainerWrapperBordered]: contentContainerWrapperBordered
})}>${this.renderActionsStart()}${this.renderContentContainer()}${this.renderActionsEnd()}</div></div>${this.renderContentBottom()}</div>${this.renderDefaultContainer()}` });
}
}
customElement("calcite-list-item", ListItem);
export {
ListItem
};