Skip to content

Commit 3baef99

Browse files
authored
feat(v4): add combobox with checkbox example (#6862)
* feat(v4): add combobox with checkbox example * fix: remove unused checkbox * fix: rounded
1 parent a7b3dbf commit 3baef99

File tree

2 files changed

+69
-3
lines changed

2 files changed

+69
-3
lines changed

apps/v4/components/app-sidebar.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,14 @@ const data = {
151151
],
152152
},
153153
],
154-
components: Object.values(Index).filter(
155-
(item) => item.type === "registry:ui"
156-
),
154+
components: Object.values(Index)
155+
.filter((item) => item.type === "registry:ui")
156+
.concat([
157+
{
158+
name: "combobox",
159+
},
160+
])
161+
.sort((a, b) => a.name.localeCompare(b.name)),
157162
}
158163

159164
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {

apps/v4/components/combobox-demo.tsx

+61
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export function ComboboxDemo() {
119119
timezones={[...timezones]}
120120
selectedTimezone={timezones[0].timezones[0]}
121121
/>
122+
<ComboboxWithCheckbox frameworks={[...frameworks]} />
122123
</div>
123124
)
124125
}
@@ -342,3 +343,63 @@ function TimezoneCombobox({
342343
</Popover>
343344
)
344345
}
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

Comments
 (0)