@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
162 lines (161 loc) • 7.91 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 { ref } from "lit-html/directives/ref.js";
import { keyed } from "lit-html/directives/keyed.js";
import { nothing, html } from "lit";
import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina";
import { c as componentFocusable } from "../../chunks/component.js";
import { u as updateHostInteraction, I as InteractiveContainer } from "../../chunks/interactive.js";
import { b as defaultMenuPlacement } from "../../chunks/floating-ui.js";
import { u as useT9n } from "../../chunks/useT9n.js";
import { css } from "@lit/reactive-element/css-tag.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 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.disabled = false;
this.messages = useT9n({ blocking: true });
this.moveToItems = [];
this.open = false;
this.overlayPositioning = "absolute";
this.placement = defaultMenuPlacement;
this.scale = "m";
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 = { hasSetInfo: [16, {}, { state: true }], isSetDisabled: [16, {}, { state: true }], disabled: [7, {}, { reflect: true, type: Boolean }], flipPlacements: [0, {}, { attribute: false }], label: 1, messageOverrides: [0, {}, { attribute: false }], messages: [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 }], widthScale: [3, {}, { reflect: true }] };
}
static {
this.styles = styles;
}
get hasSetInfo() {
return typeof this.setPosition === "number" && typeof this.setSize === "number";
}
get isSetDisabled() {
const { setPosition, setSize, moveToItems } = this;
return this.hasSetInfo ? setPosition < 1 || setSize < 1 || setSize < 2 && moveToItems.length < 1 : false;
}
async setFocus() {
await componentFocusable(this);
this.dropdownEl?.setFocus();
}
willUpdate(changes) {
if (changes.has("open") && (this.hasUpdated || this.open !== false)) {
this.openHandler();
}
}
updated() {
updateHostInteraction(this);
}
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 } = this;
if (!this.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 });
}
render() {
const { disabled, flipPlacements, open, overlayPositioning, placement, scale, widthScale } = this;
const text = this.getLabel();
const isDisabled = disabled || this.isSetDisabled;
return 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} .widthScale=${widthScale} ${ref(this.setDropdownEl)}><calcite-action .active=${open} appearance=transparent class=${safeClassMap(CSS.handle)} .dragHandle=${true} .icon=${disabled ? ICONS.blank : ICONS.drag} .label=${text} .scale=${scale} slot=trigger .text=${text} title=${text ?? nothing}></calcite-action>${this.renderGroup()}${this.renderMoveToGroup()}</calcite-dropdown>` });
}
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>`);
}
renderGroup() {
return this.hasSetInfo ? keyed("reorder", html`<calcite-dropdown-group .groupTitle=${this.messages.reorder} .scale=${this.scale} selection-mode=none>${this.renderTop()}${this.renderUp()}${this.renderDown()}${this.renderBottom()}</calcite-dropdown-group>`) : null;
}
renderMoveToGroup() {
const { messages, moveToItems, scale } = this;
return moveToItems.length ? keyed("move-to-items", html`<calcite-dropdown-group .groupTitle=${messages.moveTo} .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
};