Checkbox
Used in forms when a user needs to select multiple values from several options
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return <Checkbox>Accept terms and conditions</Checkbox>
}
Setup
If you don't already have the snippet, run the following command to add the
checkbox
snippet
npx @chakra-ui/cli snippet add checkbox
The snippet includes a closed component composition for the Checkbox
Usage
import { Checkbox } from "@/components/ui/checkbox"
<Checkbox>Click me</Checkbox>
Examples
Variants
Use the variant
prop to change the visual style of the checkbox.
outline
subtle
solid
import { For, HStack, Stack, Text } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<HStack align="flex-start">
<For each={["outline", "subtle", "solid"]}>
{(variant) => (
<Stack align="flex-start" flex="1" key={variant}>
<Text>{variant}</Text>
<Checkbox defaultChecked variant={variant}>
Checkbox
</Checkbox>
</Stack>
)}
</For>
</HStack>
)
}
Colors
Use the colorPalette
prop to change the color of the checkbox.
gray
red
green
blue
teal
pink
purple
cyan
orange
yellow
import { For, Stack, Text } from "@chakra-ui/react"
import { colorPalettes } from "compositions/lib/color-palettes"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Stack gap="2" align="flex-start">
{colorPalettes.map((colorPalette) => (
<Stack
align="center"
key={colorPalette}
direction="row"
gap="10"
width="full"
>
<Text minW="8ch">{colorPalette}</Text>
<For each={["outline", "subtle", "solid"]}>
{(variant) => (
<Stack key={variant} mb="4">
<Checkbox variant={variant} colorPalette={colorPalette}>
Checkbox
</Checkbox>
<Checkbox
defaultChecked
variant={variant}
colorPalette={colorPalette}
>
Checkbox
</Checkbox>
</Stack>
)}
</For>
</Stack>
))}
</Stack>
)
}
Sizes
Use the size
prop to change the size of the checkbox.
import { For, Stack } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Stack align="flex-start" flex="1" gap="4">
<For each={["sm", "md", "lg"]}>
{(size) => (
<Checkbox defaultChecked size={size} key={size}>
Checkbox
</Checkbox>
)}
</For>
</Stack>
)
}
States
Use the disabled
or invalid
prop to change the visual state of the checkbox.
import { Stack } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Stack>
<Checkbox disabled>Disabled</Checkbox>
<Checkbox defaultChecked disabled>
Disabled
</Checkbox>
<Checkbox readOnly>Readonly</Checkbox>
<Checkbox invalid>Invalid</Checkbox>
</Stack>
)
}
Controlled
Use the checked
and onCheckedChange
props to control the state of the
checkbox.
"use client"
import { Checkbox } from "@/components/ui/checkbox"
import { useState } from "react"
const Demo = () => {
const [checked, setChecked] = useState(false)
return (
<Checkbox
checked={checked}
onCheckedChange={(e) => setChecked(!!e.checked)}
>
Accept terms and conditions
</Checkbox>
)
}
Store
An alternative way to control the checkbox is to use the RootProvider
component and the useCheckbox
store hook.
This way you can access the checkbox state and methods from outside the checkbox.
"use client"
import { Checkbox, useCheckbox } from "@chakra-ui/react"
const Demo = () => {
const checkbox = useCheckbox()
return (
<Checkbox.RootProvider value={checkbox}>
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Accept terms and conditions</Checkbox.Label>
</Checkbox.Root>
</Checkbox.RootProvider>
)
}
Hook Form
Here's an example of how to use the Checkbox
component with the
react-hook-form
library.
"use client"
import { Button, Code, HStack, Stack } from "@chakra-ui/react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Checkbox } from "@/components/ui/checkbox"
import { Field } from "@/components/ui/field"
import { Controller, useController, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
enabled: z.boolean(),
})
type FormData = z.infer<typeof formSchema>
const Demo = () => {
const form = useForm<FormData>({
resolver: zodResolver(formSchema),
defaultValues: { enabled: false },
})
const enabled = useController({
control: form.control,
name: "enabled",
})
const invalid = !!form.formState.errors.enabled
return (
<form onSubmit={form.handleSubmit((data) => console.log(data))}>
<Stack align="flex-start">
<Controller
control={form.control}
name="enabled"
render={({ field }) => (
<Field
disabled={field.disabled}
invalid={invalid}
errorText={form.formState.errors.enabled?.message}
>
<Checkbox
checked={field.value}
onCheckedChange={({ checked }) => field.onChange(checked)}
>
Checkbox
</Checkbox>
</Field>
)}
/>
<HStack>
<Button
size="xs"
variant="outline"
onClick={() => form.setValue("enabled", !enabled.field.value)}
>
Toggle
</Button>
<Button size="xs" variant="outline" onClick={() => form.reset()}>
Reset
</Button>
</HStack>
<Button size="sm" type="submit" alignSelf="flex-start">
Submit
</Button>
<Code>Checked: {JSON.stringify(enabled.field.value, null, 2)}</Code>
</Stack>
</form>
)
}
Group
Use the CheckboxGroup
component to group multiple checkboxes together.
import { CheckboxGroup, Fieldset } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Fieldset.Root>
<CheckboxGroup defaultValue={["react"]} name="framework">
<Fieldset.Legend fontSize="sm" mb="2">
Select framework
</Fieldset.Legend>
<Fieldset.Content>
<Checkbox value="react">React</Checkbox>
<Checkbox value="svelte">Svelte</Checkbox>
<Checkbox value="vue">Vue</Checkbox>
<Checkbox value="angular">Angular</Checkbox>
</Fieldset.Content>
</CheckboxGroup>
</Fieldset.Root>
)
}
Group Hook Form
Here's an example of how to use the CheckboxGroup
component with the
react-hook-form
library.
"use client"
import { Button, CheckboxGroup, Code, Fieldset } from "@chakra-ui/react"
import { zodResolver } from "@hookform/resolvers/zod"
import { Checkbox } from "@/components/ui/checkbox"
import { useController, useForm } from "react-hook-form"
import { z } from "zod"
const formSchema = z.object({
framework: z.array(z.string()).min(1, {
message: "You must select at least one framework.",
}),
})
type FormData = z.infer<typeof formSchema>
const items = [
{ label: "React", value: "react" },
{ label: "Svelte", value: "svelte" },
{ label: "Vue", value: "vue" },
{ label: "Angular", value: "angular" },
]
const Demo = () => {
const {
handleSubmit,
control,
formState: { errors },
} = useForm<FormData>({
resolver: zodResolver(formSchema),
})
const framework = useController({
control,
name: "framework",
defaultValue: [],
})
const invalid = !!errors.framework
return (
<form onSubmit={handleSubmit((data) => console.log(data))}>
<Fieldset.Root invalid={invalid}>
<Fieldset.Legend>Select your framework</Fieldset.Legend>
<CheckboxGroup
invalid={invalid}
value={framework.field.value}
onValueChange={framework.field.onChange}
name={framework.field.name}
>
<Fieldset.Content>
{items.map((item) => (
<Checkbox key={item.value} value={item.value}>
{item.label}
</Checkbox>
))}
</Fieldset.Content>
</CheckboxGroup>
{errors.framework && (
<Fieldset.ErrorText>{errors.framework.message}</Fieldset.ErrorText>
)}
<Button size="sm" type="submit" alignSelf="flex-start">
Submit
</Button>
<Code>Values: {JSON.stringify(framework.field.value, null, 2)}</Code>
</Fieldset.Root>
</form>
)
}
Custom Icon
Use the icon
prop to change the icon of the checkbox.
import { Checkbox } from "@/components/ui/checkbox"
import { HiOutlinePlus } from "react-icons/hi"
const Demo = () => {
return (
<Checkbox defaultChecked icon={<HiOutlinePlus />}>
With Custom Icon
</Checkbox>
)
}
Indeterminate
Set the checked
prop to indeterminate
to show the checkbox in an
indeterminate state.
"use client"
import { Stack } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
import { useState } from "react"
const initialValues = [
{ label: "Monday", checked: false, value: "monday" },
{ label: "Tuesday", checked: false, value: "tuesday" },
{ label: "Wednesday", checked: false, value: "wednesday" },
{ label: "Thursday", checked: false, value: "thursday" },
]
const Demo = () => {
const [values, setValues] = useState(initialValues)
const allChecked = values.every((value) => value.checked)
const indeterminate = values.some((value) => value.checked) && !allChecked
const items = values.map((item, index) => (
<Checkbox
ms="6"
key={item.value}
checked={item.checked}
onCheckedChange={(e) => {
setValues((current) => {
const newValues = [...current]
newValues[index] = { ...newValues[index], checked: !!e.checked }
return newValues
})
}}
>
{item.label}
</Checkbox>
))
return (
<Stack align="flex-start">
<Checkbox
checked={indeterminate ? "indeterminate" : allChecked}
onCheckedChange={(e) => {
setValues((current) =>
current.map((value) => ({ ...value, checked: !!e.checked })),
)
}}
>
Weekdays
</Checkbox>
{items}
</Stack>
)
}
Description
Add content to the children of the Checkbox
component to add a description.
import { Box } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Checkbox gap="4" alignItems="flex-start">
<Box lineHeight="1">I agree to the terms and conditions</Box>
<Box fontWeight="normal" color="fg.muted" mt="1">
By clicking this, you agree to our Terms and Privacy Policy.
</Box>
</Checkbox>
)
}
Link
Render an anchor tag as the checkbox label.
import { Link } from "@chakra-ui/react"
import { Checkbox } from "@/components/ui/checkbox"
const Demo = () => {
return (
<Checkbox>
I agree to the{" "}
<Link colorPalette="teal" href="https://google.com">
terms and conditions
</Link>
</Checkbox>
)
}
Without Snippet
If you don't want to use the snippet, you can use the Checkbox
component from
the @chakra-ui/react
package.
import { Checkbox } from "@chakra-ui/react"
const Demo = () => {
return (
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Accept terms and conditions</Checkbox.Label>
</Checkbox.Root>
)
}
Props
Root
Prop | Default | Type |
---|---|---|
value | '\'on\'' | string The value of checkbox input. Useful for form submission. |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' | 'accent' The color palette of the component |
size | 'md' | 'sm' | 'md' | 'lg' The size of the component |
variant | 'outline' | 'outline' | 'subtle' The variant of the component |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
checked | CheckedState The checked state of the checkbox | |
defaultChecked | CheckedState The checked state of the checkbox when it is first rendered. Use this when you do not need to control the state of the checkbox. | |
disabled | boolean Whether the checkbox is disabled | |
form | string The id of the form that the checkbox belongs to. | |
id | string The unique identifier of the machine. | |
ids | Partial<{
root: string
hiddenInput: string
control: string
label: string
}> The ids of the elements in the checkbox. Useful for composition. | |
invalid | boolean Whether the checkbox is invalid | |
name | string The name of the input field in a checkbox. Useful for form submission. | |
onCheckedChange | (details: CheckedChangeDetails) => void The callback invoked when the checked state changes. | |
readOnly | boolean Whether the checkbox is read-only | |
required | boolean Whether the checkbox is required | |
as | React.ElementType The underlying element to render. | |
unstyled | boolean Whether to remove the component's style. |