UNPKG

dap-design-system

Version:

Official design system for the DÁP (dap.gov.hu)

439 lines (438 loc) 16.8 kB
var f = (u, e, t) => new Promise((n, a) => { var p = (r) => { try { b(t.next(r)); } catch (y) { a(y); } }, m = (r) => { try { b(t.throw(r)); } catch (y) { a(y); } }, b = (r) => r.done ? n(r.value) : Promise.resolve(r.value).then(p, m); b((t = t.apply(u, e)).next()); }); import { clsx as h } from "../../node_modules/clsx/dist/clsx.js"; import "../../node_modules/@lit/reactive-element/reactive-element.js"; import "../../node_modules/lit-html/lit-html.js"; import "../../node_modules/lit-element/lit-element.js"; import { property as d } from "../../node_modules/@lit/reactive-element/decorators/property.js"; import { state as $ } from "../../node_modules/@lit/reactive-element/decorators/state.js"; import { query as v } from "../../node_modules/@lit/reactive-element/decorators/query.js"; import { ifDefined as s } from "../../node_modules/lit-html/directives/if-defined.js"; import { html as i } from "../../node_modules/lit-html/static.js"; import { getValidityStateObject as D } from "../../common/utils.js"; import { GenericFormElement as w } from "../../internal/mixin/genericFormElement.js"; import "../../localization/localization.js"; import k from "../feedback/feedback.component.js"; import S from "../form/form-label/form-label.component.js"; import A from "../icon/icon.component.js"; import L from "../icon-button/icon-button.component.js"; import C from "../icons/arrows/arrows-arrow-down-s-line/arrows-arrow-down-s-line.component.js"; import I from "../icons/system/system-loading-spinner/system-loading-spinner.component.js"; import x from "../option-list/option-list.component.js"; import V from "../popup/popup.component.js"; import O from "../tooltip/tooltip.component.js"; import B from "../tray/tray.component.js"; import T from "../typography/typography.component.js"; import q from "./select.scss.js"; import g, { t as N } from "../../node_modules/i18next/dist/esm/i18next.js"; import { unsafeCSS as z } from "../../node_modules/@lit/reactive-element/css-tag.js"; var M = Object.defineProperty, l = (u, e, t, n) => { for (var a = void 0, p = u.length - 1, m; p >= 0; p--) (m = u[p]) && (a = m(e, t, a) || a); return a && M(e, t, a), a; }; const c = class c extends w { constructor() { super(...arguments), this.placement = "bottom-start", this.opened = !1, this.isMobile = !1, this.native = !1, this.loading = !1, this.noAnimation = !1, this.floatingStrategy = "absolute", this.disableViewportAutoClose = !1, this.languageChangeHandler = () => { this.requestUpdate(); }, this.handleClick = () => { this.readonly || this.disabled || (this.opened ? this.hideDropDown() : this.showDropDown()); }, this.handleKeyDown = (e) => f(this, null, function* () { if (!(e.key === "Tab" || e.key === "Shift") && !this.readonly) { if (e.preventDefault(), e.key === "Enter" || e.key === " ") return this.opened ? this.hideDropDown() : this.showDropDown(); if (e.key === "Escape") return this.hideDropDown(), this.focus(); if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "ArrowLeft" || e.key === "ArrowRight") return this.opened ? void 0 : this.showDropDown(); this.emit("dds-keydown", e), this.showDropDown(e.key); } }), this.handleListKeyDown = (e) => { e.detail.key === "Escape" && this.hideDropDown(); }, this.handleDocumentMouseDown = (e) => { const t = e.composedPath(); this && !t.includes(this) && this.hideDropDown(); }, this.handlePopupAutoClose = () => { this.hideDropDown({ skipFocus: !0 }); }, this.handleFocus = () => { this.emit("dds-focus"); }, this.handleBlur = () => { this.emit("dds-blur"); }, this.handleSelectedChange = (e) => { const t = Object.keys(e.detail).length ? e.detail : null, n = t == null ? void 0 : t.value, a = n !== this.value; this.selectedItem = t, this.hideDropDown(), this.value = n, a && this.emit("dds-change", this.selectedItem), this.setValidity(); }, this.handleOptionDeselect = () => { this.selectedItem = null, this.value = void 0, this.emit("dds-change", null), this.setValidity(); }, this.handleNativeChange = (e) => { const n = e.target.value, a = this.querySelector( `dap-ds-option-item[value="${n}"]` ); this.value = n, this.selectedItem = a ? { value: n, text: a.optionText } : { value: n, text: n }, this.emit("dds-change", this.selectedItem), this.setValidity(); }; } connectedCallback() { super.connectedCallback(), g.on("languageChanged", this.languageChangeHandler), this.addEventListener("invalid", this.handleInvalid); } disconnectedCallback() { super.disconnectedCallback(), g.off("languageChanged", this.languageChangeHandler), this.removeEventListener("invalid", this.handleInvalid); } /** * Lifecycle method to handle property changes */ updated(e) { if (super.updated(e), e.has("value")) { const t = this.value; t == null && this.selectedItem !== null && (this.selectedItem = null, this.setValidity()); } } formResetCallback() { this.internals.setValidity({}), this.internals.setFormValue(this.defaultValue), this.value = this.defaultValue, this.selectedItem = this.defaultValue; } showDropDown(e) { return f(this, null, function* () { this.opened || (this.opened = !0, document.addEventListener("mousedown", this.handleDocumentMouseDown), yield this.updateComplete, this.optionList.captureFocus(e), yield this.updateComplete, this.emit("dds-opened")); }); } hideDropDown(e) { return f(this, null, function* () { this.opened && (this.opened = !1, document.removeEventListener("mousedown", this.handleDocumentMouseDown), yield this.updateComplete, this.optionList.removeFocus(), e != null && e.skipFocus || this.focus(), this.emit("dds-closed")); }); } get focusElement() { return this.triggerButton; } /** * Get the active descendant element for aria-activedescendant * Returns the currently focused option when dropdown is open, otherwise null */ getActiveDescendant() { var t; return this.opened ? (t = this.optionList) == null ? void 0 : t.getActiveOption() : null; } /** * Get the aria-describedby value, combining description and feedback IDs */ getAriaDescribedBy() { const e = []; return this.description && e.push("description"), this.feedback && e.push("feedback"), e.length > 0 ? e.join(" ") : void 0; } // custom validation get validity() { return this.internals.validity ? this.internals.validity : D({ valueMissing: this.required && (!this.selectedItem || this.selectedItem.value === "" || this.value === "" || this.value === void 0 || this.value === null) }); } get validationMessage() { return N("form.validationMessage.select"); } /** Get the current display text for the selected item, dynamically fetching from the option */ get selectedDisplayText() { if (!this.selectedItem) return null; if (this.optionList) { const e = Array.from( this.optionList.querySelectorAll("dap-ds-option-item") ).find((t) => t.value === this.selectedItem.value); if (e) return e.optionText; } return this.selectedItem.text; } checkValidity() { const e = !!this.selectedItem && this.selectedItem.value !== "" && this.value !== "" && this.value !== void 0 && this.value !== null; return this.required ? e : !0; } reportValidity() { return this.required ? this.checkValidity() : !0; } setValidity() { this.checkValidity() ? this.internals.setValidity({}) : this.internals.setValidity( { valueMissing: this.required && (!this.selectedItem || this.selectedItem.value === "" || this.value === "" || this.value === void 0 || this.value === null) }, this.validationMessage, this.triggerButton ); } handleInvalid(e) { e.preventDefault(), this.focus(); } renderNativeOption(e) { return i` <option value=${e.value || ""} ?disabled=${e.disabled} ?selected=${e.value === this.value}> ${e.optionText} </option> `; } renderNativeOptgroup(e) { const t = Array.from( e.querySelectorAll("dap-ds-option-item") ); return i` <optgroup label=${e.label || ""} ?disabled=${e.disabled}> ${t.map((n) => this.renderNativeOption(n))} </optgroup> `; } renderNativeOptions() { return Array.from(this.children).map((t) => t.tagName === "DAP-DS-OPTION-GROUP" ? this.renderNativeOptgroup(t) : t.tagName === "DAP-DS-OPTION-ITEM" ? this.renderNativeOption(t) : ""); } renderNativeSelect() { return i` <div class="select-wrapper--native"> <select class="${h("select", `select--${this.effectiveSize}`, { "select--disabled": this.disabled, "select--readonly": this.readonly, "select--success": this.status === "success", "select--error": this.status === "error", "select--loading": this.loading })}" part="trigger" aria-labelledby=${s(this.label ? "label" : void 0)} aria-describedby=${s(this.getAriaDescribedBy())} ?disabled=${this.disabled} ?required=${this.required} @change=${this.handleNativeChange} @focus=${this.handleFocus} @blur=${this.handleBlur}> ${this.placeholder ? i`<option value="" disabled ?selected=${!this.value}> ${this.placeholder} </option>` : ""} ${this.renderNativeOptions()} </select> <div class="icon" part="indicator-icon"> ${this.loading ? i`<dap-ds-icon-loading-spinner></dap-ds-icon-loading-spinner>` : i`<slot name="indicator-icon" ><dap-ds-icon-arrow-down-s-line></dap-ds-icon-arrow-down-s-line ></slot>`} </div> </div> `; } renderTriggerElement() { var e; return i` <button slot="trigger" part="trigger" role="combobox" class="${h("select", `select--${this.effectiveSize}`, { "select--disabled": this.disabled, "select--readonly": this.readonly, "select--opened": this.opened, "select--loading": this.loading, "select--success": this.status === "success", "select--error": this.status === "error", "select--no-animation": this.noAnimation, "select--optional": this.optional })}" aria-expanded=${this.readonly || this.disabled ? "false" : this.opened ? "true" : "false"} aria-haspopup=${s( this.readonly || this.disabled ? void 0 : "listbox" )} aria-labelledby=${s(this.label ? "label" : void 0)} aria-label=${s( this.label ? void 0 : this.ariaLabel || this.selectedDisplayText || this.placeholder || void 0 )} aria-describedby=${s(this.getAriaDescribedBy())} aria-disabled=${this.disabled} aria-controls="option-list" aria-activedescendant=${s((e = this.getActiveDescendant()) == null ? void 0 : e.id)} ?required=${this.required} ?readonly=${this.readonly} ?autofocus=${this.autofocus} ?disabled=${this.disabled} tabindex=${this.readonly || this.disabled ? -1 : 0} @blur=${this.handleBlur} @focus=${this.handleFocus} @keydown=${this.handleKeyDown} @click=${this.handleClick}> <span class="text">${this.selectedDisplayText || this.placeholder}</span> <div class="${h("icon", { "icon--opened": this.opened, "icon--no-animation": this.noAnimation })}" part="indicator-icon"> ${this.loading ? i`<dap-ds-icon-loading-spinner></dap-ds-icon-loading-spinner>` : i`<slot name="indicator-icon" ><dap-ds-icon-arrow-down-s-line></dap-ds-icon-arrow-down-s-line ></slot>`} </div> </button>`; } renderOptionList() { return i` <dap-ds-option-list class="option-list" part="option-list" exportparts="option-item, option-item-base, option-item-label, option-item-prefix, option-item-suffix" id="option-list" aria-labelledby=${s(this.label ? "label" : void 0)} searchMode="typehead" size=${s(this.effectiveSize)} value=${this.value} disableDelaySet @dds-option-change=${this.handleSelectedChange} @dds-keydown=${this.handleListKeyDown} @dds-option-deselect=${this.handleOptionDeselect}> <slot></slot> </dap-ds-option-list>`; } render() { return i` <div class="label-container"> ${this.label && i`<dap-ds-form-label part="label" id="label" .size=${this.effectiveSize} .required=${this.required} .requiredLabel=${this.requiredLabel} .optional=${this.optional} .optionalLabel=${this.optionalLabel} .subtle=${this.subtle} .disabled=${this.disabled} class=${h("label")} .noMargin=${!!this.description} for="input" .hideLabel=${this.hideLabel} label=${s(this.label)}> </dap-ds-form-label>`} ${this.tooltip && i` <dap-ds-tooltip part="tooltip" content=${this.tooltip} mode="toggle" placement=${this.tooltipPlacement}> <dap-ds-icon-button clean slot="trigger" size=${this.effectiveSize} iconSize=${this.effectiveSize === "xs" ? "16" : "22"} aria-label=${this.tooltipAriaLabel} class="input-group__toggle-button"> <dap-ds-icon name="information-line" class="info-button"></dap-ds-icon> </dap-ds-icon-button> </dap-ds-tooltip>`} </div> ${this.description && i` <dap-ds-typography part="description" variant="description" class=${h("input-description")} size=${s(this.effectiveSize)} id="description"> ${this.description} </dap-ds-typography> `} <div> ${this.native ? this.renderNativeSelect() : this.isMobile ? i` ${this.renderTriggerElement()} <dap-ds-tray part="mobile-tray" exportparts="content: mobile-content, body: mobile-body, header: mobile-header, footer: mobile-footer" ?open=${this.opened} closeButton="false" header="false" >${this.renderOptionList()}</dap-ds-tray > ` : i`<dap-ds-popup floatingStrategy=${s(this.floatingStrategy)} part="base" exportparts="popup:popup-base" class="select-popup" ?opened=${this.opened} ?hasArrow=${!1} overflow placement=${this.placement} maxHeight=${s(this.maxHeight)} ?sync=${this.sync} ?disableViewportAutoClose=${this.disableViewportAutoClose} @dds-close=${this.handlePopupAutoClose} size=${s(this.effectiveSize)}> ${this.renderTriggerElement()} ${this.renderOptionList()} </dap-ds-popup>`} ${this.feedback && i`<dap-ds-feedback part="feedback" feedbackType=${s(this.feedbackType)} feedbackSize="${s(this.effectiveSize)}" id="feedback" .subtle=${this.subtle}> ${this.feedback} </dap-ds-feedback>`} </div>`; } }; c.tagName = "dap-ds-select", c.dependencies = { "dap-ds-icon-loading-spinner": I, "dap-ds-icon-arrow-down-s-line": C, "dap-ds-option-list": x, "dap-ds-form-label": S, "dap-ds-tooltip": O, "dap-ds-icon-button": L, "dap-ds-icon": A, "dap-ds-typography": T, "dap-ds-popup": V, "dap-ds-tray": B, "dap-ds-feedback": k }, c.styles = z(q); let o = c; l([ v("button") ], o.prototype, "triggerButton"); l([ v("dap-ds-option-list") ], o.prototype, "optionList"); l([ d({ reflect: !0 }) ], o.prototype, "placement"); l([ d({ type: Boolean, reflect: !0 }) ], o.prototype, "opened"); l([ d() ], o.prototype, "placeholder"); l([ d({ type: Boolean }) ], o.prototype, "sync"); l([ d({ type: Boolean }) ], o.prototype, "isMobile"); l([ d({ type: Boolean }) ], o.prototype, "native"); l([ d({ type: Boolean }) ], o.prototype, "loading"); l([ d({ type: Number }) ], o.prototype, "maxHeight"); l([ d({ type: Boolean }) ], o.prototype, "noAnimation"); l([ d({ reflect: !0 }) ], o.prototype, "floatingStrategy"); l([ d({ type: Boolean }) ], o.prototype, "disableViewportAutoClose"); l([ $() ], o.prototype, "selectedItem"); export { o as default }; //# sourceMappingURL=select.component.js.map