source dump of claude code
at main 157 lines 2.9 kB view raw
1import { useCallback, useState } from 'react' 2import type { OptionWithDescription } from './select.js' 3import { useSelectNavigation } from './use-select-navigation.js' 4 5export type UseSelectStateProps<T> = { 6 /** 7 * Number of items to display. 8 * 9 * @default 5 10 */ 11 visibleOptionCount?: number 12 13 /** 14 * Options. 15 */ 16 options: OptionWithDescription<T>[] 17 18 /** 19 * Initially selected option's value. 20 */ 21 defaultValue?: T 22 23 /** 24 * Callback for selecting an option. 25 */ 26 onChange?: (value: T) => void 27 28 /** 29 * Callback for canceling the select. 30 */ 31 onCancel?: () => void 32 33 /** 34 * Callback for focusing an option. 35 */ 36 onFocus?: (value: T) => void 37 38 /** 39 * Value to focus 40 */ 41 focusValue?: T 42} 43 44export type SelectState<T> = { 45 /** 46 * Value of the currently focused option. 47 */ 48 focusedValue: T | undefined 49 50 /** 51 * 1-based index of the focused option in the full list. 52 * Returns 0 if no option is focused. 53 */ 54 focusedIndex: number 55 56 /** 57 * Index of the first visible option. 58 */ 59 visibleFromIndex: number 60 61 /** 62 * Index of the last visible option. 63 */ 64 visibleToIndex: number 65 66 /** 67 * Value of the selected option. 68 */ 69 value: T | undefined 70 71 /** 72 * All options. 73 */ 74 options: OptionWithDescription<T>[] 75 76 /** 77 * Visible options. 78 */ 79 visibleOptions: Array<OptionWithDescription<T> & { index: number }> 80 81 /** 82 * Whether the focused option is an input type. 83 */ 84 isInInput: boolean 85 86 /** 87 * Focus next option and scroll the list down, if needed. 88 */ 89 focusNextOption: () => void 90 91 /** 92 * Focus previous option and scroll the list up, if needed. 93 */ 94 focusPreviousOption: () => void 95 96 /** 97 * Focus next page and scroll the list down by a page. 98 */ 99 focusNextPage: () => void 100 101 /** 102 * Focus previous page and scroll the list up by a page. 103 */ 104 focusPreviousPage: () => void 105 106 /** 107 * Focus a specific option by value. 108 */ 109 focusOption: (value: T | undefined) => void 110 111 /** 112 * Select currently focused option. 113 */ 114 selectFocusedOption: () => void 115 116 /** 117 * Callback for selecting an option. 118 */ 119 onChange?: (value: T) => void 120 121 /** 122 * Callback for canceling the select. 123 */ 124 onCancel?: () => void 125} 126 127export function useSelectState<T>({ 128 visibleOptionCount = 5, 129 options, 130 defaultValue, 131 onChange, 132 onCancel, 133 onFocus, 134 focusValue, 135}: UseSelectStateProps<T>): SelectState<T> { 136 const [value, setValue] = useState<T | undefined>(defaultValue) 137 138 const navigation = useSelectNavigation<T>({ 139 visibleOptionCount, 140 options, 141 initialFocusValue: undefined, 142 onFocus, 143 focusValue, 144 }) 145 146 const selectFocusedOption = useCallback(() => { 147 setValue(navigation.focusedValue) 148 }, [navigation.focusedValue]) 149 150 return { 151 ...navigation, 152 value, 153 selectFocusedOption, 154 onChange, 155 onCancel, 156 } 157}