Search for a command to run...
Autocomplete input and command palette with a list of suggestions.
npx shadcn@latest add @zaidan/comboboxpnpx shadcn add @zaidan/comboboxyarn dlx shadcn@latest add @zaidan/comboboxbunx shadcn@latest add @zaidan/comboboxCopy and paste the following code into your project.
1import type {2 ComboboxContentProps as ComboboxPrimitiveContentProps,3 ComboboxControlProps as ComboboxPrimitiveControlProps,4 ComboboxInputProps as ComboboxPrimitiveInputProps,5 ComboboxItemProps as ComboboxPrimitiveItemProps,6 ComboboxSectionProps as ComboboxPrimitiveSectionProps,7 ComboboxTriggerProps as ComboboxPrimitiveTriggerProps,8 ComboboxRootProps,9} from "@kobalte/core/combobox";10import * as ComboboxPrimitive from "@kobalte/core/combobox";11import type { PolymorphicProps } from "@kobalte/core/polymorphic";12import { Check, ChevronsUpDown, X } from "lucide-solid";13import type { ComponentProps, JSX, ValidComponent } from "solid-js";14import { mergeProps, Show, splitProps } from "solid-js";15import { cn } from "~/lib/utils";16import {17 InputGroup,18 InputGroupAddon,19 InputGroupButton,20 InputGroupInput,21} from "~/components/ui/input-group";22
23// ============================================================================24// Combobox Root25// ============================================================================26
27type ComboboxProps<O, OptGroup = never, T extends ValidComponent = "div"> = PolymorphicProps<28 T,29 ComboboxRootProps<O, OptGroup, T>30> &31 Pick<ComponentProps<T>, "class" | "children">;32
33const Combobox = <O, OptGroup = never, T extends ValidComponent = "div">(34 props: ComboboxProps<O, OptGroup, T>,35) => {36 const mergedProps = mergeProps(37 {38 sameWidth: true,39 gutter: 8,40 placement: "bottom",41 defaultFilter: "contains",42 triggerMode: "input",43 } as ComboboxProps<O>,44 props,45 );46 return <ComboboxPrimitive.Root {...mergedProps} />;47};48
49// ============================================================================50// Combobox Control51// ============================================================================52
53type ComboboxControlProps<T extends ValidComponent = "div"> = PolymorphicProps<54 T,55 ComboboxPrimitiveControlProps<T>56> &57 Pick<ComponentProps<T>, "class" | "children">;58
59const ComboboxControl = <T extends ValidComponent = "div">(props: ComboboxControlProps<T>) => {60 const [local, others] = splitProps(props as ComboboxControlProps, ["class"]);61 return (62 <ComboboxPrimitive.Control63 class={cn("z-combobox-control", local.class)}64 data-slot="combobox-control"65 {...others}66 />67 );68};69
70// ============================================================================71// Combobox Input72// ============================================================================73
74type ComboboxInputProps<T extends ValidComponent = "input"> = PolymorphicProps<75 T,76 ComboboxPrimitiveInputProps<T>77> &78 Pick<ComponentProps<"input">, "class" | "placeholder" | "disabled" | "id" | "name"> & {79 showTrigger?: boolean;80 showClear?: boolean;81 children?: JSX.Element;82 };83
84const ComboboxInput = <T extends ValidComponent = "input">(rawProps: ComboboxInputProps<T>) => {85 const props = mergeProps({ showTrigger: true, showClear: false }, rawProps);86 const [local, others] = splitProps(props as ComboboxInputProps, [87 "class",88 "showTrigger",89 "showClear",90 "children",91 "disabled",92 ]);93
94 return (95 <ComboboxPrimitive.Control96 as={InputGroup}97 class={cn("z-combobox-input w-auto", local.class)}98 data-slot="combobox-control"99 >100 {(state) => (101 <>102 {local.children}103 <ComboboxPrimitive.Input104 as={InputGroupInput}105 disabled={local.disabled}106 data-slot="combobox-input"107 {...others}108 />109 <InputGroupAddon align="inline-end">110 <Show when={local.showTrigger}>111 <ComboboxPrimitive.Trigger112 as={InputGroupButton}113 size="icon-xs"114 variant="ghost"115 data-slot="combobox-trigger"116 class="group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent"117 disabled={local.disabled}118 >119 <ComboboxPrimitive.Icon120 as={ChevronsUpDown}121 class="pointer-events-none z-combobox-trigger-icon"122 />123 </ComboboxPrimitive.Trigger>124 </Show>125 <Show when={local.showClear && state.selectedOptions().length > 0}>126 <InputGroupButton127 variant="ghost"128 size="icon-xs"129 data-slot="combobox-clear"130 class="z-combobox-clear"131 disabled={local.disabled}132 onClick={() => state.clear()}133 >134 <X class="pointer-events-none z-combobox-clear-icon" />135 </InputGroupButton>136 </Show>137 </InputGroupAddon>138 </>139 )}140 </ComboboxPrimitive.Control>141 );142};143
144// ============================================================================145// Combobox Trigger (for popup-style combobox)146// ============================================================================147
148type ComboboxTriggerProps<T extends ValidComponent = "button"> = PolymorphicProps<149 T,150 ComboboxPrimitiveTriggerProps<T>151> &152 Pick<ComponentProps<T>, "class" | "children"> & {153 size?: "sm" | "default";154 };155
156const ComboboxTrigger = <T extends ValidComponent = "button">(157 rawProps: ComboboxTriggerProps<T>,158) => {159 const props = mergeProps({ size: "default" }, rawProps);160 const [local, others] = splitProps(props as ComboboxTriggerProps, ["class", "children", "size"]);161
162 return (163 <ComboboxPrimitive.Control>164 <ComboboxPrimitive.Trigger165 class={cn(166 "z-combobox-trigger z-select-trigger flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=combobox-value]:line-clamp-1 *:data-[slot=combobox-value]:flex *:data-[slot=combobox-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",167 local.class,168 )}169 data-size={local.size}170 data-slot="combobox-trigger"171 {...others}172 >173 {local.children}174 <ComboboxPrimitive.Icon175 as={ChevronsUpDown}176 class="pointer-events-none z-combobox-trigger-icon"177 />178 </ComboboxPrimitive.Trigger>179 </ComboboxPrimitive.Control>180 );181};182
183// ============================================================================184// Combobox Content185// ============================================================================186
187type ComboboxContentProps<T extends ValidComponent = "div"> = PolymorphicProps<188 T,189 ComboboxPrimitiveContentProps<T>190> &191 Pick<ComponentProps<T>, "class">;192
193const ComboboxContent = <T extends ValidComponent = "div">(props: ComboboxContentProps<T>) => {194 const [local, others] = splitProps(props as ComboboxContentProps, ["class"]);195 return (196 <ComboboxPrimitive.Portal>197 <ComboboxPrimitive.Content198 class={cn(199 "relative isolate z-50 z-combobox-content z-menu-target max-h-(--kb-popper-available-height) min-w-32 origin-(--kb-combobox-content-transform-origin) overflow-y-auto overflow-x-hidden",200 local.class,201 )}202 data-slot="combobox-content"203 {...others}204 >205 <ComboboxPrimitive.Listbox class="z-combobox-listbox m-0 p-1" />206 </ComboboxPrimitive.Content>207 </ComboboxPrimitive.Portal>208 );209};210
211// ============================================================================212// Combobox Section (Group)213// ============================================================================214
215type ComboboxSectionProps<T extends ValidComponent = "li"> = PolymorphicProps<216 T,217 ComboboxPrimitiveSectionProps<T>218> &219 Pick<ComponentProps<T>, "class">;220
221const ComboboxSection = <T extends ValidComponent = "li">(props: ComboboxSectionProps<T>) => {222 const [local, others] = splitProps(props as ComboboxSectionProps, ["class"]);223 return (224 <ComboboxPrimitive.Section225 class={cn("z-combobox-section", local.class)}226 data-slot="combobox-section"227 {...others}228 />229 );230};231
232// ============================================================================233// Combobox Section Label234// ============================================================================235
236type ComboboxSectionLabelProps = ComponentProps<"span"> & {237 class?: string;238};239
240const ComboboxSectionLabel = (props: ComboboxSectionLabelProps) => {241 const [local, others] = splitProps(props, ["class"]);242 return (243 <span244 class={cn("z-combobox-section-label z-select-label", local.class)}245 data-slot="combobox-section-label"246 {...others}247 />248 );249};250
251// ============================================================================252// Combobox Item253// ============================================================================254
255type ComboboxItemProps<T extends ValidComponent = "li"> = PolymorphicProps<256 T,257 ComboboxPrimitiveItemProps<T>258> &259 Pick<ComponentProps<T>, "class"> & {260 children?: JSX.Element;261 };262
263const ComboboxItem = <T extends ValidComponent = "li">(props: ComboboxItemProps<T>) => {264 const [local, others] = splitProps(props as ComboboxItemProps, ["class", "children"]);265 return (266 <ComboboxPrimitive.Item267 class={cn(268 "relative z-combobox-item z-select-item flex w-full cursor-default select-none items-center outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",269 local.class,270 )}271 data-slot="combobox-item"272 {...others}273 >274 <ComboboxPrimitive.ItemLabel class="z-combobox-item-label z-select-item-text shrink-0 whitespace-nowrap">275 {local.children}276 </ComboboxPrimitive.ItemLabel>277 <ComboboxPrimitive.ItemIndicator278 as="span"279 class="z-combobox-item-indicator z-select-item-indicator"280 >281 <Check class="pointer-events-none z-combobox-item-indicator-icon z-select-item-indicator-icon" />282 </ComboboxPrimitive.ItemIndicator>283 </ComboboxPrimitive.Item>284 );285};286
287// ============================================================================288// Combobox Empty289// ============================================================================290
291type ComboboxEmptyProps = ComponentProps<"div"> & {292 class?: string;293};294
295const ComboboxEmpty = (props: ComboboxEmptyProps) => {296 const [local, others] = splitProps(props, ["class"]);297 return (298 <div299 class={cn("z-combobox-empty py-6 text-center text-sm", local.class)}300 data-slot="combobox-empty"301 {...others}302 />303 );304};305
306// ============================================================================307// Combobox Separator308// ============================================================================309
310type ComboboxSeparatorProps<T extends ValidComponent = "hr"> = ComponentProps<T> & {311 class?: string;312};313
314const ComboboxSeparator = <T extends ValidComponent = "hr">(315 props: PolymorphicProps<T, ComboboxSeparatorProps<T>>,316) => {317 const [local, others] = splitProps(props as ComboboxSeparatorProps, ["class"]);318 return (319 <hr320 class={cn("pointer-events-none z-combobox-separator z-select-separator", local.class)}321 data-slot="combobox-separator"322 {...others}323 />324 );325};326
327export {328 Combobox,329 ComboboxContent,330 ComboboxControl,331 ComboboxEmpty,332 ComboboxInput,333 ComboboxItem,334 ComboboxSection,335 ComboboxSectionLabel,336 ComboboxSeparator,337 ComboboxTrigger,338};The Combobox component uses Kobalte's Combobox primitive under the hood. Here are the main props:
| Prop | Type | Default | Description |
|---|---|---|---|
options | T[] | - | The array of options to display |
optionValue | keyof T | ((option: T) => string) | - | Key or function to get the option's value |
optionTextValue | keyof T | ((option: T) => string) | - | Key or function to get the option's text for filtering |
optionDisabled | keyof T | ((option: T) => boolean) | - | Key or function to determine if option is disabled |
optionGroupChildren | keyof T | - | Key for grouped options' children array |
value | T | - | The controlled value of the combobox |
defaultValue | T | - | The default value of the combobox |
onChange | (value: T) => void | - | Handler called when value changes |
placeholder | string | - | Placeholder text when no value is selected |
disabled | boolean | false | Whether the combobox is disabled |
validationState | "valid" | "invalid" | - | The validation state of the combobox |
multiple | boolean | false | Whether multiple options can be selected |
defaultFilter | "startsWith" | "endsWith" | "contains" | function | "contains" | The filtering strategy |
triggerMode | "input" | "focus" | "manual" | "input" | When to open the dropdown |
| Prop | Type | Default | Description |
|---|---|---|---|
showTrigger | boolean | true | Show the dropdown trigger button |
showClear | boolean | false | Show the clear button when value is selected |
placeholder | string | - | Placeholder text |
disabled | boolean | false | Whether the input is disabled |
class | string | - | Additional CSS classes |
Used for popup-style combobox (button trigger instead of input).
| Prop | Type | Default | Description |
|---|---|---|---|
size | "sm" | "default" | "default" | The size variant of the trigger |
class | string | - | Additional CSS classes |
The ComboboxContent component wraps the dropdown portal and listbox. It inherits positioning from the Combobox root.
| Prop | Type | Default | Description |
|---|---|---|---|
item | ListState.Option<T> | - | The item object from Kobalte |
disabled | boolean | false | Whether the item is disabled |
Displayed when no options match the filter.
Used for grouping options when using optionGroupChildren.
Visual separator between groups.
Here are the source code of all the examples from the preview page:
import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxBasic() { return ( <Example title="Basic"> <Combobox options={frameworks} placeholder="Select a framework..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select a framework..." /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxDisabled() { return ( <Example title="Disabled"> <Combobox options={frameworks} placeholder="Select a framework..." disabled itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select a framework..." disabled /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Field, FieldDescription, FieldError, FieldLabel } from "~/components/ui/field";function ComboboxInvalid() { return ( <Example title="Invalid"> <div class="flex flex-col gap-4"> <Combobox options={frameworks} placeholder="Select a framework..." validationState="invalid" itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select a framework..." aria-invalid="true" /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <Field data-invalid> <FieldLabel for="combobox-framework-invalid">Framework</FieldLabel> <Combobox options={frameworks} placeholder="Select a framework..." validationState="invalid" itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput id="combobox-framework-invalid" placeholder="Select a framework..." aria-invalid="true" /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <FieldDescription>Please select a valid framework.</FieldDescription> <FieldError errors={[{ message: "This field is required." }]} /> </Field> </div> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxWithClear() { return ( <Example title="With Clear Button"> <Combobox options={frameworks} placeholder="Select a framework..." defaultValue={frameworks[0]} itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select a framework..." showClear /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Show } from "solid-js";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxSectionLabel,} from "~/components/ui/combobox";function ComboboxWithGroups() { return ( <Example title="With Groups"> <Combobox<TimezoneOption, TimezoneGroup> options={timezones} optionValue={(opt) => opt} optionTextValue={(opt) => opt} optionGroupChildren="options" placeholder="Select a timezone..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} sectionComponent={(props) => ( <ComboboxSection> <ComboboxSectionLabel>{props.section.rawValue.label}</ComboboxSectionLabel> </ComboboxSection> )} > <ComboboxInput placeholder="Select a timezone..." /> <ComboboxContent> <ComboboxEmpty>No timezones found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Show } from "solid-js";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxSectionLabel, ComboboxSeparator,} from "~/components/ui/combobox";function ComboboxWithGroupsAndSeparator() { return ( <Example title="With Groups and Separator"> <Combobox<TimezoneOption, TimezoneGroup> options={timezones} optionValue={(opt) => opt} optionTextValue={(opt) => opt} optionGroupChildren="options" placeholder="Select a timezone..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} sectionComponent={(props) => ( <> <Show when={props.section.index !== 0}> <ComboboxSeparator /> </Show> <ComboboxSection> <ComboboxSectionLabel>{props.section.rawValue.label}</ComboboxSectionLabel> </ComboboxSection> </> )} > <ComboboxInput placeholder="Select a timezone..." /> <ComboboxContent> <ComboboxEmpty>No timezones found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxLargeList() { return ( <Example title="Large List (100 items)"> <Combobox options={largeList} optionValue="value" optionTextValue="label" placeholder="Search from 100 items..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue.label}</ComboboxItem> )} > <ComboboxInput placeholder="Search from 100 items..." /> <ComboboxContent> <ComboboxEmpty>No items found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Globe } from "lucide-solid";import { Show } from "solid-js";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxSectionLabel, ComboboxSeparator,} from "~/components/ui/combobox";import { InputGroupAddon } from "~/components/ui/input-group";function ComboboxWithIconAddon() { return ( <Example title="With Icon Addon"> <Combobox<TimezoneOption, TimezoneGroup> options={timezones} optionValue={(opt) => opt} optionTextValue={(opt) => opt} optionGroupChildren="options" placeholder="Select a timezone..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} sectionComponent={(props) => ( <> <Show when={props.section.index !== 0}> <ComboboxSeparator /> </Show> <ComboboxSection> <ComboboxSectionLabel>{props.section.rawValue.label}</ComboboxSectionLabel> </ComboboxSection> </> )} > <ComboboxInput placeholder="Select a timezone..."> <InputGroupAddon> <Globe class="size-4" /> </InputGroupAddon> </ComboboxInput> <ComboboxContent class="w-60"> <ComboboxEmpty>No timezones found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { toast } from "solid-sonner";import { Button } from "~/components/ui/button";import { Card, CardContent, CardFooter } from "~/components/ui/card";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Field, FieldGroup, FieldLabel } from "~/components/ui/field";function ComboboxWithForm() { const handleSubmit = (event: SubmitEvent) => { event.preventDefault(); const formData = new FormData(event.currentTarget as HTMLFormElement); const framework = formData.get("framework") as string; toast(`You selected ${framework} as your framework.`); };
return ( <Example title="Form with Combobox"> <Card class="w-full max-w-sm" size="sm"> <CardContent> <form id="form-with-combobox" class="w-full" onSubmit={handleSubmit}> <FieldGroup> <Field> <FieldLabel for="framework">Framework</FieldLabel> <Combobox options={frameworks} placeholder="Select a framework..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput id="framework" name="framework" placeholder="Select a framework..." /> <ComboboxContent> <ComboboxEmpty>No items found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Field> </FieldGroup> </form> </CardContent> <CardFooter> <Button type="submit" form="form-with-combobox"> Submit </Button> </CardFooter> </Card> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxMultiple() { return ( <Example title="Multiple Selection"> <Combobox<(typeof frameworks)[number]> options={frameworks} placeholder="Select frameworks..." multiple defaultValue={[frameworks[0]]} itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select frameworks..." /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";function ComboboxMultipleDisabled() { return ( <Example title="Multiple Selection Disabled"> <Combobox<(typeof frameworks)[number]> options={frameworks} placeholder="Select frameworks..." multiple disabled defaultValue={[frameworks[0], frameworks[1]]} itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select frameworks..." disabled /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Field, FieldDescription, FieldError, FieldLabel } from "~/components/ui/field";function ComboboxMultipleInvalid() { return ( <Example title="Multiple Selection Invalid"> <div class="flex flex-col gap-4"> <Combobox<(typeof frameworks)[number]> options={frameworks} placeholder="Select frameworks..." multiple validationState="invalid" defaultValue={[frameworks[0], frameworks[1]]} itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput placeholder="Select frameworks..." aria-invalid="true" /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <Field data-invalid> <FieldLabel for="combobox-multiple-invalid">Frameworks</FieldLabel> <Combobox<(typeof frameworks)[number]> options={frameworks} placeholder="Select frameworks..." multiple validationState="invalid" defaultValue={[frameworks[0], frameworks[1], frameworks[2]]} itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput id="combobox-multiple-invalid" placeholder="Select frameworks..." aria-invalid="true" /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <FieldDescription>Please select at least one framework.</FieldDescription> <FieldError errors={[{ message: "This field is required." }]} /> </Field> </div> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Item, ItemContent, ItemDescription, ItemTitle } from "~/components/ui/item";function ComboboxWithCustomItems() { return ( <Example title="With Custom Item Rendering"> <Combobox<(typeof countries)[number]> options={countries} optionValue="value" optionTextValue="label" placeholder="Search countries..." itemComponent={(props) => ( <ComboboxItem item={props.item}> <Item size="xs" class="p-0"> <ItemContent> <ItemTitle class="whitespace-nowrap">{props.item.rawValue.label}</ItemTitle> <ItemDescription> {props.item.rawValue.continent} ({props.item.rawValue.code}) </ItemDescription> </ItemContent> </Item> </ComboboxItem> )} > <ComboboxInput placeholder="Search countries..." /> <ComboboxContent> <ComboboxEmpty>No countries found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Example> );}import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Field, FieldDescription, FieldLabel } from "~/components/ui/field";function ComboboxWithField() { return ( <Example title="With Field"> <Field> <FieldLabel for="combobox-framework">Favorite Framework</FieldLabel> <Combobox options={frameworks} placeholder="Select a framework..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput id="combobox-framework" placeholder="Select a framework..." /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <FieldDescription>Choose your favorite JavaScript framework.</FieldDescription> </Field> </Example> );}import { createSignal } from "solid-js";import { toast } from "solid-sonner";import { Button } from "~/components/ui/button";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger,} from "~/components/ui/dialog";import { Field, FieldLabel } from "~/components/ui/field";function ComboboxInDialog() { const [open, setOpen] = createSignal(false);
return ( <Example title="In Dialog"> <Dialog open={open()} onOpenChange={setOpen}> <DialogTrigger as={Button} variant="outline"> Open Dialog </DialogTrigger> <DialogContent class="sm:max-w-[425px]"> <DialogHeader> <DialogTitle>Select Framework</DialogTitle> <DialogDescription> Choose your preferred framework from the list below. </DialogDescription> </DialogHeader> <Field> <FieldLabel for="framework-dialog" class="sr-only"> Framework </FieldLabel> <Combobox options={frameworks} placeholder="Select a framework..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput id="framework-dialog" placeholder="Select a framework..." /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> </Field> <DialogFooter> <Button type="button" variant="outline" onClick={() => setOpen(false)}> Cancel </Button> <Button type="button" onClick={() => { toast("Framework selected."); setOpen(false); }} > Confirm </Button> </DialogFooter> </DialogContent> </Dialog> </Example> );}import { ChevronDown } from "lucide-solid";import { Button } from "~/components/ui/button";import { Combobox, ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxItem,} from "~/components/ui/combobox";import { Input } from "~/components/ui/input";import { InputGroup, InputGroupAddon, InputGroupInput } from "~/components/ui/input-group";import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue,} from "~/components/ui/select";function ComboboxWithOtherInputs() { return ( <Example title="With Other Inputs"> <Combobox options={frameworks} placeholder="Select a framework..." itemComponent={(props) => ( <ComboboxItem item={props.item}>{props.item.rawValue}</ComboboxItem> )} > <ComboboxInput class="w-52" placeholder="Select a framework..." /> <ComboboxContent> <ComboboxEmpty>No frameworks found.</ComboboxEmpty> </ComboboxContent> </Combobox> <Select<(typeof selectItems)[number]> options={selectItems} optionValue="value" optionTextValue="label" defaultValue={selectItems[0]} itemComponent={(props) => ( <SelectItem item={props.item}>{props.item.rawValue.label}</SelectItem> )} > <SelectTrigger class="w-52"> <SelectValue<(typeof selectItems)[number]>> {(state) => state.selectedOption()?.label} </SelectValue> </SelectTrigger> <SelectContent> <SelectGroup /> </SelectContent> </Select> <Button variant="outline" class="w-52 justify-between font-normal text-muted-foreground"> Select a framework <ChevronDown class="size-4" /> </Button> <Input placeholder="Select a framework" class="w-52" /> <InputGroup class="w-52"> <InputGroupInput placeholder="Select a framework" /> <InputGroupAddon align="inline-end"> <ChevronDown class="size-4" /> </InputGroupAddon> </InputGroup> </Example> );}