UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

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