@@ -119,6 +119,7 @@ export function ComboboxDemo() {
119
119
timezones = { [ ...timezones ] }
120
120
selectedTimezone = { timezones [ 0 ] . timezones [ 0 ] }
121
121
/>
122
+ < ComboboxWithCheckbox frameworks = { [ ...frameworks ] } />
122
123
</ div >
123
124
)
124
125
}
@@ -342,3 +343,63 @@ function TimezoneCombobox({
342
343
</ Popover >
343
344
)
344
345
}
346
+
347
+ function ComboboxWithCheckbox ( { frameworks } : { frameworks : Framework [ ] } ) {
348
+ const [ open , setOpen ] = React . useState ( false )
349
+ const [ selectedFrameworks , setSelectedFrameworks ] = React . useState <
350
+ Framework [ ]
351
+ > ( [ ] )
352
+
353
+ return (
354
+ < Popover open = { open } onOpenChange = { setOpen } >
355
+ < PopoverTrigger asChild >
356
+ < Button
357
+ variant = "outline"
358
+ role = "combobox"
359
+ aria-expanded = { open }
360
+ className = "w-fit min-w-[280px] justify-between"
361
+ >
362
+ { selectedFrameworks . length > 0
363
+ ? selectedFrameworks . map ( ( framework ) => framework . label ) . join ( ", " )
364
+ : "Select frameworks (multi-select)..." }
365
+ < ChevronsUpDown className = "text-muted-foreground" />
366
+ </ Button >
367
+ </ PopoverTrigger >
368
+ < PopoverContent className = "w-[300px] p-0" align = "start" >
369
+ < Command >
370
+ < CommandInput placeholder = "Search framework..." />
371
+ < CommandList >
372
+ < CommandEmpty > No framework found.</ CommandEmpty >
373
+ < CommandGroup >
374
+ { frameworks . map ( ( framework ) => (
375
+ < CommandItem
376
+ key = { framework . value }
377
+ value = { framework . value }
378
+ onSelect = { ( currentValue ) => {
379
+ setSelectedFrameworks (
380
+ selectedFrameworks . some ( ( f ) => f . value === currentValue )
381
+ ? selectedFrameworks . filter (
382
+ ( f ) => f . value !== currentValue
383
+ )
384
+ : [ ...selectedFrameworks , framework ]
385
+ )
386
+ } }
387
+ >
388
+ < div
389
+ className = "border-input data-[selected=true]:border-primary data-[selected=true]:bg-primary data-[selected=true]:text-primary-foreground pointer-events-none size-4 shrink-0 rounded-[4px] border transition-all select-none *:[svg]:opacity-0 data-[selected=true]:*:[svg]:opacity-100"
390
+ data-selected = { selectedFrameworks . some (
391
+ ( f ) => f . value === framework . value
392
+ ) }
393
+ >
394
+ < CheckIcon className = "size-3.5 text-current" />
395
+ </ div >
396
+ { framework . label }
397
+ </ CommandItem >
398
+ ) ) }
399
+ </ CommandGroup >
400
+ </ CommandList >
401
+ </ Command >
402
+ </ PopoverContent >
403
+ </ Popover >
404
+ )
405
+ }
0 commit comments