UNPKG

@morpheme/autocomplete

Version:

Morpheme Autocomplete

378 lines (377 loc) 13.7 kB
import { defineComponent as R, toRefs as K, ref as E, watch as L, computed as N, openBlock as a, createBlock as V, unref as t, isRef as Q, normalizeClass as c, withCtx as n, createTextVNode as g, toDisplayString as h, createCommentVNode as m, createElementVNode as y, createVNode as u, createElementBlock as d, Transition as z, Fragment as S, renderList as A, renderSlot as C, normalizeProps as I, guardReactiveProps as F, mergeProps as M } from "vue"; import { Combobox as O, ComboboxLabel as U, ComboboxInput as j, ComboboxButton as G, ComboboxOptions as H, ComboboxOption as J } from "@headlessui/vue"; import P, { Icon as D } from "@morpheme/icon"; import { useFormValue as W } from "@morpheme/forms"; import X from "@morpheme/badge"; const Y = { class: "autocomplete-body" }, Z = { class: "autocomplete-clearable" }, _ = ["disabled"], x = { key: 0, class: "autocomplete-empty" }, ee = { key: 0, class: "autocomplete-item-selected" }, le = { key: 1, class: "autocomplete-hint" }, ye = /* @__PURE__ */ R({ __name: "VAutocomplete", props: { modelValue: { default: void 0 }, searchBy: { default: "text" }, displayText: { default: "text" }, placeholder: { default: "Search..." }, label: { default: "" }, items: { default: () => [] }, name: { default: "" }, rules: { default: "" }, notFoundText: {}, noDataText: { default: "No data." }, clearable: { type: Boolean, default: !1 }, errorClass: { default: "autocomplete-error" }, wrapperClass: { default: "" }, validationMode: { default: "aggressive" }, disabled: { type: Boolean }, hideError: { type: Boolean }, hint: {}, shadow: { type: Boolean }, readonly: { type: Boolean }, error: { type: Boolean }, transition: { default: "fade" } }, emits: ["update:modelValue", "update:query", "clear"], setup($, { emit: k }) { const i = $, { errorMessage: o, uncontrolledValue: p, clear: B } = W(i, k), { items: T } = K(i), b = E(""); L(b, (l) => k("update:query", l)); const w = N( () => b.value === "" ? T.value : T.value.filter( (l) => String(l[i.searchBy]).toLowerCase().replace(/\s+/g, "").includes(b.value.toLowerCase().replace(/\s+/g, "")) ) ), e = () => { b.value = "", B(); }; return (l, s) => (a(), V(t(O), { modelValue: t(p), "onUpdate:modelValue": s[1] || (s[1] = (r) => Q(p) ? p.value = r : null), class: c(["autocomplete", [ l.wrapperClass, { "autocomplete--error": !!t(o) || l.error, "autocomplete--selected": !!t(p), "autocomplete--disabled": l.disabled, "autocomplete--readonly": l.readonly, "autocomplete--shadow": l.shadow } ]]), as: "div" }, { default: n(() => [ l.label ? (a(), V(t(U), { key: 0, class: "autocomplete-label" }, { default: n(() => [ g(h(l.label), 1) ]), _: 1 })) : m("", !0), y("div", Y, [ y("div", { class: c(["autocomplete-field", { "autocomplete-field--error": !!t(o) || l.error }]) }, [ u(t(j), { class: c(["autocomplete-input", { "autocomplete-input--selected": !!t(p) }]), "display-value": (r) => r?.[l.displayText] || "", placeholder: l.placeholder, disabled: l.disabled, onChange: s[0] || (s[0] = (r) => b.value = r.target.value) }, null, 8, ["class", "display-value", "placeholder", "disabled"]), y("div", Z, [ l.clearable && t(p) ? (a(), d("button", { key: 0, type: "button", "aria-label": "Clear", class: "autocomplete-clearable-button", disabled: l.disabled, onClick: e }, [ u(t(D), { name: "heroicons:x-mark", class: "autocomplete-icon", "aria-hidden": "true" }) ], 8, _)) : m("", !0), u(t(G), { disabled: l.disabled }, { default: n(() => [ u(t(D), { name: "heroicons:chevron-down", class: "autocomplete-icon", "aria-hidden": "true" }) ]), _: 1 }, 8, ["disabled"]) ]) ], 2), u(z, { name: l.transition }, { default: n(() => [ u(t(H), { class: "autocomplete-options" }, { default: n(() => [ w.value.length === 0 ? (a(), d("div", x, h(l.noDataText), 1)) : m("", !0), (a(!0), d(S, null, A(w.value, (r, v) => (a(), V(t(J), { key: v, as: "template", value: r }, { default: n(({ selected: f, active: q }) => [ y("li", { class: c(["autocomplete-item", { "autocomplete-item--active": q, "autocomplete-item--inactive": !q }]) }, [ y("span", { class: c(["autocomplete-item-text", { "autocomplete-item-text--selected": f }]) }, h(r[l.displayText]), 3), f ? (a(), d("span", ee, [ u(t(D), { name: "heroicons:check", class: "autocomplete-item-selected-icon", "aria-hidden": "true" }) ])) : m("", !0) ], 2) ]), _: 2 }, 1032, ["value"]))), 128)) ]), _: 1 }) ]), _: 1 }, 8, ["name"]) ]), l.hint ? (a(), d("p", le, [ C(l.$slots, "hint", {}, () => [ g(h(l.hint), 1) ]) ])) : m("", !0), t(o) && !l.hideError ? (a(), d("div", { key: 2, class: c(l.errorClass) }, h(t(o)), 3)) : m("", !0) ]), _: 3 }, 8, ["modelValue", "class"])); } }), te = { class: "autocomplete-body" }, ae = { key: 0, class: "autocomplete-selection" }, oe = { class: "autocomplete-clearable" }, se = ["disabled"], re = { key: 0, class: "autocomplete-empty" }, ue = { key: 0, class: "autocomplete-item-selected" }, de = { key: 1, class: "autocomplete-hint" }, ie = { key: 2, class: "autocomplete-error" }, be = /* @__PURE__ */ R({ __name: "Autocomplete", props: { modelValue: {}, items: {}, multiple: { type: Boolean }, itemText: { default: "text" }, itemValue: { default: "value" }, placeholder: { default: "Search..." }, label: {}, transition: { default: "dropdown" }, error: { type: Boolean }, disabled: { type: Boolean }, clearable: { type: Boolean }, emptyText: { default: "No results." }, searchBy: {}, displayValue: {}, selectionItemProps: {}, readonly: { type: Boolean }, shadow: { type: Boolean }, hint: {}, errorMessage: {}, hideError: { type: Boolean } }, emits: ["update:modelValue", "clear"], setup($, { emit: k }) { const i = $, o = E(i.modelValue); L( () => i.modelValue, (e) => { o.value = e; }, { immediate: !0, deep: !0 } ), L( o, (e) => { k("update:modelValue", e); }, { deep: !0 } ); const p = E(""), B = N( () => p.value === "" ? i.items : i.items.filter( (e) => String(e[i.searchBy || i.itemText || i.itemValue]).toLowerCase().replace(/\s+/g, "").includes(p.value.toLowerCase().replace(/\s+/g, "")) ) ), T = () => { p.value = "", o.value = void 0, k("clear"); }, b = (e) => e?.[i.itemText] || "", w = N(() => i.displayValue ?? b); return (e, l) => (a(), V(t(O), { modelValue: o.value, "onUpdate:modelValue": l[1] || (l[1] = (s) => o.value = s), as: "div", class: c(["autocomplete autocomplete-primary", { "autocomplete--error": e.error, "autocomplete--selected": !!o.value, "autocomplete--disabled": e.disabled, "autocomplete--readonly": e.readonly, "autocomplete--shadow": e.shadow }]), multiple: e.multiple }, { default: n(() => [ e.label ? (a(), V(t(U), { key: 0, class: "autocomplete-label" }, { default: n(() => [ g(h(e.label), 1) ]), _: 1 })) : m("", !0), y("div", te, [ y("div", { class: c(["autocomplete-field", { "autocomplete-field--error": e.error }]) }, [ C(e.$slots, "selection", I(F({ selected: o.value, multiple: e.multiple, itemValue: e.itemValue, itemText: e.itemText, selectionItemProps: e.selectionItemProps })), () => [ e.multiple && o.value && o.value.length > 0 ? (a(), d("div", ae, [ (a(!0), d(S, null, A(o.value, (s, r) => C(e.$slots, "selection-item", I(M({ key: r }, { item: s, idx: r, itemText: e.itemText, itemValue: e.itemValue, remove: () => o.value?.splice(r, 1) })), () => [ u(t(X), M({ color: "primary", dismissable: "", onDismiss: (v) => o.value.splice(r, 1) }, e.selectionItemProps), { default: n(() => [ g(h(s[e.itemText]), 1) ]), _: 2 }, 1040, ["onDismiss"]) ])), 128)) ])) : m("", !0) ]), u(t(j), { class: c(["autocomplete-input", { "autocomplete-input--selected": !!o.value }]), "display-value": w.value ?? b, placeholder: e.placeholder, disabled: e.disabled, onChange: l[0] || (l[0] = (s) => p.value = s.target.value) }, null, 8, ["class", "display-value", "placeholder", "disabled"]), y("div", oe, [ e.clearable && o.value ? (a(), d("button", { key: 0, type: "button", "aria-label": "Clear", class: "autocomplete-clearable-button", disabled: e.disabled, onClick: T }, [ u(t(P), { name: "heroicons:x-mark", class: "autocomplete-icon", "aria-hidden": "true" }) ], 8, se)) : m("", !0), u(t(G), { disabled: e.disabled }, { default: n(() => [ u(t(P), { name: "heroicons:chevron-down", class: "autocomplete-icon", "aria-hidden": "true" }) ]), _: 1 }, 8, ["disabled"]) ]) ], 2), u(z, { name: e.transition }, { default: n(() => [ u(t(H), { class: "autocomplete-options" }, { default: n(() => [ B.value.length === 0 ? (a(), d("div", re, h(e.emptyText), 1)) : m("", !0), (a(!0), d(S, null, A(B.value, (s, r) => (a(), V(t(J), { key: r, as: "template", value: s }, { default: n(({ selected: v, active: f }) => [ C(e.$slots, "item", I(F({ item: s, active: f, selected: v, itemText: e.itemText, itemValue: e.itemValue })), () => [ y("li", { class: c(["autocomplete-item", { "autocomplete-item--active": f, "autocomplete-item--inactive": !f }]) }, [ y("span", { class: c(["autocomplete-item-text", { "autocomplete-item-text--selected": v }]) }, h(s[e.itemText]), 3), v ? (a(), d("span", ue, [ u(t(P), { name: "heroicons:check", class: "autocomplete-item-selected-icon", "aria-hidden": "true" }) ])) : m("", !0) ], 2) ]) ]), _: 2 }, 1032, ["value"]))), 128)) ]), _: 3 }) ]), _: 3 }, 8, ["name"]) ]), e.hint ? (a(), d("div", de, [ C(e.$slots, "hint", {}, () => [ g(h(e.hint), 1) ]) ])) : m("", !0), e.error && !e.hideError ? (a(), d("div", ie, h(e.errorMessage), 1)) : m("", !0) ]), _: 3 }, 8, ["modelValue", "multiple", "class"])); } }); export { be as Autocomplete, ye as VAutocomplete, ye as default };