1import {2 Select,3 SelectContent,4 SelectDescription,5 SelectItem,6 SelectLabel,7 SelectTrigger,8 SelectValue,9} from "~/components/ui/select";10
11export default function SelectDemo() {12 return (13 <Select14 options={["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"]}15 placeholder="Select a fruit…"16 itemComponent={(props) => (17 <SelectItem item={props.item}>{props.item.rawValue}</SelectItem>18 )}19 >20 <SelectLabel>Fruit</SelectLabel>21 <SelectTrigger aria-label="Fruit" class="w-64">22 <SelectValue<string>>{(state) => state.selectedOption()}</SelectValue>23 </SelectTrigger>24 <SelectContent />25 <SelectDescription>26 Select your favorite fruit from the list.27 </SelectDescription>28 </Select>29 );30}
npx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/select.json
yarn shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/select.json
pnpm dlx shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/select.json
bunx --bun shadcn@latest add https://solid-ui-neobrutalism.vercel.app/r/select.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 { splitProps } from "solid-js";5import * as SelectPrimitive from "@kobalte/core/select";6import { cva } from "class-variance-authority";7import { CheckIcon, ChevronsUpDownIcon } from "lucide-solid";8
9import { cn } from "~/lib/utils";10
11const Select = <Option, OptGroup = never, T extends ValidComponent = "div">(12 props: PolymorphicProps<13 T,14 SelectPrimitive.SelectRootProps<Option, OptGroup, T>15 >,16) => {17 return <SelectPrimitive.Root data-slot="select" {...props} />;18};19
20const SelectValue = <Option, T extends ValidComponent = "span">(21 props: PolymorphicProps<T, SelectPrimitive.SelectValueProps<Option, T>>,22) => {23 return <SelectPrimitive.Value data-slot="select-value" {...props} />;24};25
26const SelectHiddenSelect = (props: SelectPrimitive.SelectHiddenSelectProps) => {27 return (28 <SelectPrimitive.HiddenSelect data-slot="select-hidden-select" {...props} />29 );30};31
32type SelectTriggerProps<T extends ValidComponent = "button"> =33 SelectPrimitive.SelectTriggerProps<T> & {34 class?: string | undefined;35 children?: JSX.Element;36 };37
38const SelectTrigger = <T extends ValidComponent = "button">(39 props: PolymorphicProps<T, SelectTriggerProps<T>>,40) => {41 const [local, others] = splitProps(props as SelectTriggerProps, [42 "class",43 "children",44 ]);45 return (46 <SelectPrimitive.Trigger47 data-slot="select-trigger"48 class={cn(49 "flex h-10 w-full items-center justify-between rounded-base border-2 border-border bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50",50 local.class,51 )}52 {...others}53 >54 {local.children}55 <SelectPrimitive.Icon56 as={ChevronsUpDownIcon}57 class="size-4 opacity-50"58 ></SelectPrimitive.Icon>59 </SelectPrimitive.Trigger>60 );61};62
63type SelectContentProps<T extends ValidComponent = "div"> =64 SelectPrimitive.SelectContentProps<T> & { class?: string | undefined };65
66const SelectContent = <T extends ValidComponent = "div">(67 props: PolymorphicProps<T, SelectContentProps<T>>,68) => {69 const [local, others] = splitProps(props as SelectContentProps, ["class"]);70 return (71 <SelectPrimitive.Portal>72 <SelectPrimitive.Content73 data-slot="select-content"74 class={cn(75 "relative z-50 min-w-32 overflow-hidden rounded-base border-2 bg-background text-foreground 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",76 local.class,77 )}78 {...others}79 >80 <SelectPrimitive.Listbox class="m-0 p-1" />81 </SelectPrimitive.Content>82 </SelectPrimitive.Portal>83 );84};85
86type SelectItemProps<T extends ValidComponent = "li"> =87 SelectPrimitive.SelectItemProps<T> & {88 class?: string | undefined;89 children?: JSX.Element;90 };91
92const SelectItem = <T extends ValidComponent = "li">(93 props: PolymorphicProps<T, SelectItemProps<T>>,94) => {95 const [local, others] = splitProps(props as SelectItemProps, [96 "class",97 "children",98 ]);99 return (100 <SelectPrimitive.Item101 data-slot="select-item"102 class={cn(103 "relative mt-0 flex w-full cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 text-sm transition-colors outline-none select-none focus:bg-primary focus:text-primary-foreground ui-disabled:pointer-events-none ui-disabled:opacity-50",104 local.class,105 )}106 {...others}107 >108 <SelectPrimitive.ItemIndicator class="absolute right-2 flex size-3.5 items-center justify-center">109 <CheckIcon class="size-4" />110 </SelectPrimitive.ItemIndicator>111 <SelectPrimitive.ItemLabel>{local.children}</SelectPrimitive.ItemLabel>112 </SelectPrimitive.Item>113 );114};115
116const labelVariants = cva(117 "text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70",118 {119 variants: {120 variant: {121 label: "ui-invalid:text-destructive",122 description: "font-normal text-muted-foreground",123 error: "text-destructive text-xs",124 },125 },126 defaultVariants: {127 variant: "label",128 },129 },130);131
132type SelectLabelProps<T extends ValidComponent = "label"> =133 SelectPrimitive.SelectLabelProps<T> & {134 class?: string | undefined;135 };136
137const SelectLabel = <T extends ValidComponent = "label">(138 props: PolymorphicProps<T, SelectLabelProps<T>>,139) => {140 const [local, others] = splitProps(props as SelectLabelProps, ["class"]);141 return (142 <SelectPrimitive.Label143 data-slot="select-label"144 class={cn(labelVariants(), local.class)}145 {...others}146 />147 );148};149
150type SelectDescriptionProps<T extends ValidComponent = "div"> =151 SelectPrimitive.SelectDescriptionProps<T> & {152 class?: string | undefined;153 };154
155const SelectDescription = <T extends ValidComponent = "div">(156 props: PolymorphicProps<T, SelectDescriptionProps<T>>,157) => {158 const [local, others] = splitProps(props as SelectDescriptionProps, [159 "class",160 ]);161 return (162 <SelectPrimitive.Description163 data-slot="select-description"164 class={cn(labelVariants({ variant: "description" }), local.class)}165 {...others}166 />167 );168};169
170type SelectErrorMessageProps<T extends ValidComponent = "div"> =171 SelectPrimitive.SelectErrorMessageProps<T> & {172 class?: string | undefined;173 };174
175const SelectErrorMessage = <T extends ValidComponent = "div">(176 props: PolymorphicProps<T, SelectErrorMessageProps<T>>,177) => {178 const [local, others] = splitProps(props as SelectErrorMessageProps, [179 "class",180 ]);181 return (182 <SelectPrimitive.ErrorMessage183 data-slot="select-error-message"184 class={cn(labelVariants({ variant: "error" }), local.class)}185 {...others}186 />187 );188};189
190export {191 Select,192 SelectValue,193 SelectHiddenSelect,194 SelectTrigger,195 SelectContent,196 SelectItem,197 SelectLabel,198 SelectDescription,199 SelectErrorMessage,200};
Update the import paths to match your project setup.
1import {2 Select,3 SelectContent,4 SelectDescription,5 SelectErrorMessage,6 SelectHiddenSelect,7 SelectItem,8 SelectLabel,9 SelectTrigger,10 SelectValue,11} from "~/components/ui/select";
1<Select2 value={value()}3 onChange={setValue}4 options={["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"]}5 placeholder="Select a fruit…"6 itemComponent={(props) => (7 <SelectItem item={props.item}>{props.item.rawValue}</SelectItem>8 )}9>10 <SelectTrigger aria-label="Fruit" class="w-[180px]">11 <SelectValue<string>>{(state) => state.selectedOption()}</SelectValue>12 </SelectTrigger>13 <SelectContent />14</Select>