UNPKG

@aotearoan/neon

Version:

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

154 lines (153 loc) 5.05 kB
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