UNPKG

@aotearoan/neon

Version:

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

102 lines (101 loc) 3.67 kB
import { defineComponent as W, ref as s, onMounted as x, nextTick as g, onUnmounted as C } from "vue"; import L from "../link/NeonLink.vue.es.js"; import z from "../dropdown-menu/NeonDropdownMenu.vue.es.js"; import { NeonFunctionalColor as I } from "../../../model/common/color/NeonFunctionalColor.es.js"; import { NeonSize as _ } from "../../../model/common/size/NeonSize.es.js"; import B from "../../presentation/icon/NeonIcon.vue.es.js"; import { useRoute as F } from "vue-router"; const P = W({ name: "NeonMenu", components: { NeonDropdownMenu: z, NeonLink: L, NeonIcon: B }, 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: I.Brand }, /** * The menu size. */ size: { type: String, default: _.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(d, { emit: w }) { const m = F(), c = s(null), f = s(null), l = s([]), y = s([]), u = s([]), p = (n) => { const e = window.getComputedStyle(n), o = parseFloat(e.marginLeft || "0") + parseFloat(e.marginRight || "0"); return Math.ceil(n.offsetWidth + o); }, M = (n, e) => ({ key: n, element: e, width: p(e) }), k = () => { const n = d.menu.map( (e, o) => f.value && M(e.key, f.value[o]) || null ); l.value = n.filter((e) => e !== null); }, b = (n) => n && (m == null ? void 0 : m.path.indexOf(n)) >= 0, E = (n) => { w("click", n); }, N = (n, e, o) => { if (o.map((i) => i.width).reduce((i, a) => i ? i + a : 0) <= n - e) return o.map((i) => i.key); let t = n - e, r = []; for (let i = 0; i < o.length; i = i + 1) { const a = o[i]; if (t < a.width) { i === 1 && (r = r.filter((S) => S !== o[0].key)); break; } t = t - a.width, r.push(a.key); } return r; }, h = async () => { var v; await g(); const n = c.value && p(c.value) || 0, e = (v = c.value) == null ? void 0 : v.getElementsByClassName( "neon-menu__responsive-menu" )[0], o = e && p(e) || 0; u.value = N(n, o, l.value), y.value = d.menu.filter((t) => u.value.indexOf(t.key) < 0).flatMap((t) => [ { ...t, isGroup: t.children && t.children.length > 0 }, ...(t.children || []).map((r) => ({ ...r, grouped: !0 })) ]), l.value.forEach((t) => { t.element.hidden = u.value.indexOf(t.key) < 0; }), e && (e.hidden = l.value.length === u.value.length); }; return x(async () => { d.priorityMenuEnabled && (await g(), k(), await h(), window.addEventListener("resize", h)); }), C(() => { d.priorityMenuEnabled && window.removeEventListener("resize", h); }), { menuWrapper: c, menuItem: f, menuItems: l, responsiveMenuItems: y, visible: u, onClick: E, routeMatches: b }; } }); export { P as default }; //# sourceMappingURL=NeonMenu.es.js.map