@fifteen/design-system-vue
Version:
Vue 3 (Composition API + Typescript) implementation of the Fifteen Design System
314 lines (313 loc) • 10.9 kB
JavaScript
import de from "./FLoader.js";
/* empty css */
import { defineComponent as ce, computed as E, ref as d, watch as H, onMounted as me, nextTick as ve, openBlock as c, createElementBlock as b, normalizeClass as W, unref as r, normalizeStyle as ye, createVNode as be, mergeProps as C, withCtx as q, createElementVNode as g, withKeys as a, Fragment as ge, renderList as he, renderSlot as w, toDisplayString as I, createCommentVNode as S, createBlock as Me, withModifiers as m, normalizeProps as Oe, guardReactiveProps as ke } from "vue";
import Ce from "../vendor/@fifteen/vue3-popper/dist/popper.esm.js";
import Y from "../vendor/fast-deep-equal/es6/index.js";
import { useVModelProxy as j } from "../vendor/@fifteen/shared-lib/dist/es/composables/useVModelProxy.js";
import "../vendor/countup.js/dist/countUp.min.js";
import { useElementBounding as we, onClickOutside as Se, useMutationObserver as Fe } from "@vueuse/core";
import "../vendor/@fifteen/shared-lib/dist/es/composables/useLocaleFormat.js";
import "../vendor/@fifteen/shared-lib/dist/es/helpers/consoleWatch.js";
import { stringify as G, removeDiacritics as P } from "../vendor/@fifteen/shared-lib/dist/es/utils/text.js";
import { noop as F } from "../utils/noop.js";
import { getCssColor as _ } from "../utils/getCssColor.js";
import { genSize as J } from "../utils/genSize.js";
const _e = ["aria-selected", "onClick", "onKeydown", "onMouseenter"], xe = { class: "FMenu__option__content" }, Be = {
key: 0,
class: "FMenu__option__description"
}, Re = {
key: 1,
class: "FMenu__noOption"
}, $e = 800, Ye = /* @__PURE__ */ ce({
__name: "FMenu",
props: {
modelValue: { type: Boolean, default: !1 },
selectedOption: { default: void 0 },
options: { default: () => [] },
preventSelection: { type: Boolean, default: !1 },
preventSearch: { type: Boolean, default: !1 },
persistent: { type: Boolean, default: !1 },
emptyText: { default: "" },
width: { default: 300 },
color: { default: "primary" },
textColor: { default: "neutral--light-5" },
selectedOptionColor: { default: "primary--light-2" },
selectedOptionTextColor: { default: "primary--dark-2" },
disabled: { type: Boolean, default: !1 },
inanimated: { type: Boolean, default: !1 },
loading: { type: Boolean, default: !1 },
absolute: { type: Boolean, default: !1 },
zIndex: { default: 9999 },
offsetSkid: { default: 0 },
offsetDistance: { default: 16 },
optionHeight: { default: 52 },
preventActivation: { type: Boolean, default: !1 }
},
emits: ["update:modelValue", "update:selectedOption", "before-select-option"],
setup(Q, { expose: U, emit: X }) {
const o = Q;
U({
selectOption: k
});
const Z = X, ee = E(
() => ({
"--fmenu--width": J(o.width),
"--fmenu--color": _(o.color),
"--fmenu--text-color": _(o.textColor),
"--fmenu--selected-option-color": _(o.selectedOptionColor),
"--fmenu--selected-option-text-color": _(
o.selectedOptionTextColor
),
"--fmenu-option-height": J(o.optionHeight)
})
), te = E(
() => ({
placement: "bottom-start",
strategy: o.absolute ? "absolute" : "fixed",
zIndex: o.zIndex,
offsetSkid: String(o.offsetSkid),
offsetDistance: String(o.offsetDistance)
})
), l = j({ props: o }), M = j({
props: o,
propName: "selectedOption"
}), K = d([]), x = d(), oe = E(() => ({
"FMenu--disabled": o.disabled,
"FMenu--inanimated": o.inanimated
})), f = d(-1), B = d(!1);
async function D() {
o.disabled || (l.value = !l.value);
}
const ne = [
"button:not(.FButton)",
"[href]",
"input",
"select",
"textarea",
'[tabindex]:not([tabindex="-1"])'
].join(", ");
function R() {
if (!l.value || o.disabled) return;
Array.from(
x.value?.querySelectorAll(ne) ?? []
).some((e) => !e.hasAttribute("disabled")) || x.value?.focus();
}
function L() {
o.disabled || (l.value = !0);
}
function $() {
o.disabled || (l.value = !1);
}
H(l, (t) => {
t ? R() : v(-1);
}), H(
() => o.options,
() => {
v(0);
}
);
function v(t) {
f.value = t;
}
function h(t) {
return o.options.findIndex(
(e) => Y(e.value, M.value)
) === t;
}
function se(t) {
return {
"FMenu__option--preselected": f.value === t,
"FMenu__option--selected": h(t)
};
}
function z(t) {
B.value || v(t);
}
function le(t) {
switch (t) {
case "first":
return 0;
case "last":
return o.options.length - 1;
case "prev":
return f.value - 1 < 0 ? o.options.length - 1 : f.value - 1;
case "next":
return f.value + 1 > o.options.length - 1 ? 0 : f.value + 1;
}
}
function y(t) {
if (!l.value || !o.options.length) return;
B.value = !0;
const e = le(t);
T(e), v(e);
}
const O = d(), {
top: re,
bottom: ie,
height: ae
} = we(O);
function T(t) {
const e = K.value[t], {
top: i,
bottom: n,
height: s
} = e.getBoundingClientRect();
if (i < re.value)
return O.value.scrollTo(0, t * (s + 4));
if (n > ie.value)
return O.value.scrollTo(
0,
(t + 1) * (s + 4) - ae.value + 12
);
}
function k(t) {
if (!o.options.length || o.disabled) return;
if (!t && f.value === -1) {
if (M.value) {
const i = o.options.findIndex(
(n) => Y(n.value, M.value)
);
v(i), T(i);
}
return;
}
const e = t ?? o.options[f.value];
Z("before-select-option", e.value), !o.preventSelection && (M.value = e.value, $());
}
let p = "", A;
function ue(t) {
if (t.stopPropagation(), !l.value || o.preventSearch) return;
p = P(
p + t.key
).toLocaleLowerCase();
function e(s) {
const u = P(s.label.toLowerCase()), pe = P(G(s.value).toLowerCase());
return u.startsWith(p) || pe.startsWith(p);
}
A = setTimeout(() => {
clearTimeout(A), p = "";
}, $e);
const i = o.options.findIndex(e), n = o.options.filter(e).length;
if (i === -1) {
p = "";
return;
}
T(i), v(i), n === 1 && (p = "");
}
function fe(t) {
o.preventActivation || (L(), t.preventDefault()), k();
}
const V = d();
Se(V, () => {
o.persistent || (l.value = !1);
});
const N = d();
return me(() => {
Fe(
N,
() => ve(() => window.dispatchEvent(new Event("resize"))),
{ childList: !0 }
);
}), (t, e) => {
const i = de;
return c(), b("div", {
class: W(["FMenu", r(oe)]),
ref_key: "menuRef",
ref: V,
style: ye(r(ee)),
role: "button",
tabindex: "-1",
onKeydown: ue
}, [
be(r(Ce), C({ show: r(l) }, r(te)), {
content: q(() => [
g("div", {
class: "FMenu__content",
ref_key: "contentRef",
ref: N,
role: "listbox",
tabindex: "-1",
onClick: R,
onKeydown: a(R, ["enter"]),
onMousemove: e[12] || (e[12] = (n) => B.value = !1)
}, [
t.options.length ? (c(), b("div", {
key: 0,
class: "FMenu__optionsMenu",
ref_key: "menuOptionsRef",
ref: O
}, [
(c(!0), b(ge, null, he(t.options, (n, s) => (c(), b("div", {
class: W(["FMenu__option", se(s)]),
ref_for: !0,
ref_key: "optionRefs",
ref: K,
key: r(G)(n.value),
role: "option",
tabindex: "-1",
"aria-selected": h(s),
onClick: (u) => k(n),
onKeydown: a((u) => k(n), ["enter"]),
onMouseenter: (u) => z(s),
onMouseleave: e[9] || (e[9] = (u) => z(-1)),
onFocus: e[10] || (e[10] = //@ts-ignore
(...u) => r(F) && r(F)(...u)),
onFocusout: e[11] || (e[11] = //@ts-ignore
(...u) => r(F) && r(F)(...u))
}, [
w(t.$slots, "option-prefix", C({ ref_for: !0 }, { option: n, index: s, isSelected: h(s) })),
g("div", xe, [
w(t.$slots, "option", C({ ref_for: !0 }, { option: n, index: s, isSelected: h(s) }), () => [
g("span", null, I(n.label), 1)
]),
n.description ? (c(), b("span", Be, I(n.description), 1)) : S("", !0)
]),
e[13] || (e[13] = g("div", { class: "FMenu__option__spacer" }, null, -1)),
w(t.$slots, "option-suffix", C({ ref_for: !0 }, { option: n, index: s, isSelected: h(s) }))
], 42, _e))), 128))
], 512)) : S("", !0),
t.options.length === 0 ? (c(), b("div", Re, [
t.loading ? (c(), Me(i, {
key: 0,
class: "FMenu__loader",
height: "20"
})) : S("", !0),
g("span", null, I(t.emptyText), 1)
])) : S("", !0)
], 544)
]),
default: q(() => [
g("div", {
class: "FMenu__activator",
ref_key: "activatorRef",
ref: x,
role: "button",
tabindex: "-1",
onKeydown: [
e[0] || (e[0] = a(m((n) => y("next"), ["prevent"]), ["down"])),
e[1] || (e[1] = a(m((n) => y("prev"), ["prevent"]), ["up"])),
e[2] || (e[2] = a(m((n) => y("first"), ["prevent"]), ["home"])),
e[3] || (e[3] = a(m((n) => y("last"), ["prevent"]), ["end"])),
e[4] || (e[4] = a(m((n) => {
y("next"), r(l) && n.preventDefault();
}, ["exact"]), ["tab"])),
e[5] || (e[5] = a(m((n) => {
y("prev"), r(l) && n.preventDefault();
}, ["shift"]), ["tab"])),
e[6] || (e[6] = a((n) => fe(n), ["enter"])),
e[7] || (e[7] = a(m((n) => $(), ["prevent"]), ["esc"]))
],
onClick: e[8] || (e[8] = (n) => !t.preventActivation && D())
}, [
w(t.$slots, "activator", Oe(ke({ toggleMenu: D, openMenu: L, closeMenu: $ })))
], 544)
]),
_: 3
}, 16, ["show"])
], 38);
};
}
});
export {
Ye as default
};