UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

162 lines (161 loc) • 7.91 kB
/*! 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} @calciteDropdownBeforeClose=${this.handleBeforeClose} @calciteDropdownBeforeOpen=${this.handleBeforeOpen} @calciteDropdownClose=${this.handleClose} @calciteDropdownOpen=${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} @calciteDropdownItemSelect=${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} @calciteDropdownItemSelect=${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 };