UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

119 lines (118 loc) • 6.29 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 { D as DEBOUNCE, c as customElement } from "../../chunks/runtime.js"; import { debounce } from "lodash-es"; import { html } from "lit"; import { createRef, ref } from "lit-html/directives/ref.js"; import { LitElement, createEvent, safeClassMap } from "@arcgis/lumina"; import { f as filter } from "../../chunks/filter.js"; import { u as updateHostInteraction, I as InteractiveContainer } from "../../chunks/interactive.js"; import { c as componentFocusable } from "../../chunks/component.js"; import { u as useT9n } from "../../chunks/useT9n.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { container: "container" }; const ICONS = { search: "search" }; const styles = css`:host{box-sizing:border-box;background-color:var(--calcite-color-foreground-1);color:var(--calcite-color-text-2);font-size:var(--calcite-font-size--1)}:host *{box-sizing:border-box}: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;inline-size:100%}:host([disabled]) ::slotted([calcite-hydrated][disabled]),:host([disabled]) [calcite-hydrated][disabled]{opacity:1}.interaction-container{display:contents}.container{display:flex;inline-size:100%}:host([scale=s]) .container{padding:var(--calcite-filter-content-space, var(--calcite-spacing-sm))}:host([scale=m]) .container{padding:var(--calcite-filter-content-space, var(--calcite-spacing-md))}:host([scale=l]) .container{padding:var(--calcite-filter-content-space, var(--calcite-spacing-lg))}label{position:relative;margin-block:0px;display:flex;inline-size:100%;align-items:center;overflow:hidden}calcite-input{inline-size:100%;--calcite-input-background-color: var(--calcite-filter-input-background-color);--calcite-input-border-color: var(--calcite-filter-input-border-color);--calcite-input-corner-radius: var(--calcite-filter-input-corner-radius);--calcite-input-shadow: var(--calcite-filter-input-shadow);--calcite-input-icon-color: var(--calcite-filter-input-icon-color);--calcite-input-text-color: var(--calcite-filter-input-text-color);--calcite-input-placeholder-text-color: var(--calcite-filter-input-placeholder-text-color);--calcite-input-actions-background-color: var(--calcite-filter-input-actions-background-color);--calcite-input-actions-background-color-hover: var(--calcite-filter-input-actions-background-color-hover);--calcite-input-actions-background-color-press: var(--calcite-filter-input-actions-background-color-press);--calcite-input-actions-icon-color: var(--calcite-filter-input-actions-icon-color);--calcite-input-actions-icon-color-hover: var(--calcite-filter-input-actions-icon-color-hover);--calcite-input-actions-icon-color-press: var(--calcite-filter-input-actions-icon-color-press)}:host([hidden]){display:none}[hidden]{display:none}`; class Filter extends LitElement { constructor() { super(...arguments); this.filterDebounced = debounce((value, emit = false, onFilter) => this.updateFiltered(filter(this.items ?? [], value, this.filterProps), emit, onFilter), DEBOUNCE.filter); this.textInput = createRef(); this._value = ""; this.messages = useT9n(); this.disabled = false; this.filteredItems = []; this.items = []; this.scale = "m"; this.calciteFilterChange = createEvent({ cancelable: false }); } static { this.properties = { disabled: [7, {}, { reflect: true, type: Boolean }], filterProps: [0, {}, { attribute: false }], filteredItems: [0, {}, { attribute: false }], items: [0, {}, { attribute: false }], label: 1, messageOverrides: [0, {}, { attribute: false }], placeholder: 1, scale: [3, {}, { reflect: true }], value: 1 }; } static { this.shadowRootOptions = { mode: "open", delegatesFocus: true }; } static { this.styles = styles; } get value() { return this._value; } set value(value) { const oldValue = this._value; if (value !== oldValue) { this._value = value; this.valueHandler(value); } } async filter(value = this.value) { return new Promise((resolve) => { this.value = value; this.updateFiltered(filter(this.items ?? [], value, this.filterProps), false, resolve); }); } async setFocus() { await componentFocusable(this); return this.textInput.value?.setFocus(); } async load() { this.updateFiltered(filter(this.items ?? [], this.value, this.filterProps)); } willUpdate(changes) { if (changes.has("items") && (this.hasUpdated || this.items?.length > 0) || changes.has("filterProps")) { this.filterDebounced(this.value); } } updated() { updateHostInteraction(this); } disconnectedCallback() { super.disconnectedCallback(); this.filterDebounced.cancel(); } valueHandler(value) { this.filterDebounced(value); } inputHandler(event) { const target = event.target; this.value = target.value; this.filterDebounced(target.value, true); } keyDownHandler(event) { if (event.defaultPrevented) { return; } if (event.key === "Escape") { this.clear(); event.preventDefault(); } if (event.key === "Enter") { event.preventDefault(); } } clear() { this.value = ""; this.filterDebounced("", true); this.setFocus(); } updateFiltered(filtered, emit = false, callback) { this.filteredItems = filtered; if (emit) { this.calciteFilterChange.emit(); } callback?.(); } render() { const { disabled, scale } = this; return InteractiveContainer({ disabled, children: html`<div class=${safeClassMap(CSS.container)}><label><calcite-input clearable .disabled=${disabled} .icon=${ICONS.search} .label=${this.label ?? this.messages.label} .messageOverrides=${{ clear: this.messages.clear }} @keydown=${this.keyDownHandler} @calciteInputInput=${this.inputHandler} .placeholder=${this.placeholder} .scale=${scale} type=text .value=${this.value} ${ref(this.textInput)}></calcite-input></label></div>` }); } } customElement("calcite-filter", Filter); export { Filter };