dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
259 lines (258 loc) • 8.95 kB
JavaScript
import { clsx as m } from "../../node_modules/clsx/dist/clsx.js";
import "../../node_modules/@lit/reactive-element/reactive-element.js";
import { nothing as b } from "../../node_modules/lit-html/lit-html.js";
import "../../node_modules/lit-element/lit-element.js";
import { property as r } from "../../node_modules/@lit/reactive-element/decorators/property.js";
import { query as y } from "../../node_modules/@lit/reactive-element/decorators/query.js";
import { ifDefined as s } from "../../node_modules/lit-html/directives/if-defined.js";
import { unsafeStatic as f, html as h } from "../../node_modules/lit-html/static.js";
import { GenericFormElement as v } from "../../internal/mixin/genericFormElement.js";
import "../../localization/localization.js";
import L from "../icon/icon.component.js";
import $ from "../icons/system/system-loading-spinner/system-loading-spinner.component.js";
import T from "./_styles/button.scss.js";
import { buttonVariants as x } from "./button.variants.js";
import { t as c } from "../../node_modules/i18next/dist/esm/i18next.js";
import { unsafeCSS as _ } from "../../node_modules/@lit/reactive-element/css-tag.js";
var k = Object.defineProperty, a = (p, t, i, n) => {
for (var o = void 0, d = p.length - 1, u; d >= 0; d--)
(u = p[d]) && (o = u(t, i, o) || o);
return o && k(t, i, o), o;
};
const g = {
lg: 24,
md: 20,
sm: 16,
xs: 16
}, l = class l extends v {
constructor() {
super(...arguments), this.variant = "primary", this.size = "md", this.loading = !1, this.danger = !1, this.shape = "button", this.htmlType = "button", this.target = "_self", this.loadingTimeout = 0, this.hc = !1, this.active = !1, this.oklchPoc = !1, this._ariaLabelForButton = null, this._ignoreNextAriaLabelChange = !1;
}
getSecureRel() {
var t, i;
return this.target === "_blank" ? (t = this.rel) != null ? t : "noreferrer noopener" : (i = this.rel) != null ? i : "";
}
validateAriaPressed() {
if (this.ariaPressed && !["true", "false", "mixed"].includes(this.ariaPressed)) {
console.warn('aria-pressed must be "true", "false", or "mixed"');
return;
}
return this.ariaPressed;
}
getAriaExpanded() {
if (this.ariaExpanded && !["true", "false"].includes(this.ariaExpanded)) {
console.warn('aria-expanded must be "true" or "false"');
return;
}
return this.ariaExpanded;
}
validateProperties() {
var t;
this.shape === "circle" && !this.effectiveAriaLabel && !((t = this.textContent) != null && t.trim()) && !this.ariaHidden && console.warn(
"Circle buttons require aria-label or visible text for accessibility"
), this.href && this.htmlType !== "button" && console.warn(
"htmlType is ignored when href is provided - button will render as anchor"
), this.href && !this.isValidUrl(this.href) && console.warn("Invalid URL provided for href attribute");
}
isValidUrl(t) {
try {
return t.startsWith("/") || t.startsWith("./") || t.startsWith("../") || new URL(t), !0;
} catch (i) {
return !1;
}
}
handleClick(t) {
if (this.disabled || this.loading)
return t.preventDefault(), t.stopPropagation(), !1;
let i = !1;
if (this.htmlType !== "button") {
const n = document.createElement("button");
n.type = this.htmlType, this.insertAdjacentElement("afterend", n), n.click(), n.remove(), i = !0;
}
return this.hc && this.toggleHighContrast(), i;
}
handleKeyDown(t) {
if (this.href && (t.key === " " || t.key === "Enter")) {
if (this.disabled || this.loading) {
t.preventDefault(), t.stopPropagation();
return;
}
t.key === " " && (t.preventDefault(), t.stopPropagation(), this.button.click());
}
}
toggleHighContrast() {
document.body.classList.toggle("high-contrast-theme");
}
startLoadingTimeout() {
this.loadingTimeout > 0 && (this.loadingTimer = window.setTimeout(() => {
this.loading = !1, this.emit(
"dds-loading-timeout",
{
timeout: this.loadingTimeout
},
{
bubbles: !0
}
);
}, this.loadingTimeout));
}
clearLoadingTimeout() {
this.loadingTimer && (clearTimeout(this.loadingTimer), this.loadingTimer = void 0);
}
/**
* `this.button` is a `@query`, so it is null until Lit has rendered the shadow root.
* A caller focusing a button the same tick it mounts -- a "Save" button that appears
* only after the form it belongs to opens, say -- would otherwise get a TypeError,
* not a no-op. Throwing out of a focus() call breaks whatever effect made it.
*/
focus(t) {
var i;
(i = this.button) == null || i.focus(t);
}
blur() {
var t;
(t = this.button) == null || t.blur();
}
/**
* @ignore
*/
get focusElement() {
return this.button;
}
/** Aria-label for the inner button; survives host attribute removal so Lit does not clear it */
get effectiveAriaLabel() {
var t;
return (t = this.ariaLabel) != null ? t : this._ariaLabelForButton;
}
updated(t) {
if (super.updated(t), t.has("ariaLabel")) {
const i = this.ariaLabel;
i != null && i !== "" ? this._ariaLabelForButton = i : this._ignoreNextAriaLabelChange || (this._ariaLabelForButton = null), this._ignoreNextAriaLabelChange = !1;
}
this.ariaLabel != null && this.ariaLabel !== "" && (this._ignoreNextAriaLabelChange = !0, this.removeAttribute("aria-label")), t.has("loading") && (this.loading ? this.startLoadingTimeout() : this.clearLoadingTimeout());
}
firstUpdated(t) {
super.firstUpdated(t), this.validateProperties();
}
disconnectedCallback() {
super.disconnectedCallback(), this.clearLoadingTimeout();
}
render() {
var t;
return h`
<${f(this.href ? "a" : "button")}
part="base"
.disabled=${this.disabled}
aria-disabled=${this.disabled}
aria-hidden=${s(this.ariaHidden)}
aria-expanded=${s(this.getAriaExpanded())}
aria-controls=${s(this.ariaControls)}
aria-label=${s(this.effectiveAriaLabel)}
aria-haspopup=${s(this.ariaHasPopup)}
aria-describedby=${s(this.ariaDescribedBy)}
aria-pressed=${s(this.validateAriaPressed())}
role=${s(this.forceRole)}
.autofocus=${this.autofocus}
tabindex=${s(this.href && this.disabled ? "-1" : void 0)}
type=${s(this.href ? null : this.htmlType)}
name=${s(this.name)}
href=${s(this.href)}
target=${s(this.target)}
rel=${s(this.getSecureRel())}
class=${m(
x({
intent: this.variant,
size: this.effectiveSize,
shape: this.shape
}),
{
"dds-button--danger": this.danger,
"dds-button--loading": this.loading,
"dds-button--active": this.active,
// An anchor never reflects a disabled attribute, so the [disabled]
// styling cannot reach it. Style off the class, as link--disabled does.
"button--disabled": this.disabled
}
)}
=${this.handleClick}
=${this.handleKeyDown}>
<div part="high-contrast" class="button__highcontrast"></div>
${this.loading ? this._getLoadingSpinner() : h` <span part="content" class="button__text">
<slot></slot>
</span>`}
${this.target === "_blank" ? h`<span class="sr-only">
${(t = this.targetBlankText) != null ? t : c("opensInNewTab")}</span
>` : b}
</${f(this.href ? "a" : "button")}>
`;
}
getLoadingIconSize(t) {
return g[t] || g.md;
}
_getLoadingSpinner() {
return h`
<span class="button__spinner" aria-live="polite">
<dap-ds-icon-loading-spinner
size=${this.getLoadingIconSize(this.effectiveSize)}
aria-label=${c("loading")}></dap-ds-icon-loading-spinner>
</span>
`;
}
};
l.tagName = "dap-ds-button", l.dependencies = {
"dap-ds-icon": L,
"dap-ds-icon-loading-spinner": $
}, l.styles = _(T);
let e = l;
a([
y(".button")
], e.prototype, "button");
a([
r({ reflect: !0 })
], e.prototype, "variant");
a([
r({ reflect: !0 })
], e.prototype, "size");
a([
r({ type: Boolean, reflect: !0 })
], e.prototype, "loading");
a([
r({ type: Boolean })
], e.prototype, "danger");
a([
r({ reflect: !0 })
], e.prototype, "shape");
a([
r()
], e.prototype, "htmlType");
a([
r()
], e.prototype, "href");
a([
r()
], e.prototype, "target");
a([
r()
], e.prototype, "rel");
a([
r({ type: Number })
], e.prototype, "loadingTimeout");
a([
r({ type: Boolean })
], e.prototype, "hc");
a([
r({ type: Boolean })
], e.prototype, "active");
a([
r({ type: Boolean, attribute: "data-oklch-poc", reflect: !0 })
], e.prototype, "oklchPoc");
a([
r({ type: String })
], e.prototype, "targetBlankText");
a([
r({ type: String })
], e.prototype, "forceRole");
export {
e as default
};
//# sourceMappingURL=button.component.js.map