1import {2 Combobox,3 ComboboxContent,4 ComboboxControl,5 ComboboxInput,6 ComboboxItem,7 ComboboxItemIndicator,8 ComboboxItemLabel,9 ComboboxSection,10 ComboboxTrigger,11} from "~/components/ui/combobox";12
13interface Food {14 value: string;15 label: string;16 disabled: boolean;17}18interface Category {19 label: string;20 options: Food[];21}22const ALL_OPTIONS: Category[] = [23 {24 label: "Fruits",25 options: [26 { value: "apple", label: "Apple", disabled: false },27 { value: "banana", label: "Banana", disabled: false },28 { value: "blueberry", label: "Blueberry", disabled: false },29 { value: "grapes", label: "Grapes", disabled: true },30 { value: "pineapple", label: "Pineapple", disabled: false },31 ],32 },33 {34 label: "Meat",35 options: [36 { value: "beef", label: "Beef", disabled: false },37 { value: "chicken", label: "Chicken", disabled: false },38 { value: "lamb", label: "Lamb", disabled: false },39 { value: "pork", label: "Pork", disabled: false },40 ],41 },42];43
44export default function ComboboxDemo() {45 return (46 <Combobox<Food, Category>47 options={ALL_OPTIONS}48 optionValue="value"49 optionTextValue="label"50 optionLabel="label"51 optionDisabled="disabled"52 optionGroupChildren="options"53 placeholder="Search a food…"54 itemComponent={(props) => (55 <ComboboxItem item={props.item}>56 <ComboboxItemLabel>{props.item.rawValue.label}</ComboboxItemLabel>57 <ComboboxItemIndicator />58 </ComboboxItem>59 )}60 sectionComponent={(props) => (61 <ComboboxSection>{props.section.rawValue.label}</ComboboxSection>62 )}63 >64 <ComboboxControl aria-label="Food" class="bg-background">65 <ComboboxInput />66 <ComboboxTrigger />67 </ComboboxControl>68 <ComboboxContent />69 </Combobox>70 );71}
npx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/combobox.json
yarn shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/combobox.json
pnpm dlx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/combobox.json
bunx --bun shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/combobox.json
Install the following dependencies
npm install @kobalte/core
yarn add @kobalte/core
pnpm add @kobalte/core
bun add @kobalte/core
Copy and paste the following code into your project
1import type { PolymorphicProps } from "@kobalte/core/polymorphic";2import type { JSX, ValidComponent } from "solid-js";3
4import { Show, splitProps } from "solid-js";5import * as ComboboxPrimitive from "@kobalte/core/combobox";6import CheckIcon from "lucide-solid/icons/check";7import ChevronsUpDownIcon from "lucide-solid/icons/chevrons-up-down";8
9import { cn } from "~/lib/utils";10
11const Combobox = <Option, OptGroup = never, T extends ValidComponent = "div">(12 props: PolymorphicProps<13 T,14 ComboboxPrimitive.ComboboxRootProps<Option, OptGroup, T>15 >,16) => {17 return <ComboboxPrimitive.Root data-slot="combobox" {...props} />;18};19
20const ComboboxItemLabel = <T extends ValidComponent = "div">(21 props: PolymorphicProps<T, ComboboxPrimitive.ComboboxItemLabelProps<T>>,22) => {23 return (24 <ComboboxPrimitive.ItemLabel data-slot="combobox-item-label" {...props} />25 );26};27
28const ComboboxHiddenSelect = (29 props: ComboboxPrimitive.ComboboxHiddenSelectProps,30) => {31 return (32 <ComboboxPrimitive.HiddenSelect33 data-slot="combobox-hidden-select"34 {...props}35 />36 );37};38
39type ComboboxItemProps<T extends ValidComponent = "li"> =40 ComboboxPrimitive.ComboboxItemProps<T> & {41 class?: string | undefined;42 };43
44const ComboboxItem = <T extends ValidComponent = "li">(45 props: PolymorphicProps<T, ComboboxItemProps<T>>,46) => {47 const [local, others] = splitProps(props as ComboboxItemProps, ["class"]);48 return (49 <ComboboxPrimitive.Item50 data-slot="combobox-item"51 class={cn(52 "relative flex cursor-default items-center justify-between rounded-sm px-2 py-1.5 text-sm outline-none select-none ui-disabled:pointer-events-none ui-disabled:opacity-50 ui-highlighted:bg-primary ui-highlighted:text-primary-foreground",53 local.class,54 )}55 {...others}56 />57 );58};59
60type ComboboxItemIndicatorProps<T extends ValidComponent = "div"> =61 ComboboxPrimitive.ComboboxItemIndicatorProps<T> & {62 children?: JSX.Element;63 };64
65const ComboboxItemIndicator = <T extends ValidComponent = "div">(66 props: PolymorphicProps<T, ComboboxItemIndicatorProps<T>>,67) => {68 const [local, others] = splitProps(props as ComboboxItemIndicatorProps, [69 "children",70 ]);71 return (72 <ComboboxPrimitive.ItemIndicator73 data-slot="combobox-item-indicator"74 {...others}75 >76 <Show when={local.children} fallback={<CheckIcon class="size-4" />}>77 {(children) => children()}78 </Show>79 </ComboboxPrimitive.ItemIndicator>80 );81};82
83type ComboboxSectionProps<T extends ValidComponent = "li"> =84 ComboboxPrimitive.ComboboxSectionProps<T> & { class?: string | undefined };85
86const ComboboxSection = <T extends ValidComponent = "li">(87 props: PolymorphicProps<T, ComboboxSectionProps<T>>,88) => {89 const [local, others] = splitProps(props as ComboboxSectionProps, ["class"]);90 return (91 <ComboboxPrimitive.Section92 data-slot="combobox-section"93 class={cn(94 "overflow-hidden p-1 px-2 py-1.5 text-xs font-medium text-muted-foreground",95 local.class,96 )}97 {...others}98 />99 );100};101
102type ComboboxControlProps<103 U,104 T extends ValidComponent = "div",105> = ComboboxPrimitive.ComboboxControlProps<U, T> & {106 class?: string | undefined;107};108
109const ComboboxControl = <T, U extends ValidComponent = "div">(110 props: PolymorphicProps<U, ComboboxControlProps<T>>,111) => {112 const [local, others] = splitProps(props as ComboboxControlProps<T>, [113 "class",114 ]);115 return (116 <ComboboxPrimitive.Control117 data-slot="combobox-control"118 class={cn(119 "flex h-10 items-center rounded-base border-2 border-border px-3",120 local.class,121 )}122 {...others}123 />124 );125};126
127type ComboboxInputProps<T extends ValidComponent = "input"> =128 ComboboxPrimitive.ComboboxInputProps<T> & { class?: string | undefined };129
130const ComboboxInput = <T extends ValidComponent = "input">(131 props: PolymorphicProps<T, ComboboxInputProps<T>>,132) => {133 const [local, others] = splitProps(props as ComboboxInputProps, ["class"]);134 return (135 <ComboboxPrimitive.Input136 data-slot="combobox-input"137 class={cn(138 "flex size-full rounded-base bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",139 local.class,140 )}141 {...others}142 />143 );144};145
146type ComboboxTriggerProps<T extends ValidComponent = "button"> =147 ComboboxPrimitive.ComboboxTriggerProps<T> & {148 class?: string | undefined;149 children?: JSX.Element;150 };151
152const ComboboxTrigger = <T extends ValidComponent = "button">(153 props: PolymorphicProps<T, ComboboxTriggerProps<T>>,154) => {155 const [local, others] = splitProps(props as ComboboxTriggerProps, [156 "class",157 "children",158 ]);159 return (160 <ComboboxPrimitive.Trigger161 data-slot="combobox-trigger"162 class={cn("size-4 opacity-50", local.class)}163 {...others}164 >165 <ComboboxPrimitive.Icon>166 <Show167 when={local.children}168 fallback={<ChevronsUpDownIcon class="size-4" />}169 >170 {(children) => children()}171 </Show>172 </ComboboxPrimitive.Icon>173 </ComboboxPrimitive.Trigger>174 );175};176
177type ComboboxContentProps<T extends ValidComponent = "div"> =178 ComboboxPrimitive.ComboboxContentProps<T> & { class?: string | undefined };179
180const ComboboxContent = <T extends ValidComponent = "div">(181 props: PolymorphicProps<T, ComboboxContentProps<T>>,182) => {183 const [local, others] = splitProps(props as ComboboxContentProps, ["class"]);184 return (185 <ComboboxPrimitive.Portal>186 <ComboboxPrimitive.Content187 data-slot="combobox-content"188 class={cn(189 "relative z-50 min-w-32 overflow-hidden rounded-base border-2 border-border bg-background text-foreground fade-in-80 ui-expanded:animate-in ui-expanded:fade-in-0 ui-expanded:zoom-in-95 ui-closed:animate-out ui-closed:fade-out-0 ui-closed:zoom-out-95",190 local.class,191 )}192 {...others}193 >194 <ComboboxPrimitive.Listbox class="m-0 p-1" />195 </ComboboxPrimitive.Content>196 </ComboboxPrimitive.Portal>197 );198};199
200export {201 Combobox,202 ComboboxItem,203 ComboboxItemLabel,204 ComboboxItemIndicator,205 ComboboxSection,206 ComboboxControl,207 ComboboxTrigger,208 ComboboxInput,209 ComboboxHiddenSelect,210 ComboboxContent,211};
Update the import paths to match your project setup.
1import {2 Combobox,3 ComboboxContent,4 ComboboxControl,5 ComboboxHiddenSelect,6 ComboboxInput,7 ComboboxItem,8 ComboboxItemIndicator,9 ComboboxItemLabel,10 ComboboxSection,11 ComboboxTrigger,12} from "~/components/ui/combobox";
1<Combobox<Food, Category>2 options={ALL_OPTIONS}3 optionValue="value"4 optionTextValue="label"5 optionLabel="label"6 optionDisabled="disabled"7 optionGroupChildren="options"8 placeholder="Search a food…"9 itemComponent={(props) => (10 <ComboboxItem item={props.item}>11 <ComboboxItemLabel>{props.item.rawValue.label}</ComboboxItemLabel>12 <ComboboxItemIndicator />13 </ComboboxItem>14 )}15 sectionComponent={(props) => (16 <ComboboxSection>{props.section.rawValue.label}</ComboboxSection>17 )}18>19 <ComboboxControl aria-label="Food" class="bg-background">20 <ComboboxInput />21 <ComboboxTrigger />22 </ComboboxControl>23 <ComboboxContent />24</Combobox>