@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
154 lines (153 loc) • 5.05 kB
JavaScript
import { defineComponent as C, useAttrs as V, ref as a, watch as D, onMounted as O, onUnmounted as _, computed as w } from "vue";
import { NeonSize as q } from "../../../common/enums/NeonSize.es.js";
import { NeonFunctionalColor as z } from "../../../common/enums/NeonFunctionalColor.es.js";
import E from "../../presentation/dropdown/NeonDropdown.vue.es.js";
import K from "../../presentation/icon/NeonIcon.vue.es.js";
import T from "../input/NeonInput.vue.es.js";
import U from "../chip/NeonChip.vue.es.js";
import { NeonDropdownPlacement as r } from "../../../common/enums/NeonDropdownPlacement.es.js";
import { NeonScrollUtils as F } from "../../../common/utils/NeonScrollUtils.es.js";
const X = C({
name: "NeonSearch",
components: {
NeonChip: U,
NeonDropdown: E,
NeonIcon: K,
NeonInput: T
},
props: {
/**
* Either a string indicating the key of the selected option ('' if there is no selection) or an array of selected
* NeonSearchOption in the case when multiple = true (necessary to display them as chips).
*/
modelValue: { type: [String, Array], required: !0 },
/**
* Placeholder to display in search input when there is no search string entered.
*/
placeholder: { type: String, required: !0 },
/**
* The list of search results.
*/
options: { type: Array, required: !0 },
/**
* Allow multi-select.
*/
multiple: { type: Boolean, default: !1 },
/**
* Disable the search
*/
disabled: { type: Boolean, default: !1 },
/**
* The size of the dropdown - Small, Medium or Large.
*/
size: { type: String, default: q.Medium },
/**
* The color of the search.
*/
color: { type: String, default: z.LowContrast },
/**
* Placement of the dropdown contents.
*/
placement: { type: String, default: r.BottomLeft }
},
emits: [
/**
* emitted when the user changes the selection.
* @type {string | NeonSearchOption[]} either the selected option's key (single select) or an array of the
* selected options (multi-select).
*/
"update:modelValue",
/**
* emitted when the user types in filter box.
* @type {string} the current filter criteria. This can be used by the application to filter the displayed options.
*/
"filter-changed"
],
setup(o, { emit: f }) {
const k = V(), p = a(null), u = a(o.placement), i = a(!1), s = a(null), n = a(-1), d = a("");
D(
() => i.value,
(e) => {
e && o.options.length > 0 && (s.value = o.options[0].key, n.value = 0);
}
);
const S = () => {
switch (u.value) {
case r.TopLeft:
case r.TopRight:
case r.LeftBottom:
case r.RightBottom:
return !0;
}
return !1;
}, N = () => {
var t;
const e = (t = p.value) == null ? void 0 : t.querySelector(".neon-search__option--highlighted");
F.scrollIntoView(e);
}, h = (e, t) => {
const l = n.value + e;
l >= 0 && l <= o.options.length - 1 && (n.value = l, s.value = o.options[n.value].key, t.preventDefault(), setTimeout(N));
}, c = (e) => {
f("update:modelValue", e);
}, g = (e) => {
o.multiple || c(""), d.value = e, f("filter-changed", e);
}, y = (e) => {
if (o.multiple) {
const t = o.modelValue.map((m) => m), l = t.findIndex((m) => m.key === e.key);
l >= 0 ? t.splice(l, 1) : t.push(e), c(t);
} else
c(e.key);
g(o.multiple ? "" : e.label.toString());
}, v = (e) => {
if (i.value)
switch (e.code) {
case "ArrowUp":
case "ArrowDown":
{
const t = S() ? -1 : 1;
e.code === "ArrowUp" ? h(-1 * t, e) : h(1 * t, e);
}
break;
case "Enter":
case "Space":
e.target.classList.contains("neon-search__input") || (y(o.options[n.value]), e.preventDefault());
break;
case "Tab":
!e.ctrlKey && !e.metaKey && !e.altKey && (i.value = !1);
break;
}
}, b = (e) => {
u.value = e;
};
O(() => {
document.addEventListener("keydown", v);
}), _(() => {
document.removeEventListener("keydown", v);
});
const I = w(() => {
const { onFilterChanged: e, ...t } = k;
return t;
}), A = (e) => {
s.value = e, n.value = o.options.findIndex((t) => t.key === e);
}, L = () => i.value = !0, x = (e) => c(o.modelValue.filter((t) => t.key !== e.key)), B = w(() => o.multiple ? o.options : o.options.filter((e) => e.label !== d.value));
return {
dropdown: p,
open: i,
highlightedKey: s,
filter: d,
sanitizedAttributes: I,
computedOptions: B,
dropdownPlacement: u,
onPlacement: b,
onFilterChange: g,
clickOption: y,
changeHighlighted: A,
showOptions: L,
removeSelected: x
};
}
});
export {
X as default
};
//# sourceMappingURL=NeonSearch.es.js.map