@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
141 lines (140 loc) • 4.3 kB
JavaScript
import { defineComponent as B, useAttrs as L, ref as r, onMounted as S, onUnmounted as D, watch as H } from "vue";
import { NeonSize as I } from "../../../model/common/size/NeonSize.es.js";
import { NeonFunctionalColor as A } from "../../../model/common/color/NeonFunctionalColor.es.js";
import C from "../../presentation/dropdown/NeonDropdown.vue.es.js";
import { NeonDropdownPlacement as i } from "../../../model/presentation/dropdown/NeonDropdownPlacement.es.js";
import { NeonScrollUtils as E } from "../../../utils/common/dom/NeonScrollUtils.es.js";
import x from "../../presentation/icon/NeonIcon.vue.es.js";
import K from "../link/NeonLink.vue.es.js";
import { NeonHorizontalPosition as O } from "../../../model/common/position/NeonHorizontalPosition.es.js";
const V = B({
name: "NeonDropdownMenu",
components: {
NeonDropdown: C,
NeonIcon: x,
NeonLink: K
},
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: I.Medium },
/**
* The dropdown color.
*/
color: { type: String, default: A.LowContrast },
/**
* Whether the dropdown button is disabled or not.
*/
disabled: { type: Boolean, default: !1 },
/**
* Placement of the dropdown contents.
*/
placement: { type: String, default: i.BottomLeft },
/**
* 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"
],
setup(t, { emit: u }) {
const h = L(), f = r(null), m = r(null), v = r([]), a = 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 i.TopLeft:
case i.TopRight:
case i.LeftBottom:
case i.RightBottom:
return !0;
}
return !1;
}, k = () => {
var o, l;
const e = (l = (o = f.value) == null ? void 0 : o.dropdownContent) == null ? void 0 : l.querySelector(
".neon-dropdown-menu__item--highlighted"
);
e && (e.focus(), E.scrollIntoView(e));
}, s = (e, o) => {
const l = n.value + e;
l >= 0 && l <= t.model.length - 1 && (n.value = l, c.value = t.model[n.value].key, o.preventDefault(), setTimeout(k));
}, d = (e) => {
if (!t.disabled && a.value)
switch (e.code) {
case "ArrowUp":
case "ArrowDown":
{
const o = g() ? -1 : 1;
e.code === "ArrowUp" ? s(-1 * o, e) : s(1 * o, e);
}
break;
case "Enter":
case "Space":
t.model[n.value] && !t.model[n.value].disabled && (p(t.model[n.value]), e.preventDefault());
break;
case "Tab":
!e.ctrlKey && !e.metaKey && !e.altKey && (a.value = !1);
break;
case "Escape":
a.value = !1;
break;
}
}, p = (e) => {
var o;
if (!e.disabled) {
if (e.href) {
const l = (o = v.value[n.value]) == null ? void 0 : o.firstElementChild;
l && l.click();
} else
u("click", e);
a.value = !1;
}
}, b = () => {
t.openOnHover && (a.value = !0);
}, N = () => {
t.openOnHover && (a.value = !1);
};
return S(() => {
document.addEventListener("keydown", d);
}), D(() => {
document.removeEventListener("keydown", d);
}), H(
() => a.value,
(e) => {
e && (c.value = t.model[0].key, n.value = 0);
}
), {
dropdown: f,
items: v,
open: a,
highlightedKey: c,
highlightedIndex: n,
attrs: h,
emit: u,
changeHighlighted: w,
keyboardHandler: d,
onBlur: N,
onFocus: b,
clickItem: p,
navigateBy: s,
onPlacement: y,
NeonHorizontalPosition: O
};
}
});
export {
V as default
};
//# sourceMappingURL=NeonDropdownMenu.es.js.map