dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
266 lines (264 loc) • 10.7 kB
JavaScript
import { clsx as o } 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 l } from "../../node_modules/@lit/reactive-element/decorators/property.js";
import { query as b } from "../../node_modules/@lit/reactive-element/decorators/query.js";
import { ifDefined as d } from "../../node_modules/lit-html/directives/if-defined.js";
import { html as h } from "../../node_modules/lit-html/static.js";
import { LabeledChoiceElement as y } from "../../internal/mixin/labeledChoiceElement.js";
import f from "../feedback/feedback.component.js";
import m from "../form/form-label/form-label.component.js";
import k from "../typography/typography.component.js";
import v from "./_styles/radio-button.scss.js";
import { unsafeCSS as $ } from "../../node_modules/@lit/reactive-element/css-tag.js";
var _ = Object.defineProperty, n = (p, e, t, a) => {
for (var s = void 0, c = p.length - 1, u; c >= 0; c--)
(u = p[c]) && (s = u(e, t, s) || s);
return s && _(e, t, s), s;
};
const I = typeof ElementInternals != "undefined" && "ariaDescription" in ElementInternals.prototype;
var i;
const r = (i = class extends y {
constructor() {
super(), this.focusable = !1, this.preventDefault = !1, this.readonly = !1, this.border = !1, this.type = "normal", this._onHostKeydown = (t) => {
t.key === "Enter" && (t.preventDefault(), HTMLElement.prototype.click.apply(this));
}, i.nextId++;
const e = typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID().slice(0, 8) : Date.now().toString(36);
this.inputId = `input-${i.nextId}-${e}`, this.labelId = `label-${i.nextId}-${e}`, this.descriptionId = `description-${i.nextId}-${e}`, this.feedbackId = `feedback-${i.nextId}-${e}`, this.internals.role = "radio";
}
connectedCallback() {
super.connectedCallback(), this.setAttribute("role", "radio"), this.addEventListener("focus", this.onFocus), this.addEventListener("blur", this.onBlur), this.addEventListener("keydown", this._onHostKeydown);
}
disconnectedCallback() {
super.disconnectedCallback(), this.removeEventListener("focus", this.onFocus), this.removeEventListener("blur", this.onBlur), this.removeEventListener("keydown", this._onHostKeydown);
}
_syncHostAria() {
const e = this.checked ? "true" : "false";
this.internals.ariaChecked = e, this.setAttribute("aria-checked", e), this.posInSet != null ? this.setAttribute("aria-posinset", String(this.posInSet)) : this.removeAttribute("aria-posinset"), this.setSize != null ? this.setAttribute("aria-setsize", String(this.setSize)) : this.removeAttribute("aria-setsize"), this.internals.ariaPosInSet = this.posInSet != null ? String(this.posInSet) : null, this.internals.ariaSetSize = this.setSize != null ? String(this.setSize) : null, this.internals.ariaDisabled = this.disabled ? "true" : null, this.internals.ariaRequired = this.required ? "true" : null;
let t;
I ? (this.internals.ariaLabel = this.label || null, this.internals.ariaDescription = this.description || null, t = this.label || "") : (t = [this.label, this.description].filter(Boolean).join(". "), this.internals.ariaLabel = t || null), t ? this.setAttribute("aria-label", t) : this.removeAttribute("aria-label");
const a = (this.focusable || this.checked) && !this.disabled;
this.setAttribute("tabindex", a ? "0" : "-1");
}
/**
* Handles click events on the radio button.
* Manages the checked state and emits change events.
* @private
*/
handleClick() {
if (this.preventDefault || this.disabled || this.readonly)
return;
this.checked = !0;
const { checked: e, value: t, disabled: a } = this;
try {
this.emit("dds-change", {
checked: e,
// `?? ''` not `|| ''` — a radio may legitimately carry `false` or `0`
value: t != null ? t : "",
disabled: a,
readonly: this.readonly,
type: "radio"
});
} catch (s) {
console.error("Error emitting radio button change event:", s);
}
try {
this.setValidity();
} catch (s) {
console.error("Error setting radio button validity:", s);
}
}
formResetCallback() {
this.internals.setValidity({}), this.internals.setFormValue(this.defaultValue), this.value = this.defaultValue, this.checked = this.defaultValue === this.value;
}
/**
* Handles input events on the radio button.
* Emits the dds-input event with current radio button state.
* @private
*/
handleInput() {
const { checked: e, value: t, disabled: a } = this, s = new CustomEvent("dds-input", {
bubbles: !0,
cancelable: !1,
composed: !0,
detail: { checked: e, value: t, disabled: a, readonly: this.readonly }
});
this.dispatchEvent(s);
}
get focusElement() {
if (!this.input)
throw new Error(
"Radio button input element not found. Component may not be properly initialized."
);
return this.input;
}
focus() {
!this.disabled && !this.readonly && HTMLElement.prototype.focus.apply(this);
}
blur() {
HTMLElement.prototype.blur.apply(this);
}
/**
* Handles invalid events on the radio button input.
* Prevents the default browser validation UI from showing and manages invalid state.
* @param {Event} event - The invalid event
* @private
*/
handleInvalid(e) {
e.preventDefault(), this.invalid || (this.invalid = !0);
}
updated(e) {
if (super.updated(e), this._syncHostAria(), !(this.closest("dap-ds-radio-group") !== null) && (e.has("required") || e.has("checked") || e.has("disabled")) && this.innerInput && this.innerInput instanceof HTMLInputElement) {
const a = !this.innerInput.checkValidity();
this.invalid !== a && (this.invalid = a);
}
}
render() {
return h`
<div part="base">
<label
part="base-label"
class=${o("radio choice", `radio--${this.size}`, {
"radio--checked": this.checked,
"radio--disabled": this.disabled,
"radio--readonly": this.readonly,
"radio--required": this.required,
"choice--readonly": this.readonly,
"choice--disabled": this.disabled,
"choice__label--right": this.labelPlacement === "right",
"choice__label--left": this.labelPlacement === "left"
})}>
<div
part="wrapper"
class=${o("input__wrapper", {
"input__wrapper--background": this.type === "background",
"input__wrapper--border": this.border
})}>
<input
part="input"
type="radio"
class=${o("radio__input", {
"radio__input--background": this.type === "background"
})}
id=${this.inputId}
value=${d(this.value)}
.checked=${this.checked}
.disabled=${this.disabled}
.required=${this.required}
?readonly=${this.readonly}
tabindex="-1"
aria-hidden="true"
aria-checked=${this.checked ? "true" : "false"}
=${this.handleInvalid}
=${this.handleClick}
=${this.handleInput} />
<span
part="control"
class=${o("input__control", {
"input__control--disabled": this.disabled,
"input__control--readonly": this.readonly,
"input__control--invalid": this.invalid,
"input__control--checked": this.checked
})}>
<slot name="iconcontent">
<span class="radio__icon"></span>
</slot>
<span
part="high-contrast"
class=${o(
"input__control-high-contrast",
`input__control-high-contrast--${this.size}`,
{
"input__control-high-contrast--disabled": this.disabled,
"input__control-high-contrast--readonly": this.readonly
}
)}></span>
</span>
<div
part="label-container"
class=${o("choice__label-container", {
"choice__label-container--disabled": this.disabled,
"choice__label-container--readonly": this.readonly,
"choice__label--bottom": this.descriptionPlacement === "top",
"choice__label--top": this.descriptionPlacement === "bottom"
})}>
${this.label && h`<dap-ds-form-label
id=${this.labelId}
class="label"
part="label"
.size=${this.size}
.required=${this.required}
.requiredLabel=${this.requiredLabel}
.optional=${this.optional}
.optionalLabel=${this.optionalLabel}
aria-hidden="true"
.disabled=${this.disabled || this.readonly}
.readonly=${this.readonly}
.hideLabel=${this.hideLabel}
label=${d(this.label)}
subtle
.noMargin=${!0}
renderAs="span">
</dap-ds-form-label>`}
${this.description && h`
<dap-ds-typography
class="description"
variant="description"
part="description"
aria-hidden="true"
size=${d(this.size)}
id=${this.descriptionId}>
${this.description}
</dap-ds-typography>
`}
</div>
</div>
${this.feedback && h`
<dap-ds-feedback
part="feedback"
feedbackType=${d(this.feedbackType)}
feedbackSize=${d(this.size)}
id="feedback"
.subtle=${this.subtle}>
${this.feedback}
</dap-ds-feedback>
`}
</label>
</div>
`;
}
}, i.tagName = "dap-ds-radio-button", i.dependencies = {
"dap-ds-form-label": m,
"dap-ds-typography": k,
"dap-ds-feedback": f
}, i.nextId = 0, i.styles = $(v), i);
n([
b(".radio__input")
], r.prototype, "input");
n([
l({ type: Boolean })
], r.prototype, "focusable");
n([
l({ type: Number })
], r.prototype, "posInSet");
n([
l({ type: Number })
], r.prototype, "setSize");
n([
l({ type: Boolean, reflect: !0 })
], r.prototype, "preventDefault");
n([
l({ type: Boolean, reflect: !0 })
], r.prototype, "readonly");
n([
l({ type: Boolean })
], r.prototype, "border");
n([
l({ type: String })
], r.prototype, "type");
let P = r;
export {
P as default
};
//# sourceMappingURL=radio-button.component.js.map