dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
264 lines (263 loc) • 9.08 kB
JavaScript
import { clsx as v } 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 a } from "../../node_modules/@lit/reactive-element/decorators/property.js";
import { query as f } from "../../node_modules/@lit/reactive-element/decorators/query.js";
import { ifDefined as p } from "../../node_modules/lit-html/directives/if-defined.js";
import { html as s, unsafeStatic as u } from "../../node_modules/lit-html/static.js";
import { DdsElement as m } from "../../internal/dds-hu-element.js";
import { SizedMixin as b } from "../../internal/mixin/sizedMixin.js";
import "../../localization/localization.js";
import y from "./accordion.scss.js";
import { unsafeCSS as $ } from "../../node_modules/@lit/reactive-element/css-tag.js";
import { t as _ } from "../../node_modules/i18next/dist/esm/i18next.js";
var L = Object.defineProperty, I = Object.getOwnPropertyDescriptor, n = (h, e, t, d) => {
for (var r = d > 1 ? void 0 : d ? I(e, t) : e, c = h.length - 1, l; c >= 0; c--)
(l = h[c]) && (r = (d ? l(e, t, r) : l(r)) || r);
return d && r && L(e, t, r), r;
};
const g = [
"default",
"collapsed",
"clean",
"clean-collapsed"
], S = b(m);
var o;
const i = (o = class extends S {
constructor() {
super(), this._headingLevel = 4, this._variant = "default", this.opened = !1, this.disabled = !1, this.loading = !1, this.iconLocation = "right", this.lastItem = !1, this.handleKeyDown = (t) => {
this.disabled || this.loading || (t.key === "Enter" || t.key === " ") && (t.preventDefault(), this.toggle());
}, this.handleClick = (t) => {
if (this.disabled || this.loading) {
t.preventDefault();
return;
}
this.toggle();
}, o.nextId++;
const e = typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID().slice(0, 8) : Date.now().toString(36);
this.accordionId = `accordion-${o.nextId}-${e}`, this.buttonId = `${this.accordionId}-button`, this.contentId = `${this.accordionId}-content`;
}
/**
* The element that actually takes focus -- the toggle button inside the shadow root.
*
* Without this, `accordionElement.focus()` silently does nothing: the host has no
* tabindex and does not delegate focus, so a caller trying to move focus to an
* accordion header (after committing an inline edit, say) drops focus to <body>.
* Mirrors the `focusElement` contract that FocusableMixin defines and that
* dap-ds-modal's focus trap already looks for.
*/
get focusElement() {
var e;
return (e = this.button) != null ? e : this;
}
focus(e) {
const t = this.focusElement;
if (t === this) {
HTMLElement.prototype.focus.call(this, e);
return;
}
t.focus(e);
}
blur() {
const e = this.focusElement;
if (e === this) {
HTMLElement.prototype.blur.call(this);
return;
}
e.blur();
}
/** Display size for accordion styling (sm or lg); other effective sizes map to sm. */
get accordionDisplaySize() {
return this.effectiveSize === "lg" ? "lg" : "sm";
}
get headingLevel() {
return this._headingLevel;
}
set headingLevel(e) {
const t = this._headingLevel;
e < 1 || e > 6 ? (console.warn("headingLevel must be between 1 and 6, using default of 4"), this._headingLevel = 4) : this._headingLevel = e, this.requestUpdate("headingLevel", t);
}
get variant() {
return this._variant;
}
set variant(e) {
const t = this._variant;
g.includes(e) ? this._variant = e : (console.warn(`Invalid accordion variant: ${e}. Using default.`), this._variant = "default"), this.requestUpdate("variant", t);
}
/**
* Renders the heading content. Override in subclasses to customize heading rendering.
* @returns Template result for heading content
*/
headingRender() {
return s`<div>${this.heading}</div>`;
}
/**
* Renders additional content. Override in subclasses to add custom content.
* @returns Template result for additional content
*/
contentRender() {
return s`<div></div>`;
}
validateProperties() {
(this.headingLevel < 1 || this.headingLevel > 6) && console.warn("headingLevel must be between 1 and 6"), g.includes(this.variant) || console.warn(`Invalid accordion variant: ${this.variant}. Using default.`);
}
firstUpdated(e) {
super.firstUpdated(e), this.validateProperties();
}
onChange() {
const e = this.opened ? "dds-opened" : "dds-closed", t = {
open: this.opened,
item: this
};
this.emit(e, t);
}
toggle() {
this.disabled || this.loading || (this.opened = !this.opened, this.onChange());
}
get accordionClasses() {
return v("accordion", {
"accordion--opened": this.opened,
"accordion--disabled": this.disabled,
"accordion--loading": this.loading,
"accordion--sm": this.accordionDisplaySize === "sm",
"accordion--lg": this.accordionDisplaySize === "lg",
"accordion--icon-left": this.iconLocation === "left",
"accordion--icon-right": this.iconLocation === "right",
[`accordion--${this.variant}`]: this.variant,
"accordion--last-item": this.lastItem
});
}
renderIconOrSpinner() {
var e;
return this.loading ? s`
<span
class="accordion__loading"
role="status"
aria-live="polite"
aria-label="${(e = this.loadingAriaLabel) != null ? e : _("loading")}">
<dap-ds-icon-loading-spinner size="16"></dap-ds-icon-loading-spinner>
</span>
` : s`
<span
class="accordion__icon-wrapper"
aria-hidden="true"
part="icon-wrapper">
<slot name="icon-opened" class="accordion__icon-opened">
<dap-ds-icon
exportparts="icon:open-icon, base:open-icon-base"
size=${this.effectiveSize === "xxs" ? "xs" : this.effectiveSize}
name="arrow-up-s-line"
class="open-icon">
</dap-ds-icon>
</slot>
<slot name="icon-closed" class="accordion__icon-closed">
<dap-ds-icon
exportparts="icon:close-icon, base:close-icon-base"
size=${this.effectiveSize === "xxs" ? "xs" : this.effectiveSize}
name="arrow-down-s-line"
class="close-icon">
</dap-ds-icon>
</slot>
</span>
`;
}
renderButtons() {
var e, t;
return s`
<button
class="accordion__button"
type="button"
part="button"
id="${this.buttonId}"
aria-controls="${this.contentId}"
aria-expanded="${this.opened}"
aria-disabled="${this.disabled}"
aria-label=${p((e = this.ariaLabel) != null ? e : this.heading)}
aria-describedby=${p((t = this.ariaDescribedBy) != null ? t : void 0)}
?disabled=${this.disabled}
=${this.handleClick}
=${this.handleKeyDown}>
${this.renderIconOrSpinner()}
<span part="heading-text" class="accordion__heading-text">
<slot name="heading"> ${this.headingRender()} </slot>
</span>
</button>
`;
}
renderContent() {
return s`
<div
part="content"
class="accordion__content"
id="${this.contentId}"
aria-labelledby="${this.buttonId}"
role="region"
aria-hidden="${!this.opened}">
<div part="content-container" class="accordion-content__container">
<slot></slot>
${this.contentRender()}
</div>
</div>
`;
}
renderHeading() {
return s`
<div class="accordion__heading" part="heading">
<${u(`h${this.headingLevel}`)}
class="accordion__heading-content">
${this.renderButtons()}
</${u(`h${this.headingLevel}`)}>
</div>
`;
}
/**
* Renders the complete accordion component. Override in subclasses to customize the entire accordion structure.
* @returns Template result for the complete accordion
*/
renderAccordion() {
return s`
<div part="base" class=${this.accordionClasses}>
${this.renderHeading()} ${this.renderContent()}
</div>
`;
}
}, o.styles = $(y), o.nextId = 0, o);
n([
f('[part="button"]')
], i.prototype, "button", 2);
n([
f('[part="content"]')
], i.prototype, "content", 2);
n([
a({ type: Number })
], i.prototype, "headingLevel", 1);
n([
a({ type: Boolean, reflect: !0 })
], i.prototype, "opened", 2);
n([
a({ type: Boolean, reflect: !0 })
], i.prototype, "disabled", 2);
n([
a({ type: Boolean, reflect: !0 })
], i.prototype, "loading", 2);
n([
a({ type: String })
], i.prototype, "heading", 2);
n([
a({ type: String })
], i.prototype, "loadingAriaLabel", 2);
n([
a({ type: String })
], i.prototype, "iconLocation", 2);
n([
a({ type: String })
], i.prototype, "variant", 1);
n([
a({ type: Boolean })
], i.prototype, "lastItem", 2);
let N = i;
export {
N as AccordionBaseElement
};
//# sourceMappingURL=accordion-base-element.js.map