UNPKG

reka-ui

Version:

Vue port for Radix UI Primitives.

259 lines (256 loc) 7.26 kB
import { createContext } from "../shared/createContext.js"; import { useDirection } from "../shared/useDirection.js"; import { useFilter } from "../shared/useFilter.js"; import { usePrimitiveElement } from "../Primitive/usePrimitiveElement.js"; import { PopperRoot_default } from "../Popper/PopperRoot.js"; import { ListboxRoot_default } from "../Listbox/ListboxRoot.js"; import { computed, createBlock, createVNode, defineComponent, getCurrentInstance, isRef, mergeProps, nextTick, onMounted, openBlock, ref, renderSlot, toRefs, unref, withCtx } from "vue"; import { createEventHook, useVModel } from "@vueuse/core"; //#region src/Combobox/ComboboxRoot.vue?vue&type=script&setup=true&lang.ts const [injectComboboxRootContext, provideComboboxRootContext] = createContext("ComboboxRoot"); var ComboboxRoot_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComponent({ __name: "ComboboxRoot", props: { open: { type: Boolean, required: false, default: void 0 }, defaultOpen: { type: Boolean, required: false }, resetSearchTermOnBlur: { type: Boolean, required: false, default: true }, resetSearchTermOnSelect: { type: Boolean, required: false, default: true }, openOnFocus: { type: Boolean, required: false, default: false }, openOnClick: { type: Boolean, required: false, default: false }, ignoreFilter: { type: Boolean, required: false }, resetModelValueOnClear: { type: Boolean, required: false, default: false }, modelValue: { type: null, required: false }, defaultValue: { type: null, required: false }, multiple: { type: Boolean, required: false }, dir: { type: String, required: false }, disabled: { type: Boolean, required: false }, highlightOnHover: { type: Boolean, required: false, default: true }, by: { type: [String, Function], required: false }, asChild: { type: Boolean, required: false }, as: { type: null, required: false }, name: { type: String, required: false }, required: { type: Boolean, required: false } }, emits: [ "update:modelValue", "highlight", "update:open" ], setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const { primitiveElement, currentElement: parentElement } = usePrimitiveElement(); const { multiple, disabled, ignoreFilter, resetSearchTermOnSelect, openOnFocus, openOnClick, dir: propDir, resetModelValueOnClear, highlightOnHover } = toRefs(props); const dir = useDirection(propDir); const modelValue = useVModel(props, "modelValue", emits, { defaultValue: props.defaultValue ?? (multiple.value ? [] : void 0), passive: props.modelValue === void 0, deep: true }); const open = useVModel(props, "open", emits, { defaultValue: props.defaultOpen, passive: props.open === void 0 }); async function onOpenChange(val) { open.value = val; filterSearch.value = ""; if (val) { await nextTick(); primitiveElement.value?.highlightSelected(); isUserInputted.value = true; inputElement.value?.focus(); } else { isUserInputted.value = false; setTimeout(() => { if (!val && props.resetSearchTermOnBlur) resetSearchTerm.trigger(); }, 1); } } const resetSearchTerm = createEventHook(); const isUserInputted = ref(false); const isVirtual = ref(false); const inputElement = ref(); const triggerElement = ref(); const highlightedElement = computed(() => primitiveElement.value?.highlightedElement ?? void 0); const allItems = ref(/* @__PURE__ */ new Map()); const allGroups = ref(/* @__PURE__ */ new Map()); const { contains } = useFilter({ sensitivity: "base" }); const filterSearch = ref(""); const filterState = computed((oldValue) => { if (!filterSearch.value || props.ignoreFilter || isVirtual.value) return { count: allItems.value.size, items: oldValue?.items ?? /* @__PURE__ */ new Map(), groups: oldValue?.groups ?? new Set(allGroups.value.keys()) }; let itemCount = 0; const filteredItems = /* @__PURE__ */ new Map(); const filteredGroups = /* @__PURE__ */ new Set(); for (const [id, value] of allItems.value) { const score = contains(value, filterSearch.value); filteredItems.set(id, score ? 1 : 0); if (score) itemCount++; } for (const [groupId, group] of allGroups.value) for (const itemId of group) if (filteredItems.get(itemId) > 0) { filteredGroups.add(groupId); break; } return { count: itemCount, items: filteredItems, groups: filteredGroups }; }); const inst = getCurrentInstance(); onMounted(() => { if (inst?.exposed) { inst.exposed.highlightItem = primitiveElement.value?.highlightItem; inst.exposed.highlightFirstItem = primitiveElement.value?.highlightFirstItem; inst.exposed.highlightSelected = primitiveElement.value?.highlightSelected; } }); __expose({ filtered: filterState, highlightedElement, highlightItem: primitiveElement.value?.highlightItem, highlightFirstItem: primitiveElement.value?.highlightFirstItem, highlightSelected: primitiveElement.value?.highlightSelected }); provideComboboxRootContext({ modelValue, multiple, disabled, open, onOpenChange, contentId: "", isUserInputted, isVirtual, inputElement, highlightedElement, onInputElementChange: (val) => inputElement.value = val, triggerElement, onTriggerElementChange: (val) => triggerElement.value = val, parentElement, resetSearchTermOnSelect, onResetSearchTerm: resetSearchTerm.on, allItems, allGroups, filterSearch, filterState, ignoreFilter, openOnFocus, openOnClick, resetModelValueOnClear }); return (_ctx, _cache) => { return openBlock(), createBlock(unref(PopperRoot_default), null, { default: withCtx(() => [createVNode(unref(ListboxRoot_default), mergeProps({ ref_key: "primitiveElement", ref: primitiveElement }, _ctx.$attrs, { modelValue: unref(modelValue), "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => isRef(modelValue) ? modelValue.value = $event : null), style: { pointerEvents: unref(open) ? "auto" : void 0 }, as: _ctx.as, "as-child": _ctx.asChild, dir: unref(dir), multiple: unref(multiple), name: _ctx.name, required: _ctx.required, disabled: unref(disabled), "highlight-on-hover": unref(highlightOnHover), by: props.by, onHighlight: _cache[1] || (_cache[1] = ($event) => emits("highlight", $event)) }), { default: withCtx(() => [renderSlot(_ctx.$slots, "default", { open: unref(open), modelValue: unref(modelValue) })]), _: 3 }, 16, [ "modelValue", "style", "as", "as-child", "dir", "multiple", "name", "required", "disabled", "highlight-on-hover", "by" ])]), _: 3 }); }; } }); //#endregion //#region src/Combobox/ComboboxRoot.vue var ComboboxRoot_default = ComboboxRoot_vue_vue_type_script_setup_true_lang_default; //#endregion export { ComboboxRoot_default, injectComboboxRootContext }; //# sourceMappingURL=ComboboxRoot.js.map