@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
134 lines (133 loc) • 6.5 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 { 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
};