Search for a command to run...
A styled native HTML select element with consistent design system integration.
npx shadcn@latest add @zaidan/native-selectpnpx shadcn add @zaidan/native-selectyarn dlx shadcn@latest add @zaidan/native-selectbunx shadcn@latest add @zaidan/native-selectCopy and paste the following code into your project.
1import { ChevronDown } from "lucide-solid";2import { type ComponentProps, mergeProps, splitProps } from "solid-js";3import { cn } from "~/lib/utils";4
5type NativeSelectProps = ComponentProps<"select"> & {6 size?: "sm" | "default";7};8
9function NativeSelect(props: NativeSelectProps) {10 const mergedProps = mergeProps({ size: "default" }, props);11 const [local, others] = splitProps(mergedProps, ["class", "size"]);12 return (13 <div14 class={cn(15 "group/native-select relative z-native-select-wrapper w-fit has-[select:disabled]:opacity-50",16 local.class,17 )}18 data-slot="native-select-wrapper"19 data-size={local.size}20 >21 <select22 data-slot="native-select"23 data-size={local.size}24 class="z-native-select outline-none disabled:pointer-events-none disabled:cursor-not-allowed"25 {...others}26 />27 <ChevronDown28 class="pointer-events-none absolute z-native-select-icon select-none"29 data-slot="native-select-icon"30 />31 </div>32 );33}34
35function NativeSelectOption(props: ComponentProps<"option">) {36 return <option data-slot="native-select-option" {...props} />;37}38
39function NativeSelectOptGroup(props: ComponentProps<"optgroup">) {40 const [local, others] = splitProps(props, ["class"]);41 return <optgroup data-slot="native-select-optgroup" class={cn(local.class)} {...others} />;42}43
44export { NativeSelect, NativeSelectOptGroup, NativeSelectOption };Here are the source code of all the examples from the preview page:
import { NativeSelect, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectBasic() { return ( <Example title="Basic"> <NativeSelect> <NativeSelectOption value="">Select a fruit</NativeSelectOption> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> <NativeSelectOption value="grapes" disabled> Grapes </NativeSelectOption> <NativeSelectOption value="pineapple">Pineapple</NativeSelectOption> </NativeSelect> </Example> );}Organize options using NativeSelectOptGroup for better categorization.
import { NativeSelect, NativeSelectOptGroup, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectWithGroups() { return ( <Example title="With Groups"> <NativeSelect> <NativeSelectOption value="">Select a food</NativeSelectOption> <NativeSelectOptGroup label="Fruits"> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> </NativeSelectOptGroup> <NativeSelectOptGroup label="Vegetables"> <NativeSelectOption value="carrot">Carrot</NativeSelectOption> <NativeSelectOption value="broccoli">Broccoli</NativeSelectOption> <NativeSelectOption value="spinach">Spinach</NativeSelectOption> </NativeSelectOptGroup> </NativeSelect> </Example> );}The native select supports different sizes for various use cases.
import { NativeSelect, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectSizes() { return ( <Example title="Sizes"> <div class="flex flex-col gap-4"> <NativeSelect size="sm"> <NativeSelectOption value="">Select a fruit</NativeSelectOption> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> </NativeSelect> <NativeSelect size="default"> <NativeSelectOption value="">Select a fruit</NativeSelectOption> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> </NativeSelect> </div> </Example> );}Use with the Field component for proper form labeling and descriptions.
import { Field, FieldDescription, FieldLabel } from "~/components/ui/field";import { NativeSelect, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectWithField() { return ( <Example title="With Field"> <Field> <FieldLabel for="native-select-country">Country</FieldLabel> <NativeSelect id="native-select-country"> <NativeSelectOption value="">Select a country</NativeSelectOption> <NativeSelectOption value="us">United States</NativeSelectOption> <NativeSelectOption value="uk">United Kingdom</NativeSelectOption> <NativeSelectOption value="ca">Canada</NativeSelectOption> <NativeSelectOption value="au">Australia</NativeSelectOption> </NativeSelect> <FieldDescription>Select your country of residence.</FieldDescription> </Field> </Example> );}Disable individual options or the entire select component.
import { NativeSelect, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectDisabled() { return ( <Example title="Disabled"> <NativeSelect disabled> <NativeSelectOption value="">Disabled</NativeSelectOption> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> </NativeSelect> </Example> );}Show validation errors with the aria-invalid attribute and error styling.
import { NativeSelect, NativeSelectOption,} from "~/components/ui/native-select";function NativeSelectInvalid() { return ( <Example title="Invalid"> <NativeSelect aria-invalid="true"> <NativeSelectOption value="">Error state</NativeSelectOption> <NativeSelectOption value="apple">Apple</NativeSelectOption> <NativeSelectOption value="banana">Banana</NativeSelectOption> <NativeSelectOption value="blueberry">Blueberry</NativeSelectOption> </NativeSelect> </Example> );}NativeSelect when you need native browser behavior, better performance, or mobile-optimized dropdowns.Select when you need custom styling, animations, or complex interactions.The NativeSelect component provides native HTML select functionality with consistent styling that matches your design system.
aria-hidden="true" to avoid duplication.aria-label or aria-labelledby for additional context when needed.1<NativeSelect aria-label="Choose your preferred language">2 <NativeSelectOption value="en">English</NativeSelectOption>3 <NativeSelectOption value="es">Spanish</NativeSelectOption>4 <NativeSelectOption value="fr">French</NativeSelectOption>5</NativeSelect>