UNPKG

@aotearoan/neon

Version:

Neon is a lightweight design library of Vue 3 components with minimal dependencies.

100 lines (99 loc) 3.6 kB
import { defineComponent as x, ref as o, onMounted as L, nextTick as w, onUnmounted as z } from "vue"; import C from "../link/NeonLink.vue.es.js"; import I from "../dropdown-menu/NeonDropdownMenu.vue.es.js"; import { NeonFunctionalColor as B } from "../../../common/enums/NeonFunctionalColor.es.js"; import { NeonSize as F } from "../../../common/enums/NeonSize.es.js"; import O from "../../presentation/icon/NeonIcon.vue.es.js"; import { useRoute as R } from "vue-router"; const T = x({ name: "NeonMenu", components: { NeonDropdownMenu: I, NeonLink: C, NeonIcon: O }, props: { /** * The menu configuration. This can have two levels, i.e. a top level horizontal menu and, if required, a dropdown * menu containing the second level. The highlighted 'active' menu is determined by the current Vue route. */ menu: { type: Array, required: !0 }, /** * The menu highlight color (excludes low-contrast and neutral). */ color: { type: String, default: B.Brand }, /** * The menu size. */ size: { type: String, default: F.Large }, /** * Whether to enable the priority menu which automatically calculates the available screen space and displays * as many of the menu items as possible, moving the remaining items into the overflow menu. */ priorityMenuEnabled: { type: Boolean, default: !0 } }, emits: [ /** * Emitted when a user clicks on a menu item. * @type {string} the key of the menu item clicked. */ "click" ], setup(s, { emit: M }) { const c = R(), m = o(null), f = o(null), r = o(null), l = o([]), y = o([]), u = o([]), p = (t) => { const n = window.getComputedStyle(t), e = parseFloat(n.marginLeft || "0") + parseFloat(n.marginRight || "0"); return Math.ceil(t.offsetWidth + e); }, k = (t, n) => ({ key: t, element: n, width: p(n) }), b = () => { const t = s.menu.map( (n, e) => f.value && k(n.key, f.value[e]) || null ); l.value = t.filter((n) => n !== null); }, E = (t) => t && (c == null ? void 0 : c.path.indexOf(t)) >= 0, N = (t) => { M("click", t); }, S = (t, n, e) => { if (e.map((i) => i.width).reduce((i, a) => i ? i + a : 0) <= t - n) return e.map((i) => i.key); let h = t - n, d = []; for (let i = 0; i < e.length; i = i + 1) { const a = e[i]; if (h < a.width) { i === 1 && (d = d.filter((W) => W !== e[0].key)); break; } h = h - a.width, d.push(a.key); } return d; }, v = async () => { await w(); const t = m.value && p(m.value) || 0, n = r.value && p(r.value) || 0; u.value = S(t, n, l.value), y.value = s.menu.filter((e) => u.value.indexOf(e.key) < 0).flatMap((e) => [ { ...e, isGroup: e.children && e.children.length > 0 }, ...(e.children || []).map((g) => ({ ...g, grouped: !0 })) ]), l.value.forEach((e) => { e.element.hidden = u.value.indexOf(e.key) < 0; }), r.value && (r.value.hidden = l.value.length === u.value.length); }; return L(async () => { s.priorityMenuEnabled && (await w(), b(), await v(), window.addEventListener("resize", v)); }), z(() => { s.priorityMenuEnabled && window.removeEventListener("resize", v); }), { menuWrapper: m, menuItem: f, menuItems: l, responsiveButton: r, responsiveMenuItems: y, visible: u, onClick: N, routeMatches: E }; } }); export { T as default }; //# sourceMappingURL=NeonMenu.es.js.map