Select (Native)
Used to pick a value from predefined options.
import { NativeSelect } from "@chakra-ui/react"
const Demo = () => {
return (
<NativeSelect.Root size="sm" width="240px">
<NativeSelect.Field placeholder="Select option">
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)
}
Usage
import { NativeSelect } from "@chakra-ui/react"
<NativeSelect.Root>
<NativeSelect.Field>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
Examples
Sizes
Use the size
prop to change the size of the select component.
import { For, NativeSelect, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack gap="4" width="240px">
<For each={["xs", "sm", "md", "lg", "xl"]}>
{(size) => (
<NativeSelect.Root key={size} size={size}>
<NativeSelect.Field placeholder="Select option">
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)}
</For>
</Stack>
)
}
Variants
Use the variant
prop to change the appearance of the select component.
import { For, NativeSelect, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack gap="4" width="240px">
<For each={["outline", "subtle", "plain"]}>
{(variant) => (
<NativeSelect.Root key={variant} variant={variant}>
<NativeSelect.Field placeholder={`variant (${variant})`}>
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)}
</For>
</Stack>
)
}
Controlled
Use the value
and onChange
props to control the select component.
"use client"
import { NativeSelect } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [value, setValue] = useState("")
return (
<NativeSelect.Root size="sm" width="240px">
<NativeSelect.Field
placeholder="Select option"
value={value}
onChange={(e) => setValue(e.currentTarget.value)}
>
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)
}
Disabled
Pass the disabled
prop to the NativeSelect.Root
component to disable the
select component.
import { NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithDisabled = () => (
<NativeSelect.Root disabled>
<NativeSelect.Field placeholder="Select option">
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)
Invalid
Compose the native and Field
component to set the invalid set and show the
error text.
import { Field, NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithInvalid = () => (
<Field.Root invalid width="240px">
<NativeSelect.Root>
<NativeSelect.Field placeholder="Select option">
<option value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
<option value="Option 3">Option 3</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
<Field.ErrorText>This is an error</Field.ErrorText>
</Field.Root>
)
Alternatively, you can use the invalid
prop on the NativeSelect.Root
component as well.
import { NativeSelect } from "@chakra-ui/react"
export const NativeSelectWithInvalidRoot = () => (
<NativeSelect.Root invalid width="240px">
<NativeSelect.Field placeholder="Select option">
<option value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
<option value="Option 3">Option 3</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)
Hook Form
Here is an example of how to use the NativeSelect
component with
react-hook-form
.
"use client"
import { Button, Field, NativeSelect } from "@chakra-ui/react"
import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
framework: z.string().min(1, { message: "Framework is required" }),
})
type FormValues = z.infer<typeof formSchema>
const Demo = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<FormValues>({
resolver: zodResolver(formSchema),
})
const onSubmit = handleSubmit((data) => console.log(data))
return (
<form onSubmit={onSubmit}>
<Field.Root invalid={!!errors.framework}>
<Field.Label>Framework</Field.Label>
<NativeSelect.Root size="sm" width="240px">
<NativeSelect.Field
placeholder="Select option"
{...register("framework")}
>
<option value="react">React</option>
<option value="vue">Vue</option>
<option value="angular">Angular</option>
<option value="svelte">Svelte</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
<Field.ErrorText>{errors.framework?.message}</Field.ErrorText>
</Field.Root>
<Button size="sm" type="submit" mt="4">
Submit
</Button>
</form>
)
}
Ref
Here's how to access the underlying element reference
import { NativeSelect } from "@chakra-ui/react"
const Demo = () => {
const ref = useRef<HTMLSelectElement | null>(null)
return (
<NativeSelect.Root>
<NativeSelect.Field ref={ref}>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
)
}
Closed Component
Here's how to setup the Native Select for a closed component composition.
"use client"
import { NativeSelect as Select } from "@chakra-ui/react"
import * as React from "react"
type FieldProp = "name" | "value" | "onChange" | "defaultValue"
interface NativeSelectProps
extends Omit<Select.RootProps, FieldProp>,
Pick<Select.FieldProps, FieldProp> {
icon?: React.ReactNode
items: Array<{ label: string; value: string; disabled?: boolean }>
}
export const NativeSelect = React.forwardRef<
HTMLSelectElement,
NativeSelectProps
>(function NativeSelect(props, ref) {
const {
icon,
children,
name,
items,
value,
defaultValue,
onChange,
...rest
} = props
return (
<Select.Root {...rest}>
<Select.Field
ref={ref}
name={name}
value={value}
defaultValue={defaultValue}
onChange={onChange}
>
{children}
{items?.map((item) => (
<option key={item.value} value={item.value} disabled={item.disabled}>
{item.label}
</option>
))}
</Select.Field>
<Select.Indicator>{icon}</Select.Indicator>
</Select.Root>
)
})
If you want to automatically add the closed component to your project, run the command:
npx @chakra-ui/cli snippet add native-select
Props
Root
Prop | Default | Type |
---|---|---|
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' The color palette of the component |
variant | 'outline' | 'outline' | 'subtle' | 'plain' The variant of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' The size of the component |
disabled | boolean | undefined | |
invalid | boolean | undefined | |
as | React.ElementType The underlying element to render. | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | boolean Whether to remove the component's style. |
Explorer
Explore the Select (Native)
component parts interactively. Click on parts in
the sidebar to highlight them in the preview.
Component Anatomy
Hover to highlight, click to select parts
root
field
indicator
native-select.recipe.ts