import React, {useEffect, useState} from 'react' import {getSuggestion} from '../helpers/search.js' import Input from 'ink-text-input' import {Divider} from './Divider.js' import {Box, Text, useInput, useApp, type Key} from 'ink' export function SearchBox({ components, helper, initialQuery, onKeyDown, onChange, onSubmit, }: { components: T[] helper: string initialQuery?: string onKeyDown?: (i: string, k: Key, app: ReturnType) => void onChange?: (item: T) => void onSubmit?: (item: T) => void }) { const [query, setQuery] = useState(initialQuery ?? '') const [queryMode, setQueryMode] = useState(true) const [isLoading, setLoading] = useState(false) const [suggestions, setSuggestions] = useState([]) const [selected, setSelected] = useState(-1) useEffect(() => { if (queryMode) { setLoading(true) getSuggestion( components.map(({key}) => key), query, ).then((result) => { setSuggestions(result) setSelected(-1) }) } }, [query, queryMode]) useEffect(() => { if (onChange) { const found = components.find(({key}) => key === suggestions[selected]) found && onChange(found) } }, [selected, suggestions, onChange]) const app = useApp() useInput((i, k) => { if (k.downArrow) { setSelected((p) => (p >= suggestions.length - 1 ? 0 : p + 1)) setQueryMode(false) } if (k.upArrow) { setSelected((p) => (p <= 0 ? suggestions.length - 1 : p - 1)) setQueryMode(false) } onKeyDown?.(i, k, app) }) useEffect(() => { if (!queryMode && suggestions[selected]) { setQuery(suggestions[selected]) } }, [queryMode, selected]) return ( {helper} Search? { setQueryMode(true) setQuery(v) }} showCursor placeholder={' query'} onSubmit={() => { const found = components.find(({key}) => key === suggestions[selected]) found && onSubmit?.(found) }} /> {suggestions.map((name, index) => { return ( {components[components.findIndex(({key}) => key === name)].displayName} ) })} ) }