@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
102 lines (101 loc) • 3.67 kB
JavaScript
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