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