import type { ComputedRef, Ref, ShallowRef } from 'vue'; import type { CommandFilterFunction } from './utils'; import { useContextFactory } from '@robonen/vue'; export interface CommandItemInfo { value: string; /** Display/searchable text. Filtering targets this instead of the identity `value`. */ textValue: string; keywords: string[]; disabled: boolean; onSelect?: () => void; } export interface CommandContext { /** Committed selected value (v-model). */ modelValue: Ref; setModelValue: (value: string | undefined) => void; /** Current search term (v-model:searchTerm). */ searchTerm: Ref; setSearchTerm: (value: string) => void; /** Currently highlighted item value (keyboard / pointer focus). */ selectedValue: Ref; setSelectedValue: (value: string | undefined) => void; /** Behavior flags. */ shouldFilter: Ref; loop: Ref; filterFunction: Ref; /** Effective reading direction (per-root override or `ConfigProvider`). */ dir: Ref<'ltr' | 'rtl'>; /** A11y identifiers. */ listId: Ref; labelId: Ref; getItemId: (value: string) => string; /** Registries. */ allItems: ShallowRef>; filteredItems: ComputedRef>; registerItem: (info: CommandItemInfo) => void; unregisterItem: (value: string) => void; allGroups: ShallowRef>>; registerGroup: (groupId: string) => void; unregisterGroup: (groupId: string) => void; registerGroupItem: (groupId: string, value: string) => void; unregisterGroupItem: (groupId: string, value: string) => void; /** DOM. */ listElement: ShallowRef; setListElement: (el: HTMLElement | undefined) => void; /** Returns selectable item values sorted by score desc, then DOM order. */ getSelectableItems: () => string[]; /** Commits the currently-highlighted item: updates modelValue + fires its select callback. */ commitSelected: () => void; /** Clears the search term and, when `resetValue`, the committed selection too. */ clear: (resetValue?: boolean) => void; /** Registered input element (so a clear/cancel affordance can refocus it). */ inputElement: ShallowRef; setInputElement: (el: HTMLElement | undefined) => void; } export interface CommandGroupContext { id: Ref; forceMount: Ref; } export interface CommandItemContext { /** Whether this item matches the committed `modelValue`. */ isSelected: Ref; } export const { inject: useCommandContext, provide: provideCommandContext, } = useContextFactory('Command'); export const { inject: useCommandGroupContext, provide: provideCommandGroupContext, } = useContextFactory('CommandGroup'); export const { inject: useCommandItemContext, provide: provideCommandItemContext, } = useContextFactory('CommandItem');