UNPKG

@aotearoan/neon

Version:

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

182 lines (181 loc) 6.65 kB
import { defineComponent as O, useAttrs as T, ref as l, watch as b, onMounted as _, onUnmounted as z, computed as f } from "vue"; import { NeonSize as K } from "../../../model/common/size/NeonSize.es.js"; import { NeonFunctionalColor as P } from "../../../model/common/color/NeonFunctionalColor.es.js"; import U from "../../presentation/dropdown/NeonDropdown.vue.es.js"; import q from "../../presentation/icon/NeonIcon.vue.es.js"; import F from "../input/NeonInput.vue.es.js"; import M from "../chip/NeonChip.vue.es.js"; import { NeonDropdownPlacement as u } from "../../../model/presentation/dropdown/NeonDropdownPlacement.es.js"; import { NeonScrollUtils as R } from "../../../utils/common/dom/NeonScrollUtils.es.js"; import { NeonInputMode as H } from "../../../model/user-input/input/NeonInputMode.es.js"; const te = O({ name: "NeonSearch", components: { NeonChip: M, NeonDropdown: U, NeonIcon: q, NeonInput: F }, props: { /** * The selected model value(s). In the case of single select this should be set to a single NeonSearchOption or null. * In the case of multiple selection (multiple=true) pass an Array of selected NeonSearchOptions or an empty array * if nothing is selected. */ modelValue: { type: [Object, Array] }, /** * 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: K.Medium }, /** * The color of the search. */ color: { type: String, default: P.Primary }, /** * The HTML autocomplete mode as specified <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values">here</a>. * NOTE: No enum is provided in Neon as some values can be used in combination, please refer to the full list of values in the preceding link. */ autocomplete: { type: String, default: "on" }, /** * The HTML input mode as specified <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode">here</a>. * This can be used to simplify populating the filter field, e.g. providing the user's country from their address. */ inputmode: { type: String, default: H.Text }, /** * Placement of the dropdown contents. */ placement: { type: String, default: u.BottomLeft } }, emits: [ /** * @type {NeonSearchOption | NeonSearchOption[] | null} either the selected option (single select) or an array of * the selected options (multi-select). In the case nothing is selected in single select mode <null> is returned & * for multiple selection an empty array is returned. */ "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(t, { emit: y }) { var S; const I = T(), h = l(null), p = l(null), d = l(t.placement), i = l(!1), c = l(null), a = l(-1), r = l(!t.multiple && ((S = t.modelValue) == null ? void 0 : S.label) || ""); b( () => i.value, (e) => { e && t.options.length > 0 && (c.value = t.options[0].key, a.value = 0); } ), b( () => t.modelValue, (e) => { t.multiple || (r.value = (e == null ? void 0 : e.label) || ""); } ); const N = () => { switch (d.value) { case u.TopLeft: case u.TopRight: case u.LeftBottom: case u.RightBottom: return !0; } return !1; }, A = () => { var n, o; const e = (o = (n = h.value) == null ? void 0 : n.dropdownContent) == null ? void 0 : o.querySelector( ".neon-search__option--highlighted" ); e && (e.focus(), R.scrollIntoView(e)); }, g = (e, n) => { const o = a.value + e; o >= 0 && o <= t.options.length - 1 && (a.value = o, c.value = t.options[a.value].key, n.preventDefault(), setTimeout(A)); }, s = (e) => { y("update:modelValue", e); }, v = (e) => { !t.multiple && t.modelValue && s(null), r.value = e, y("filter-changed", e); }, w = (e) => { if (t.multiple) { const n = t.modelValue.map((m) => m), o = n.findIndex((m) => m.key === e.key); o >= 0 ? n.splice(o, 1) : n.push(e), s(n); } else s(e); v(t.multiple ? "" : e.label.toString()); }, k = (e) => { var n; if (i.value) switch (e.code) { case "ArrowUp": case "ArrowDown": { const o = N() ? -1 : 1; e.code === "ArrowUp" ? g(-1 * o, e) : g(1 * o, e); } break; case "Enter": case "Space": e.target.classList.contains("neon-search__input") || (w(t.options[a.value]), e.preventDefault()); break; case "Tab": document.activeElement !== ((n = p.value) == null ? void 0 : n.neonInput) && !e.ctrlKey && !e.metaKey && !e.altKey && (i.value = !1); break; } }, V = (e) => { d.value = e; }; _(() => { document.addEventListener("keydown", k); }), z(() => { document.removeEventListener("keydown", k); }); const x = f(() => { const { onFilterChanged: e, ...n } = I; return n; }), B = (e) => { c.value = e, a.value = t.options.findIndex((n) => n.key === e); }, C = () => i.value = !0, D = (e) => s(t.modelValue.filter((n) => n.key !== e.key)), L = f(() => t.multiple ? t.options : t.options.filter((e) => e.label !== r.value)), E = f( () => { var e; return t.multiple && Array.isArray(t.modelValue) ? t.modelValue[0] && t.modelValue[0].key : ((e = t.modelValue) == null ? void 0 : e.key) || null; } ); return { dropdown: h, searchInput: p, open: i, highlightedKey: c, filter: r, sanitizedAttributes: x, computedOptions: L, dropdownPlacement: d, onPlacement: V, onFilterChange: v, clickOption: w, changeHighlighted: B, showOptions: C, removeSelected: D, activeDescendant: E }; } }); export { te as default }; //# sourceMappingURL=NeonSearch.es.js.map