kmenu
Version:
The perfect ⌘K menu
1 lines • 51.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/state-machine.ts","../src/core.ts","../src/filters.ts"],"names":["StateMachine","initialState","name","transition","previousState","state","callback","generateIdFromLabel","label","CommandCore","config","e","options","query","normalizedQuery","option","labelMatch","keywordMatch","k","value","processedOptions","usedIds","processOption","id","baseId","children","child","counter","uniqueId","reordered","ungroupedItems","opt","groupOrder","group","groupItems","parentId","flattened","childOptions","index","direction","activeElement","listRect","activeRect","now","scrollBehavior","extraMargin","topThreshold","itemHeight","targetScroll","elementTop","elementHeight","containerHeight","newIndex","event","handler","optionsToFilter","filtered","firstEnabled","parentMenuId","parentOption","el","target","isActive","i","activeOption","result","simpleFilter","startsWithFilter","fuzzyFilter","queryChars","text","score","lastIndex","consecutiveMatches","char","item","a","b","createRegexFilter","pattern","flags","regex"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * All states for the internal state machine.\n */\nexport type State = \"idle\" | \"open\" | \"navigating\" | \"filtering\" | \"selected\";\n\n/**\n * A named transition describing allowed `from` state(s) and the resulting `to` state.\n */\nexport interface StateTransition {\n from: State | State[];\n to: State;\n guard?: () => boolean;\n}\n\nexport class StateMachine {\n private currentState: State;\n private transitions = new Map<string, StateTransition>();\n private listeners = new Map<State, Set<() => void>>();\n\n constructor(initialState: State = \"idle\") {\n this.currentState = initialState;\n }\n\n /** Register a named transition. */\n defineTransition(name: string, transition: StateTransition): void {\n this.transitions.set(name, transition);\n }\n\n /** Attempt a transition by name. Returns `true` if applied. */\n transition(name: string): boolean {\n const transition = this.transitions.get(name);\n if (!transition) return false;\n\n const fromStates = Array.isArray(transition.from)\n ? transition.from\n : [transition.from];\n\n if (!fromStates.includes(this.currentState)) return false;\n\n if (transition.guard && !transition.guard()) return false;\n\n const previousState = this.currentState;\n this.currentState = transition.to;\n\n this.notifyListeners(previousState);\n this.notifyListeners(this.currentState);\n\n return true;\n }\n\n /** Get the current state. */\n getState(): State {\n return this.currentState;\n }\n\n /** Subscribe to callbacks when a state is entered. */\n onStateEnter(state: State, callback: () => void): () => void {\n if (!this.listeners.has(state)) {\n this.listeners.set(state, new Set());\n }\n this.listeners.get(state)!.add(callback);\n\n return () => {\n this.listeners.get(state)?.delete(callback);\n };\n }\n\n private notifyListeners(state: State): void {\n this.listeners.get(state)?.forEach((callback) => callback());\n }\n}\n","import { StateMachine } from \"./state-machine\";\n\nfunction generateIdFromLabel(label: string): string {\n return label\n .toLowerCase()\n .replace(/[^a-z0-9\\s]/g, \"\")\n .replace(/\\s+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .substring(0, 50);\n}\n\n/**\n * Describes an actionable or navigable option in the command menu.\n */\nexport interface CommandOption<T = any> {\n id?: string;\n label: string;\n keywords?: string[];\n disabled?: boolean;\n group?: string;\n data?: T;\n children?: CommandOption<T>[];\n parent?: string;\n action?: () => void | Promise<void> | CommandOption<T>[];\n}\n\n/**\n * Breadcrumb segment representing the current submenu path.\n */\nexport interface Breadcrumb {\n id: string;\n label: string;\n}\n\n/**\n * Complete immutable snapshot of the command system state.\n */\nexport interface CommandState<T = any> {\n open: boolean;\n input: string;\n activeId?: string;\n activeIndex: number;\n filtered: CommandOption<T>[];\n options: CommandOption<T>[];\n groups: Map<string, CommandOption<T>[]>;\n menuStack: string[];\n currentLevel: number;\n breadcrumbs: Breadcrumb[];\n allOptions: CommandOption<T>[];\n currentOptions: CommandOption<T>[];\n}\n\n/**\n * Discriminated union of events emitted by the command core.\n */\nexport type CommandEvent<T = any> =\n | { type: \"open\" }\n | { type: \"close\" }\n | { type: \"change\"; input: string }\n | { type: \"select\"; option: CommandOption<T> }\n | { type: \"navigate\"; activeId: string | undefined; activeIndex: number }\n | { type: \"submenu\"; option: CommandOption<T>; level: number }\n | { type: \"back\"; level: number };\n\n/** Handler for a specific command event type. */\nexport type EventHandler<T = any> = (event: CommandEvent<T>) => void;\n/** Function that filters `options` using a text `query`. */\nexport type FilterFunction<T = any> = (\n options: CommandOption<T>[],\n query: string\n) => CommandOption<T>[];\n/** Callback to unsubscribe an event handler. */\nexport type Unsubscribe = () => void;\n\n/**\n * Configuration for the `CommandCore` behavior and callbacks.\n */\nexport interface CommandCoreConfig<T = any> {\n filter?: FilterFunction<T>;\n onOpen?: () => void;\n onClose?: () => void;\n onChange?: (input: string) => void;\n onSelect?: (option: CommandOption<T>) => void;\n}\n\n/**\n * Headless command menu engine with filtering, navigation, and submenu support.\n * Provides ARIA props and emits events for UI integration.\n */\nexport class CommandCore<T = any> {\n private stateMachine: StateMachine;\n private state: CommandState<T>;\n private listeners = new Map<CommandEvent<T>[\"type\"], Set<EventHandler<T>>>();\n private filter: FilterFunction<T>;\n private keydownHandler?: (e: KeyboardEvent) => void;\n private globalKeyHandler?: (e: KeyboardEvent) => void;\n private inputElement?: HTMLInputElement;\n private listElement?: HTMLElement;\n private optionElements = new Map<string, HTMLElement>();\n private destroyed = false;\n private lastScrollTime = 0;\n\n constructor(config: CommandCoreConfig<T> = {}) {\n this.stateMachine = new StateMachine(\"idle\");\n\n this.state = {\n open: false,\n input: \"\",\n activeId: undefined,\n activeIndex: -1,\n filtered: [],\n options: [],\n groups: new Map(),\n menuStack: [],\n currentLevel: 0,\n breadcrumbs: [],\n allOptions: [],\n currentOptions: [],\n };\n\n this.filter = config.filter || this.defaultFilter;\n\n this.setupStateMachine();\n this.setupGlobalKeyboardShortcut();\n\n if (config.onOpen) this.on(\"open\", config.onOpen);\n if (config.onClose) this.on(\"close\", config.onClose);\n if (config.onChange)\n this.on(\n \"change\",\n (e) => e.type === \"change\" && config.onChange!(e.input)\n );\n if (config.onSelect)\n this.on(\n \"select\",\n (e) => e.type === \"select\" && config.onSelect!(e.option)\n );\n }\n\n private setupStateMachine(): void {\n this.stateMachine.defineTransition(\"open\", { from: \"idle\", to: \"open\" });\n this.stateMachine.defineTransition(\"startNavigating\", {\n from: [\"open\", \"filtering\"],\n to: \"navigating\",\n });\n this.stateMachine.defineTransition(\"startFiltering\", {\n from: [\"open\", \"navigating\"],\n to: \"filtering\",\n });\n this.stateMachine.defineTransition(\"select\", {\n from: [\"navigating\", \"filtering\"],\n to: \"selected\",\n });\n this.stateMachine.defineTransition(\"close\", {\n from: [\"open\", \"navigating\", \"filtering\", \"selected\"],\n to: \"idle\",\n });\n\n this.stateMachine.onStateEnter(\"open\", () => {\n this.state.open = true;\n this.emit({ type: \"open\" });\n this.updateFiltered();\n this.selectFirstAvailableOption();\n requestAnimationFrame(() => this.inputElement?.focus());\n });\n\n this.stateMachine.onStateEnter(\"idle\", () => {\n this.state.open = false;\n this.state.input = \"\";\n this.state.activeId = undefined;\n this.state.activeIndex = -1;\n this.emit({ type: \"close\" });\n });\n\n this.stateMachine.onStateEnter(\"selected\", () => {\n this.stateMachine.transition(\"close\");\n });\n }\n\n private setupGlobalKeyboardShortcut(): void {\n this.globalKeyHandler = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === \"k\") {\n e.preventDefault();\n this.toggle();\n }\n };\n\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"keydown\", this.globalKeyHandler);\n }\n }\n\n private defaultFilter: FilterFunction<T> = (options, query) => {\n if (!query) return options;\n\n const normalizedQuery = query.toLowerCase();\n\n return options.filter((option) => {\n if (option.disabled) return false;\n\n const labelMatch = option.label.toLowerCase().includes(normalizedQuery);\n const keywordMatch = option.keywords?.some((k) =>\n k.toLowerCase().includes(normalizedQuery)\n );\n\n return labelMatch || keywordMatch;\n });\n };\n\n /** Open the command menu if not destroyed. */\n open(): void {\n if (this.destroyed) return;\n this.stateMachine.transition(\"open\");\n }\n\n /** Close the command menu if not destroyed. */\n close(): void {\n if (this.destroyed) return;\n this.stateMachine.transition(\"close\");\n }\n\n /** Toggle the command menu open/closed state. */\n toggle(): void {\n if (this.destroyed) return;\n this.state.open ? this.close() : this.open();\n }\n\n /**\n * Set the input query and update the filtered options.\n * Emits a `change` event with the latest input.\n */\n setInput(value: string): void {\n if (this.destroyed) return;\n\n this.state.input = value;\n this.stateMachine.transition(\"startFiltering\");\n this.updateFiltered();\n this.emit({ type: \"change\", input: value });\n }\n\n /**\n * Replace the registered options and rebuild all derived state.\n */\n registerOptions(options: CommandOption<T>[]): void {\n if (this.destroyed) return;\n\n const processedOptions = this.processOptionsWithIds(options);\n\n this.state.options = [...processedOptions];\n this.state.groups.clear();\n\n this.state.allOptions = this.flattenOptions(processedOptions);\n\n this.state.currentOptions = [...processedOptions];\n\n this.state.menuStack = [];\n this.state.currentLevel = 0;\n this.state.breadcrumbs = [];\n\n this.rebuildGroups();\n\n this.updateFiltered();\n }\n\n private processOptionsWithIds(\n options: CommandOption<T>[]\n ): CommandOption<T>[] {\n const usedIds = new Set<string>();\n\n const processOption = (option: CommandOption<T>): CommandOption<T> => {\n let id = option.id;\n if (!id) {\n const baseId = generateIdFromLabel(option.label);\n id = this.ensureUniqueId(baseId, usedIds);\n }\n\n usedIds.add(id);\n\n const children = option.children\n ? option.children.map((child) => processOption(child))\n : undefined;\n\n return {\n ...option,\n id,\n children,\n };\n };\n\n return options.map((option) => processOption(option));\n }\n\n private ensureUniqueId(baseId: string, usedIds: Set<string>): string {\n if (!usedIds.has(baseId)) {\n return baseId;\n }\n\n let counter = 1;\n let uniqueId = `${baseId}-${counter}`;\n\n while (usedIds.has(uniqueId)) {\n counter++;\n uniqueId = `${baseId}-${counter}`;\n }\n\n return uniqueId;\n }\n\n private rebuildGroups(): void {\n this.state.groups.clear();\n\n this.state.currentOptions.forEach((option) => {\n if (option.group) {\n if (!this.state.groups.has(option.group)) {\n this.state.groups.set(option.group, []);\n }\n this.state.groups.get(option.group)!.push(option);\n }\n });\n }\n\n private reorderByGroups(options: CommandOption<T>[]): CommandOption<T>[] {\n if (this.state.groups.size === 0) {\n return options;\n }\n\n const reordered: CommandOption<T>[] = [];\n const ungroupedItems = options.filter((opt) => !opt.group);\n\n reordered.push(...ungroupedItems);\n\n const groupOrder: string[] = [];\n for (const option of this.state.currentOptions) {\n if (option.group && !groupOrder.includes(option.group)) {\n groupOrder.push(option.group);\n }\n }\n\n for (const group of groupOrder) {\n const groupItems = options.filter((opt) => opt.group === group);\n reordered.push(...groupItems);\n }\n\n return reordered;\n }\n\n private flattenOptions(\n options: CommandOption<T>[],\n parentId?: string\n ): CommandOption<T>[] {\n const flattened: CommandOption<T>[] = [];\n\n options.forEach((option) => {\n if (parentId) {\n option.parent = parentId;\n }\n\n flattened.push(option);\n\n if (option.children && option.children.length > 0) {\n const childOptions = this.flattenOptions(option.children, option.id);\n flattened.push(...childOptions);\n }\n });\n\n return flattened;\n }\n\n /**\n * Set the active option by filtered index. Optionally provide the\n * navigation direction to optimize scroll behavior.\n */\n setActiveByIndex(index: number, direction?: \"up\" | \"down\"): void {\n if (this.destroyed) return;\n\n const option = this.state.filtered[index];\n if (!option || option.disabled) return;\n\n this.state.activeIndex = index;\n this.state.activeId = option.id;\n this.stateMachine.transition(\"startNavigating\");\n\n this.emit({ type: \"navigate\", activeId: option.id, activeIndex: index });\n this.updateAriaActiveDescendant();\n this.scrollActiveIntoView(direction);\n }\n\n private scrollActiveIntoView(direction?: \"up\" | \"down\"): void {\n if (!this.state.activeId || !this.listElement) return;\n\n const activeElement = this.optionElements.get(this.state.activeId);\n if (!activeElement) return;\n\n const listRect = this.listElement.getBoundingClientRect();\n const activeRect = activeElement.getBoundingClientRect();\n\n const now = Date.now();\n const isRapidScroll = now - this.lastScrollTime < 100;\n const scrollBehavior: ScrollBehavior = isRapidScroll ? \"auto\" : \"smooth\";\n this.lastScrollTime = now;\n\n const extraMargin = 8;\n\n if (direction === \"up\") {\n const topThreshold = listRect.top + listRect.height * 0.25;\n\n if (activeRect.top < topThreshold) {\n const itemHeight = activeRect.height;\n const bufferItems = 2;\n const targetScroll =\n this.listElement.scrollTop - itemHeight * bufferItems - extraMargin;\n\n this.listElement.scrollTo({\n top: Math.max(0, targetScroll),\n behavior: scrollBehavior,\n });\n }\n } else if (direction === \"down\") {\n if (activeRect.bottom > listRect.bottom) {\n const elementTop = activeElement.offsetTop;\n const elementHeight = activeElement.offsetHeight;\n const containerHeight = this.listElement.clientHeight;\n\n const targetScroll =\n elementTop - containerHeight + elementHeight + extraMargin;\n\n this.listElement.scrollTo({\n top: Math.max(0, targetScroll),\n behavior: scrollBehavior,\n });\n }\n } else {\n if (activeRect.top < listRect.top) {\n const elementTop = activeElement.offsetTop;\n const targetScroll = elementTop - extraMargin;\n\n this.listElement.scrollTo({\n top: Math.max(0, targetScroll),\n behavior: scrollBehavior,\n });\n } else if (activeRect.bottom > listRect.bottom) {\n const elementTop = activeElement.offsetTop;\n const elementHeight = activeElement.offsetHeight;\n const containerHeight = this.listElement.clientHeight;\n const targetScroll =\n elementTop - containerHeight + elementHeight + extraMargin;\n\n this.listElement.scrollTo({\n top: Math.max(0, targetScroll),\n behavior: scrollBehavior,\n });\n }\n }\n }\n\n /** Set the active option by option id. */\n setActiveById(id: string): void {\n if (this.destroyed) return;\n\n const index = this.state.filtered.findIndex((opt) => opt.id === id);\n if (index >= 0) {\n this.setActiveByIndex(index);\n }\n }\n\n /** Move the active selection to the previous enabled option. */\n navigateUp(): void {\n if (this.destroyed) return;\n\n let newIndex = this.state.activeIndex - 1;\n\n while (newIndex >= 0 && this.state.filtered[newIndex]?.disabled) {\n newIndex--;\n }\n\n if (newIndex >= 0) {\n this.setActiveByIndex(newIndex, \"up\");\n }\n }\n\n /** Move the active selection to the next enabled option. */\n navigateDown(): void {\n if (this.destroyed) return;\n\n let newIndex = this.state.activeIndex + 1;\n\n while (\n newIndex < this.state.filtered.length &&\n this.state.filtered[newIndex]?.disabled\n ) {\n newIndex++;\n }\n\n if (newIndex < this.state.filtered.length) {\n this.setActiveByIndex(newIndex, \"down\");\n }\n }\n\n /** Subscribe to a command event. Returns an unsubscribe function. */\n on(event: CommandEvent<T>[\"type\"], handler: EventHandler<T>): Unsubscribe {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n\n this.listeners.get(event)!.add(handler);\n\n return () => {\n this.listeners.get(event)?.delete(handler);\n };\n }\n\n /** Get a shallow-copied snapshot of the current state. */\n getState(): CommandState<T> {\n return { ...this.state };\n }\n\n private emit(event: CommandEvent<T>): void {\n const handlers = this.listeners.get(event.type);\n handlers?.forEach((handler) => handler(event));\n }\n\n private updateFiltered(): void {\n let optionsToFilter: CommandOption<T>[];\n\n if (this.state.input.trim()) {\n optionsToFilter =\n this.state.currentLevel === 0\n ? this.state.allOptions\n : this.state.currentOptions;\n } else {\n optionsToFilter = this.state.currentOptions;\n }\n\n const filtered = this.filter(optionsToFilter, this.state.input);\n\n this.state.filtered = this.reorderByGroups(filtered);\n\n if (\n this.state.activeId &&\n !this.state.filtered.some((opt) => opt.id === this.state.activeId)\n ) {\n this.state.activeId = undefined;\n this.state.activeIndex = -1;\n this.selectFirstAvailableOption();\n } else if (this.state.activeId) {\n this.state.activeIndex = this.state.filtered.findIndex(\n (opt) => opt.id === this.state.activeId\n );\n } else if (this.state.open) {\n this.selectFirstAvailableOption();\n }\n }\n\n private selectFirstAvailableOption(): void {\n const firstEnabled = this.state.filtered.findIndex((opt) => !opt.disabled);\n if (firstEnabled >= 0) {\n this.setActiveByIndex(firstEnabled);\n }\n }\n\n /** Enter a submenu using the given parent `option` with children. */\n enterSubmenu(option: CommandOption<T>): void {\n if (this.destroyed || !option.children || option.children.length === 0)\n return;\n\n this.state.menuStack.push(option.id!);\n this.state.currentLevel++;\n\n this.state.breadcrumbs.push({\n id: option.id!,\n label: option.group || option.label,\n });\n\n this.state.currentOptions = [...option.children];\n\n this.rebuildGroups();\n\n this.state.input = \"\";\n this.state.activeId = undefined;\n this.state.activeIndex = -1;\n\n this.updateFiltered();\n this.selectFirstAvailableOption();\n\n this.emit({ type: \"submenu\", option, level: this.state.currentLevel });\n this.emit({ type: \"change\", input: this.state.input });\n }\n\n /** Go back one submenu level. Returns `false` if already at root. */\n goBack(): boolean {\n if (this.destroyed || this.state.menuStack.length === 0) return false;\n\n this.state.menuStack.pop();\n this.state.currentLevel--;\n this.state.breadcrumbs.pop();\n\n if (this.state.currentLevel === 0) {\n this.state.currentOptions = [...this.state.options];\n } else {\n const parentMenuId =\n this.state.menuStack[this.state.menuStack.length - 1];\n if (parentMenuId) {\n const parentOption = this.findOptionById(parentMenuId);\n if (parentOption && parentOption.children) {\n this.state.currentOptions = [...parentOption.children];\n } else {\n this.state.currentOptions = [...this.state.options];\n this.state.menuStack = [];\n this.state.currentLevel = 0;\n this.state.breadcrumbs = [];\n }\n } else {\n this.state.currentOptions = [...this.state.options];\n this.state.menuStack = [];\n this.state.currentLevel = 0;\n this.state.breadcrumbs = [];\n }\n }\n\n this.rebuildGroups();\n\n this.state.input = \"\";\n this.state.activeId = undefined;\n this.state.activeIndex = -1;\n\n this.updateFiltered();\n\n this.emit({ type: \"change\", input: this.state.input });\n\n this.emit({ type: \"back\", level: this.state.currentLevel });\n\n return true;\n }\n\n private findOptionById(id: string): CommandOption<T> | undefined {\n return this.state.allOptions.find((option) => option.id === id);\n }\n\n private updateAriaActiveDescendant(): void {\n if (this.inputElement && this.state.activeId) {\n this.inputElement.setAttribute(\n \"aria-activedescendant\",\n `kmenu-option-${this.state.activeId}`\n );\n } else if (this.inputElement) {\n this.inputElement.removeAttribute(\"aria-activedescendant\");\n }\n }\n\n /**\n * Return ARIA attributes for the combobox container element.\n */\n getComboboxProps() {\n return {\n role: \"combobox\" as const,\n \"aria-expanded\": this.state.open,\n \"aria-haspopup\": \"listbox\" as const,\n \"aria-controls\": \"kmenu-listbox\",\n };\n }\n\n /**\n * Return ARIA attributes and event handlers for the input element.\n */\n getInputProps() {\n return {\n ref: (el: HTMLInputElement | null) => {\n if (el) this.inputElement = el;\n },\n role: \"combobox\" as const,\n \"aria-autocomplete\": \"list\" as const,\n \"aria-expanded\": this.state.open,\n \"aria-controls\": \"kmenu-listbox\",\n \"aria-activedescendant\": this.state.activeId\n ? `kmenu-option-${this.state.activeId}`\n : undefined,\n value: this.state.input,\n onInput: (e: Event) => {\n const target = e.target as HTMLInputElement;\n this.setInput(target.value);\n },\n onKeyDown: (e: KeyboardEvent) => {\n this.handleKeyDown(e);\n },\n };\n }\n\n /** Return ARIA attributes for the listbox element. */\n getListboxProps() {\n return {\n ref: (el: HTMLElement | null) => {\n if (el) this.listElement = el;\n },\n id: \"kmenu-listbox\",\n role: \"listbox\" as const,\n \"aria-label\": \"Commands\",\n tabIndex: -1,\n };\n }\n\n /**\n * Return ARIA attributes and event handlers for an option element by id.\n */\n getOptionProps(id: string) {\n const option = this.state.allOptions.find((opt) => opt.id === id);\n const isActive = this.state.activeId === id;\n const index = this.state.filtered.findIndex((opt) => opt.id === id);\n\n return {\n ref: (el: HTMLElement | null) => {\n if (el) {\n this.optionElements.set(id, el);\n } else {\n this.optionElements.delete(id);\n }\n },\n id: `kmenu-option-${id}`,\n role: \"option\" as const,\n \"aria-selected\": isActive,\n \"aria-disabled\": option?.disabled,\n tabIndex: -1,\n onClick: () => {\n if (option && !option.disabled) {\n this.state.activeId = id;\n this.state.activeIndex = index;\n this.selectActive();\n }\n },\n onMouseEnter: () => {\n if (option && !option.disabled && index >= 0) {\n this.setActiveByIndex(index);\n }\n },\n };\n }\n\n private handleKeyDown(e: KeyboardEvent): void {\n switch (e.key) {\n case \"ArrowUp\":\n e.preventDefault();\n this.navigateUp();\n break;\n\n case \"ArrowDown\":\n e.preventDefault();\n this.navigateDown();\n break;\n\n case \"Tab\":\n e.preventDefault();\n if (e.shiftKey) {\n this.navigateUp();\n } else {\n this.navigateDown();\n }\n break;\n\n case \"Enter\":\n e.preventDefault();\n this.selectActive();\n break;\n\n case \"Escape\":\n e.preventDefault();\n this.close();\n break;\n\n case \"Backspace\":\n if (this.state.input === \"\" && this.state.currentLevel > 0) {\n e.preventDefault();\n this.goBack();\n }\n break;\n\n case \"Home\":\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n const firstEnabled = this.state.filtered.findIndex(\n (opt) => !opt.disabled\n );\n if (firstEnabled >= 0) {\n this.setActiveByIndex(firstEnabled);\n }\n }\n break;\n\n case \"End\":\n if (e.ctrlKey || e.metaKey) {\n e.preventDefault();\n for (let i = this.state.filtered.length - 1; i >= 0; i--) {\n if (!this.state.filtered[i]?.disabled) {\n this.setActiveByIndex(i);\n break;\n }\n }\n }\n break;\n }\n }\n\n /** Select the active option or enter its submenu if it has children. */\n selectActive(): void {\n if (this.destroyed || !this.state.activeId) return;\n\n const activeOption = this.state.filtered.find(\n (opt) => opt.id === this.state.activeId\n );\n\n if (!activeOption || activeOption.disabled) return;\n\n if (activeOption.children && activeOption.children.length > 0) {\n this.enterSubmenu(activeOption);\n } else {\n this.emit({ type: \"select\", option: activeOption });\n this.stateMachine.transition(\"select\");\n\n if (activeOption.action) {\n const result = activeOption.action();\n if (result instanceof Promise) {\n result.catch(console.error);\n } else if (Array.isArray(result)) {\n activeOption.children = result;\n this.enterSubmenu(activeOption);\n return;\n }\n }\n }\n }\n\n /** Cleanup event listeners and internal references. Safe to call multiple times. */\n destroy(): void {\n if (this.destroyed) return;\n\n this.destroyed = true;\n this.close();\n\n if (this.globalKeyHandler && typeof window !== \"undefined\") {\n window.removeEventListener(\"keydown\", this.globalKeyHandler);\n }\n\n this.listeners.clear();\n this.optionElements.clear();\n this.inputElement = undefined;\n this.listElement = undefined;\n }\n}\n","import type { CommandOption, FilterFunction } from \"./core\";\n\n/**\n * Case-insensitive contains match across label and keywords.\n */\nexport const simpleFilter: FilterFunction = (options, query) => {\n if (!query) return options;\n\n const normalizedQuery = query.toLowerCase();\n\n return options.filter((option) => {\n if (option.disabled) return false;\n\n const labelMatch = option.label.toLowerCase().includes(normalizedQuery);\n const keywordMatch = option.keywords?.some((k) =>\n k.toLowerCase().includes(normalizedQuery)\n );\n\n return labelMatch || keywordMatch;\n });\n};\n\n/**\n * Case-insensitive starts-with match across label and keywords.\n */\nexport const startsWithFilter: FilterFunction = (options, query) => {\n if (!query) return options;\n\n const normalizedQuery = query.toLowerCase();\n\n return options.filter((option) => {\n if (option.disabled) return false;\n\n const labelMatch = option.label.toLowerCase().startsWith(normalizedQuery);\n const keywordMatch = option.keywords?.some((k) =>\n k.toLowerCase().startsWith(normalizedQuery)\n );\n\n return labelMatch || keywordMatch;\n });\n};\n\n/**\n * Simple fuzzy matcher that rewards consecutive and word-boundary matches.\n */\nexport const fuzzyFilter: FilterFunction = (options, query) => {\n if (!query) return options;\n\n const normalizedQuery = query.toLowerCase();\n const queryChars = normalizedQuery.split(\"\");\n\n const scored = opti