UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

134 lines (133 loc) • 6.5 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 { nothing, html } from "lit"; import { createRef, ref } from "lit-html/directives/ref.js"; 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 { u as useT9n } from "../../chunks/useT9n.js"; import { l as logger } from "../../chunks/logger.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { handle: "handle", handleSelected: "handle--selected" }; const ICONS = { drag: "drag" }; const SUBSTITUTIONS = { itemLabel: "{itemLabel}", position: "{position}", total: "{total}" }; 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}.handle{display:flex;align-items:center;justify-content:center;align-self:stretch;border-style:none;outline-color:transparent;color:var(--calcite-handle-icon-color, var(--calcite-color-border-input));background-color:var(--calcite-handle-background-color, transparent);padding-block:.75rem;padding-inline:.25rem;line-height:0}.handle calcite-icon{color:inherit}:host(:not([disabled])) .handle{cursor:move}:host(:not([disabled])) .handle:hover{color:var(--calcite-handle-icon-color-hover, var(--calcite-color-text-1));background-color:var(--calcite-handle-background-color-hover, var(--calcite-color-foreground-2))}:host(:not([disabled])) .handle:focus{outline:2px solid var(--calcite-color-focus, var(--calcite-ui-focus-color, var(--calcite-color-brand)));outline-offset:calc(-2px*(1 - (2*clamp(0,var(--calcite-offset-invert-focus),1))));color:var(--calcite-handle-icon-color-hover, var(--calcite-color-text-1))}:host(:not([disabled])) .handle--selected{color:var(--calcite-handle-icon-color-selected, var(--calcite-color-text-1));background-color:var(--calcite-handle-background-color-selected, var(--calcite-color-foreground-3))}: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 Handle extends LitElement { constructor() { super(...arguments); this.handleButton = createRef(); this.messages = useT9n({ blocking: true }); this.blurUnselectDisabled = false; this.disabled = false; this.selected = false; this.calciteHandleChange = createEvent({ cancelable: false }); this.calciteHandleNudge = createEvent({ cancelable: false }); this.calciteInternalAssistiveTextChange = createEvent({ cancelable: false }); } static { this.properties = { blurUnselectDisabled: [5, {}, { type: Boolean }], disabled: [7, {}, { reflect: true, type: Boolean }], dragHandle: [3, {}, { reflect: true }], label: 1, messageOverrides: [0, {}, { attribute: false }], selected: [7, {}, { reflect: true, type: Boolean }], setPosition: [9, {}, { type: Number }], setSize: [9, {}, { type: Number }] }; } static { this.styles = styles; } async setFocus() { await componentFocusable(this); this.handleButton.value?.focus(); } willUpdate(changes) { if (changes.has("messages") || changes.has("label") || changes.has("selected") && (this.hasUpdated || this.selected !== false) || changes.has("setPosition") || changes.has("setSize")) { this.handleAriaTextChange(); } } updated() { updateHostInteraction(this); } loaded() { logger.deprecated("component", { name: "handle", removalVersion: 4, suggested: "sort-handle" }); } handleAriaTextChange() { const message = this.getAriaText("live"); if (message) { this.calciteInternalAssistiveTextChange.emit({ message }); } } getTooltip() { const { label, messages } = this; if (!messages) { return ""; } if (!label) { return messages.dragHandleUntitled; } return messages.dragHandle.replace(SUBSTITUTIONS.itemLabel, label); } getAriaText(type) { const { setPosition, setSize, label, messages, selected } = this; if (!messages || !label || typeof setSize !== "number" || typeof setPosition !== "number") { return null; } const text = type === "label" ? selected ? messages.dragHandleChange : messages.dragHandleIdle : selected ? messages.dragHandleActive : messages.dragHandleCommit; const replacePosition = text.replace(SUBSTITUTIONS.position, setPosition.toString()); const replaceLabel = replacePosition.replace(SUBSTITUTIONS.itemLabel, label); return replaceLabel.replace(SUBSTITUTIONS.total, setSize.toString()); } handleKeyDown(event) { if (this.disabled) { return; } switch (event.key) { case " ": this.selected = !this.selected; this.calciteHandleChange.emit(); event.preventDefault(); break; case "ArrowUp": if (!this.selected) { return; } event.preventDefault(); this.calciteHandleNudge.emit({ direction: "up" }); break; case "ArrowDown": if (!this.selected) { return; } event.preventDefault(); this.calciteHandleNudge.emit({ direction: "down" }); break; } } handleBlur() { if (this.blurUnselectDisabled || this.disabled) { return; } if (this.selected) { this.selected = false; this.calciteHandleChange.emit(); } } render() { return InteractiveContainer({ disabled: this.disabled, children: html`<span .ariaChecked=${this.disabled ? null : this.selected} .ariaDisabled=${this.disabled ? this.disabled : null} .ariaLabel=${this.disabled ? null : this.getAriaText("label")} class=${safeClassMap({ [CSS.handle]: true, [CSS.handleSelected]: !this.disabled && this.selected })} @blur=${this.handleBlur} @keydown=${this.handleKeyDown} role=radio tabindex=${(this.disabled ? null : 0) ?? nothing} title=${this.getTooltip() ?? nothing} ${ref(this.handleButton)}><calcite-icon .icon=${ICONS.drag} scale=s></calcite-icon></span>` }); } } customElement("calcite-handle", Handle); export { Handle };