UNPKG

@aotearoan/neon

Version:

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

138 lines (137 loc) 4.09 kB
import { defineComponent as B, useAttrs as D, ref as r, onMounted as I, onUnmounted as L, watch as S } from "vue"; import { NeonSize as A } from "../../../common/enums/NeonSize.es.js"; import { NeonFunctionalColor as E } from "../../../common/enums/NeonFunctionalColor.es.js"; import H from "../../presentation/dropdown/NeonDropdown.vue.es.js"; import { NeonDropdownPlacement as s } from "../../../common/enums/NeonDropdownPlacement.es.js"; import { NeonScrollUtils as O } from "../../../common/utils/NeonScrollUtils.es.js"; import x from "../../presentation/icon/NeonIcon.vue.es.js"; import C from "../link/NeonLink.vue.es.js"; const z = B({ name: "NeonDropdownMenu", components: { NeonDropdown: H, NeonIcon: x, NeonLink: C }, props: { /** * A list of menu items to render in the dropdown menu. */ model: { type: Array, required: !0 }, /** * The size of the dropdown - Small, Medium or Large. */ size: { type: String, default: A.Medium }, /** * The dropdown color. */ color: { type: String, default: E.LowContrast }, /** * Whether the dropdown button is disabled or not. */ disabled: { type: Boolean, default: !1 }, /** * Instead of opening on click (default), open on hover. */ openOnHover: { type: Boolean, default: !1 } }, emits: [ /** * emitted when the user clicks on a menu item. * @type {NeonDropdownMenuItem} the menu item the user clicked on. */ "click", /** * emitted on initialisation * @type {HTMLElement} the reference to the HTMLElement for the dropdown menu button. */ "button-ref" ], setup(t, { emit: d }) { const p = D(), f = r(null), m = r(null), v = r([]), l = r(!1), c = r(null), n = r(-1), w = (e) => { c.value = e, n.value = t.model.findIndex((o) => o.key === e); }, y = (e) => { m.value = e; }, g = () => { switch (m.value) { case s.TopLeft: case s.TopRight: case s.LeftBottom: case s.RightBottom: return !0; } return !1; }, k = () => { var o; const e = (o = f.value) == null ? void 0 : o.querySelector(".neon-dropdown-menu__item--highlighted"); O.scrollIntoView(e); }, i = (e, o) => { const a = n.value + e; a >= 0 && a <= t.model.length - 1 && (n.value = a, c.value = t.model[n.value].key, o.preventDefault(), setTimeout(k)); }, u = (e) => { if (!t.disabled && l.value) switch (e.code) { case "ArrowUp": case "ArrowDown": { const o = g() ? -1 : 1; e.code === "ArrowUp" ? i(-1 * o, e) : i(1 * o, e); } break; case "Enter": case "Space": t.model[n.value] && !t.model[n.value].disabled && (h(t.model[n.value]), e.preventDefault()); break; case "Tab": !e.ctrlKey && !e.metaKey && !e.altKey && (l.value = !1); break; case "Escape": l.value = !1; break; } }, h = (e) => { var o; if (!e.disabled) { if (e.href) { const a = (o = v.value[n.value]) == null ? void 0 : o.firstElementChild; a && a.click(); } else d("click", e); l.value = !1; } }, b = () => { t.openOnHover && (l.value = !0); }, N = () => { t.openOnHover && (l.value = !1); }; return I(() => { document.addEventListener("keydown", u); }), L(() => { document.removeEventListener("keydown", u); }), S( () => l.value, (e) => { e && (c.value = t.model[0].key, n.value = 0); } ), { dropdown: f, items: v, open: l, highlightedKey: c, highlightedIndex: n, attrs: p, emit: d, changeHighlighted: w, keyboardHandler: u, onBlur: N, onFocus: b, clickItem: h, navigateBy: i, onPlacement: y }; } }); export { z as default }; //# sourceMappingURL=NeonDropdownMenu.es.js.map