{"version":3,"file":"vue-ui-select.umd.cjs","sources":["../src/symbols.ts","../src/composables/useSelectState.ts","../src/utils/objectSource.ts","../src/composables/useModelBinding.ts","../src/composables/useSelectFiltering.ts","../src/composables/useSelectKeyboard.ts","../src/utils/scrollChaining.ts","../src/composables/useSelectPositioning.ts","../src/composables/useSelectTagging.ts","../src/composables/useSelectAccessibility.ts","../src/composables/useThemeClasses.ts","../src/utils/highlight.ts","../src/components/UiSelect.vue","../src/components/UiSelectMatch.vue","../src/components/UiSelectChoices.vue","../src/components/UiSelectNoChoice.vue","../src/utils/debounce.ts","../src/index.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { UiSelectContext, UiSelectPluginOptions } from './types'\n\n/** Provide/inject key for parent UiSelect → child components */\nexport const UI_SELECT_CONTEXT: InjectionKey<UiSelectContext> = Symbol('UiSelectContext')\n\n/** Provide/inject key for global plugin options */\nexport const UI_SELECT_OPTIONS: InjectionKey<UiSelectPluginOptions> = Symbol('UiSelectOptions')\n","import * as VueRuntime from 'vue'\nimport { ref, watch, type Ref } from 'vue'\nimport type { DropdownPosition, ThemeName } from '../types'\n\n// useId() is SSR-safe and produces ids that match between server and client.\n// The peer range requires Vue 3.5 for exactly this reason. The counter below is\n// only a backstop for a host that ignores the peer range: it is not SSR-safe,\n// because it climbs for the life of the process.\nlet uidCounter = 0\nconst vueUseId = (VueRuntime as any).useId as (() => string) | undefined\n\nexport function useSelectState(props: {\n  modelValue: Ref<any>\n  multiple: Ref<boolean>\n  disabled: Ref<boolean>\n  loading: Ref<boolean>\n  searchEnabled: Ref<boolean>\n  resetSearchInput: Ref<boolean>\n  closeOnSelect: Ref<boolean>\n  clearable: Ref<boolean>\n  appendToBody: Ref<boolean>\n  position: Ref<DropdownPosition>\n  theme: Ref<ThemeName>\n  placeholder: Ref<string>\n  tagging: Ref<boolean | ((search: string) => any)>\n  taggingLabel: Ref<string | false>\n  taggingTokens: Ref<string[]>\n  removeSelected: Ref<boolean>\n  lockChoice: Ref<((item: any) => boolean) | undefined>\n  inputId: Ref<string | undefined>\n  autofocus: Ref<boolean>\n  limit: Ref<number | undefined>\n}) {\n  let generatedId: string | undefined\n  if (vueUseId && (VueRuntime as any).getCurrentInstance?.()) {\n    generatedId = vueUseId()\n  }\n  const uid = generatedId ? `ui-select-${generatedId}` : `ui-select-${++uidCounter}`\n  const isOpen = ref(false)\n  const search = ref('')\n  const activeIndex = ref(-1)\n\n  // Element refs\n  const rootRef = ref<HTMLElement | null>(null)\n  const inputRef = ref<HTMLInputElement | null>(null)\n  const dropdownRef = ref<HTMLElement | null>(null)\n\n  function open() {\n    if (props.disabled.value || isOpen.value) return\n    isOpen.value = true\n  }\n\n  function close() {\n    if (!isOpen.value) return\n    isOpen.value = false\n    activeIndex.value = -1\n  }\n\n  function toggle() {\n    if (isOpen.value) close()\n    else open()\n  }\n\n  /**\n   * `options` exists for the focus we trigger ourselves when the dropdown opens:\n   * the search input sits inside a dropdown that may be teleported to <body>, and\n   * the browser's default focus behaviour scrolls to reveal it — jerking the page\n   * away from whatever the user was reading. Callers of the public focus() get\n   * the normal, scrolling behaviour.\n   */\n  function focus(options?: FocusOptions) {\n    // The search input is not always there to receive focus: in single mode it\n    // is rendered inside the dropdown and so only exists while open, and with\n    // search disabled it never exists at all. The root carries the combobox role\n    // and is always mounted, so it is the fallback — otherwise `autofocus` and\n    // the exposed focus() were silent no-ops and focus stayed on <body>.\n    const target = inputRef.value ?? rootRef.value\n    target?.focus(options)\n  }\n\n  function blur() {\n    // Release whichever of our own elements actually holds focus, for the same\n    // reason: blur() used to reach only the input.\n    const active = typeof document !== 'undefined' ? document.activeElement : null\n    if (active && (active === inputRef.value || active === rootRef.value)) {\n      ;(active as HTMLElement).blur()\n      return\n    }\n    inputRef.value?.blur()\n  }\n\n  // Reset search on close if configured\n  watch(isOpen, (val) => {\n    if (!val && props.resetSearchInput.value) {\n      search.value = ''\n    }\n  })\n\n  return {\n    uid,\n    isOpen,\n    search,\n    activeIndex,\n    rootRef,\n    inputRef,\n    dropdownRef,\n    open,\n    close,\n    toggle,\n    focus,\n    blur,\n  }\n}\n","import type { ObjectSourceItem } from '../types'\n\n/**\n * Marks the { key, value } objects WE create when flattening a Record source.\n *\n * Provenance, not shape. The old test — two own keys named `key` and `value` —\n * also matched a consumer's own data (a country list of { key, value } pairs is\n * perfectly ordinary), and silently unwrapped it into slots and v-model.\n * Non-enumerable, so it stays out of JSON.stringify, Object.keys and spreads.\n */\nconst OBJECT_SOURCE_ITEM = Symbol('uiSelectObjectSourceItem')\n\n/**\n * Convert a Record<string, V> into an array of { key, value } objects\n * suitable for iteration and display.\n */\nexport function normalizeObjectSource<V = any>(\n  obj: Record<string, V>\n): ObjectSourceItem<V>[] {\n  return Object.entries(obj).map(([key, value]) => {\n    const item = { key, value } as ObjectSourceItem<V>\n    Object.defineProperty(item, OBJECT_SOURCE_ITEM, { value: true, enumerable: false })\n    return item\n  })\n}\n\n/** True only for a wrapper this module produced. */\nexport function isObjectSourceItem(item: any): item is ObjectSourceItem {\n  return item != null && typeof item === 'object' && (item as any)[OBJECT_SOURCE_ITEM] === true\n}\n\n/** The value inside one of our wrappers; anything else is returned untouched. */\nexport function unwrapObjectSourceItem(item: any): any {\n  return isObjectSourceItem(item) ? item.value : item\n}\n\n/**\n * Get the value to use for v-model binding based on bindProperty.\n * For object sources, item is { key, value }.\n */\nexport function resolveBindValue(item: any, bindProperty?: string): any {\n  if (!bindProperty) return item\n  return getNestedValue(item, bindProperty)\n}\n\n/**\n * Get a nested property value using dot notation.\n * e.g. getNestedValue({ a: { b: 1 } }, 'a.b') => 1\n */\nexport function getNestedValue(obj: any, path: string): any {\n  if (!obj || !path) return obj\n  return path.split('.').reduce((acc, key) => acc?.[key], obj)\n}\n\n/**\n * Resolve the identity of an item using trackBy config.\n */\nexport function resolveTrackBy(item: any, trackBy?: string | ((item: any) => any)): any {\n  if (!trackBy) return item\n  if (typeof trackBy === 'function') return trackBy(item)\n  return getNestedValue(item, trackBy)\n}\n","import { ref, watch, computed, type Ref } from 'vue'\nimport {\n  resolveTrackBy,\n  resolveBindValue,\n  isObjectSourceItem,\n  unwrapObjectSourceItem,\n} from '../utils/objectSource'\n\n/**\n * Serializes a value with sorted object keys so { a: 1, b: 2 } and { b: 2, a: 1 }\n * compare equal. Used for trackBy-less object equality where consumers may\n * round-trip values through serialization.\n */\nfunction stableStringify(val: any, memo?: Map<any, string>): string {\n  if (memo && val !== null && typeof val === 'object') {\n    const hit = memo.get(val)\n    if (hit !== undefined) return hit\n    const computed = stableStringify(val)\n    memo.set(val, computed)\n    return computed\n  }\n  // Rebuilding each object in the replacer defeats JSON.stringify's own cycle\n  // detection — it only ever sees the fresh copies — so a self-referencing item\n  // (a tree node with a parent backlink is ordinary data) recursed until the\n  // stack overflowed, taking the whole dropdown down on first render. Track the\n  // originals ourselves. Repeats serialize to a marker, which keeps the output\n  // deterministic and therefore still usable for equality.\n  const seen = new WeakSet<object>()\n  return JSON.stringify(val, (_key, v) => {\n    if (v && typeof v === 'object') {\n      if (seen.has(v)) return '[Circular]'\n      seen.add(v)\n      if (!Array.isArray(v)) {\n        return Object.keys(v).sort().reduce<Record<string, any>>((acc, k) => {\n          acc[k] = v[k]\n          return acc\n        }, {})\n      }\n    }\n    return v\n  })\n}\n\nexport function useModelBinding(opts: {\n  modelValue: Ref<any>\n  multiple: Ref<boolean>\n  trackBy: Ref<string | ((item: any) => any) | undefined>\n  bindProperty: Ref<string | undefined>\n  rawItems: Ref<any[]>\n  /**\n   * Same predicate `removeItem` honours. Clearing reaches the same state by a\n   * different door — the × button, Backspace and the exposed clear() — so it\n   * has to respect locked items too, or the lock is trivially bypassed.\n   */\n  lockChoice?: Ref<((item: any) => boolean) | undefined>\n  emit: (event: string, ...args: any[]) => void\n}) {\n  const { modelValue, multiple, trackBy, bindProperty, rawItems, lockChoice, emit } = opts\n\n  function isLocked(item: any): boolean {\n    const fn = lockChoice?.value\n    return typeof fn === 'function' ? !!fn(unwrapObjectSourceItem(item)) : false\n  }\n\n  // Internal \"selected\" always stores full item(s)\n  const selected = ref<any>(multiple.value ? [] : null)\n\n  /**\n   * Bumped only by a committed user action — select, remove, clear. Hydration\n   * from a parent write does not touch it.\n   *\n   * The synthetic `input` event used to be driven by a deep watcher on\n   * `selected`, which also fired for a programmatic v-model assignment and for\n   * async re-hydration. A native control stays silent when code assigns to\n   * .value, so a form reset was marking the field dirty.\n   */\n  const commits = ref(0)\n\n  // --- Hydrate: convert modelValue into internal selected ---\n  function hydrateSelected(mv: any) {\n    if (mv == null || mv === undefined) {\n      selected.value = multiple.value ? [] : null\n      return\n    }\n\n    if (multiple.value) {\n      if (!Array.isArray(mv)) {\n        selected.value = []\n        return\n      }\n      if (bindProperty.value) {\n        // mv is an array of bound keys. Resolve each one in the order the model\n        // gives, preferring in turn:\n        //   1. a matching item in the current list,\n        //   2. an object we had already resolved for that key,\n        //   3. the bare key, to be hydrated once items arrive.\n        //\n        // Step 2 is what single mode has always done. Without it, a remote search\n        // that narrowed `items` downgraded every chip whose item fell out of the\n        // new page, so a tag rendered its raw id — or `undefined` through a slot\n        // reading a property. Resolving positionally also keeps the model's own\n        // order; unresolved values used to be shunted to the end.\n        const previous = Array.isArray(selected.value) ? selected.value : []\n        selected.value = mv.map((v: any) => {\n          const found = findItemByBoundValue(v)\n          if (found) return found\n          const alreadyResolved = previous.find(\n            (it: any) =>\n              it != null &&\n              typeof it === 'object' &&\n              stableStringify(resolveBindValue(it, bindProperty.value)) === stableStringify(v)\n          )\n          return alreadyResolved ?? v\n        })\n      } else {\n        selected.value = [...mv]\n      }\n    } else {\n      if (bindProperty.value) {\n        const found = findItemByBoundValue(mv)\n        if (found) {\n          selected.value = found\n        } else if (\n          // Keep current resolved object if its bound value still matches mv,\n          // so clearing async results or setting an ID before items load\n          // doesn't downgrade a full object to a raw primitive.\n          selected.value != null &&\n          typeof selected.value === 'object' &&\n          resolveBindValue(selected.value, bindProperty.value) === mv\n        ) {\n          // no-op: keep existing resolved object\n        } else {\n          selected.value = mv\n        }\n      } else {\n        selected.value = mv\n      }\n    }\n  }\n\n  function findItemByBoundValue(val: any): any {\n    return rawItems.value.find((item: any) => {\n      const bv = resolveBindValue(item, bindProperty.value)\n      return bv === val || stableStringify(bv) === stableStringify(val)\n    })\n  }\n\n  // Hydrate on mount and when modelValue changes externally\n  watch(modelValue, hydrateSelected, { immediate: true })\n\n  // Reconcile when `multiple` prop flips at runtime. Without this, the internal\n  // selected ref keeps its old shape (scalar vs array) and array-only paths crash.\n  watch(multiple, (isMulti) => {\n    if (isMulti) {\n      if (!Array.isArray(selected.value)) {\n        selected.value = selected.value != null ? [selected.value] : []\n      }\n    } else {\n      if (Array.isArray(selected.value)) {\n        selected.value = selected.value.length > 0 ? selected.value[0] : null\n      }\n    }\n    emitModelValue()\n  })\n\n  // Re-hydrate when items change (async hydration support).\n  // Only re-hydrate when rawItems is non-empty so that clearing\n  // async search results doesn't downgrade a resolved object back\n  // to a primitive key (which would blank the display).\n  watch(rawItems, () => {\n    if (bindProperty.value && modelValue.value != null && rawItems.value.length > 0) {\n      hydrateSelected(modelValue.value)\n    }\n  })\n\n  function unwrapForEmit(item: any): any {\n    return unwrapObjectSourceItem(item)\n  }\n\n  /**\n   * The value v-model holds right now. Shared with the event payloads, so a\n   * handler's `model` is always exactly what the parent just received — it used\n   * to be the internal array, which for a dictionary source meant the consumer\n   * saw { key, value } wrappers in `model` while v-model held bare values.\n   */\n  function currentModelValue(): any {\n    if (multiple.value) {\n      const arr = Array.isArray(selected.value) ? selected.value : []\n      return bindProperty.value\n        ? arr.map((it: any) =>\n            typeof it === 'object' ? resolveBindValue(it, bindProperty.value) : it\n          )\n        : arr.map(unwrapForEmit)\n    }\n    return bindProperty.value\n      ? selected.value != null && typeof selected.value === 'object'\n        ? resolveBindValue(selected.value, bindProperty.value)\n        : selected.value\n      : unwrapForEmit(selected.value)\n  }\n\n  // --- Emit: convert selected back to modelValue ---\n  function emitModelValue() {\n    emit('update:modelValue', currentModelValue())\n  }\n\n  // --- Selection methods ---\n  function isItemSelected(item: any): boolean {\n    if (multiple.value) {\n      const arr = Array.isArray(selected.value) ? selected.value : []\n      return arr.some((sel: any) => itemsEqual(sel, item))\n    }\n    return itemsEqual(selected.value, item)\n  }\n\n  function itemsEqual(a: any, b: any, memo?: Map<any, string>): boolean {\n    if (a === b) return true\n    if (a == null || b == null) return false\n\n    // v-model round-trips a dictionary source as the bare value, so after the\n    // parent writes it back the selection is a value while the dropdown rows are\n    // still { key, value } wrappers. Compare through the wrapper when exactly\n    // one side has one; when both do, compare them as they are, since trackBy\n    // may address the wrapper itself (`key`, or `value.id`).\n    const aWrapped = isObjectSourceItem(a)\n    const bWrapped = isObjectSourceItem(b)\n    if (aWrapped !== bWrapped) {\n      return itemsEqual(unwrapObjectSourceItem(a), unwrapObjectSourceItem(b), memo)\n    }\n\n    const tby = trackBy.value\n    if (tby) {\n      const ka = resolveTrackBy(a, tby)\n      const kb = resolveTrackBy(b, tby)\n      // Two items that merely both LACK the key are not thereby the same item.\n      // undefined === undefined used to fuse every keyless item into one, so a\n      // trackBy alongside string tags silently refused every tag after the first.\n      if (ka !== undefined && kb !== undefined) return ka === kb\n      // Otherwise fall through to structural comparison.\n    }\n    if (typeof a === 'object' && typeof b === 'object') {\n      return stableStringify(a, memo) === stableStringify(b, memo)\n    }\n    return false\n  }\n\n  /**\n   * A membership test for the whole current selection, for use across one pass\n   * over the item list.\n   *\n   * `remove-selected` asked isItemSelected() per item, and without a trackBy\n   * each of those calls re-serialized every selected item from scratch: 10,000\n   * items against 50 selections took 1.7 seconds of pure JSON work. The memo\n   * lives only as long as the returned function, so a pass serializes each item\n   * and each selection once — and because it is discarded afterwards, an item\n   * mutated between renders can never be compared against a stale string.\n   * Equality itself is unchanged: this is the same itemsEqual.\n   */\n  function createSelectionMatcher(): (item: any) => boolean {\n    const arr = multiple.value\n      ? (Array.isArray(selected.value) ? selected.value : [])\n      : (selected.value == null ? [] : [selected.value])\n    if (arr.length === 0) return () => false\n    const memo = new Map<any, string>()\n    return (item: any) => arr.some((sel: any) => itemsEqual(sel, item, memo))\n  }\n\n  function selectItem(item: any) {\n    if (item == null) return\n    if (multiple.value) {\n      // Re-selecting something already in the list changes nothing, so it must\n      // say nothing. It used to fall through and emit update:modelValue and\n      // select with an unchanged model — phantom events for consumers keeping\n      // side state, reachable via Enter on a visible selected row and via a\n      // repeated tagging token.\n      if (isItemSelected(item)) return\n      const arr = Array.isArray(selected.value) ? [...selected.value] : []\n      arr.push(item)\n      selected.value = arr\n    } else {\n      selected.value = item\n    }\n    commits.value += 1\n    emitModelValue()\n    // The item as the consumer recognises it, and the model they now hold.\n    emit('select', { item: unwrapForEmit(item), model: currentModelValue() })\n  }\n\n  function removeItem(item: any) {\n    if (multiple.value) {\n      const arr = Array.isArray(selected.value) ? [...selected.value] : []\n      const idx = arr.findIndex((sel: any) => itemsEqual(sel, item))\n      if (idx !== -1) {\n        arr.splice(idx, 1)\n        selected.value = arr\n        commits.value += 1\n        emitModelValue()\n        emit('remove', { item: unwrapForEmit(item), model: currentModelValue() })\n      }\n    } else {\n      const prev = selected.value\n      selected.value = null\n      commits.value += 1\n      emitModelValue()\n      emit('remove', { item: unwrapForEmit(prev), model: currentModelValue() })\n    }\n  }\n\n  function clearSelection() {\n    // Clearing an already-empty selection is a no-op — no model write, no\n    // events. The x icon and the keyboard path are gated on a selection\n    // anyway; this covers the exposed clear() method.\n    if (multiple.value) {\n      const prev = Array.isArray(selected.value) ? [...selected.value] : []\n      if (prev.length === 0) return\n      // Locked items survive the clear; with no lockChoice this is the whole\n      // list, so the payloads are identical to before.\n      const removable = prev.filter((item) => !isLocked(item))\n      if (removable.length === 0) return\n      selected.value = prev.filter((item) => isLocked(item))\n      commits.value += 1\n      emitModelValue()\n      // Per-item parity with removeItem(), so @remove handlers that maintain\n      // side state stay in sync when everything is cleared at once.\n      const model = currentModelValue()\n      removable.forEach((item) => emit('remove', { item: unwrapForEmit(item), model }))\n      emit('clear', { items: removable.map(unwrapForEmit), model })\n    } else {\n      const prev = selected.value\n      if (prev == null) return\n      if (isLocked(prev)) return\n      selected.value = null\n      commits.value += 1\n      emitModelValue()\n      const cleared = unwrapForEmit(prev)\n      emit('remove', { item: cleared, model: currentModelValue() })\n      emit('clear', { items: [cleared], model: currentModelValue() })\n    }\n  }\n\n  return {\n    selected,\n    commits,\n    isItemSelected,\n    createSelectionMatcher,\n    selectItem,\n    removeItem,\n    clearSelection,\n    itemsEqual,\n  }\n}\n","import { computed, type Ref, type ComputedRef } from 'vue'\nimport {\n  normalizeObjectSource,\n  getNestedValue,\n  isObjectSourceItem,\n  unwrapObjectSourceItem,\n} from '../utils/objectSource'\nimport type { GroupedItems, ChoicesConfig, EmptyReason } from '../types'\n\nexport function useSelectFiltering(opts: {\n  search: Ref<string>\n  choicesConfig: Ref<ChoicesConfig | null>\n  isItemSelected: (item: any) => boolean\n  /** Builds a membership test for one pass; see useModelBinding. */\n  createSelectionMatcher?: () => (item: any) => boolean\n  removeSelected: Ref<boolean>\n}) {\n  const { search, choicesConfig, isItemSelected, createSelectionMatcher, removeSelected } = opts\n\n  // Raw items normalized to an array\n  const rawItems = computed<any[]>(() => {\n    const cfg = choicesConfig.value\n    if (!cfg) return []\n    const items = cfg.items.value\n    // Plain objects (Records / dictionaries) are auto-detected and normalised;\n    // arrays pass through as-is.\n    if (items && typeof items === 'object' && !Array.isArray(items)) {\n      return normalizeObjectSource(items as Record<string, any>)\n    }\n    return Array.isArray(items) ? items : []\n  })\n\n  // Everything that matches the term, BEFORE the selection is subtracted.\n  // Kept separate from filteredItems so the empty state can tell \"nothing\n  // matched\" apart from \"it matched, but you have already picked it\".\n  const searchedItems = computed<any[]>(() => {\n    const cfg = choicesConfig.value\n    if (!cfg) return rawItems.value\n\n    let result = [...rawItems.value]\n\n    // Minimum input length. Measured on the TRIMMED term, matching the search\n    // below: untrimmed, three spaces cleared a threshold of 3 and then matched\n    // everything, so whitespace alone revealed the whole list.\n    if (\n      cfg.minimumInputLength.value > 0 &&\n      search.value.trim().length < cfg.minimumInputLength.value\n    ) {\n      return []\n    }\n\n    // Apply search filter\n    const q = search.value.trim().toLowerCase()\n    if (q) {\n      if (cfg.filterFn.value) {\n        // Consumer predicates address the value, exactly as the `choice` slot\n        // does; the { key, value } wrapper is ours, not theirs.\n        result = result.filter((item) =>\n          cfg.filterFn.value!(unwrapObjectSourceItem(item), search.value))\n      } else {\n        const fields = cfg.searchFields.value\n        result = result.filter((item) => matchesSearch(item, q, fields))\n      }\n    }\n\n    // Apply sort\n    if (cfg.sortFn.value) {\n      const sortFn = cfg.sortFn.value\n      result.sort((a, b) => sortFn(unwrapObjectSourceItem(a), unwrapObjectSourceItem(b)))\n    }\n\n    return result\n  })\n\n  // Filtered items (after search and selection removal, before grouping)\n  const filteredItems = computed<any[]>(() => {\n    if (!removeSelected.value) return searchedItems.value\n    // One matcher for the whole pass rather than a fresh comparison per item.\n    const isSelected = createSelectionMatcher ? createSelectionMatcher() : isItemSelected\n    return searchedItems.value.filter((item) => !isSelected(item))\n  })\n\n  /**\n   * Why the list is empty, or null when it is not.\n   *\n   * A blank panel was the worst answer the component could give: on an edit\n   * screen whose single select held its only option, remove-selected hid that\n   * option and the user was shown nothing at all. The three reasons call for\n   * three different messages, so they are told apart here rather than left to\n   * a guess in the template.\n   */\n  const emptyReason = computed<EmptyReason | null>(() => {\n    if (filteredItems.value.length > 0) return null\n    // Something matched; only the selection subtraction emptied the list.\n    if (searchedItems.value.length > 0) return 'all-selected'\n    if (search.value.trim()) return 'no-results'\n    return 'no-options'\n  })\n\n  // Grouped items\n  const groupedItems = computed<GroupedItems[]>(() => {\n    const cfg = choicesConfig.value\n    if (!cfg || !cfg.groupBy.value) {\n      return [{ label: undefined, items: filteredItems.value }]\n    }\n\n    const groupBy = cfg.groupBy.value\n    const map = new Map<string | undefined, any[]>()\n    const order: (string | undefined)[] = []\n\n    for (const item of filteredItems.value) {\n      const target = unwrapObjectSourceItem(item)\n      const rawLabel = typeof groupBy === 'function'\n        ? groupBy(target)\n        : getNestedValue(target, groupBy)\n      // `undefined` is this module's word for \"ungrouped\", and every downstream\n      // check tests for it exactly. A null or empty label therefore became a\n      // REAL group: it rendered a blank header, and the array form of\n      // groupFilter — which keeps only `undefined` plus its named groups —\n      // deleted it along with every item in it. Numbers become their text, so\n      // group-by=\"year\" still works.\n      const groupLabel =\n        rawLabel == null || rawLabel === '' ? undefined : String(rawLabel)\n      if (!map.has(groupLabel)) {\n        map.set(groupLabel, [])\n        order.push(groupLabel)\n      }\n      map.get(groupLabel)!.push(item)\n    }\n\n    let groups = order.map((label) => ({\n      label,\n      items: map.get(label)!,\n    }))\n\n    // Apply group filter. Both forms keep the ungrouped (undefined-label) group,\n    // sorted last — the array form used to silently drop items that lacked the\n    // groupBy property, while the function form kept them.\n    const gf = cfg.groupFilter.value\n    if (gf) {\n      if (Array.isArray(gf)) {\n        groups = groups.filter((g) => g.label === undefined || gf.includes(g.label))\n        groups.sort((a, b) => {\n          if (a.label === undefined) return 1\n          if (b.label === undefined) return -1\n          return gf.indexOf(a.label) - gf.indexOf(b.label)\n        })\n      } else if (typeof gf === 'function') {\n        const labels = groups.map((g) => g.label).filter((l): l is string => l !== undefined)\n        const filtered = gf(labels)\n        groups = groups.filter((g) => g.label === undefined || filtered.includes(g.label))\n        groups.sort((a, b) => {\n          if (a.label === undefined) return 1\n          if (b.label === undefined) return -1\n          return filtered.indexOf(a.label) - filtered.indexOf(b.label)\n        })\n      }\n    }\n\n    return groups\n  })\n\n  // Flat list of all visible items (for keyboard navigation indexing)\n  const flatFilteredItems = computed<any[]>(() => {\n    const result: any[] = []\n    for (const group of groupedItems.value) {\n      result.push(...group.items)\n    }\n    return result\n  })\n\n  return {\n    rawItems,\n    filteredItems,\n    groupedItems,\n    flatFilteredItems,\n    emptyReason,\n  }\n}\n\n/**\n * Whether one search-field value contains the query.\n *\n * Only primitives are searchable. An object stringifies to \"[object Object]\",\n * so a field pointing at one used to match every row for the query \"object\";\n * an array stringified to comma-joined text, which matched across element\n * boundaries. Arrays are searched element by element instead, which is what a\n * `tags: ['red','blue']` field is for.\n */\nfunction fieldMatches(val: any, query: string): boolean {\n  if (val == null) return false\n  if (Array.isArray(val)) return val.some((entry) => fieldMatches(entry, query))\n  const kind = typeof val\n  if (kind !== 'string' && kind !== 'number' && kind !== 'boolean') return false\n  return String(val).toLowerCase().includes(query)\n}\n\nfunction matchesSearch(item: any, query: string, fields: string[]): boolean {\n  // Unwrap object-source items so search-fields target the value, not the wrapper\n  const target = unwrapObjectSourceItem(item)\n\n  if (typeof target === 'string') {\n    return target.toLowerCase().includes(query)\n  }\n  if (typeof target === 'number') {\n    return String(target).includes(query)\n  }\n  if (typeof target !== 'object' || target === null) {\n    return false\n  }\n\n  if (fields.length > 0) {\n    return fields.some((field) => fieldMatches(getNestedValue(target, field), query))\n  }\n\n  // Object items with no declared search-fields pass through: the component\n  // only filters what it was told to filter. The old fallback matched against\n  // EVERY field, which silently re-filtered remote results — an API answering\n  // a code or fuzzy query had its rows dropped unless the consumer knew to\n  // pass filter-fn=\"() => true\". A remote list now works with no config, and\n  // a local object list that stops narrowing is a loud dev-time signal to add\n  // search-fields. Primitive items keep matching by value (see above).\n  return true\n}\n","import { type Ref, type ComputedRef } from 'vue'\nimport { unwrapObjectSourceItem } from '../utils/objectSource'\n\nexport function useSelectKeyboard(opts: {\n  isOpen: Ref<boolean>\n  search: Ref<string>\n  activeIndex: Ref<number>\n  flatFilteredItems: ComputedRef<any[]>\n  multiple: Ref<boolean>\n  disabled: Ref<boolean>\n  selected: Ref<any>\n  tagging: Ref<boolean | ((search: string) => any)>\n  taggingTokens: Ref<string[]>\n  disableChoice: Ref<((item: any) => boolean) | undefined>\n  clearable?: Ref<boolean>\n  /** Locked items refuse removal, so Backspace must step past them. */\n  lockChoice?: Ref<((item: any) => boolean) | undefined>\n  /** At the limit the unselected rows are disabled, so navigation skips them. */\n  isAtLimit?: Ref<boolean>\n  /** Reported with `limit-reached`; see reportTagLimit(). */\n  limit?: Ref<number | undefined>\n  /** Decides where Tab has to resume from — see the Tab case. */\n  appendToBody?: Ref<boolean>\n\n  open: () => void\n  close: () => void\n  selectItem: (item: any) => void\n  removeItem: (item: any) => void\n  isItemSelected: (item: any) => boolean\n  createTag: (search: string) => any\n  /** Whether the \"(new)\" row is on offer for the current term. */\n  shouldShowTagRow?: () => boolean\n  /** The visible option whose text equals a term, ignoring case. */\n  findExistingByTerm?: (term: string) => any\n  focus: () => void\n  /**\n   * Focuses the root element. In single mode the search input lives inside the\n   * dropdown, so closing unmounts it and a plain focus() has nothing left to\n   * target — keyboard focus would fall to <body>.\n   */\n  focusHost: () => void\n  /** Moves focus past the whole widget; see the Tab case. */\n  focusSibling?: (backwards: boolean) => boolean\n  clearSelection?: () => void\n\n  dropdownRef: Ref<HTMLElement | null>\n  inputRef: Ref<HTMLInputElement | null>\n\n  emit: (event: string, ...args: any[]) => void\n}) {\n  const {\n    isOpen, search, activeIndex, flatFilteredItems,\n    multiple, disabled, selected, tagging, taggingTokens,\n    disableChoice, clearable, lockChoice, appendToBody, isAtLimit, limit,\n    open, close, selectItem, removeItem, isItemSelected,\n    createTag, shouldShowTagRow, findExistingByTerm,\n    focus, focusHost, focusSibling, clearSelection,\n    dropdownRef, inputRef, emit,\n  } = opts\n\n  // Controls that own their keystrokes: the clear button, a tag's remove button,\n  // and anything focusable a consumer put in a slot.\n  const INTERACTIVE_SELECTOR =\n    'button, a[href], input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]'\n\n  /**\n   * True when the keystroke belongs to a control inside the widget that is not\n   * our own search box. The handler is bound on the root, so those events bubble\n   * into it: Enter on the clear button was preventDefault()ed and opened the\n   * dropdown instead of clearing, and a comma typed into a consumer's slot input\n   * created a tag.\n   */\n  function isForeignTarget(e: KeyboardEvent): boolean {\n    const target = e.target as HTMLElement | null\n    if (!target || typeof target.closest !== 'function') return false\n    if (target === inputRef.value) return false\n    const control = target.closest(INTERACTIVE_SELECTOR)\n    return !!control && control !== inputRef.value\n  }\n\n  /** Keystrokes aimed at our own search box, where text-editing defaults win. */\n  function isSearchBoxTarget(e: KeyboardEvent): boolean {\n    return !!inputRef.value && e.target === inputRef.value\n  }\n\n  function isLockedItem(item: any): boolean {\n    const fn = lockChoice?.value\n    return typeof fn === 'function' ? !!fn(unwrapObjectSourceItem(item)) : false\n  }\n\n  /**\n   * Reports a tag that the limit refused, and says whether it did.\n   *\n   * Tagging never reaches the select handler at the limit: createTag() returns\n   * null first. The option rows show they are full by going disabled, but a\n   * token keystroke has no row to grey out, so the refusal was invisible.\n   * Reported once per commit attempt, not once per token.\n   */\n  function reportTagLimit(term: string): boolean {\n    if (!isAtLimit?.value) return false\n    emit('limit-reached', { item: term, limit: limit?.value })\n    return true\n  }\n\n  function isChoiceDisabled(item: any): boolean {\n    if (disableChoice.value && disableChoice.value(unwrapObjectSourceItem(item))) return true\n    // Keep in step with the rendered rows: what looks disabled must not be\n    // reachable by arrow keys either.\n    if (isAtLimit?.value && !isItemSelected(item)) return true\n    return false\n  }\n\n  /**\n   * Builds the splitter for the configured tagging tokens.\n   *\n   * Tokens are matched as literal ALTERNATIVES rather than as a character class.\n   * A class silently reinterpreted them: '-' between two tokens became a range,\n   * so [',','-',';'] compiled to [,-;] and treated every digit as a separator,\n   * while [';','-',','] compiled to [;-,] and threw \"range out of order\" out of\n   * the search watcher. A class also decayed a multi-character token like ', '\n   * into its individual characters.\n   *\n   * Longest first, so a token that starts with another token still wins.\n   * Returns null when nothing usable is configured.\n   */\n  function buildTokenSplitter(): RegExp | null {\n    const literals = taggingTokens.value.filter((t) => typeof t === 'string' && t.length > 0)\n    if (literals.length === 0) return null\n    const pattern = [...literals]\n      .sort((a, b) => b.length - a.length)\n      .map((t) => t.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'))\n      .join('|')\n    return new RegExp(pattern)\n  }\n\n  function findNextEnabled(startIdx: number, direction: 1 | -1): number {\n    const items = flatFilteredItems.value\n    if (items.length === 0) return -1\n    let idx = startIdx\n    const max = items.length\n    for (let i = 0; i < max; i++) {\n      idx += direction\n      if (idx < 0) idx = max - 1\n      if (idx >= max) idx = 0\n      if (!isChoiceDisabled(items[idx])) return idx\n    }\n    return -1\n  }\n\n  function scrollActiveIntoView() {\n    if (!dropdownRef.value || activeIndex.value < 0) return\n    const el = dropdownRef.value.querySelector(\n      `[data-ui-select-choice-index=\"${activeIndex.value}\"]`\n    ) as HTMLElement | null\n    if (el && typeof el.scrollIntoView === 'function') {\n      el.scrollIntoView({ block: 'nearest' })\n    }\n  }\n\n  // The search box and the root both run this handler, and the event bubbles\n  // from one to the other. It used to be stopped at the input, which prevented\n  // the double-handling but also hid every search-box keystroke from a\n  // consumer's own @keydown on <ui-select>. Marking the event lets it bubble\n  // normally while still being acted on once.\n  const HANDLED = '__uiSelectHandled'\n\n  function handleKeyDown(e: KeyboardEvent) {\n    if ((e as any)[HANDLED]) return\n    ;(e as any)[HANDLED] = true\n    if (disabled.value) return\n    // Skip during IME composition (CJK input). keyCode 229 is the legacy IME signal.\n    // eslint-disable-next-line @typescript-eslint/no-deprecated\n    if (e.isComposing || e.keyCode === 229) return\n    // Leave another control's keystrokes to it. Escape is the exception: closing\n    // the dropdown is reasonable from anywhere inside the widget.\n    if (e.key !== 'Escape' && isForeignTarget(e)) return\n\n    const items = flatFilteredItems.value\n\n    switch (e.key) {\n      case 'ArrowDown': {\n        e.preventDefault()\n        if (!isOpen.value) {\n          open()\n          activeIndex.value = findNextEnabled(-1, 1)\n        } else {\n          activeIndex.value = findNextEnabled(activeIndex.value, 1)\n        }\n        scrollActiveIntoView()\n        emitHighlight()\n        break\n      }\n\n      case 'ArrowUp': {\n        e.preventDefault()\n        if (!isOpen.value) {\n          open()\n          activeIndex.value = findNextEnabled(items.length, -1)\n        } else {\n          activeIndex.value = findNextEnabled(activeIndex.value, -1)\n        }\n        scrollActiveIntoView()\n        emitHighlight()\n        break\n      }\n\n      case 'Enter': {\n        e.preventDefault()\n        if (isOpen.value && activeIndex.value >= 0 && activeIndex.value < items.length) {\n          const item = items[activeIndex.value]\n          if (!isChoiceDisabled(item)) {\n            selectItem(item)\n          }\n        } else if (isOpen.value && tagging.value && search.value.trim()) {\n          const term = search.value.trim()\n          // The click path only offers the \"(new)\" row when the term is really\n          // novel. Enter ignored that and always minted a raw string, so typing\n          // an existing option's name — or a different casing of it — committed\n          // a look-alike duplicate instead of the option itself.\n          if (shouldShowTagRow?.() === false) {\n            const existing = findExistingByTerm?.(term)\n            // An existing option is a normal pick, so the disabled row and the\n            // select handler between them already say no. Only a genuinely new\n            // term needs reporting from here.\n            if (existing !== undefined) {\n              if (!isChoiceDisabled(existing)) selectItem(existing)\n            } else {\n              reportTagLimit(term)\n            }\n          } else {\n            const tag = createTag(term)\n            if (tag != null) selectItem(tag)\n          }\n        } else if (!isOpen.value) {\n          open()\n        }\n        break\n      }\n\n      case 'Escape': {\n        if (isOpen.value) {\n          e.preventDefault()\n          e.stopPropagation()\n          close()\n          // Single mode: the input just unmounted with the dropdown, so focus\n          // the root. Multiple mode: the input lives in the match row and\n          // survives the close, so it keeps focus.\n          if (multiple.value) focus()\n          else focusHost()\n        }\n        break\n      }\n\n      case 'Tab': {\n        // Close without preventing default, to allow natural tab flow.\n        if (isOpen.value) {\n          close()\n          // Closing unmounts the focused search input before the browser gets to\n          // perform Tab's default action, so it has no starting point left and\n          // focus lands on <body>. Move focus ourselves, and only then suppress\n          // the default. If there is nowhere to go, leave the browser to it.\n          if (focusSibling?.(e.shiftKey)) {\n            e.preventDefault()\n          } else if (!multiple.value) {\n            focusHost()\n          }\n        }\n        break\n      }\n\n      case 'Backspace': {\n        if (search.value === '') {\n          if (multiple.value) {\n            const arr = Array.isArray(selected.value) ? selected.value : []\n            // Walk back to the nearest removable tag. Targeting the last one\n            // blindly meant a locked tag at the end made Backspace do nothing\n            // at all, rather than removing the one before it.\n            for (let i = arr.length - 1; i >= 0; i--) {\n              if (!isLockedItem(arr[i])) {\n                removeItem(arr[i])\n                break\n              }\n            }\n          } else if (clearable?.value && selected.value != null && clearSelection) {\n            clearSelection()\n          }\n        }\n        break\n      }\n\n      case 'Home': {\n        // Inside the search box these are text-editing keys; cancelling them\n        // stopped the user jumping the caret in a long search term.\n        if (isSearchBoxTarget(e)) break\n        if (isOpen.value && items.length > 0) {\n          e.preventDefault()\n          activeIndex.value = findNextEnabled(-1, 1)\n          scrollActiveIntoView()\n          emitHighlight()\n        }\n        break\n      }\n\n      case 'End': {\n        if (isSearchBoxTarget(e)) break\n        if (isOpen.value && items.length > 0) {\n          e.preventDefault()\n          activeIndex.value = findNextEnabled(items.length, -1)\n          scrollActiveIntoView()\n          emitHighlight()\n        }\n        break\n      }\n\n      default: {\n        // Tagging token check\n        if (tagging.value && taggingTokens.value.includes(e.key)) {\n          e.preventDefault()\n          const term = search.value.trim()\n          if (term && !reportTagLimit(term)) {\n            const tag = createTag(term)\n            if (tag != null) {\n              selectItem(tag)\n            }\n          }\n        }\n        break\n      }\n    }\n  }\n\n  function emitHighlight() {\n    const items = flatFilteredItems.value\n    if (activeIndex.value >= 0 && activeIndex.value < items.length) {\n      emit('highlight', items[activeIndex.value])\n    }\n  }\n\n  /**\n   * Handle paste events — split pasted text by tagging tokens and create\n   * individual tags for each non-empty segment.\n   */\n  function handlePaste(e: ClipboardEvent) {\n    if (!tagging.value || taggingTokens.value.length === 0) return\n\n    const text = e.clipboardData?.getData('text')\n    if (!text) return\n\n    const re = buildTokenSplitter()\n    if (!re) return\n    const parts = text.split(re).map((s) => s.trim()).filter(Boolean)\n\n    if (parts.length <= 1 && !re.test(text)) {\n      // No tokens found in pasted text — let the browser handle normally\n      return\n    }\n\n    e.preventDefault()\n\n    if (reportTagLimit(text.trim())) return\n\n    // Also tag whatever was already typed in the search box\n    const existing = search.value.trim()\n    if (existing) {\n      const tag = createTag(existing)\n      if (tag != null) selectItem(tag)\n    }\n\n    for (const part of parts) {\n      const tag = createTag(part)\n      if (tag != null) selectItem(tag)\n    }\n  }\n\n  let isHandlingTokens = false\n  /** Guards handleSearchInput against reporting the same stuck term repeatedly. */\n  let tokenLimitReported = false\n\n  /**\n   * Called after `search` changes (via `@input` or v-model watcher).\n   * Handles token characters that slip past the keydown handler — e.g. from\n   * mobile soft-keyboards, IME, or browser auto-fill.\n   */\n  function handleSearchInput() {\n    if (isHandlingTokens) return\n    if (!tagging.value || taggingTokens.value.length === 0) return\n\n    const val = search.value\n    if (!val) { tokenLimitReported = false; return }\n\n    const re = buildTokenSplitter()\n    if (!re || !re.test(val)) { tokenLimitReported = false; return }\n\n    const parts = val.split(re).map((s) => s.trim()).filter(Boolean)\n\n    // Unlike the paths above, this one runs on every keystroke, and at the\n    // limit it deliberately leaves the text in place — so it would report again\n    // for each further character typed. Once per stuck term is enough; the flag\n    // clears as soon as the tokens go, or the limit does.\n    if (parts.length > 0 && isAtLimit?.value) {\n      if (!tokenLimitReported) {\n        tokenLimitReported = true\n        reportTagLimit(val.trim())\n      }\n      return\n    }\n    tokenLimitReported = false\n\n    // Build the tags BEFORE touching the search box. Clearing first meant a\n    // batch that produced nothing — limit reached, or a factory that rejected\n    // every part — silently ate what the user had typed.\n    const tags = parts.map((part) => createTag(part)).filter((tag) => tag != null)\n    if (tags.length === 0) return\n\n    // Set guard so the recursive search-watcher fires only once (for the empty value).\n    isHandlingTokens = true\n    try {\n      search.value = ''\n      for (const tag of tags) selectItem(tag)\n    } finally {\n      isHandlingTokens = false\n    }\n  }\n\n  return {\n    handleKeyDown,\n    handlePaste,\n    handleSearchInput,\n    scrollActiveIntoView,\n  }\n}\n","// Teleporting the dropdown to <body> moves it out of the DOM subtree it visually\n// belongs to. The browser chains wheel scrolling along DOM ancestors, so once the\n// dropdown's own list is exhausted the scroll is handed to <body> — never to the\n// container the select actually sits in. App shells commonly scroll on an inner\n// element and leave <body> at overflow:hidden, and there the page simply stops\n// responding to the wheel for as long as the dropdown is open.\n//\n// These helpers let the dropdown forward what it cannot consume itself back to\n// the container it visually belongs to.\n\nconst SCROLLABLE_OVERFLOW = /^(auto|scroll|overlay)$/\n\n// Sub-pixel scroll heights are common, so treat \"within a pixel of the end\" as\n// the end — otherwise the last fraction of a pixel swallows the event forever.\nconst END_OF_SCROLL_TOLERANCE = 1\n\nexport type ScrollAxis = 'x' | 'y'\n\nexport function isScrollable(el: HTMLElement, axis: ScrollAxis): boolean {\n  const style = getComputedStyle(el)\n  const overflow = axis === 'y' ? style.overflowY : style.overflowX\n  if (!SCROLLABLE_OVERFLOW.test(overflow)) return false\n\n  return axis === 'y' ? el.scrollHeight > el.clientHeight : el.scrollWidth > el.clientWidth\n}\n\n/**\n * Whether `el` can still move in the direction `delta` points, so a scroll that\n * has already bottomed out is passed on instead of being silently absorbed.\n */\nexport function canScrollFurther(el: HTMLElement, delta: number, axis: ScrollAxis): boolean {\n  if (delta === 0) return false\n\n  const offset = axis === 'y' ? el.scrollTop : el.scrollLeft\n  const max =\n    axis === 'y' ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth\n\n  return delta < 0 ? offset > 0 : offset < max - END_OF_SCROLL_TOLERANCE\n}\n\n/**\n * Nearest scrolling ancestor of `start`, stopping at <body>: the document itself\n * is reachable by the browser's own chaining and needs no help from us.\n */\nexport function findScrollableAncestor(\n  start: HTMLElement | null,\n  axis: ScrollAxis,\n): HTMLElement | null {\n  let el = start?.parentElement ?? null\n\n  while (el && el !== document.body && el !== document.documentElement) {\n    if (isScrollable(el, axis)) return el\n    el = el.parentElement\n  }\n\n  return null\n}\n\n// Wheel deltas arrive in pixels, lines or pages depending on the input device.\nconst LINE_HEIGHT = 16\nconst PAGE_HEIGHT_FALLBACK = 400\n\nexport function normalizeWheelDelta(event: WheelEvent, viewportSize: number): number {\n  if (event.deltaMode === 1) return event.deltaY * LINE_HEIGHT\n  if (event.deltaMode === 2) return event.deltaY * (viewportSize || PAGE_HEIGHT_FALLBACK)\n\n  return event.deltaY\n}\n\n\nconst CLIPPING_OVERFLOW = /(auto|scroll|hidden|clip)/\n\n/**\n * Whether `el` has been scrolled out of view of an ancestor that clips it.\n *\n * This matters only for a teleported dropdown. Hanging off <body>, it is not\n * clipped by the containers its trigger lives in, so once the trigger scrolls\n * out of one the dropdown carries on being painted over whatever now occupies\n * that space — anchored to a control the user can no longer see.\n */\nexport function isClippedByAncestor(el: HTMLElement | null): boolean {\n  if (!el) return false\n  const rect = el.getBoundingClientRect()\n  let node = el.parentElement\n\n  while (node && node !== document.body && node !== document.documentElement) {\n    const style = getComputedStyle(node)\n    const clips =\n      CLIPPING_OVERFLOW.test(style.overflow) ||\n      CLIPPING_OVERFLOW.test(style.overflowX) ||\n      CLIPPING_OVERFLOW.test(style.overflowY)\n\n    if (clips) {\n      const box = node.getBoundingClientRect()\n      const outside =\n        rect.bottom <= box.top ||\n        rect.top >= box.bottom ||\n        rect.right <= box.left ||\n        rect.left >= box.right\n      if (outside) return true\n    }\n    node = node.parentElement\n  }\n\n  return false\n}\n","import { ref, onBeforeUnmount, watch, type Ref, nextTick } from 'vue'\nimport type { DropdownPosition } from '../types'\nimport {\n  canScrollFurther,\n  findScrollableAncestor,\n  isClippedByAncestor,\n  isScrollable,\n  normalizeWheelDelta,\n} from '../utils/scrollChaining'\n\nexport function useSelectPositioning(opts: {\n  isOpen: Ref<boolean>\n  appendToBody: Ref<boolean>\n  position: Ref<DropdownPosition>\n  rootRef: Ref<HTMLElement | null>\n  dropdownRef: Ref<HTMLElement | null>\n}) {\n  const { isOpen, appendToBody, position, rootRef, dropdownRef } = opts\n\n  const resolvedPosition = ref<'up' | 'down'>('down')\n  const teleportStyle = ref<Record<string, string>>({})\n  const dropdownMaxHeight = ref<string | undefined>(undefined)\n\n  // Small breathing room (px) between the dropdown and the top edge of the viewport\n  const VIEWPORT_PADDING = 8\n\n\n  /**\n   * Where the teleported dropdown's coordinates are measured from, in DOCUMENT\n   * coordinates.\n   *\n   * An absolutely positioned child of <body> normally resolves against the\n   * initial containing block: anchored at the document origin and the size of\n   * the viewport. But if <body> or <html> is itself positioned or transformed,\n   * it resolves against that element's PADDING BOX instead — so an app shell\n   * that does no more than `body { position: relative; margin: 40px }` shifted\n   * every teleported dropdown by its own margin.\n   *\n   * For the ordinary static case this returns the initial containing block, and\n   * the arithmetic below reduces exactly to what it was.\n   */\n  function containingBlock() {\n    const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n    const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft\n    const body = document.body\n    // Treat an empty computed value as the initial one: not every environment\n    // reports `static` / `none` explicitly.\n    const host = [body, document.documentElement].find((el) => {\n      if (!el) return false\n      const style = getComputedStyle(el)\n      const position = style.position || 'static'\n      const transform = style.transform || 'none'\n      return position !== 'static' || transform !== 'none'\n    })\n\n    if (!host) {\n      return { top: 0, left: 0, height: window.innerHeight, scrollTop, scrollLeft }\n    }\n\n    const style = getComputedStyle(host)\n    const rect = host.getBoundingClientRect()\n    return {\n      top: rect.top + scrollTop + (parseFloat(style.borderTopWidth) || 0),\n      left: rect.left + scrollLeft + (parseFloat(style.borderLeftWidth) || 0),\n      height: host.clientHeight,\n      scrollTop,\n      scrollLeft,\n    }\n  }\n\n  function calculatePosition() {\n    if (!rootRef.value) return\n\n    const rootEl = rootRef.value\n    const rect = rootEl.getBoundingClientRect()\n\n    if (position.value === 'up') {\n      resolvedPosition.value = 'up'\n    } else if (position.value === 'down') {\n      resolvedPosition.value = 'down'\n    } else {\n      // Auto: check available space\n      const spaceBelow = window.innerHeight - rect.bottom\n      const spaceAbove = rect.top\n      // The dropdown's own CONTENT height, independent of any cap we applied.\n      // Measuring the rendered height instead made this decision depend on its\n      // own previous output: capping the list to fit above makes it fit below,\n      // which flips it down, which removes the cap, which stops it fitting\n      // below, which flips it up — forever, with the ResizeObserver driving a\n      // turn of the loop on every resize. It only bites when the space above\n      // exceeds the space below by less than the viewport padding, but a\n      // vertically centred control sits exactly there.\n      const el = dropdownRef.value\n      const dropdownHeight = el ? Math.max(el.scrollHeight, el.offsetHeight) || 300 : 300\n      resolvedPosition.value = spaceBelow < dropdownHeight && spaceAbove > spaceBelow ? 'up' : 'down'\n    }\n\n    // Cap dropdown height when opening upward so it never touches viewport top\n    if (resolvedPosition.value === 'up') {\n      const availableAbove = rect.top - VIEWPORT_PADDING\n      dropdownMaxHeight.value = `${Math.max(availableAbove, 100)}px`\n    } else {\n      dropdownMaxHeight.value = undefined\n    }\n\n    // Calculate teleport positioning\n    if (appendToBody.value) {\n      const cb = containingBlock()\n      const { scrollTop, scrollLeft } = cb\n      // The trigger's edges in document coordinates.\n      const triggerTop = rect.top + scrollTop\n      const triggerBottom = rect.bottom + scrollTop\n      const triggerLeft = rect.left + scrollLeft\n      // A teleported dropdown is not clipped by the containers its trigger sits\n      // in, so once the trigger scrolls out of one the dropdown keeps being\n      // painted over whatever is now in that space. Hide it rather than close\n      // it: the selection, the search term and the highlight all survive, and it\n      // comes straight back when the trigger scrolls into view again.\n      const hidden = isClippedByAncestor(rootRef.value)\n      const visibility = hidden ? 'hidden' : 'visible'\n      const pointerEvents = hidden ? 'none' : 'auto'\n\n      // `right: auto` is not decoration. The themes give the dropdown both\n      // `left: 0` and `right: 0` so that, rendered in place, it stretches to the\n      // control's width. Teleported, we set `left` and `width` inline — which\n      // leaves left, right and width all specified, i.e. over-constrained. CSS\n      // resolves that by dropping one of them, and which one depends on the\n      // writing direction: LTR drops `right`, RTL drops `left`. So in an RTL\n      // document the dropdown ignored its inline `left` and pinned itself to the\n      // right edge of the viewport instead of to its own control.\n      if (resolvedPosition.value === 'up') {\n        teleportStyle.value = {\n          position: 'absolute',\n          right: 'auto',\n          left: `${triggerLeft - cb.left}px`,\n          // `bottom` counts UP from the containing block's bottom edge. Equating\n          // that with the trigger's top edge gives the expression below; adding\n          // the scroll offset instead of subtracting it put the dropdown\n          // 2*scrollTop too high, off-screen on any scrolled page.\n          bottom: `${cb.top + cb.height - triggerTop}px`,\n          width: `${rect.width}px`,\n          zIndex: '9999',\n          visibility,\n          pointerEvents,\n        }\n      } else {\n        teleportStyle.value = {\n          position: 'absolute',\n          right: 'auto',\n          left: `${triggerLeft - cb.left}px`,\n          top: `${triggerBottom - cb.top}px`,\n          width: `${rect.width}px`,\n          zIndex: '9999',\n          visibility,\n          pointerEvents,\n        }\n      }\n    }\n  }\n\n  /**\n   * Teleporting to <body> takes the dropdown out of the scroll container it\n   * visually belongs to, and the browser chains wheel scrolling along DOM\n   * ancestors. So a wheel over an open dropdown reaches <body> — which app\n   * shells routinely leave at overflow:hidden — and the page stops scrolling\n   * entirely until the dropdown closes.\n   *\n   * Bridge that gap: anything scrollable inside the dropdown gets the scroll\n   * first, and only what is left over is handed to the select's own container.\n   */\n  function handleDropdownWheel(event: WheelEvent) {\n    const dropdownEl = dropdownRef.value\n    if (!appendToBody.value || !dropdownEl) return\n\n    // First refusal to the dropdown's own scrollers (the choices list).\n    let node = event.target as HTMLElement | null\n    while (node && dropdownEl.contains(node)) {\n      if (isScrollable(node, 'y') && canScrollFurther(node, event.deltaY, 'y')) return\n      node = node.parentElement\n    }\n\n    // Walk outwards through the ancestors, not just to the nearest one. The\n    // browser would chain past a scroller that has reached its end and carry on\n    // to the next one out; teleporting severs the dropdown from all of them, so\n    // stopping at the first exhausted scroller left a panel inside a scrolling\n    // page body unable to scroll the page at all.\n    let container = findScrollableAncestor(rootRef.value, 'y')\n    while (container && !canScrollFurther(container, event.deltaY, 'y')) {\n      container = findScrollableAncestor(container, 'y')\n    }\n    if (!container) return\n\n    // preventDefault only once there is something of ours to scroll, so the\n    // browser's own chaining still applies in every other case.\n    event.preventDefault()\n    container.scrollTop += normalizeWheelDelta(event, container.clientHeight)\n  }\n\n  let scrollListener: (() => void) | null = null\n  let resizeListener: (() => void) | null = null\n  let dropdownObserver: ResizeObserver | null = null\n  let wheelTarget: HTMLElement | null = null\n  let repositionFrame = 0\n\n  // The scroll listener is capture-phase on window, so it fires for EVERY scroll\n  // anywhere in the document — including the dropdown's own list. Recalculating\n  // synchronously per event means a getBoundingClientRect (forced layout) per\n  // scroll tick; coalesce to one recalculation per frame instead.\n  function scheduleReposition() {\n    if (repositionFrame) return\n    repositionFrame = requestAnimationFrame(() => {\n      repositionFrame = 0\n      calculatePosition()\n    })\n  }\n\n  function addListeners() {\n    scrollListener = () => scheduleReposition()\n    resizeListener = () => scheduleReposition()\n    window.addEventListener('scroll', scrollListener, true)\n    window.addEventListener('resize', resizeListener)\n    // Observe the TRIGGER as well as the dropdown. A teleported dropdown is\n    // anchored to the trigger's edges, so the trigger changing height moves the\n    // anchor — which is routine in multiple mode, where adding a tag can wrap\n    // the row onto another line. It happened to work already, because growing\n    // the trigger reflows the page and that fires the scroll listener, but that\n    // is incidental: a trigger that grows without disturbing anything around it\n    // would leave the dropdown behind.\n    if (typeof ResizeObserver !== 'undefined') {\n      const observed = [dropdownRef.value, rootRef.value].filter(Boolean) as HTMLElement[]\n      if (observed.length > 0) {\n        dropdownObserver = new ResizeObserver(() => calculatePosition())\n        observed.forEach((el) => dropdownObserver!.observe(el))\n      }\n    }\n    // Only teleported dropdowns need the bridge; in place, chaining already works.\n    if (appendToBody.value && dropdownRef.value) {\n      wheelTarget = dropdownRef.value\n      wheelTarget.addEventListener('wheel', handleDropdownWheel, { passive: false })\n    }\n  }\n\n  function removeListeners() {\n    if (scrollListener) {\n      window.removeEventListener('scroll', scrollListener, true)\n      scrollListener = null\n    }\n    if (resizeListener) {\n      window.removeEventListener('resize', resizeListener)\n      resizeListener = null\n    }\n    if (dropdownObserver) {\n      dropdownObserver.disconnect()\n      dropdownObserver = null\n    }\n    if (wheelTarget) {\n      wheelTarget.removeEventListener('wheel', handleDropdownWheel)\n      wheelTarget = null\n    }\n    if (repositionFrame) {\n      cancelAnimationFrame(repositionFrame)\n      repositionFrame = 0\n    }\n  }\n\n  watch(isOpen, async (val) => {\n    if (val) {\n      await nextTick()\n      calculatePosition()\n      addListeners()\n    } else {\n      removeListeners()\n    }\n  })\n\n  // Recalculate when position-influencing props change while open.\n  watch([position, appendToBody], () => {\n    if (!isOpen.value) return\n    calculatePosition()\n    // appendToBody decides whether the wheel bridge is needed, so rebind it.\n    removeListeners()\n    addListeners()\n  })\n\n  onBeforeUnmount(() => {\n    removeListeners()\n  })\n\n  return {\n    resolvedPosition,\n    teleportStyle,\n    dropdownMaxHeight,\n    calculatePosition,\n  }\n}\n","import type { Ref, ComputedRef } from 'vue'\n\nexport function useSelectTagging(opts: {\n  tagging: Ref<boolean | ((search: string) => any)>\n  taggingLabel: Ref<string | false>\n  taggingTokens: Ref<string[]>\n  search: Ref<string>\n  multiple: Ref<boolean>\n  limit: Ref<number | undefined>\n  selected: Ref<any>\n  flatFilteredItems: ComputedRef<any[]>\n  isItemSelected: (item: any) => boolean\n  itemsEqual: (a: any, b: any) => boolean\n}) {\n  const {\n    tagging, taggingLabel, search,\n    multiple, limit, selected,\n    flatFilteredItems, isItemSelected, itemsEqual,\n  } = opts\n\n  /** Returns true if tagging is enabled */\n  function isTaggingEnabled(): boolean {\n    return !!tagging.value\n  }\n\n  // shouldShowTagRow is called from the template, and it used to build a tag\n  // just to inspect it — running the consumer's factory on every render. A\n  // factory of the documented `(s) => ({ id: nextId++, name: s })` shape then\n  // burned an id per render rather than per tag. Cache the preview per term.\n  let previewTerm: string | null = null\n  let previewValue: any = null\n\n  function previewTag(term: string): any {\n    if (previewTerm === term) return previewValue\n    previewTerm = term\n    previewValue = createTag(term)\n    return previewValue\n  }\n\n  /**\n   * The item in the visible list whose text is exactly this term, ignoring case\n   * — the same comparison that hides the \"(new)\" row. Enter uses it to commit\n   * the real option instead of a look-alike string.\n   */\n  function findExistingByTerm(term: string): any {\n    const needle = term.trim().toLowerCase()\n    if (!needle) return undefined\n    return flatFilteredItems.value.find(\n      (item) => typeof item === 'string' && item.toLowerCase() === needle\n    )\n  }\n\n  /**\n   * Create a tag object from the current search string.\n   * If tagging is a function, calls it; otherwise returns the raw string.\n   */\n  function createTag(searchText: string): any {\n    if (!searchText.trim()) return null\n\n    // Check limit\n    if (multiple.value && limit.value != null) {\n      const arr = Array.isArray(selected.value) ? selected.value : []\n      if (arr.length >= limit.value) return null\n    }\n\n    const tagFn = tagging.value\n    if (typeof tagFn === 'function') {\n      const result = tagFn(searchText)\n      // Reject null/undefined or strings that are empty after trimming.\n      // Object results are accepted as-is; consumers are responsible for shape.\n      if (result == null) return null\n      if (typeof result === 'string' && !result.trim()) return null\n      return result\n    }\n    return searchText\n  }\n\n  /**\n   * Whether the \"create tag\" row should be shown in the dropdown.\n   * Only show when:\n   * 1. Tagging is enabled\n   * 2. There's search text\n   * 3. The exact search text does not already exist in the items\n   * 4. The search text is not already selected\n   */\n  function shouldShowTagRow(): boolean {\n    if (!isTaggingEnabled()) return false\n    const q = search.value.trim()\n    if (!q) return false\n\n    // Check limit\n    if (multiple.value && limit.value != null) {\n      const arr = Array.isArray(selected.value) ? selected.value : []\n      if (arr.length >= limit.value) return false\n    }\n\n    // Check if exact match exists in filtered items\n    const potentialTag = previewTag(q)\n    if (potentialTag == null) return false\n\n    // Check if already in filtered items\n    const existsInItems = flatFilteredItems.value.some((item) =>\n      itemsEqual(item, potentialTag) ||\n      (typeof item === 'string' && item.toLowerCase() === q.toLowerCase()) ||\n      (typeof potentialTag === 'string' && typeof item === 'string' && item.toLowerCase() === potentialTag.toLowerCase())\n    )\n    if (existsInItems) return false\n\n    // Check if already selected\n    if (isItemSelected(potentialTag)) return false\n\n    return true\n  }\n\n  /**\n   * Get the display label for the tag row.\n   */\n  function getTagRowLabel(): string {\n    const label = taggingLabel.value\n    if (label === false) return search.value.trim()\n    return `${search.value.trim()} ${label}`\n  }\n\n  return {\n    isTaggingEnabled,\n    createTag,\n    findExistingByTerm,\n    shouldShowTagRow,\n    getTagRowLabel,\n  }\n}\n","import { computed, type Ref, type ComputedRef } from 'vue'\n\nexport function useSelectAccessibility(opts: {\n  uid: string\n  isOpen: Ref<boolean>\n  activeIndex: Ref<number>\n  multiple: Ref<boolean>\n  disabled: Ref<boolean>\n  selected: Ref<any>\n  flatFilteredItems: ComputedRef<any[]>\n  placeholder: Ref<string>\n  inputId: Ref<string | undefined>\n  appendToBody?: Ref<boolean>\n  /** When there is no search input, the root is the focused element. */\n  searchEnabled?: Ref<boolean>\n}) {\n  const {\n    uid, isOpen, activeIndex, multiple, disabled, flatFilteredItems,\n    placeholder, inputId, appendToBody, searchEnabled,\n  } = opts\n\n  const listboxId = `${uid}-listbox`\n  const inputElId = computed(() => inputId.value || `${uid}-input`)\n\n  const activeDescendantId = computed(() => {\n    if (activeIndex.value >= 0 && activeIndex.value < flatFilteredItems.value.length) {\n      return `${uid}-option-${activeIndex.value}`\n    }\n    return undefined\n  })\n\n  /** ARIA attributes for the root combobox container */\n  const rootAriaAttrs = computed(() => ({\n    role: 'combobox',\n    'aria-expanded': isOpen.value,\n    'aria-haspopup': 'listbox' as const,\n    // aria-owns is only needed when the listbox is NOT a DOM descendant (teleported).\n    'aria-owns': isOpen.value && appendToBody?.value ? listboxId : undefined,\n    'aria-disabled': disabled.value || undefined,\n    // With no search input the root is what the user focuses, so the active\n    // option has to be announced from here or arrow-key navigation is silent.\n    // (With an input, that input carries it instead — see inputAriaAttrs.)\n    'aria-activedescendant': searchEnabled?.value === false ? activeDescendantId.value : undefined,\n    // NOTE: aria-multiselectable is deliberately NOT here. It is not an allowed\n    // attribute on role=\"combobox\"; it belongs on the listbox, which now\n    // receives it via listboxAriaAttrs.\n  }))\n\n  /** ARIA attributes for the search input */\n  const inputAriaAttrs = computed(() => ({\n    role: 'searchbox',\n    'aria-autocomplete': 'list' as const,\n    'aria-controls': isOpen.value ? listboxId : undefined,\n    'aria-activedescendant': activeDescendantId.value,\n    'aria-label': placeholder.value || 'Search',\n    id: inputElId.value,\n  }))\n\n  /** ARIA attributes for the dropdown listbox */\n  const listboxAriaAttrs = computed(() => ({\n    role: 'listbox',\n    id: listboxId,\n    'aria-multiselectable': multiple.value || undefined,\n    'aria-label': 'Options',\n  }))\n\n  /** Generate ARIA attributes for an individual option */\n  function optionAriaAttrs(index: number, isSelected: boolean, isDisabled: boolean) {\n    return {\n      role: 'option',\n      id: `${uid}-option-${index}`,\n      'aria-selected': isSelected,\n      'aria-disabled': isDisabled || undefined,\n    }\n  }\n\n  /** ARIA attributes for group headers */\n  function groupHeaderAriaAttrs(label: string) {\n    return {\n      role: 'presentation',\n      'aria-label': label,\n    }\n  }\n\n  return {\n    listboxId,\n    inputElId,\n    activeDescendantId,\n    rootAriaAttrs,\n    inputAriaAttrs,\n    listboxAriaAttrs,\n    optionAriaAttrs,\n    groupHeaderAriaAttrs,\n  }\n}\n","import { computed, type Ref } from 'vue'\nimport type { ThemeName } from '../types'\n\n/**\n * Provides theme-specific data attributes and class helpers.\n * Components use semantic CSS classes + data attributes.\n * Each theme CSS file targets these hooks.\n */\nexport function useThemeClasses(theme: Ref<ThemeName>) {\n\n  const themeDataAttr = computed(() => ({\n    'data-ui-select-theme': theme.value,\n  }))\n\n  /** \n   * Generates data attributes for a specific component part.\n   * These are used by theme CSS selectors.\n   */\n  function partAttrs(part: string, state?: Record<string, boolean | string | undefined>) {\n    const attrs: Record<string, string | boolean | undefined> = {\n      [`data-ui-select-${part}`]: '',\n    }\n    if (state) {\n      for (const [key, val] of Object.entries(state)) {\n        if (val === true) {\n          attrs[`data-${key}`] = ''\n        } else if (typeof val === 'string') {\n          attrs[`data-${key}`] = val\n        }\n      }\n    }\n    return attrs\n  }\n\n  return {\n    themeDataAttr,\n    partAttrs,\n  }\n}\n","/**\n * Wraps matching portions of `text` in <mark> tags for visual highlighting.\n * Escapes HTML to prevent XSS.\n *\n * Matching runs on the RAW text and escaping happens per segment afterwards.\n * The old escape-first order had two failure modes on text containing\n * `& < > \" '`: a search term with one of those characters could never match\n * its own escaped text (\"AT&T\" vs \"AT&amp;T\"), and a term like \"amp\" or \"lt\"\n * matched INSIDE an entity, splitting it with <mark> and corrupting the\n * rendered output.\n */\nexport function highlightText(text: string, search: string): string {\n  const raw = text ?? ''\n  if (!search || !raw) return escapeHtml(raw)\n\n  const regex = new RegExp(escapeRegExp(search), 'gi')\n  let result = ''\n  let lastIndex = 0\n\n  for (const match of raw.matchAll(regex)) {\n    const start = match.index ?? 0\n    result += escapeHtml(raw.slice(lastIndex, start))\n    result += `<mark>${escapeHtml(match[0])}</mark>`\n    lastIndex = start + match[0].length\n  }\n\n  return result + escapeHtml(raw.slice(lastIndex))\n}\n\nfunction escapeHtml(str: string): string {\n  return str\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#39;')\n}\n\nfunction escapeRegExp(str: string): string {\n  return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n","<script lang=\"ts\">\nimport {\n  defineComponent,\n  provide,\n  inject,\n  toRef,\n  toRefs,\n  computed,\n  watch,\n  ref,\n  shallowRef,\n  onMounted,\n  onBeforeUnmount,\n  onBeforeUpdate,\n  onUpdated,\n  nextTick,\n  type PropType,\n} from 'vue'\nimport type {\n  DropdownPosition,\n  ThemeName,\n  ChoicesConfig,\n  UiSelectContext,\n  UiSelectPluginOptions,\n  UiSelectMessages,\n  NoChoiceSlotScope,\n} from '../types'\nimport { UI_SELECT_CONTEXT, UI_SELECT_OPTIONS } from '../symbols'\nimport { useSelectState } from '../composables/useSelectState'\nimport { useModelBinding } from '../composables/useModelBinding'\nimport { useSelectFiltering } from '../composables/useSelectFiltering'\nimport { useSelectKeyboard } from '../composables/useSelectKeyboard'\nimport { useSelectPositioning } from '../composables/useSelectPositioning'\nimport { useSelectTagging } from '../composables/useSelectTagging'\nimport { useSelectAccessibility } from '../composables/useSelectAccessibility'\nimport { useThemeClasses } from '../composables/useThemeClasses'\nimport { highlightText } from '../utils/highlight'\nimport { normalizeObjectSource, unwrapObjectSourceItem } from '../utils/objectSource'\n\nexport default defineComponent({\n  name: 'UiSelect',\n  inheritAttrs: false,\n  props: {\n    modelValue: { type: null as unknown as PropType<any>, default: undefined },\n    multiple: { type: Boolean, default: false },\n    disabled: { type: Boolean, default: false },\n    searchEnabled: { type: Boolean as PropType<boolean | undefined>, default: undefined },\n    resetSearchInput: { type: Boolean, default: true },\n    closeOnSelect: { type: Boolean as PropType<boolean | undefined>, default: undefined },\n    appendToBody: { type: Boolean as PropType<boolean | undefined>, default: undefined },\n    position: { type: String as PropType<DropdownPosition>, default: 'auto' },\n    theme: { type: String as PropType<ThemeName | undefined>, default: undefined },\n    placeholder: { type: String, default: '' },\n    // `undefined` rather than `false`, like the other plugin-defaultable props:\n    // Vue casts a Boolean-typed prop to `false` when omitted, and that would make\n    // `props.clearable ?? pluginOptions.defaults.clearable` resolve before it\n    // ever reached the plugin value.\n    clearable: { type: Boolean as PropType<boolean | undefined>, default: undefined },\n    tagging: { type: [Boolean, Function] as PropType<boolean | ((search: string) => any)>, default: false },\n    taggingLabel: { type: [String, Boolean] as PropType<string | false>, default: '(new)' },\n    taggingTokens: { type: Array as PropType<string[]>, default: () => [','] },\n    limit: { type: Number as PropType<number | undefined>, default: undefined },\n    // Same shape as `clearable`: a Boolean prop with a concrete default is\n    // never \"absent\", which would put the plugin default out of reach.\n    removeSelected: { type: Boolean as PropType<boolean | undefined>, default: undefined },\n    loading: { type: Boolean, default: false },\n    autofocus: { type: Boolean, default: false },\n    inputId: { type: String as PropType<string | undefined>, default: undefined },\n    lockChoice: { type: Function as PropType<((item: any) => boolean) | undefined>, default: undefined },\n    // Milliseconds to wait after typing stops before emitting `search`. Sits here\n    // rather than on <ui-select-choices> because it modifies this component's\n    // event; 0 emits on every keystroke.\n    debounce: { type: Number, default: 0 },\n  },\n  // 'paste' is deliberately NOT declared. Nothing emits it, and declaring an\n  // event strips the matching listener from $attrs — so `@paste` on <ui-select>\n  // was swallowed instead of reaching the DOM. Undeclared, it falls through to\n  // the root element and behaves like a native paste listener.\n  emits: ['update:modelValue', 'select', 'remove', 'clear', 'search', 'highlight', 'open', 'close', 'limit-reached'],\n  setup(props, { emit, attrs, expose }) {\n    const propRefs = toRefs(props)\n\n    // ---- Plugin options (resolves theme + bool defaults when prop is omitted) ----\n    const pluginOptions = inject<UiSelectPluginOptions | null>(UI_SELECT_OPTIONS, null)\n    const effectiveTheme = computed<ThemeName>(\n      () => props.theme ?? pluginOptions?.theme ?? 'tailwind'\n    )\n    // Prop → plugin defaults → hard-coded default. Hardcoded values preserve\n    // current behavior so the plugin defaults block is purely additive.\n    const effectiveSearchEnabled = computed<boolean>(\n      () => props.searchEnabled ?? pluginOptions?.defaults?.searchEnabled ?? true\n    )\n    const effectiveCloseOnSelect = computed<boolean>(\n      () => props.closeOnSelect ?? pluginOptions?.defaults?.closeOnSelect ?? true\n    )\n    const effectiveAppendToBody = computed<boolean>(\n      () => props.appendToBody ?? pluginOptions?.defaults?.appendToBody ?? false\n    )\n    const effectiveClearable = computed<boolean>(\n      () => props.clearable ?? pluginOptions?.defaults?.clearable ?? false\n    )\n    const effectiveRemoveSelected = computed<boolean>(\n      () => props.removeSelected ?? pluginOptions?.defaults?.removeSelected ?? true\n    )\n\n    // The default empty-state copy. English unless the plugin says otherwise;\n    // markup or per-instance text goes through <ui-select-no-choice> instead.\n    const messages = computed<Required<UiSelectMessages>>(() => ({\n      noOptions: 'No options',\n      noResults: 'No results',\n      noOtherOptions: 'No other options',\n      allSelected: 'All options selected',\n      ...pluginOptions?.messages,\n    }))\n\n    // ---- Choices config (registered by UiSelectChoices child) ----\n    const choicesConfig = shallowRef<ChoicesConfig | null>(null)\n    function registerChoicesConfig(config: ChoicesConfig) {\n      choicesConfig.value = config\n    }\n    /**\n     * Registration used to be one-way, so a <ui-select-choices> removed by v-if\n     * kept feeding its items through the stale config and the keyboard could\n     * still select from a list that was no longer on screen.\n     *\n     * The identity check matters when one choices list replaces another: the\n     * incoming child registers before the outgoing one unmounts, so a blind\n     * clear would wipe the new registration.\n     */\n    function unregisterChoicesConfig(config: ChoicesConfig) {\n      if (choicesConfig.value === config) choicesConfig.value = null\n    }\n\n    // ---- No-choice content (registered by UiSelectNoChoice child) ----\n    const noChoiceContent = shallowRef<((scope: NoChoiceSlotScope) => any) | null>(null)\n    function registerNoChoiceContent(renderFn: (scope: NoChoiceSlotScope) => any) {\n      noChoiceContent.value = renderFn\n    }\n\n    // ---- Core state ----\n    const state = useSelectState({\n      modelValue: propRefs.modelValue,\n      multiple: propRefs.multiple,\n      disabled: propRefs.disabled,\n      loading: propRefs.loading,\n      searchEnabled: effectiveSearchEnabled,\n      resetSearchInput: propRefs.resetSearchInput,\n      closeOnSelect: effectiveCloseOnSelect,\n      clearable: effectiveClearable,\n      appendToBody: effectiveAppendToBody,\n      position: propRefs.position,\n      theme: effectiveTheme,\n      placeholder: propRefs.placeholder,\n      tagging: propRefs.tagging as any,\n      taggingLabel: propRefs.taggingLabel as any,\n      taggingTokens: propRefs.taggingTokens,\n      removeSelected: effectiveRemoveSelected,\n      lockChoice: propRefs.lockChoice as any,\n      inputId: propRefs.inputId,\n      autofocus: propRefs.autofocus,\n      limit: propRefs.limit as any,\n    })\n\n    // ---- Model binding (initial, before filtering can resolve isItemSelected) ----\n    const trackBy = computed(() => choicesConfig.value?.trackBy?.value)\n    const bindProperty = computed(() => choicesConfig.value?.bindProperty?.value)\n\n    // Placeholder raw items used for initial model binding hydration\n    const placeholderRawItems = computed<any[]>(() => {\n      const cfg = choicesConfig.value\n      if (!cfg) return []\n      const items = cfg.items?.value\n      if (Array.isArray(items)) return items\n      if (items && typeof items === 'object') {\n        // Same flattening as useSelectFiltering, so hydration and the rendered\n        // rows agree on what an object-source wrapper is.\n        return normalizeObjectSource(items as Record<string, any>)\n      }\n      return []\n    })\n\n    const model = useModelBinding({\n      modelValue: propRefs.modelValue,\n      multiple: propRefs.multiple,\n      trackBy,\n      bindProperty,\n      rawItems: placeholderRawItems,\n      lockChoice: propRefs.lockChoice as any,\n      emit: emit as any,\n    })\n\n    /**\n     * Whether a multi-select has taken as many items as it is allowed.\n     *\n     * Reaching the limit used to do nothing visible: further clicks were simply\n     * dropped, so the list looked broken. The remaining options are now disabled\n     * — already-selected ones stay enabled, or the user would be stranded at the\n     * limit with no way back down.\n     */\n    const isAtLimit = computed<boolean>(() => {\n      if (!props.multiple || props.limit == null) return false\n      const arr = Array.isArray(model.selected.value) ? model.selected.value : []\n      return arr.length >= props.limit\n    })\n\n    // ---- Filtering (uses resolved isItemSelected) ----\n    const filtering = useSelectFiltering({\n      search: state.search,\n      choicesConfig,\n      isItemSelected: model.isItemSelected,\n      createSelectionMatcher: model.createSelectionMatcher,\n      removeSelected: effectiveRemoveSelected,\n    })\n\n    // ---- Tagging ----\n    const taggingUtil = useSelectTagging({\n      tagging: propRefs.tagging as any,\n      taggingLabel: propRefs.taggingLabel as any,\n      taggingTokens: propRefs.taggingTokens,\n      search: state.search,\n      multiple: propRefs.multiple,\n      limit: propRefs.limit as any,\n      selected: model.selected,\n      flatFilteredItems: filtering.flatFilteredItems,\n      isItemSelected: model.isItemSelected,\n      itemsEqual: model.itemsEqual,\n    })\n\n    // ---- Keyboard ----\n    const keyboard = useSelectKeyboard({\n      isOpen: state.isOpen,\n      search: state.search,\n      activeIndex: state.activeIndex,\n      flatFilteredItems: filtering.flatFilteredItems,\n      multiple: propRefs.multiple,\n      disabled: propRefs.disabled,\n      selected: model.selected,\n      tagging: propRefs.tagging as any,\n      taggingTokens: propRefs.taggingTokens,\n      disableChoice: computed(() => choicesConfig.value?.disableChoice?.value),\n      clearable: effectiveClearable,\n      lockChoice: propRefs.lockChoice as any,\n      appendToBody: effectiveAppendToBody,\n      isAtLimit,\n      limit: propRefs.limit,\n      open: state.open,\n      close: state.close,\n      selectItem: handleSelect,\n      removeItem: handleRemove,\n      isItemSelected: model.isItemSelected,\n      createTag: taggingUtil.createTag,\n      shouldShowTagRow: taggingUtil.shouldShowTagRow,\n      findExistingByTerm: taggingUtil.findExistingByTerm,\n      focus: state.focus,\n      focusHost,\n      focusSibling,\n      clearSelection: model.clearSelection,\n      dropdownRef: state.dropdownRef,\n      inputRef: state.inputRef,\n      emit: emit as any,\n    })\n\n    // ---- Positioning ----\n    const positioning = useSelectPositioning({\n      isOpen: state.isOpen,\n      appendToBody: effectiveAppendToBody,\n      position: propRefs.position,\n      rootRef: state.rootRef,\n      dropdownRef: state.dropdownRef,\n    })\n\n    // ---- Accessibility ----\n    const a11y = useSelectAccessibility({\n      uid: state.uid,\n      isOpen: state.isOpen,\n      activeIndex: state.activeIndex,\n      multiple: propRefs.multiple,\n      disabled: propRefs.disabled,\n      selected: model.selected,\n      flatFilteredItems: filtering.flatFilteredItems,\n      placeholder: propRefs.placeholder,\n      inputId: propRefs.inputId,\n      appendToBody: effectiveAppendToBody,\n      searchEnabled: effectiveSearchEnabled,\n    })\n\n    // A combobox with no accessible name is announced as just \"combobox\". The\n    // placeholder is the only label the component knows about, so it stands in —\n    // but only when the consumer has supplied nothing of their own, since\n    // rootAriaAttrs is spread AFTER $attrs and would otherwise win.\n    const rootAriaLabel = computed<Record<string, string>>(() => {\n      const out: Record<string, string> = {}\n      if (attrs['aria-label'] || attrs['aria-labelledby']) return out\n      if (props.placeholder) out['aria-label'] = props.placeholder\n      return out\n    })\n\n    // ---- Theme ----\n    const themeClasses = useThemeClasses(effectiveTheme)\n\n    // ---- Focus management ----\n    // Focuses the root element (always mounted), for the moments when the\n    // single-mode search input is about to unmount with the dropdown and a\n    // plain focus() would let keyboard focus fall to <body>. preventScroll for\n    // the same reason as on open: restoring focus must never move the page.\n    function focusHost() {\n      state.rootRef.value?.focus({ preventScroll: true })\n    }\n\n    const TABBABLE_SELECTOR = [\n      'a[href]',\n      'button:not([disabled])',\n      'input:not([disabled])',\n      'select:not([disabled])',\n      'textarea:not([disabled])',\n      '[tabindex]:not([tabindex=\"-1\"])',\n    ].join(',')\n\n    /**\n     * Moves focus to the tab stop immediately before or after the whole widget.\n     *\n     * Tab cannot simply be left to the browser. Closing the dropdown unmounts the\n     * focused search input on Vue's next flush, and that flush is a microtask —\n     * it runs before the browser performs Tab's default action. The sequential\n     * focus starting point is therefore gone by the time the browser looks for\n     * it, and focus falls to <body>. Verified in Chrome: focusing the root first\n     * did not help either, because the starting point had already been captured.\n     *\n     * Returns false when there is nowhere to go, so the caller can leave the\n     * browser's own behaviour alone.\n     */\n    function focusSibling(backwards: boolean): boolean {\n      const root = state.rootRef.value\n      if (!root) return false\n      const dropdown = state.dropdownRef.value\n      const candidates = Array.from(\n        document.querySelectorAll<HTMLElement>(TABBABLE_SELECTOR)\n      ).filter((el) => {\n        if (root.contains(el)) return false\n        if (dropdown && dropdown.contains(el)) return false\n        return el.getClientRects().length > 0\n      })\n      if (candidates.length === 0) return false\n\n      const firstAfter = candidates.findIndex(\n        (el) => !!(root.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING)\n      )\n      const target = backwards\n        ? candidates[(firstAfter === -1 ? candidates.length : firstAfter) - 1]\n        : firstAfter === -1\n          ? undefined\n          : candidates[firstAfter]\n\n      if (!target) return false\n      target.focus()\n      return true\n    }\n\n    // ---- Event handlers ----\n    function handleSelect(item: any) {\n      if (props.disabled) return\n      // Refusing a pick silently left the user with no idea why nothing had\n      // happened. Report it, so the application can say so — but only when\n      // something was actually refused: re-picking an item already in the list\n      // changes nothing and is not a refusal.\n      if (isAtLimit.value && !model.isItemSelected(item)) {\n        emit('limit-reached', { item: unwrapObjectSourceItem(item), limit: props.limit })\n        return\n      }\n\n      model.selectItem(item)\n\n      if (props.resetSearchInput) {\n        state.search.value = ''\n      }\n\n      // Restore focus only if it was ours to begin with. A programmatic\n      // select() from application code must not pull the caret away from\n      // wherever the user actually is — and in multi mode that stolen focus\n      // then reopened the dropdown through the input's own handler.\n      const restoreFocus = isInsideWidget(document.activeElement)\n\n      if (props.multiple) {\n        if (effectiveCloseOnSelect.value) {\n          state.close()\n        }\n        // Same reason as on open: returning focus after a pick must not move the\n        // page out from under the user mid-selection.\n        if (restoreFocus) nextTick(() => state.focus({ preventScroll: true }))\n      } else {\n        state.close()\n        // The input unmounts with the dropdown; without this, focus falls to\n        // <body> after every single-mode selection (click or Enter alike).\n        if (restoreFocus) focusHost()\n      }\n    }\n\n    // Creates a tag from the current search text and selects it — the click\n    // action of the \"(new)\" tag row rendered by UiSelectChoices.\n    function selectSearchAsTag() {\n      const term = state.search.value.trim()\n      // createTag() refuses at the limit and returns null, so the refusal would\n      // never reach handleSelect to be reported. Same reasoning as the keyboard\n      // tag paths.\n      if (isAtLimit.value) {\n        if (term) emit('limit-reached', { item: term, limit: props.limit })\n        return\n      }\n      const tag = taggingUtil.createTag(term)\n      if (tag != null) handleSelect(tag)\n    }\n\n    function handleRemove(item: any) {\n      if (props.disabled) return\n      if (props.lockChoice && props.lockChoice(unwrapObjectSourceItem(item))) return\n      model.removeItem(item)\n    }\n\n    // ---- Search watcher → emit search event + token check ----\n    //\n    // `debounce` delays only the emitted event, never the local filtering: the\n    // list stays instant while a remote search waits for the user to stop typing.\n    // Held in a plain timer rather than the debounce() util so a pending emit can\n    // be cancelled — otherwise closing the dropdown resets `search` and a stale\n    // term fires afterwards.\n    let searchEmitTimer: ReturnType<typeof setTimeout> | null = null\n\n    function cancelPendingSearchEmit() {\n      if (searchEmitTimer) {\n        clearTimeout(searchEmitTimer)\n        searchEmitTimer = null\n      }\n    }\n\n    watch(state.search, (val) => {\n      // Typing is an unambiguous request to search, so it opens the list. This\n      // is what the multi-mode input's `focus` handler used to stand in for —\n      // but focus arrives for reasons the user did not ask for, such as the\n      // window being re-activated, which reopened a dropdown they had closed.\n      if (val !== '' && !state.isOpen.value) state.open()\n\n      cancelPendingSearchEmit()\n\n      // An empty term is not a query — it means \"clear\". Emit it at once so a\n      // remote consumer drops its results immediately, and so closing the\n      // dropdown (which resets the search) behaves the same at any delay.\n      if (props.debounce > 0 && val !== '') {\n        searchEmitTimer = setTimeout(() => {\n          searchEmitTimer = null\n          emit('search', val)\n        }, props.debounce)\n      } else {\n        emit('search', val)\n      }\n\n      state.activeIndex.value = -1\n      // Check for token separators in the updated search text\n      keyboard.handleSearchInput()\n    })\n\n    // A closed dropdown has no search to report; drop anything still in flight.\n    watch(state.isOpen, (open) => {\n      if (!open) cancelPendingSearchEmit()\n    })\n\n    // The highlight is an index into the visible list, so anything that reshapes\n    // that list without touching the search — a remote result arriving, an item\n    // removed by remove-selected — used to leave it pointing at a different\n    // option. Follow the item instead: keep the highlight on it if it is still\n    // there, and drop it if it is not.\n    watch(filtering.flatFilteredItems, (items, previousItems) => {\n      const index = state.activeIndex.value\n      if (index < 0) return\n      const active = previousItems?.[index]\n      if (active === undefined) {\n        state.activeIndex.value = -1\n        return\n      }\n      state.activeIndex.value = items.findIndex((item) => model.itemsEqual(item, active))\n    })\n\n    // ---- Auto-close on disabled ----\n    watch(() => props.disabled, (val: boolean) => {\n      if (val && state.isOpen.value) state.close()\n    })\n\n    // ---- Validator-friendly DOM event listeners on the root ----\n    // External validators (oop-validator, VeeValidate, etc.) listen for native\n    // `input` / `blur` events on the form element. We dispatch them on the root\n    // <div> so the component participates in the same contract as a native <input>.\n    // Driven by committed user actions, not by the value changing. A parent\n    // writing v-model — a programmatic set, or a form reset — must no more fire\n    // `input` than assigning to a native input's .value does.\n    watch(model.commits, () => {\n      nextTick(dispatchInputEvent)\n    }, { flush: 'post' })\n\n    // ---- Synthetic DOM events for validation library integration ----\n    // External validators (oop-validator, VeeValidate, hand-rolled) typically\n    // listen for `input` and `blur` on the form element. Since our root is a\n    // <div> we must dispatch these ourselves so the component participates in\n    // the same DOM-event contract as a native <input>.\n\n    /** Fires after every committed model change. */\n    function dispatchInputEvent() {\n      const root = state.rootRef.value\n      if (!root) return\n      root.dispatchEvent(new Event('input', { bubbles: true, cancelable: false }))\n    }\n\n    /**\n     * The widget is root + the dropdown, which may be teleported to <body> and\n     * therefore not a DOM descendant of the root at all. Every focus decision\n     * below treats the two as one thing.\n     */\n    function isInsideWidget(node: Node | null | undefined): boolean {\n      if (!node) return false\n      const root = state.rootRef.value\n      if (root && (root === node || root.contains(node))) return true\n      const dropdown = state.dropdownRef.value\n      return !!(dropdown && (dropdown === node || dropdown.contains(node)))\n    }\n\n    // One synthetic blur per visit. Set again whenever focus re-enters, so a\n    // user who leaves and comes back is reported each time, but the focusout and\n    // click-outside paths below cannot both report the same departure.\n    let blurPending = true\n\n    function reportBlur() {\n      if (!blurPending) return\n      blurPending = false\n      const root = state.rootRef.value\n      if (!root) return\n      root.dispatchEvent(new Event('blur', { bubbles: false, cancelable: false }))\n    }\n\n    function handleFocusIn(e: FocusEvent) {\n      if (isInsideWidget(e.target as Node)) blurPending = true\n    }\n\n    /**\n     * Fires when keyboard/pointer focus has truly left the widget.\n     *\n     * Bound on the document rather than the root: with append-to-body the search\n     * input lives in the teleported dropdown, so a focusout there never reached a\n     * root-bound listener and the blur was simply never dispatched.\n     */\n    function handleFocusOut(e: FocusEvent) {\n      if (!isInsideWidget(e.target as Node)) return\n      const next = e.relatedTarget as Node | null\n      if (isInsideWidget(next)) return\n      if (!next) {\n        // Focus has gone nowhere yet — the focused element was removed, or the\n        // pointer landed on something unfocusable. It may still be settling back\n        // inside the widget (single mode closes, then refocuses the root), so\n        // decide once it has come to rest.\n        nextTick(() => {\n          if (!isInsideWidget(document.activeElement)) reportBlur()\n        })\n        return\n      }\n      reportBlur()\n    }\n\n    /**\n     * A native `blur` also fires on the root every time focus hops from it into\n     * our own search input — which is exactly what opening the dropdown does.\n     * A validator listening for `blur` would mark the field touched before the\n     * user has chosen anything. Focus is still inside the widget, so nothing has\n     * really been left: stop that one event before other listeners on the root\n     * see it. Anything that genuinely leaves is untouched.\n     */\n    function suppressInternalBlur(e: FocusEvent) {\n      if (e.target !== state.rootRef.value) return\n      if (isInsideWidget(e.relatedTarget as Node)) e.stopImmediatePropagation()\n    }\n\n    // ---- Open/close watchers → emit events ----\n    watch(state.isOpen, (val) => {\n      if (val) {\n        emit('open')\n        nextTick(() => {\n          if (effectiveSearchEnabled.value) {\n            // preventScroll: opening a dropdown must never move the page. The\n            // search input can be teleported far down the document, and letting\n            // the browser scroll it into view yanks the user away from the form.\n            state.focus({ preventScroll: true })\n          }\n        })\n      } else {\n        emit('close')\n      }\n    })\n\n    // ---- Click outside handler ----\n    function handleClickOutside(e: Event) {\n      if (!state.rootRef.value) return\n      const target = e.target as Node\n      if (isInsideWidget(target)) return\n      // Whether the widget held focus has to be read BEFORE closing, while the\n      // search input still exists. Clicking unfocusable page chrome moves focus\n      // to <body> without a usable focusout relatedTarget, so a widget closed\n      // this way used to report no blur at all and validators never saw the\n      // field as touched.\n      const active = document.activeElement as HTMLElement | null\n      const hadFocus = isInsideWidget(active)\n      state.close()\n      if (!hadFocus) return\n      // Hand focus back the way a browser does when the pointer lands elsewhere.\n      // This also drives the ordinary focusout path, so the report below is\n      // usually a no-op guarded by `blurPending`.\n      if (active && typeof active.blur === 'function') active.blur()\n      // Report only once focus has actually left. Dispatching synchronously from\n      // mousedown puts the blur BEFORE the browser has moved focus, and a\n      // validator that checks where focus went correctly ignores it.\n      nextTick(() => {\n        if (!isInsideWidget(document.activeElement)) reportBlur()\n      })\n    }\n\n    /**\n     * Vue rewrites the root's `class` attribute whenever our own classes change\n     * — opening the dropdown alone does it — and that assignment wipes any class\n     * something else put on the element directly. Validators do exactly that:\n     * oop-validator, VeeValidate and friends add `v-invalid` and the like from a\n     * directive, so an invalid field lost its error styling the moment it was\n     * opened, and got it back only on the validator's next update.\n     *\n     * It used to be masked rather than handled: a spurious `blur` fired on the\n     * root every time the dropdown opened, and validators re-applied their\n     * classes in response. Suppressing that blur — which was marking fields\n     * touched before the user had done anything — removed the accidental repair,\n     * so carry the foreign classes across our own updates deliberately.\n     */\n    let foreignClasses: string[] = []\n\n    function isOwnClass(name: string): boolean {\n      return name === 'ui-select' || name.startsWith('ui-select--')\n    }\n\n    onBeforeUpdate(() => {\n      const root = state.rootRef.value\n      if (!root) return\n      foreignClasses = Array.from(root.classList).filter((c) => !isOwnClass(c))\n    })\n\n    onUpdated(() => {\n      const root = state.rootRef.value\n      if (!root || foreignClasses.length === 0) return\n      for (const name of foreignClasses) {\n        if (!root.classList.contains(name)) root.classList.add(name)\n      }\n    })\n\n    onMounted(() => {\n      document.addEventListener('mousedown', handleClickOutside)\n      document.addEventListener('touchstart', handleClickOutside, { passive: true })\n      // focusin/focusout bubble, so the document catches them even for a dropdown\n      // teleported out of the root's subtree. The handlers filter to a true\n      // widget-exit before dispatching the synthetic `blur` on the root.\n      document.addEventListener('focusin', handleFocusIn)\n      document.addEventListener('focusout', handleFocusOut)\n      // Also keep the root-bound listener, so a focusout dispatched directly at\n      // the root still reports even in environments where it does not bubble.\n      state.rootRef.value?.addEventListener('focusout', handleFocusOut)\n      // Capture phase, and registered before any consumer listener on the root,\n      // so the spurious open-time blur is stopped before it is observed.\n      state.rootRef.value?.addEventListener('blur', suppressInternalBlur as EventListener, true)\n      if (props.autofocus) {\n        nextTick(() => state.focus())\n      }\n    })\n\n    onBeforeUnmount(() => {\n      document.removeEventListener('mousedown', handleClickOutside)\n      document.removeEventListener('touchstart', handleClickOutside)\n      document.removeEventListener('focusin', handleFocusIn)\n      document.removeEventListener('focusout', handleFocusOut)\n      state.rootRef.value?.removeEventListener('focusout', handleFocusOut)\n      state.rootRef.value?.removeEventListener('blur', suppressInternalBlur as EventListener, true)\n      cancelPendingSearchEmit()\n    })\n\n    // ---- Provide context to children ----\n    const context: UiSelectContext = {\n      isOpen: state.isOpen,\n      search: state.search,\n      activeIndex: state.activeIndex,\n      multiple: toRef(props, 'multiple'),\n      disabled: toRef(props, 'disabled'),\n      loading: toRef(props, 'loading'),\n      theme: effectiveTheme,\n      position: toRef(props, 'position'),\n      selected: model.selected,\n      isItemSelected: model.isItemSelected,\n      selectItem: handleSelect,\n      removeItem: handleRemove,\n      clearSelection: model.clearSelection,\n      rawItems: filtering.rawItems as any,\n      filteredItems: filtering.filteredItems,\n      groupedItems: filtering.groupedItems,\n      flatFilteredItems: filtering.flatFilteredItems,\n      searchEnabled: effectiveSearchEnabled,\n      resetSearchInput: toRef(props, 'resetSearchInput'),\n      closeOnSelect: effectiveCloseOnSelect,\n      clearable: effectiveClearable,\n      appendToBody: effectiveAppendToBody,\n      placeholder: toRef(props, 'placeholder'),\n      tagging: toRef(props, 'tagging') as any,\n      taggingLabel: toRef(props, 'taggingLabel') as any,\n      taggingTokens: toRef(props, 'taggingTokens'),\n      removeSelected: effectiveRemoveSelected,\n      lockChoice: toRef(props, 'lockChoice') as any,\n      inputId: toRef(props, 'inputId'),\n      registerChoicesConfig,\n      unregisterChoicesConfig,\n      noChoiceContent,\n      registerNoChoiceContent,\n      emptyReason: filtering.emptyReason,\n      messages,\n      open: state.open,\n      close: state.close,\n      toggle: state.toggle,\n      focus: state.focus,\n      blur: state.blur,\n      highlighted: highlightText,\n      rootRef: state.rootRef,\n      inputRef: state.inputRef,\n      dropdownRef: state.dropdownRef,\n      uid: state.uid,\n      isAtLimit,\n      inputAriaAttrs: a11y.inputAriaAttrs,\n      // The listbox attrs were computed and then never bound to anything, so the\n      // rendered list hand-rolled role and id and dropped aria-label and\n      // aria-multiselectable entirely — a multi-select never announced that more\n      // than one option could be chosen.\n      listboxAriaAttrs: a11y.listboxAriaAttrs,\n      resolvedPosition: positioning.resolvedPosition,\n      dropdownMaxHeight: positioning.dropdownMaxHeight,\n      teleportStyle: positioning.teleportStyle,\n      handlePaste: keyboard.handlePaste,\n      handleKeyDown: keyboard.handleKeyDown,\n      shouldShowTagRow: taggingUtil.shouldShowTagRow,\n      getTagRowLabel: taggingUtil.getTagRowLabel,\n      selectSearchAsTag,\n    }\n\n    provide(UI_SELECT_CONTEXT, context)\n\n    // ---- Expose for template refs ----\n    expose({\n      selected: model.selected,\n      search: state.search,\n      isOpen: state.isOpen,\n      activeIndex: state.activeIndex,\n      filteredItems: filtering.filteredItems,\n      open: state.open,\n      close: state.close,\n      toggle: state.toggle,\n      focus: state.focus,\n      blur: state.blur,\n      clear: model.clearSelection,\n      select: handleSelect,\n      remove: handleRemove,\n    })\n\n    return {\n      uid: state.uid,\n      isOpen: state.isOpen,\n      search: state.search,\n      activeIndex: state.activeIndex,\n      rootRef: state.rootRef,\n      inputRef: state.inputRef,\n      dropdownRef: state.dropdownRef,\n      selected: model.selected,\n      resolvedPosition: positioning.resolvedPosition,\n      teleportStyle: positioning.teleportStyle,\n      handleKeyDown: keyboard.handleKeyDown,\n      handlePaste: keyboard.handlePaste,\n      shouldShowTagRow: taggingUtil.shouldShowTagRow,\n      rootAriaAttrs: a11y.rootAriaAttrs,\n      rootAriaLabel,\n      inputAriaAttrs: a11y.inputAriaAttrs,\n      themeDataAttr: themeClasses.themeDataAttr,\n      effectiveTheme,\n      effectiveSearchEnabled,\n      open: state.open,\n      close: state.close,\n      toggle: state.toggle,\n      focus: state.focus,\n      handleSelect,\n      handleRemove,\n    }\n  },\n})\n</script>\n\n<template>\n  <div\n    ref=\"rootRef\"\n    v-bind=\"{ ...$attrs, ...rootAriaLabel, ...rootAriaAttrs, ...themeDataAttr }\"\n    :class=\"[\n      'ui-select',\n      `ui-select--${effectiveTheme}`,\n      {\n        'ui-select--open': isOpen,\n        'ui-select--closed': !isOpen,\n        'ui-select--disabled': $props.disabled,\n        'ui-select--multiple': $props.multiple,\n        'ui-select--single': !$props.multiple,\n        'ui-select--focus': isOpen,\n        'ui-select--loading': $props.loading,\n      },\n    ]\"\n    data-ui-select=\"\"\n    :data-open=\"isOpen || undefined\"\n    :data-disabled=\"$props.disabled || undefined\"\n    :data-multiple=\"$props.multiple || undefined\"\n    :data-position=\"resolvedPosition\"\n    :tabindex=\"$props.disabled ? -1 : (effectiveSearchEnabled && $props.multiple ? -1 : 0)\"\n    @keydown=\"handleKeyDown\"\n    @paste=\"handlePaste\"\n  >\n    <!-- All child components (UiSelectMatch, UiSelectChoices, UiSelectNoChoice) render via default slot -->\n    <slot />\n\n    <!-- Loading spinner -->\n    <div\n      v-if=\"$props.loading\"\n      class=\"ui-select__spinner\"\n      data-ui-select-spinner=\"\"\n      data-testid=\"ui-select-spinner\"\n    >\n      <slot name=\"spinner\">\n        <span class=\"ui-select__spinner-icon\" />\n      </slot>\n    </div>\n  </div>\n</template>\n","<script lang=\"ts\">\nimport { defineComponent, inject, computed, nextTick } from 'vue'\nimport { UI_SELECT_CONTEXT } from '../symbols'\nimport type { UiSelectContext, MatchSingleSlotScope, MatchMultiSlotScope } from '../types'\nimport { unwrapObjectSourceItem as unwrapObjectSourceItemUtil } from '../utils/objectSource'\n\nexport default defineComponent({\n  name: 'UiSelectMatch',\n  props: {\n    placeholder: { type: String, default: '' },\n  },\n  setup(props) {\n    const ctx = inject(UI_SELECT_CONTEXT) as UiSelectContext\n\n    const resolvedPlaceholder = computed(() => props.placeholder || ctx.placeholder.value || '')\n\n    const hasSelection = computed(() => {\n      if (ctx.multiple.value) {\n        return Array.isArray(ctx.selected.value) && ctx.selected.value.length > 0\n      }\n      return ctx.selected.value != null\n    })\n\n    const selectedItems = computed<any[]>(() => {\n      if (!ctx.multiple.value) return []\n      return Array.isArray(ctx.selected.value) ? ctx.selected.value : []\n    })\n\n    const unwrapObjectSourceItem = unwrapObjectSourceItemUtil\n\n    // Single mode slot scope\n    const singleSlotScope = computed<MatchSingleSlotScope>(() => ({\n      selected: unwrapObjectSourceItem(ctx.selected.value),\n      search: ctx.search.value,\n      isOpen: ctx.isOpen.value,\n    }))\n\n    /**\n     * The clear and tag-remove buttons unmount themselves as a result of the\n     * action they perform. Activated by keyboard they hold focus at that moment,\n     * so it fell to <body> and the keyboard user was stranded. (With a pointer\n     * the buttons never take focus — see @mousedown.prevent — so there is\n     * nothing to restore, and we leave focus where it is.)\n     */\n    function restoreFocusIfDetached(el: EventTarget | null) {\n      const button = el as HTMLElement | null\n      if (!button || document.activeElement !== button) return\n      nextTick(() => {\n        if (button.isConnected) return\n        const root = ctx.rootRef.value\n        if (!root) return\n        const input = ctx.inputRef.value\n        if (input && root.contains(input)) input.focus({ preventScroll: true })\n        else root.focus({ preventScroll: true })\n      })\n    }\n\n    function handleClear(e: Event) {\n      e.stopPropagation()\n      const button = e.currentTarget\n      ctx.clearSelection()\n      restoreFocusIfDetached(button)\n    }\n\n    function handleRemoveItem(item: any, e?: Event) {\n      e?.stopPropagation()\n      const button = e?.currentTarget ?? null\n      ctx.removeItem(item)\n      restoreFocusIfDetached(button)\n    }\n\n    /**\n     * Every remove button used to be labelled just \"Remove\", so a screen-reader\n     * user moving between tags heard the same thing each time and could not tell\n     * which one they were about to drop. Objects have no reliable text, so they\n     * keep the generic label.\n     */\n    function tagRemoveLabel(item: any): string {\n      const value = unwrapObjectSourceItem(item)\n      const text = typeof value === 'string' || typeof value === 'number' ? String(value) : ''\n      return text ? `Remove ${text}` : 'Remove'\n    }\n\n    function isItemLocked(item: any): boolean {\n      if (ctx.lockChoice.value) return ctx.lockChoice.value(unwrapObjectSourceItemUtil(item))\n      return false\n    }\n\n    function handleControlClick() {\n      if (!ctx.disabled.value) {\n        ctx.toggle()\n      }\n    }\n\n    return {\n      ctx,\n      resolvedPlaceholder,\n      hasSelection,\n      selectedItems,\n      singleSlotScope,\n      handleClear,\n      handleRemoveItem,\n      isItemLocked,\n      tagRemoveLabel,\n      handleControlClick,\n      unwrapObjectSourceItem,\n    }\n  },\n})\n</script>\n\n<template>\n  <div\n    class=\"ui-select-match\"\n    data-ui-select-match=\"\"\n    data-testid=\"ui-select-match\"\n    @click=\"handleControlClick\"\n  >\n    <!-- Single mode -->\n    <template v-if=\"!ctx.multiple.value\">\n      <div class=\"ui-select-match__content\" data-ui-select-match-content=\"\">\n        <!-- Placeholder -->\n        <span\n          v-if=\"!hasSelection\"\n          class=\"ui-select-match__placeholder\"\n          data-ui-select-placeholder=\"\"\n          data-testid=\"ui-select-placeholder\"\n        >\n          {{ resolvedPlaceholder }}\n        </span>\n\n        <!-- Selected display -->\n        <span\n          v-else\n          class=\"ui-select-match__selection\"\n          data-ui-select-selection=\"\"\n          data-testid=\"ui-select-selection\"\n        >\n          <slot v-bind=\"singleSlotScope\">\n            {{ typeof singleSlotScope.selected === 'object' ? JSON.stringify(singleSlotScope.selected) : singleSlotScope.selected }}\n          </slot>\n        </span>\n      </div>\n\n      <!-- Clear button -->\n      <button\n        v-if=\"ctx.clearable.value && hasSelection && !ctx.disabled.value\"\n        class=\"ui-select-match__clear\"\n        type=\"button\"\n        data-ui-select-clear=\"\"\n        data-testid=\"ui-select-clear\"\n        aria-label=\"Clear selection\"\n        @click=\"handleClear\"\n        @mousedown.prevent\n      >\n        <span aria-hidden=\"true\">&times;</span>\n      </button>\n\n      <!-- Caret -->\n      <span class=\"ui-select-match__caret\" data-ui-select-caret=\"\" aria-hidden=\"true\" />\n    </template>\n\n    <!-- Multiple mode -->\n    <template v-else>\n      <div class=\"ui-select-match__tags\" data-ui-select-tags=\"\" data-testid=\"ui-select-tags\">\n        <span\n          v-for=\"(item, idx) in selectedItems\"\n          :key=\"idx\"\n          class=\"ui-select-match__tag\"\n          :class=\"{\n            'ui-select-match__tag--locked': isItemLocked(item),\n          }\"\n          data-ui-select-tag=\"\"\n          data-testid=\"ui-select-tag\"\n        >\n          <slot\n            name=\"tag\"\n            :item=\"unwrapObjectSourceItem(item)\"\n            :index=\"idx\"\n            :remove=\"handleRemoveItem\"\n            :removeItem=\"handleRemoveItem\"\n            :isLocked=\"isItemLocked(item)\"\n          >\n            {{ typeof unwrapObjectSourceItem(item) === 'object' ? JSON.stringify(unwrapObjectSourceItem(item)) : unwrapObjectSourceItem(item) }}\n          </slot>\n          <button\n            v-if=\"!$slots.tag && !isItemLocked(item) && !ctx.disabled.value\"\n            class=\"ui-select-match__tag-remove\"\n            type=\"button\"\n            data-ui-select-tag-remove=\"\"\n            data-testid=\"ui-select-tag-remove\"\n            :aria-label=\"tagRemoveLabel(item)\"\n            @click.stop=\"handleRemoveItem(item, $event)\"\n            @mousedown.prevent\n          >\n            <span aria-hidden=\"true\">&times;</span>\n          </button>\n        </span>\n\n        <!-- Inline search input for multi mode -->\n        <input\n          v-if=\"ctx.searchEnabled.value\"\n          :ref=\"(el: any) => { ctx.inputRef.value = el }\"\n          v-model=\"ctx.search.value\"\n          class=\"ui-select-match__search-input\"\n          type=\"text\"\n          data-ui-select-input=\"\"\n          data-testid=\"ui-select-input\"\n          autocomplete=\"off\"\n          :placeholder=\"selectedItems.length === 0 ? resolvedPlaceholder : ''\"\n          :disabled=\"ctx.disabled.value\"\n          v-bind=\"ctx.inputAriaAttrs.value\"\n          @click.stop=\"ctx.open()\"\n          @paste.stop=\"ctx.handlePaste\"\n        />\n\n        <!-- Placeholder when no items and no search -->\n        <span\n          v-if=\"selectedItems.length === 0 && !ctx.searchEnabled.value\"\n          class=\"ui-select-match__placeholder\"\n          data-ui-select-placeholder=\"\"\n          data-testid=\"ui-select-placeholder\"\n        >\n          {{ resolvedPlaceholder }}\n        </span>\n      </div>\n\n      <!-- Clear all. `clearable` is documented as a plain prop and the README's\n           own multi-select example passes it, but the control only ever existed\n           in the single-mode branch, so it did nothing here. Locked tags are\n           kept: clearSelection refuses them. -->\n      <button\n        v-if=\"ctx.clearable.value && hasSelection && !ctx.disabled.value\"\n        class=\"ui-select-match__clear\"\n        type=\"button\"\n        data-ui-select-clear=\"\"\n        data-testid=\"ui-select-clear\"\n        aria-label=\"Clear all selections\"\n        @click=\"handleClear\"\n        @mousedown.prevent\n      >\n        <span aria-hidden=\"true\">&times;</span>\n      </button>\n    </template>\n  </div>\n</template>\n","<script lang=\"ts\">\nimport { defineComponent, inject, toRef, computed, onBeforeUnmount, type PropType } from 'vue'\nimport { UI_SELECT_CONTEXT } from '../symbols'\nimport type { NoChoiceSlotScope, UiSelectContext, ChoicesConfig, ChoiceSlotScope } from '../types'\nimport { highlightText } from '../utils/highlight'\nimport { isObjectSourceItem, unwrapObjectSourceItem } from '../utils/objectSource'\n\nexport default defineComponent({\n  name: 'UiSelectChoices',\n  props: {\n    items: { type: [Array, Object] as PropType<any[] | Record<string, any>>, default: () => [] },\n    trackBy: { type: [String, Function] as PropType<string | ((item: any) => any) | undefined>, default: undefined },\n    bindProperty: { type: String as PropType<string | undefined>, default: undefined },\n    searchFields: { type: Array as PropType<string[]>, default: () => [] },\n    filterFn: { type: Function as PropType<((item: any, search: string) => boolean) | undefined>, default: undefined },\n    groupBy: { type: [String, Function] as PropType<string | ((item: any) => string | undefined) | undefined>, default: undefined },\n    groupFilter: { type: [Array, Function] as PropType<string[] | ((groups: string[]) => string[]) | undefined>, default: undefined },\n    disableChoice: { type: Function as PropType<((item: any) => boolean) | undefined>, default: undefined },\n    sortFn: { type: Function as PropType<((a: any, b: any) => number) | undefined>, default: undefined },\n    minimumInputLength: { type: Number, default: 0 },\n    showCheckboxes: { type: Boolean, default: false },\n  },\n  setup(props) {\n    const ctx = inject(UI_SELECT_CONTEXT) as UiSelectContext\n\n    // Register choices config with parent UiSelect\n    const choicesConfig: ChoicesConfig = {\n      items: toRef(props, 'items') as any,\n      trackBy: toRef(props, 'trackBy') as any,\n      bindProperty: toRef(props, 'bindProperty') as any,\n      searchFields: toRef(props, 'searchFields'),\n      filterFn: toRef(props, 'filterFn') as any,\n      groupBy: toRef(props, 'groupBy') as any,\n      groupFilter: toRef(props, 'groupFilter') as any,\n      disableChoice: toRef(props, 'disableChoice') as any,\n      sortFn: toRef(props, 'sortFn') as any,\n      minimumInputLength: toRef(props, 'minimumInputLength'),\n    }\n\n    // Register immediately for fast reactivity\n    ctx.registerChoicesConfig(choicesConfig)\n\n    onBeforeUnmount(() => {\n      ctx.unregisterChoicesConfig?.(choicesConfig)\n    })\n\n    // Pre-compute groups annotated with a positional flatIndex per item.\n    // Indexing by position (not by item identity) handles duplicate primitives\n    // and objects that share trackBy keys without collisions.\n    const indexedGroups = computed(() => {\n      const groups: { label: string | undefined; items: { item: any; flatIndex: number }[] }[] = []\n      let flatIndex = 0\n      for (const group of ctx.groupedItems.value) {\n        groups.push({\n          label: group.label,\n          items: group.items.map((item: any) => ({ item, flatIndex: flatIndex++ })),\n        })\n      }\n      return groups\n    })\n\n    function isChoiceDisabled(item: any): boolean {\n      // The value, like every other consumer callback and the choice slot.\n      if (props.disableChoice && props.disableChoice(unwrapObjectSourceItem(item))) return true\n      // At the limit nothing further can be taken, so the rows say so rather\n      // than swallowing the click. Selected rows stay enabled: they are the way\n      // back down.\n      if (ctx.isAtLimit?.value && !ctx.isItemSelected(item)) return true\n      return false\n    }\n\n    function getChoiceSlotScope(item: any, index: number): ChoiceSlotScope {\n      const unwrapped = isObjectSourceItem(item)\n      return {\n        item: unwrapped ? item.value : item,\n        ...(unwrapped ? { key: item.key } : {}),\n        index,\n        search: ctx.search.value,\n        highlighted: highlightText,\n        isActive: ctx.activeIndex.value === index,\n        isSelected: ctx.isItemSelected(item),\n        isDisabled: isChoiceDisabled(item),\n      }\n    }\n\n    function handleItemClick(item: any, e: Event) {\n      e.stopPropagation()\n      if (isChoiceDisabled(item)) return\n      // When checkboxes are shown, toggle selection on/off\n      if (props.showCheckboxes && ctx.isItemSelected(item)) {\n        ctx.removeItem(item)\n        return\n      }\n      if (!ctx.removeSelected.value && ctx.isItemSelected(item)) return\n      ctx.selectItem(item)\n    }\n\n    function handleItemMouseEnter(item: any, flatIdx: number) {\n      ctx.activeIndex.value = flatIdx\n    }\n\n    // Show the \"type N more characters\" prompt whenever the term is short —\n    // including before the first keystroke. It used to require a non-empty\n    // search, so opening the dropdown fell through to the no-choice slot and\n    // announced \"No results\" about a list it had not been allowed to search yet.\n    // Trimmed, to agree with the filter's own threshold.\n    const searchLength = computed(() => ctx.search.value.trim().length)\n\n    const showMinimumLengthMessage = computed(() => {\n      if (props.minimumInputLength <= 0) return false\n      return searchLength.value < props.minimumInputLength\n    })\n\n    const remainingChars = computed(() => props.minimumInputLength - searchLength.value)\n\n    // Default English copy; localize via the `minimum-length` slot.\n    const minimumLengthMessage = computed(() => {\n      const remaining = remainingChars.value\n      return `Please enter ${remaining} more character${remaining !== 1 ? 's' : ''}`\n    })\n\n    /**\n     * The dropdown swallows mousedown so clicking options never steals focus\n     * from the search input — but two regions need the default action back:\n     * the search box itself (caret placement, drag-selection, double-click\n     * word select are all mousedown defaults), and the scrollbar of the\n     * choices list, which some engines refuse to drag when the event is\n     * cancelled. offsetX/Y beyond the client box means the scrollbar (LTR).\n     */\n    /**\n     * A scrollbar belongs to the element that scrolls, and a click on it lands\n     * outside that element's client box. Both halves matter: the old check\n     * compared against whatever the event target happened to be, and an inline\n     * element reports clientWidth and clientHeight of 0. A custom #choice\n     * template almost always renders one — a <span> around the label — so\n     * clicking the option's text rather than the row's padding looked like a\n     * scrollbar drag, the default was allowed, focus was stolen from the search\n     * input, and in multiple mode close-on-select immediately reopened.\n     */\n    function isScrollbarClick(target: HTMLElement, e: MouseEvent): boolean {\n      const scrollsY = target.scrollHeight > target.clientHeight\n      const scrollsX = target.scrollWidth > target.clientWidth\n      if (!scrollsY && !scrollsX) return false\n      // offsetX is measured from the padding edge, so a vertical scrollbar shows\n      // up beyond the client width — except in a right-to-left element, where\n      // the scrollbar sits on the LEFT and the offset comes out negative.\n      return (\n        (scrollsY && (e.offsetX > target.clientWidth || e.offsetX < 0)) ||\n        (scrollsX && e.offsetY > target.clientHeight)\n      )\n    }\n\n    function handleDropdownMousedown(e: MouseEvent) {\n      const target = e.target as HTMLElement | null\n      if (!target) return\n      if (target.closest('[data-ui-select-search]')) return\n      if (isScrollbarClick(target, e)) return\n      e.preventDefault()\n    }\n\n    const isEmpty = computed(() => ctx.flatFilteredItems.value.length === 0)\n\n    const hasNoChoiceContent = computed(() => ctx.noChoiceContent.value !== null)\n\n    // Wrapping the render fn in a computed keeps one component object alive for\n    // as long as the content itself is unchanged. Inline in the template it was\n    // a new literal per render, which Vue reads as a different component type\n    // and so unmounts and remounts the consumer's empty state every time.\n    const noChoiceComponent = computed(() => {\n      const render = ctx.noChoiceContent.value\n      return render ? { render: () => render(noChoiceScope.value) } : null\n    })\n\n    /** What a custom <ui-select-no-choice> slot is told about the empty list. */\n    const noChoiceScope = computed<NoChoiceSlotScope>(() => ({\n      reason: ctx.emptyReason?.value ?? 'no-options',\n      search: ctx.search.value.trim(),\n      multiple: ctx.multiple.value,\n    }))\n\n    /**\n     * The message shown when the consumer supplied no empty state of their\n     * own. An empty panel told the user nothing — worst of all on an edit\n     * screen whose single select held its only option, where remove-selected\n     * hid that option and the panel opened onto a blank sliver.\n     */\n    const defaultEmptyMessage = computed<string>(() => {\n      const m = ctx.messages?.value\n      if (!m) return ''\n      switch (ctx.emptyReason?.value) {\n        case 'no-results': return m.noResults\n        case 'all-selected': return ctx.multiple.value ? m.allSelected : m.noOtherOptions\n        default: return m.noOptions\n      }\n    })\n\n    const dropdownStyle = computed<Record<string, string>>(() => {\n      const style: Record<string, string> = {}\n      if (ctx.appendToBody.value && ctx.teleportStyle?.value) {\n        Object.assign(style, ctx.teleportStyle.value)\n      }\n      if (ctx.dropdownMaxHeight?.value) {\n        style.maxHeight = ctx.dropdownMaxHeight.value\n        style.overflowY = 'auto'\n      }\n      return style\n    })\n\n    return {\n      ctx,\n      indexedGroups,\n      isChoiceDisabled,\n      getChoiceSlotScope,\n      handleItemClick,\n      handleItemMouseEnter,\n      handleDropdownMousedown,\n      showMinimumLengthMessage,\n      minimumLengthMessage,\n      remainingChars,\n      isEmpty,\n      hasNoChoiceContent,\n      noChoiceComponent,\n      defaultEmptyMessage,\n      dropdownStyle,\n    }\n  },\n})\n</script>\n\n<template>\n  <Teleport to=\"body\" :disabled=\"!ctx.appendToBody.value\">\n    <Transition name=\"ui-select-dropdown\">\n      <div\n        v-if=\"ctx.isOpen.value\"\n        :ref=\"(el: any) => { ctx.dropdownRef.value = el }\"\n        class=\"ui-select__dropdown\"\n        :class=\"[\n          'ui-select__dropdown--' + ctx.theme.value,\n          { 'ui-select__dropdown--up': ctx.resolvedPosition?.value === 'up' },\n        ]\"\n        :data-position=\"ctx.resolvedPosition?.value\"\n        :style=\"dropdownStyle\"\n        data-ui-select-dropdown=\"\"\n        data-testid=\"ui-select-dropdown\"\n        @mousedown=\"handleDropdownMousedown\"\n      >\n        <!-- Search input for single mode -->\n        <div\n          v-if=\"ctx.searchEnabled.value && !ctx.multiple.value\"\n          class=\"ui-select__search\"\n          data-ui-select-search=\"\"\n          data-testid=\"ui-select-search\"\n        >\n          <input\n            :ref=\"(el: any) => { ctx.inputRef.value = el }\"\n            v-model=\"ctx.search.value\"\n            type=\"text\"\n            class=\"ui-select__input\"\n            data-ui-select-input=\"\"\n            data-testid=\"ui-select-input\"\n            autocomplete=\"off\"\n            :placeholder=\"ctx.placeholder.value\"\n            v-bind=\"ctx.inputAriaAttrs.value\"\n            @click.stop\n            @keydown=\"ctx.handleKeyDown\"\n            @paste.stop=\"ctx.handlePaste\"\n          />\n        </div>\n\n        <!-- Choices list. Rendered whenever the dropdown is open, even while the\n             minimum-length prompt is showing: the search input's aria-controls\n             names this element, and it used to point at an id that was not in\n             the document at that moment. The prompt lives inside it, which is\n             also where a status about the list belongs. -->\n        <div\n          class=\"ui-select-choices\"\n          data-ui-select-choices=\"\"\n          data-testid=\"ui-select-choices\"\n          :data-show-checkboxes=\"showCheckboxes || undefined\"\n          v-bind=\"ctx.listboxAriaAttrs.value\"\n        >\n          <!-- Minimum length prompt -->\n          <div\n            v-if=\"showMinimumLengthMessage\"\n            class=\"ui-select-choices__minimum-length\"\n            data-ui-select-minimum-length=\"\"\n            data-testid=\"ui-select-minimum-length\"\n            role=\"presentation\"\n          >\n            <!-- Localizable: the default is English-only copy. -->\n            <slot\n              name=\"minimum-length\"\n              :remaining=\"remainingChars\"\n              :minimum=\"minimumInputLength\"\n            >{{ minimumLengthMessage }}</slot>\n          </div>\n\n          <template v-for=\"(group, groupIdx) in indexedGroups\" :key=\"groupIdx\">\n            <!-- Group header -->\n            <div\n              v-if=\"group.label !== undefined\"\n              class=\"ui-select-choices__group-header\"\n              data-ui-select-group-header=\"\"\n              data-testid=\"ui-select-group-header\"\n              role=\"presentation\"\n              :aria-label=\"group.label\"\n            >\n              <slot name=\"group-header\" :groupName=\"group.label\">{{ group.label }}</slot>\n            </div>\n\n            <!-- Group items -->\n            <div\n              v-for=\"({ item, flatIndex }) in group.items\"\n              :key=\"flatIndex\"\n              class=\"ui-select-choices__row\"\n              :class=\"{\n                'ui-select-choices__row--active': ctx.activeIndex.value === flatIndex,\n                'ui-select-choices__row--selected': ctx.isItemSelected(item),\n                'ui-select-choices__row--disabled': isChoiceDisabled(item),\n              }\"\n              :data-ui-select-choice-index=\"flatIndex\"\n              data-ui-select-choice=\"\"\n              data-testid=\"ui-select-choice\"\n              :data-active=\"ctx.activeIndex.value === flatIndex || undefined\"\n              :data-selected=\"ctx.isItemSelected(item) || undefined\"\n              :data-disabled=\"isChoiceDisabled(item) || undefined\"\n              role=\"option\"\n              :id=\"ctx.uid + '-option-' + flatIndex\"\n              :aria-selected=\"ctx.isItemSelected(item)\"\n              :aria-disabled=\"isChoiceDisabled(item) || undefined\"\n              @click=\"handleItemClick(item, $event)\"\n              @mouseenter=\"handleItemMouseEnter(item, flatIndex)\"\n            >\n              <input\n                v-if=\"showCheckboxes\"\n                type=\"checkbox\"\n                :checked=\"ctx.isItemSelected(item)\"\n                class=\"ui-select-choices__checkbox\"\n                data-ui-select-checkbox=\"\"\n                tabindex=\"-1\"\n                aria-hidden=\"true\"\n                @click.prevent\n              />\n              <slot name=\"choice\" v-bind=\"getChoiceSlotScope(item, flatIndex)\">\n                {{ typeof item === 'object' ? JSON.stringify(item) : item }}\n              </slot>\n            </div>\n          </template>\n\n          <!-- \"(new)\" tag row — create the current search term as a tag.\n               Hover clears the active item so Enter also creates the tag. -->\n          <div\n            v-if=\"ctx.shouldShowTagRow()\"\n            class=\"ui-select-choices__row ui-select-choices__tag-row\"\n            data-ui-select-tag-row=\"\"\n            data-testid=\"ui-select-tag-row\"\n            role=\"option\"\n            :aria-selected=\"false\"\n            @click.stop=\"ctx.selectSearchAsTag()\"\n            @mouseenter=\"ctx.activeIndex.value = -1\"\n          >\n            <slot name=\"tag-row\" :search=\"ctx.search.value\" :label=\"ctx.getTagRowLabel()\">\n              {{ ctx.getTagRowLabel() }}\n            </slot>\n          </div>\n\n          <!-- No results / empty state. The tag row supersedes it: \"no results,\n               but you can create this\" reads as the row alone. Suppressed while\n               loading too — an in-flight request has not established that there\n               are no results, and saying so flickers on every remote keystroke. -->\n          <div\n            v-if=\"isEmpty && !ctx.loading.value && !showMinimumLengthMessage && !ctx.shouldShowTagRow()\"\n            class=\"ui-select-no-choice\"\n            data-ui-select-no-choice=\"\"\n            data-testid=\"ui-select-no-choice\"\n            :data-empty-reason=\"ctx.emptyReason?.value || undefined\"\n          >\n            <component :is=\"noChoiceComponent\" v-if=\"hasNoChoiceContent && noChoiceComponent\" />\n            <span v-else class=\"ui-select-no-choice__default\">{{ defaultEmptyMessage }}</span>\n          </div>\n        </div>\n      </div>\n    </Transition>\n  </Teleport>\n</template>\n","<script lang=\"ts\">\nimport { defineComponent, inject, onBeforeUnmount, useSlots } from 'vue'\nimport { UI_SELECT_CONTEXT } from '../symbols'\nimport type { UiSelectContext, NoChoiceSlotScope } from '../types'\n\nexport default defineComponent({\n  name: 'UiSelectNoChoice',\n  setup() {\n    const ctx = inject(UI_SELECT_CONTEXT) as UiSelectContext\n    const slots = useSlots()\n\n    // Register slot render function with context for UiSelectChoices to\n    // consume. The scope says WHY the list is empty, so a custom slot can\n    // tell \"nothing matched\" from \"you have already picked it\".\n    const renderFn = (scope: NoChoiceSlotScope) => {\n      return slots.default ? slots.default(scope) : null\n    }\n\n    ctx.registerNoChoiceContent(renderFn)\n\n    onBeforeUnmount(() => {\n      if (ctx.noChoiceContent.value === renderFn) {\n        ctx.noChoiceContent.value = null\n      }\n    })\n\n    // This component renders nothing — its content is rendered by UiSelectChoices\n    return () => null\n  },\n})\n</script>\n","/**\n * Creates a debounced version of a function.\n */\nexport function debounce<T extends (...args: any[]) => any>(\n  fn: T,\n  delay: number\n): (...args: Parameters<T>) => void {\n  let timer: ReturnType<typeof setTimeout> | null = null\n  return (...args: Parameters<T>) => {\n    if (timer) clearTimeout(timer)\n    timer = setTimeout(() => {\n      fn(...args)\n      timer = null\n    }, delay)\n  }\n}\n","// ============================================================\n// vue-ui-select — Public Entry Point\n// ============================================================\n\nimport type { App, Plugin } from 'vue'\nimport UiSelect from './components/UiSelect.vue'\nimport UiSelectMatch from './components/UiSelectMatch.vue'\nimport UiSelectChoices from './components/UiSelectChoices.vue'\nimport UiSelectNoChoice from './components/UiSelectNoChoice.vue'\nimport { UI_SELECT_OPTIONS } from './symbols'\nimport type { UiSelectPluginOptions } from './types'\n\n// ---- Plugin ----\n\n/**\n * Turns a component-name prefix into one usable in a kebab-case tag name,\n * always ending in a single separating hyphen. 'My', 'my', 'my-' and 'MyOrg'\n * become 'my-', 'my-', 'my-' and 'my-org-'.\n */\nfunction toKebabPrefix(prefix: string): string {\n  if (!prefix) return ''\n  const kebab = prefix\n    .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n    .toLowerCase()\n    .replace(/[-_\\s]+$/, '')\n  return kebab ? `${kebab}-` : ''\n}\n\nexport const UiSelectPlugin: Plugin = {\n  install(app: App, options?: UiSelectPluginOptions) {\n    const opts: UiSelectPluginOptions = {\n      theme: 'tailwind',\n      ...options,\n    }\n\n    app.provide(UI_SELECT_OPTIONS, opts)\n\n    const prefix = opts.prefix || ''\n    app.component(`${prefix}UiSelect`, UiSelect)\n    app.component(`${prefix}UiSelectMatch`, UiSelectMatch)\n    app.component(`${prefix}UiSelectChoices`, UiSelectChoices)\n    app.component(`${prefix}UiSelectNoChoice`, UiSelectNoChoice)\n\n    // Also register kebab-case aliases. The prefix is kebab-cased first: pasting\n    // a PascalCase prefix straight onto a kebab name produced `Myui-select`,\n    // which no template can write. `My` and `my-` both give `my-ui-select`.\n    const kebab = toKebabPrefix(prefix)\n    app.component(`${kebab}ui-select`, UiSelect)\n    app.component(`${kebab}ui-select-match`, UiSelectMatch)\n    app.component(`${kebab}ui-select-choices`, UiSelectChoices)\n    app.component(`${kebab}ui-select-no-choice`, UiSelectNoChoice)\n  },\n}\n\n// ---- Component exports ----\n\nexport { UiSelect, UiSelectMatch, UiSelectChoices, UiSelectNoChoice }\n\n// ---- Type exports ----\n\nexport type {\n  UiSelectProps,\n  UiSelectChoicesProps,\n  UiSelectMatchProps,\n  UiSelectEmits,\n  UiSelectContext,\n  UiSelectPluginOptions,\n  UiSelectPluginDefaults,\n  ChoiceSlotScope,\n  MatchSingleSlotScope,\n  MatchMultiSlotScope,\n  GroupedItems,\n  ObjectSourceItem,\n  DropdownPosition,\n  ThemeName,\n  SelectEventPayload,\n  RemoveEventPayload,\n  ClearEventPayload,\n  LimitReachedPayload,\n  UiSelectMessages,\n  EmptyReason,\n  NoChoiceSlotScope,\n  ChoicesConfig,\n} from './types'\n\n// ---- Utility exports ----\n\nexport { highlightText } from './utils/highlight'\nexport { normalizeObjectSource, resolveBindValue, getNestedValue, resolveTrackBy } from './utils/objectSource'\nexport { debounce } from './utils/debounce'\n\n// ---- Symbol exports ----\n\nexport { UI_SELECT_CONTEXT, UI_SELECT_OPTIONS } from './symbols'\n\n// ---- Default export ----\n\nexport default UiSelectPlugin\n"],"names":["UI_SELECT_CONTEXT","UI_SELECT_OPTIONS","uidCounter","vueUseId","VueRuntime","useSelectState","props","generatedId","uid","isOpen","ref","search","activeIndex","rootRef","inputRef","dropdownRef","open","close","toggle","focus","options","target","blur","active","_a","watch","val","OBJECT_SOURCE_ITEM","normalizeObjectSource","obj","key","value","item","isObjectSourceItem","unwrapObjectSourceItem","resolveBindValue","bindProperty","getNestedValue","path","acc","resolveTrackBy","trackBy","stableStringify","memo","hit","computed","seen","_key","v","k","useModelBinding","opts","modelValue","multiple","rawItems","lockChoice","emit","isLocked","fn","selected","commits","hydrateSelected","mv","previous","found","findItemByBoundValue","it","bv","isMulti","emitModelValue","unwrapForEmit","currentModelValue","arr","isItemSelected","sel","itemsEqual","b","aWrapped","bWrapped","tby","ka","kb","createSelectionMatcher","selectItem","removeItem","idx","prev","clearSelection","removable","model","cleared","useSelectFiltering","choicesConfig","removeSelected","cfg","items","searchedItems","result","q","fields","matchesSearch","sortFn","a","filteredItems","isSelected","emptyReason","groupedItems","groupBy","map","order","rawLabel","groupLabel","groups","label","gf","g","labels","l","filtered","flatFilteredItems","group","fieldMatches","query","entry","kind","field","useSelectKeyboard","disabled","tagging","taggingTokens","disableChoice","clearable","appendToBody","isAtLimit","limit","createTag","shouldShowTagRow","findExistingByTerm","focusHost","focusSibling","INTERACTIVE_SELECTOR","isForeignTarget","e","control","isSearchBoxTarget","isLockedItem","reportTagLimit","term","isChoiceDisabled","buildTokenSplitter","literals","t","pattern","findNextEnabled","startIdx","direction","max","i","scrollActiveIntoView","el","HANDLED","handleKeyDown","emitHighlight","existing","tag","handlePaste","text","re","parts","s","part","isHandlingTokens","tokenLimitReported","handleSearchInput","tags","SCROLLABLE_OVERFLOW","END_OF_SCROLL_TOLERANCE","isScrollable","axis","overflow","canScrollFurther","delta","offset","findScrollableAncestor","start","LINE_HEIGHT","PAGE_HEIGHT_FALLBACK","normalizeWheelDelta","event","viewportSize","CLIPPING_OVERFLOW","isClippedByAncestor","rect","node","style","box","useSelectPositioning","position","resolvedPosition","teleportStyle","dropdownMaxHeight","VIEWPORT_PADDING","containingBlock","scrollTop","scrollLeft","host","transform","calculatePosition","spaceBelow","spaceAbove","dropdownHeight","availableAbove","cb","triggerTop","triggerBottom","triggerLeft","hidden","visibility","pointerEvents","handleDropdownWheel","dropdownEl","container","scrollListener","resizeListener","dropdownObserver","wheelTarget","repositionFrame","scheduleReposition","addListeners","observed","removeListeners","nextTick","onBeforeUnmount","useSelectTagging","taggingLabel","isTaggingEnabled","previewTerm","previewValue","previewTag","needle","searchText","tagFn","potentialTag","getTagRowLabel","useSelectAccessibility","placeholder","inputId","searchEnabled","listboxId","inputElId","activeDescendantId","rootAriaAttrs","inputAriaAttrs","listboxAriaAttrs","optionAriaAttrs","index","isDisabled","groupHeaderAriaAttrs","useThemeClasses","theme","themeDataAttr","partAttrs","state","attrs","highlightText","raw","escapeHtml","regex","escapeRegExp","lastIndex","match","str","_sfc_main$3","defineComponent","expose","propRefs","toRefs","pluginOptions","inject","effectiveTheme","effectiveSearchEnabled","effectiveCloseOnSelect","effectiveAppendToBody","effectiveClearable","effectiveRemoveSelected","messages","shallowRef","registerChoicesConfig","config","unregisterChoicesConfig","noChoiceContent","registerNoChoiceContent","renderFn","_b","placeholderRawItems","filtering","taggingUtil","keyboard","handleSelect","handleRemove","positioning","a11y","rootAriaLabel","out","themeClasses","TABBABLE_SELECTOR","backwards","root","dropdown","candidates","firstAfter","restoreFocus","isInsideWidget","selectSearchAsTag","searchEmitTimer","cancelPendingSearchEmit","previousItems","dispatchInputEvent","blurPending","reportBlur","handleFocusIn","handleFocusOut","next","suppressInternalBlur","handleClickOutside","hadFocus","foreignClasses","isOwnClass","name","onBeforeUpdate","c","onUpdated","onMounted","context","toRef","provide","_openBlock","_createElementBlock","_mergeProps","_ctx","_cache","args","_renderSlot","_hoisted_2","_createElementVNode","_sfc_main$2","ctx","resolvedPlaceholder","hasSelection","selectedItems","unwrapObjectSourceItemUtil","singleSlotScope","restoreFocusIfDetached","button","input","handleClear","handleRemoveItem","tagRemoveLabel","isItemLocked","handleControlClick","_Fragment","_hoisted_4","_renderList","_normalizeClass","_createTextVNode","_toDisplayString","_withModifiers","$event","_hoisted_5","_createCommentVNode","_withDirectives","_hoisted_6","_vModelText","_hoisted_7","_hoisted_1","_hoisted_3","_normalizeProps","_guardReactiveProps","_sfc_main$1","indexedGroups","flatIndex","getChoiceSlotScope","unwrapped","handleItemClick","handleItemMouseEnter","flatIdx","searchLength","showMinimumLengthMessage","remainingChars","minimumLengthMessage","remaining","isScrollbarClick","scrollsY","scrollsX","handleDropdownMousedown","isEmpty","hasNoChoiceContent","noChoiceComponent","render","noChoiceScope","defaultEmptyMessage","m","dropdownStyle","_createBlock","_Teleport","_createVNode","_Transition","_withCtx","_normalizeStyle","groupIdx","_hoisted_8","_c","_resolveDynamicComponent","_hoisted_10","_hoisted_9","_sfc_main","slots","useSlots","scope","debounce","delay","timer","toKebabPrefix","prefix","kebab","UiSelectPlugin","app","UiSelect","UiSelectMatch","UiSelectChoices","UiSelectNoChoice"],"mappings":"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"}