@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
186 lines (185 loc) • 9.13 kB
JavaScript
/* COPYRIGHT Esri - https://js.arcgis.com/5.0/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { ref } from "lit/directives/ref.js";
import { keyed } from "lit/directives/keyed.js";
import { css, nothing, html } from "lit";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { d as defaultMenuPlacement } from "../../chunks/floating-ui.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { u as useSetFocus } from "../../chunks/useSetFocus.js";
import { u as useInteractive } from "../../chunks/useInteractive.js";
const CSS = {
handle: "handle",
dropdown: "dropdown"
};
const ICONS = {
drag: "drag",
blank: "blank"
};
const SUBSTITUTIONS = {
label: "{label}",
position: "{position}",
total: "{total}"
};
const REORDER_VALUES = ["top", "up", "down", "bottom"];
const SLOTS = {
trigger: "trigger"
};
const IDS = {
add: "add",
move: "move",
reorder: "reorder"
};
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}.dropdown{block-size:100%}: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 SortHandle extends LitElement {
constructor() {
super(...arguments);
this.focusSetter = useSetFocus()(this);
this.interactiveContainer = useInteractive(this);
this.disabled = false;
this.messages = useT9n({ blocking: true });
this.addToItems = [];
this.moveToItems = [];
this.open = false;
this.overlayPositioning = "absolute";
this.placement = defaultMenuPlacement;
this.scale = "m";
this.sortDisabled = false;
this.topLayerDisabled = false;
this.calciteSortHandleAdd = createEvent({ cancelable: true });
this.calciteSortHandleBeforeClose = createEvent({ cancelable: false });
this.calciteSortHandleBeforeOpen = createEvent({ cancelable: false });
this.calciteSortHandleClose = createEvent({ cancelable: false });
this.calciteSortHandleMove = createEvent({ cancelable: true });
this.calciteSortHandleOpen = createEvent({ cancelable: false });
this.calciteSortHandleReorder = createEvent({ cancelable: true });
}
static {
this.properties = { disabled: [7, {}, { reflect: true, type: Boolean }], flipPlacements: [0, {}, { attribute: false }], label: 1, messageOverrides: [0, {}, { attribute: false }], messages: [0, {}, { attribute: false }], addToItems: [0, {}, { attribute: false }], moveToItems: [0, {}, { attribute: false }], open: [7, {}, { reflect: true, type: Boolean }], overlayPositioning: [3, {}, { reflect: true }], placement: [3, {}, { reflect: true }], scale: [3, {}, { reflect: true }], setPosition: [9, {}, { type: Number }], setSize: [9, {}, { type: Number }], sortDisabled: [7, {}, { reflect: true, type: Boolean }], topLayerDisabled: [7, {}, { reflect: true, type: Boolean }], widthScale: [3, {}, { reflect: true }] };
}
static {
this.styles = styles;
}
get hasSetInfo() {
return typeof this.setPosition === "number" && typeof this.setSize === "number";
}
get hasValidSetInfo() {
return this.hasSetInfo ? this.setPosition > 0 && this.setSize > 1 : true;
}
get hasReorderItems() {
return !this.sortDisabled && this.hasValidSetInfo;
}
get hasNoItems() {
return !this.hasReorderItems && this.moveToItems.length < 1 && this.addToItems.length < 1;
}
async setFocus(options) {
return this.focusSetter(() => this.dropdownEl, options);
}
willUpdate(changes) {
if (changes.has("open") && (this.hasUpdated || this.open !== false)) {
this.openHandler();
}
}
openHandler() {
if (this.disabled) {
this.open = false;
return;
}
if (this.dropdownEl) {
this.dropdownEl.open = this.open;
}
}
setDropdownEl(el) {
if (!el) {
return;
}
this.dropdownEl = el;
this.openHandler();
}
getLabel() {
const { label, messages, setPosition, setSize, hasSetInfo } = this;
if (!hasSetInfo) {
return label ?? "";
}
let formattedLabel = label ? messages.repositionLabel.replace(SUBSTITUTIONS.label, label) : messages.reposition;
formattedLabel = formattedLabel.replace(SUBSTITUTIONS.position, setPosition ? setPosition.toString() : "");
return formattedLabel.replace(SUBSTITUTIONS.total, setSize ? setSize.toString() : "");
}
handleBeforeOpen(event) {
event.stopPropagation();
this.calciteSortHandleBeforeOpen.emit();
}
handleOpen(event) {
event.stopPropagation();
this.calciteSortHandleOpen.emit();
this.open = true;
}
handleBeforeClose(event) {
event.stopPropagation();
this.calciteSortHandleBeforeClose.emit();
}
handleClose(event) {
event.stopPropagation();
this.calciteSortHandleClose.emit();
this.open = false;
}
handleReorder(event) {
this.calciteSortHandleReorder.emit({
reorder: event.target.dataset.value
});
}
handleMoveTo(event) {
const id = event.target.dataset.id;
const moveTo = this.moveToItems.find((item) => item.id === id);
this.calciteSortHandleMove.emit({ moveTo });
}
handleAddTo(event) {
const id = event.target.dataset.id;
const addTo = this.addToItems.find((item) => item.id === id);
this.calciteSortHandleAdd.emit({ addTo });
}
render() {
const { disabled, flipPlacements, open, overlayPositioning, placement, scale, widthScale, hasNoItems } = this;
const text = this.getLabel();
const isDisabled = disabled || hasNoItems;
return this.interactiveContainer({ disabled, children: html`<calcite-dropdown class=${safeClassMap(CSS.dropdown)} .disabled=${isDisabled} .flipPlacements=${flipPlacements} =${this.handleBeforeClose} =${this.handleBeforeOpen} =${this.handleClose} =${this.handleOpen} .overlayPositioning=${overlayPositioning} .placement=${placement} .scale=${scale} .topLayerDisabled=${this.topLayerDisabled} .widthScale=${widthScale} ${ref(this.setDropdownEl)}><calcite-action .active=${open} .aria=${{ expanded: open }} class=${safeClassMap(CSS.handle)} .dragHandle=${true} .icon=${disabled ? ICONS.blank : ICONS.drag} .label=${text} .scale=${scale} slot=${SLOTS.trigger} .text=${text} title=${text ?? nothing}></calcite-action>${this.renderReorderGroup()}${this.renderMoveToGroup()}${this.renderAddToGroup()}</calcite-dropdown>` });
}
renderAddToItem(addToItem) {
return keyed(addToItem.id, html`<calcite-dropdown-item data-id=${addToItem.id ?? nothing} .label=${addToItem.label} =${this.handleAddTo}>${addToItem.label}</calcite-dropdown-item>`);
}
renderMoveToItem(moveToItem) {
return keyed(moveToItem.id, html`<calcite-dropdown-item data-id=${moveToItem.id ?? nothing} .label=${moveToItem.label} =${this.handleMoveTo}>${moveToItem.label}</calcite-dropdown-item>`);
}
renderReorderGroup() {
return this.hasReorderItems ? keyed("reorder", html`<calcite-dropdown-group .groupTitle=${this.messages.reorder} id=${IDS.reorder} .scale=${this.scale} selection-mode=none>${this.renderTop()}${this.renderUp()}${this.renderDown()}${this.renderBottom()}</calcite-dropdown-group>`) : null;
}
renderAddToGroup() {
const { messages, addToItems, scale } = this;
return addToItems.length ? keyed("add-to-items", html`<calcite-dropdown-group .groupTitle=${messages.addTo} id=${IDS.add} .scale=${scale} selection-mode=none>${addToItems.map((addToItem) => this.renderAddToItem(addToItem))}</calcite-dropdown-group>`) : null;
}
renderMoveToGroup() {
const { messages, moveToItems, scale } = this;
return moveToItems.length ? keyed("move-to-items", html`<calcite-dropdown-group .groupTitle=${messages.moveTo} id=${IDS.move} .scale=${scale} selection-mode=none>${moveToItems.map((moveToItem) => this.renderMoveToItem(moveToItem))}</calcite-dropdown-group>`) : null;
}
renderDropdownItem(positionIndex, label) {
return keyed(REORDER_VALUES[positionIndex], html`<calcite-dropdown-item data-value=${REORDER_VALUES[positionIndex] ?? nothing} .label=${label} =${this.handleReorder}>${label}</calcite-dropdown-item>`);
}
renderTop() {
const { setPosition } = this;
return setPosition !== 1 && setPosition !== 2 ? this.renderDropdownItem(0, this.messages.moveToTop) : null;
}
renderUp() {
return this.setPosition !== 1 ? this.renderDropdownItem(1, this.messages.moveUp) : null;
}
renderDown() {
return this.setPosition !== this.setSize ? this.renderDropdownItem(2, this.messages.moveDown) : null;
}
renderBottom() {
const { setPosition, setSize } = this;
return setPosition !== setSize && setPosition !== setSize - 1 ? this.renderDropdownItem(3, this.messages.moveToBottom) : null;
}
}
customElement("calcite-sort-handle", SortHandle);
export {
SortHandle
};