dap-design-system
Version:
Official design system for the DÁP (dap.gov.hu)
232 lines (231 loc) • 10.2 kB
JavaScript
var g = Object.getPrototypeOf;
var w = Reflect.get;
var c = (h, t, e) => w(g(h), e, t);
var m = (h, t, e) => new Promise((i, a) => {
var s = (r) => {
try {
o(e.next(r));
} catch (f) {
a(f);
}
}, l = (r) => {
try {
o(e.throw(r));
} catch (f) {
a(f);
}
}, o = (r) => r.done ? i(r.value) : Promise.resolve(r.value).then(s, l);
o((e = e.apply(h, t)).next());
});
import { clsx as y } 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 p } from "../../node_modules/@lit/reactive-element/decorators/property.js";
import { query as C } from "../../node_modules/@lit/reactive-element/decorators/query.js";
import { ifDefined as I } from "../../node_modules/lit-html/directives/if-defined.js";
import { html as A } from "../../node_modules/lit-html/static.js";
import { DdsElement as _ } from "../../internal/dds-hu-element.js";
import b from "./navigation-menu.scss.js";
import { unsafeCSS as D } from "../../node_modules/@lit/reactive-element/css-tag.js";
var k = Object.defineProperty, u = (h, t, e, i) => {
for (var a = void 0, s = h.length - 1, l; s >= 0; s--)
(l = h[s]) && (a = l(t, e, a) || a);
return a && k(t, e, a), a;
};
const d = class d extends _ {
constructor() {
super(...arguments), this.orientation = "horizontal", this.fullWidth = !1, this.allowMultipleOpen = !0, this.tabMode = "group", this._handleNavigationItemClick = (t) => {
const e = t;
this.emit("dds-navigation-item-click", e.detail);
}, this._handleDropdownOpen = (t) => {
if (this.allowMultipleOpen)
return;
const e = t.target, i = e.parentElement;
((i == null ? void 0 : i.querySelectorAll(":scope > dap-ds-navigation-menu-item")) || []).forEach((s) => {
s !== e && s.opened && s.hideDropDown();
});
}, this._handleSlotChange = () => {
this.handleSlotChange();
}, this._handleFocusIn = (t) => {
if (this.tabMode !== "items") return;
const e = t.target, a = this.getAllItems().find(
(s) => s === e || s.contains(e)
);
a && this.setCurrentItem(a);
};
}
connectedCallback() {
super.connectedCallback(), this.activeHref || (this.activeHref = window.location.pathname);
}
updated(t) {
super.updated(t), t.has("activeHref") && this._updateActiveHref(), t.has("fullWidth") && this._updateChildFullWidth(), t.has("orientation") && this._updateOrientation(), t.has("tabMode") && (this._applyTabMode(), this._updateTabMode());
}
firstUpdated(t) {
return m(this, null, function* () {
c(d.prototype, this, "firstUpdated").call(this, t), this._updateChildFullWidth(), this._updateOrientation(), yield this.updateComplete, requestAnimationFrame(() => {
this._handleSlotChange();
});
});
}
/** Handle keyboard navigation for top-level menubar items only */
handleKeyDown(t) {
const e = this.getAllItems(), i = this.getCurrentItem();
if (e.length === 0) return;
const a = t.target, s = this.querySelectorAll("dap-ds-navigation-menu-item");
let l = !1;
if (s.forEach((o) => {
!e.includes(o) && o.contains(a) && (l = !0);
}), !l) {
if (t.key === "Enter" || t.key === " ") {
if (i) {
const o = i.querySelector(
'[slot="trigger"]'
), r = (o == null ? void 0 : o.tagName.toLowerCase()) === "a" || (o == null ? void 0 : o.tagName.toLowerCase()) === "dap-ds-link";
(!r || t.key === " ") && (t.preventDefault(), t.stopPropagation()), i.hasNestedItems || i.hasContent ? (t.preventDefault(), t.stopPropagation(), i.opened || i.showDropDown()) : (!r || t.key === " ") && (o == null || o.click());
}
} else if ([
"ArrowDown",
"ArrowUp",
"ArrowLeft",
"ArrowRight",
"Home",
"End"
].includes(t.key)) {
let o = i ? e.indexOf(i) : 0;
this.orientation === "horizontal" ? t.key === "ArrowLeft" ? (t.preventDefault(), t.stopPropagation(), o--, o < 0 && (o = e.length - 1), this.setCurrentItem(e[o]), e[o].focus()) : t.key === "ArrowRight" ? (t.preventDefault(), t.stopPropagation(), o++, o > e.length - 1 && (o = 0), this.setCurrentItem(e[o]), e[o].focus()) : (t.key === "ArrowDown" || t.key === "ArrowUp") && i ? (i.hasNestedItems || i.hasContent) && (t.preventDefault(), t.stopPropagation(), i.opened ? t.key === "ArrowDown" ? i.focusFirstDropdownChild() : i.focusLastDropdownChild() : (i.showDropDown(), this.updateComplete.then(() => {
t.key === "ArrowDown" ? i.focusFirstDropdownChild() : i.focusLastDropdownChild();
}))) : t.key === "Home" ? (t.preventDefault(), t.stopPropagation(), this.setCurrentItem(e[0]), e[0].focus()) : t.key === "End" && (t.preventDefault(), t.stopPropagation(), this.setCurrentItem(e[e.length - 1]), e[e.length - 1].focus()) : t.key === "ArrowUp" ? (t.preventDefault(), t.stopPropagation(), o--, o < 0 && (o = e.length - 1), this.setCurrentItem(e[o]), e[o].focus()) : t.key === "ArrowDown" ? (t.preventDefault(), t.stopPropagation(), o++, o > e.length - 1 && (o = 0), this.setCurrentItem(e[o]), e[o].focus()) : t.key === "ArrowRight" && i ? (i.hasNestedItems || i.hasContent) && (t.preventDefault(), t.stopPropagation(), i.opened ? i.focusFirstDropdownChild() : (i.showDropDown(), this.updateComplete.then(() => {
i.focusFirstDropdownChild();
}))) : t.key === "Home" ? (t.preventDefault(), t.stopPropagation(), this.setCurrentItem(e[0]), e[0].focus()) : t.key === "End" && (t.preventDefault(), t.stopPropagation(), this.setCurrentItem(e[e.length - 1]), e[e.length - 1].focus());
}
}
}
handleMouseDown(t) {
const e = t.target;
this.isMenuItem(e) && this.setCurrentItem(e);
}
handleSlotChange() {
const t = this.getAllItems();
t.length > 0 && this.setCurrentItem(t[0]), this._updateActiveHref(), this._updateChildFullWidth(), this._updateOrientation(), this._updateTabMode(), this._applyTabMode();
}
isMenuItem(t) {
return t.tagName.toLowerCase() === "dap-ds-navigation-menu-item";
}
/** Gets all slotted menu items, ignoring disabled elements */
getAllItems() {
return [...this.defaultSlot.assignedElements({ flatten: !0 })].filter(
(t) => {
const e = t;
return !(e.inert || !this.isMenuItem(e));
}
);
}
/**
* Gets the current menu item (the one marked with `data-nav-current`).
* The menu item may or may not have focus, but for keyboard interaction purposes it's considered the "active" item.
*/
getCurrentItem() {
return this.getAllItems().find((t) => t.hasAttribute("data-nav-current"));
}
/**
* Sets the current menu item. In 'group' mode (default), applies roving tabindex so only the
* active item's trigger is in the sequential tab order (tabindex="0"). In 'items' mode, all
* top-level items remain in the tab order — only the data-nav-current marker is updated.
*/
setCurrentItem(t) {
const e = this.getAllItems();
this.tabMode === "items" ? e.forEach((i) => {
i === t ? i.setAttribute("data-nav-current", "") : i.removeAttribute("data-nav-current");
}) : e.forEach((i) => {
i.setRovingTabIndex(i === t);
});
}
_updateChildFullWidth() {
this.fullWidth && this._updatePropertyRecursive("fullWidth", !0);
}
/** Recursively update activeHref property for all navigation items. */
_updateActiveHref() {
this._updatePropertyRecursive("activeHref", this.activeHref);
}
/** Recursively update orientation property for all navigation items. */
_updateOrientation() {
this._updatePropertyRecursive("orientation", this.orientation);
}
/** Update tabMode property for all top-level navigation items. */
_updateTabMode() {
this.getAllItems().forEach((t) => {
t.tabMode = this.tabMode;
});
}
/**
* Applies tab behavior based on the current tabMode:
* - 'items': All top-level item triggers get tabindex="0".
* - 'group': Restore roving tabindex — only the current/first item gets tabindex="0".
*/
_applyTabMode() {
var e, i;
const t = this.getAllItems();
if (t.length !== 0)
if (this.tabMode === "items") {
const a = (e = t.find((s) => s.hasAttribute("data-nav-current"))) != null ? e : t[0];
t.forEach((s) => s.setRovingTabIndex(!0)), t.forEach((s) => {
s !== a && s.removeAttribute("data-nav-current");
});
} else {
const a = (i = t.find((s) => s.hasAttribute("data-nav-current"))) != null ? i : t[0];
t.forEach((s) => s.setRovingTabIndex(s === a));
}
}
/** Helper method to recursively update properties on nested items. */
_updatePropertyRecursive(t, e, i = this) {
i.querySelectorAll(
":scope > dap-ds-navigation-menu-item"
).forEach((s) => {
s[t] = e, this._updatePropertyRecursive(t, e, s);
});
}
render() {
return A`
<nav
part="base"
aria-orientation=${this.orientation === "vertical" ? "vertical" : "horizontal"}
class=${y("navigation-menu", {
"navigation-menu--vertical": this.orientation === "vertical"
})}
aria-label=${I(this.ariaLabel || "Main navigation")}>
<slot
=${this._handleSlotChange}
=${this._handleNavigationItemClick}
-navigation-dropdown-open=${this._handleDropdownOpen}
=${this.handleKeyDown}
=${this.handleMouseDown}
=${this._handleFocusIn}></slot>
</nav>
`;
}
};
d.tagName = "dap-ds-navigation-menu", d.styles = D(b);
let n = d;
u([
C("slot")
], n.prototype, "defaultSlot");
u([
p({ type: String })
], n.prototype, "activeHref");
u([
p({ reflect: !0 })
], n.prototype, "orientation");
u([
p({ type: Boolean })
], n.prototype, "fullWidth");
u([
p({ type: Boolean })
], n.prototype, "allowMultipleOpen");
u([
p({ type: String })
], n.prototype, "tabMode");
export {
n as default
};
//# sourceMappingURL=navigation-menu.component.js.map