@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
152 lines (151 loc) • 8.06 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 { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { queryAssignedElements } from "lit/decorators.js";
import { S as SLOTS } from "../../chunks/resources2.js";
import { s as slotChangeHasAssignedElement } from "../../chunks/dom.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
import { I as ICONS, S as SLOTS$1, C as CSS } from "../../chunks/resources3.js";
const styles = css`:host{box-sizing:border-box;background-color:var(--calcite-color-foreground-1);color:var(--calcite-color-text-2);font-size:var(--calcite-font-size--1)}:host *{box-sizing:border-box}:host([scale=s]){--calcite-internal-action-group-gap: var(--calcite-spacing-xxs)}:host([scale=m]){--calcite-internal-action-group-gap: var(--calcite-spacing-sm)}:host([scale=l]){--calcite-internal-action-group-gap: var(--calcite-spacing-sm-plus)}:host{display:flex;flex-direction:column;padding:0;background-color:transparent;border-color:var(--calcite-action-group-border-color, var(--calcite-color-border-3));border-style:solid;border-width:0;gap:var(--calcite-internal-action-group-gap)}.container{display:flex;flex-grow:1;flex-direction:column;gap:inherit}:host([columns="1"]){--calcite-internal-action-group-columns: 1}:host([columns="2"]){--calcite-internal-action-group-columns: 2}:host([columns="3"]){--calcite-internal-action-group-columns: 3}:host([columns="4"]){--calcite-internal-action-group-columns: 4}:host([columns="5"]){--calcite-internal-action-group-columns: 5}:host([columns="6"]){--calcite-internal-action-group-columns: 6}:host(:first-child){padding-block-start:0px}:host([layout=horizontal]),:host([layout=horizontal]) .container{flex-direction:row}:host([layout=grid]){display:grid}:host([layout=grid]) .container{display:grid;place-content:stretch;background-color:transparent;gap:var(--calcite-action-group-gap, var(--calcite-internal-action-group-gap));grid-template-columns:repeat(var(--calcite-action-group-columns, var(--calcite-internal-action-group-columns, 3)),auto);padding:var(--calcite-action-group-gap, 1px)}:host([layout=horizontal]) ::slotted(calcite-action-group){border-inline-end:var(--calcite-size-px)}:host([hidden]){display:none}[hidden]{display:none}`;
var __defProp = Object.defineProperty;
var __decorateClass = (decorators, target, key, kind) => {
var result = void 0;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = decorator(target, key, result) || result;
if (result) __defProp(target, key, result);
return result;
};
class ActionGroup extends LitElement {
constructor() {
super();
this.messages = useT9n();
this.focusSetter = useSetFocus()(this);
this.hasMenuActions = false;
this.expanded = false;
this.layout = "vertical";
this.menuOpen = false;
this.overlayPositioning = "absolute";
this.scale = "m";
this.selectionMode = "none";
this.topLayerDisabled = false;
this.calciteActionGroupCollapse = createEvent({ cancelable: false });
this.calciteActionGroupExpand = createEvent({ cancelable: false });
this.listen("click", this.handleActionClick);
}
static {
this.properties = { hasMenuActions: [16, {}, { state: true }], columns: [11, {}, { type: Number, reflect: true }], expanded: [7, {}, { reflect: true, type: Boolean }], label: 1, layout: [3, {}, { reflect: true }], menuFlipPlacements: [0, {}, { attribute: false }], menuOpen: [7, {}, { reflect: true, type: Boolean }], menuPlacement: [3, {}, { reflect: true }], messageOverrides: [0, {}, { attribute: false }], overlayPositioning: [3, {}, { reflect: true }], scale: [3, {}, { reflect: true }], selectionMode: [3, {}, { reflect: true }], topLayerDisabled: [7, {}, { reflect: true, type: Boolean }] };
}
static {
this.shadowRootOptions = { mode: "open", delegatesFocus: true };
}
static {
this.styles = styles;
}
async setFocus(options) {
return this.focusSetter(() => this.el, options);
}
willUpdate(changes) {
if (this.hasUpdated || changes.has("selectionMode")) {
if (this.selectionMode !== "none") {
this.setRoleOnActions();
} else if (this.selectionMode === "none") {
this.clearActionAriaAttributes();
}
}
if (changes.has("expanded")) {
if (this.hasUpdated || this.expanded !== false) {
this.menuOpen = false;
}
if (this.hasUpdated) {
if (this.expanded) {
this.calciteActionGroupExpand.emit();
} else {
this.calciteActionGroupCollapse.emit();
}
}
}
}
setActiveAction(index, active) {
if (this.selectionMode === "multiple") {
active.active = !active.active;
this.setActionAriaChecked(active, active.active);
return;
}
if (this.selectionMode === "single") {
this.actions.forEach((action, i) => {
action.active = i === index && !action.active;
this.setActionAriaChecked(action, action.active);
});
return;
}
if (this.selectionMode === "single-persist") {
if (!this.actions[index].active) {
this.actions.forEach((action, i) => {
action.active = i === index;
this.setActionAriaChecked(action, action.active);
});
}
return;
}
}
setMenuOpen(event) {
this.menuOpen = !!event.currentTarget.open;
}
handleMenuActionsSlotChange(event) {
this.hasMenuActions = slotChangeHasAssignedElement(event);
}
handleActionClick(event) {
const target = event.target;
if (!target) {
return;
}
const index = this.actions.indexOf(target);
if (index === -1 || this.selectionMode === "none") {
return;
}
this.setActiveAction(index, target);
}
setRoleOnActions() {
this.actions.forEach((action) => {
action.aria = {
...action.aria,
role: this.selectionMode === "single" || this.selectionMode === "single-persist" ? "radio" : "checkbox"
};
this.setActionAriaChecked(action, action.active);
});
}
setActionAriaChecked(action, checked) {
action.aria = {
...action.aria,
checked: checked ? "true" : "false"
};
}
clearActionAriaAttributes() {
if (this.selectionMode === "none") {
this.actions.forEach((action) => {
if (action.aria) {
action.aria.checked = void 0;
action.aria.role = void 0;
action.aria = { ...action.aria };
}
});
}
}
renderMenu() {
const { expanded, menuOpen, scale, layout, messages, overlayPositioning, hasMenuActions, menuFlipPlacements, menuPlacement } = this;
return html`<calcite-action-menu .expanded=${expanded} .flipPlacements=${menuFlipPlacements ?? (layout === "horizontal" ? ["top", "bottom"] : ["left", "right"])} .hidden=${!hasMenuActions} .label=${messages.more} @calciteActionMenuOpen=${this.setMenuOpen} .open=${menuOpen} .overlayPositioning=${overlayPositioning} .placement=${menuPlacement ?? (layout === "horizontal" ? "bottom-start" : "leading-start")} .scale=${scale} .topLayerDisabled=${this.topLayerDisabled}><calcite-action .aria=${{ expanded }} .icon=${ICONS.menu} .scale=${scale} slot=${SLOTS.trigger} .text=${messages.more} .textEnabled=${expanded}></calcite-action><slot name=${SLOTS$1.menuActions} @slotchange=${this.handleMenuActionsSlotChange}></slot><slot name=${SLOTS$1.menuTooltip} slot=${SLOTS.tooltip}></slot></calcite-action-menu>`;
}
render() {
return html`<div .ariaLabel=${this.label} class=${safeClassMap(CSS.container)} .role=${this.selectionMode === "multiple" || this.selectionMode === "none" ? "group" : "radiogroup"}><slot></slot>${this.renderMenu()}</div>`;
}
}
__decorateClass([
queryAssignedElements({ selector: "calcite-action" })
], ActionGroup.prototype, "actions");
customElement("calcite-action-group", ActionGroup);
export {
ActionGroup
};