1- import { useEffect , useState } from 'react' ;
1+ import { useEffect , useMemo , type ComponentProps } from 'react' ;
22import { Combobox , HStack , Portal , Span , Spinner , Skeleton } from '@chakra-ui/react' ;
33import { useFilter , useListCollection } from '@chakra-ui/react' ;
44
5- type EndpointOption = {
5+ type Option = {
66 label : string ;
77 value : string ;
88} ;
99
10- interface ComboboxProps {
11- items : { label : string ; value : string } [ ] ;
12- selectedValue : string ;
10+ interface ComboboxProps extends Omit < ComponentProps < typeof Combobox . Root > , 'onChange' | 'children' | 'value' | 'collection'
11+ > {
12+ items : Option [ ] ;
13+ selectedValue ?: string ;
1314 onChange : ( value : string ) => void ;
14- isLoading ?: boolean ;
15- error ?: boolean ;
1615 placeholder ?: string ;
17- optionName ?: string ;
18- defaultToFirst ?: boolean ;
16+ isLoading ?: boolean ;
1917}
2018
2119export function ComboboxSelect ( {
2220 items,
23- selectedValue,
21+ selectedValue = '' ,
2422 onChange,
23+ placeholder = 'Select an option' ,
2524 isLoading = false ,
26- error = false ,
27- placeholder = 'Select endpoint...' ,
28- optionName = '' ,
29- defaultToFirst = false ,
25+ ...rest
3026} : ComboboxProps ) {
31- const [ cleared , setCleared ] = useState ( false ) ;
32-
33- const itemsWithAll : EndpointOption [ ] =
34- defaultToFirst && items . length > 0
35- ? items
36- : [ { label : `All ${ optionName } ` , value : '' } , ...items ] ;
3727
38- console . log ( 'Items with All option:' , itemsWithAll ) ;
28+ const itemsWithAll = useMemo ( ( ) => {
29+ return items . length > 0
30+ ? [ { label : 'All' , value : '' } , ...items ]
31+ : items ;
32+ } , [ items ] ) ;
3933
40- // Filtering
4134 const { contains } = useFilter ( { sensitivity : 'base' } ) ;
42- const { collection, set, filter } = useListCollection < EndpointOption > ( {
35+ const { collection, set, filter } = useListCollection < Option > ( {
4336 initialItems : [ ] ,
4437 itemToString : item => item . label ,
4538 itemToValue : item => item . value ,
4639 filter : contains ,
4740 } ) ;
4841
49- // Update collection whenever items change
5042 useEffect ( ( ) => {
5143 set ( itemsWithAll ) ;
52-
53- if ( defaultToFirst && itemsWithAll . length > 0 && ! selectedValue && ! cleared ) {
54- console . log ( 'Defaulting to first item:' , itemsWithAll [ 0 ] ) ;
55- onChange ( itemsWithAll [ 0 ] . value ) ;
56-
57- } else if ( ! defaultToFirst && ! selectedValue && ! cleared ) {
58- console . log ( 'Defaulting to "All" option' ) ;
59- onChange ( '' ) ;
60- }
61- } , [ items , set , selectedValue , cleared , onChange ] ) ;
44+ } , [ itemsWithAll , set ] ) ;
6245
6346 return (
6447 < Skeleton loading = { isLoading } w = 'md' >
6548 < Combobox . Root
66- size = 'xs '
49+ size = 'md '
6750 w = 'xs'
6851 collection = { collection }
69- // value={selectedValue ? [selectedValue] : []}
7052 value = { [ selectedValue ] }
7153 onValueChange = { e => {
72- onChange ( e . value [ 0 ] ?? '' ) ;
73- setCleared ( false ) ;
54+ const newValue = e . value [ 0 ] ?? '' ;
55+ onChange ( newValue ) ;
7456 } }
7557 onInputValueChange = { e => filter ( e . inputValue ) }
7658 onOpenChange = { open => {
7759 if ( open ) filter ( '' ) ;
7860 } }
7961 openOnClick
62+ { ...rest }
8063 >
8164 < Combobox . Control >
82- < Combobox . Input placeholder = { placeholder } />
65+ < Combobox . Input
66+ placeholder = { placeholder || 'Select an option' }
67+ />
8368 < Combobox . IndicatorGroup >
8469 < Combobox . ClearTrigger
8570 onClick = { ( ) => {
8671 onChange ( '' ) ;
87- setCleared ( true ) ;
8872 } }
8973 />
9074 < Combobox . Trigger />
@@ -96,14 +80,10 @@ export function ComboboxSelect({
9680 { isLoading ? (
9781 < HStack p = '2' >
9882 < Spinner size = 'xs' borderWidth = '1px' />
99- < Span > Loading endpoints ...</ Span >
83+ < Span > Loading...</ Span >
10084 </ HStack >
101- ) : error ? (
102- < Span p = '2' color = 'fg.error' >
103- Failed to load endpoints
104- </ Span >
10585 ) : collection . items . length === 0 ? (
106- < Combobox . Empty > No endpoints found</ Combobox . Empty >
86+ < Combobox . Empty > No options found</ Combobox . Empty >
10787 ) : (
10888 collection . items . map ( item => (
10989 < Combobox . Item key = { item . value } item = { item } >
@@ -120,4 +100,4 @@ export function ComboboxSelect({
120100 </ Combobox . Root >
121101 </ Skeleton >
122102 ) ;
123- }
103+ }
0 commit comments