feat(cli): add Divider and SearchBox components

A Divider and a SearchBox component have been added to the CLI. The Divider is a simple component for displaying a horizontal line. The SearchBox takes a list of components as props and provides a live search functionality, showing suggestions for user inputs.
This commit is contained in:
p-sw 2024-06-07 21:32:01 +09:00
parent 48cb320303
commit 339242cc05
2 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,24 @@
import React from 'react'
import {Box, Text} from 'ink'
export function Divider({width = 50, padding = 1, title}: {width?: number; padding?: number; title: string}) {
const length = Math.floor((width - title.length - padding * 2) / 2)
return (
<Box>
{Array.from(Array(length)).map((_, i) => (
<Text key={i}></Text>
))}
{Array.from(Array(padding)).map((_, i) => (
<Text key={i}> </Text>
))}
<Text>{title}</Text>
{Array.from(Array(padding)).map((_, i) => (
<Text key={i}> </Text>
))}
{Array.from(Array(length)).map((_, i) => (
<Text key={i}></Text>
))}
</Box>
)
}

View File

@ -0,0 +1,45 @@
import React, {useEffect, useState} from 'react'
import {getSuggestion} from '../helpers/search.js'
import Input from 'ink-text-input'
import {Divider} from './Divider.js'
import Spinner from 'ink-spinner'
import {Box, Text} from 'ink'
export function SearchBox({components}: {components: string[]}) {
const [query, setQuery] = useState<string>('')
const [isLoading, setLoading] = useState<boolean>(false)
const [suggestions, setSuggestions] = useState<string[]>([])
useEffect(() => {
setLoading(true)
getSuggestion(components, query).then((result) => {
setSuggestions(result)
setLoading(false)
})
}, [query])
return (
<Box width={50} display={'flex'} flexDirection={'column'} columnGap={4}>
<Box display={'flex'} flexDirection={'row'}>
<Box marginRight={2}>
<Text color={'greenBright'}>?</Text>
</Box>
<Input value={query} onChange={(v) => setQuery(v)} />
</Box>
<Divider title={isLoading ? 'Loading...' : `${suggestions.length} components found.`} />
{isLoading ? (
<Spinner />
) : (
<Box display={'flex'} flexDirection={'column'} columnGap={1}>
{suggestions.map((name) => {
return (
<Box borderStyle={'round'} key={name}>
<Text>{name}</Text>
</Box>
)
})}
</Box>
)}
</Box>
)
}