dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
439 lines (438 loc) • 16.8 kB
JavaScript
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