Checkbox
Used in forms when a user needs to select multiple values from several options
import { Checkbox } from "@chakra-ui/react"
const Demo = () => {
return (
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Accept terms and conditions</Checkbox.Label>
</Checkbox.Root>
)
}
Usage
import { Checkbox } from "@chakra-ui/react"<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label />
</Checkbox.Root>Shortcuts
The Checkbox component also provides a set of shortcuts for common use cases.
CheckboxControl
This component renders the Checkbox.Indicator within it by default.
This works:
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>This might be more concise, if you don't need to customize the indicator:
<Checkbox.Control />Examples
Variants
Pass the variant prop to the Checkbox.Root component to change the visual
style of the checkbox.
outline
subtle
solid
import { Checkbox, For, HStack, Stack, Text } from "@chakra-ui/react"
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.Root defaultChecked variant={variant}>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
</Stack>
)}
</For>
</HStack>
)
}
Colors
Pass the colorPalette prop to the Checkbox.Root component to change the
color of the checkbox.
gray
red
green
blue
teal
pink
purple
cyan
orange
yellow
import { Checkbox, For, Stack, Text } from "@chakra-ui/react"
import { colorPalettes } from "compositions/lib/color-palettes"
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.Root variant={variant} colorPalette={colorPalette}>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
<Checkbox.Root
defaultChecked
variant={variant}
colorPalette={colorPalette}
>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
</Stack>
)}
</For>
</Stack>
))}
</Stack>
)
}
Sizes
Pass the size prop to the Checkbox.Root component to change the size of the
checkbox.
import { Checkbox, For, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack align="flex-start" flex="1" gap="4">
<For each={["sm", "md", "lg"]}>
{(size) => (
<Checkbox.Root defaultChecked size={size} key={size}>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
)}
</For>
</Stack>
)
}
States
Pass the disabled or invalid prop to the Checkbox.Root component to change
the visual state of the checkbox.
import { Checkbox, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Stack>
<Checkbox.Root disabled>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Disabled</Checkbox.Label>
</Checkbox.Root>
<Checkbox.Root defaultChecked disabled>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Disabled</Checkbox.Label>
</Checkbox.Root>
<Checkbox.Root readOnly>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Readonly</Checkbox.Label>
</Checkbox.Root>
<Checkbox.Root invalid>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Invalid</Checkbox.Label>
</Checkbox.Root>
</Stack>
)
}
Controlled
Use the checked and onCheckedChange props to control the state of the
checkbox.
"use client"
import { Checkbox } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [checked, setChecked] = useState(false)
return (
<Checkbox.Root
checked={checked}
onCheckedChange={(e) => setChecked(!!e.checked)}
>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Accept terms and conditions</Checkbox.Label>
</Checkbox.Root>
)
}
Label Position
Here's an example of how to change the label position to the right.
import { Checkbox } from "@chakra-ui/react"
const Demo = () => {
return (
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Label>Accept terms and conditions</Checkbox.Label>
<Checkbox.Control />
</Checkbox.Root>
)
}
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.Label>Accept terms and conditions</Checkbox.Label>
</Checkbox.Root>
</Checkbox.RootProvider>
)
}
Composition
Here's an example of how to compose a checkbox with a field component.
"use client"
import { Button, Checkbox, Field, Input, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<form
onSubmit={(e) => {
e.preventDefault()
console.log(e.currentTarget.elements)
}}
>
<Stack maxW="sm" gap="4" align="flex-start">
<Field.Root>
<Field.Label>Username</Field.Label>
<Input placeholder="username" />
</Field.Root>
<Field.Root>
<Field.Label>Password</Field.Label>
<Input placeholder="password" />
</Field.Root>
<Checkbox.Root mt="2" value="remember me">
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Remember me</Checkbox.Label>
</Checkbox.Root>
<Button type="submit" variant="solid" mt="3">
Submit
</Button>
</Stack>
</form>
)
}
Hook Form
Here's an example of how to use the Checkbox component with the
react-hook-form library.
"use client"
import { Button, Checkbox, Code, Field, HStack, Stack } from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
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: standardSchemaResolver(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.Root invalid={invalid} disabled={field.disabled}>
<Checkbox.Root
checked={field.value}
onCheckedChange={({ checked }) => field.onChange(checked)}
>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>Checkbox</Checkbox.Label>
</Checkbox.Root>
<Field.ErrorText>
{form.formState.errors.enabled?.message}
</Field.ErrorText>
</Field.Root>
)}
/>
<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 { Checkbox, CheckboxGroup, Fieldset, For } from "@chakra-ui/react"
const Demo = () => {
return (
<Fieldset.Root>
<CheckboxGroup defaultValue={["react"]} name="framework">
<Fieldset.Legend fontSize="sm" mb="2">
Select framework
</Fieldset.Legend>
<Fieldset.Content>
<For each={["React", "Svelte", "Vue", "Angular"]}>
{(value) => (
<Checkbox.Root key={value} value={value}>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>{value}</Checkbox.Label>
</Checkbox.Root>
)}
</For>
</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,
Checkbox,
CheckboxGroup,
Code,
Fieldset,
} from "@chakra-ui/react"
import { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
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: standardSchemaResolver(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.Root key={item.value} value={item.value}>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>{item.label}</Checkbox.Label>
</Checkbox.Root>
))}
</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
Render a custom icon within Checkbox.Control to change the icon of the
checkbox.
import { Checkbox } from "@chakra-ui/react"
import { HiOutlinePlus } from "react-icons/hi"
const Demo = () => {
return (
<Checkbox.Root defaultChecked>
<Checkbox.HiddenInput />
<Checkbox.Control>
<HiOutlinePlus />
</Checkbox.Control>
<Checkbox.Label>With Custom Icon</Checkbox.Label>
</Checkbox.Root>
)
}
Indeterminate
Set the checked prop to indeterminate to show the checkbox in an
indeterminate state.
"use client"
import { Checkbox, Stack } from "@chakra-ui/react"
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.Root
ms="6"
key={item.value}
checked={item.checked}
onCheckedChange={(e) => {
setValues((current) => {
const newValues = [...current]
newValues[index] = { ...newValues[index], checked: !!e.checked }
return newValues
})
}}
>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>{item.label}</Checkbox.Label>
</Checkbox.Root>
))
return (
<Stack align="flex-start">
<Checkbox.Root
checked={indeterminate ? "indeterminate" : allChecked}
onCheckedChange={(e) => {
setValues((current) =>
current.map((value) => ({ ...value, checked: !!e.checked })),
)
}}
>
<Checkbox.HiddenInput />
<Checkbox.Control>
<Checkbox.Indicator />
</Checkbox.Control>
<Checkbox.Label>Weekdays</Checkbox.Label>
</Checkbox.Root>
{items}
</Stack>
)
}
Description
Here's an example of how to add some further description to the checkbox.
import { Box, Checkbox, Stack } from "@chakra-ui/react"
const Demo = () => {
return (
<Checkbox.Root gap="4" alignItems="flex-start">
<Checkbox.HiddenInput />
<Checkbox.Control />
<Stack gap="1">
<Checkbox.Label>I agree to the terms and conditions</Checkbox.Label>
<Box textStyle="sm" color="fg.muted">
By clicking this, you agree to our Terms and Privacy Policy.
</Box>
</Stack>
</Checkbox.Root>
)
}
Link
Render an anchor tag within the Checkbox.Label to add a link to the label.
import { Checkbox, Link } from "@chakra-ui/react"
const Demo = () => {
return (
<Checkbox.Root>
<Checkbox.HiddenInput />
<Checkbox.Control />
<Checkbox.Label>
I agree to the{" "}
<Link colorPalette="teal" href="https://google.com">
terms and conditions
</Link>
</Checkbox.Label>
</Checkbox.Root>
)
}
Closed Component
Here's how to setup the Checkbox for a closed component composition.
import { Checkbox as ChakraCheckbox } from "@chakra-ui/react"
import * as React from "react"
export interface CheckboxProps extends ChakraCheckbox.RootProps {
icon?: React.ReactNode
inputProps?: React.InputHTMLAttributes<HTMLInputElement>
rootRef?: React.RefObject<HTMLLabelElement | null>
}
export const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(
function Checkbox(props, ref) {
const { icon, children, inputProps, rootRef, ...rest } = props
return (
<ChakraCheckbox.Root ref={rootRef} {...rest}>
<ChakraCheckbox.HiddenInput ref={ref} {...inputProps} />
<ChakraCheckbox.Control>
{icon || <ChakraCheckbox.Indicator />}
</ChakraCheckbox.Control>
{children != null && (
<ChakraCheckbox.Label>{children}</ChakraCheckbox.Label>
)}
</ChakraCheckbox.Root>
)
},
)
If you want to automatically add the closed component to your project, run the command:
npx @chakra-ui/cli snippet add checkboxHere's how to use the it
<Checkbox>Accept terms and conditions</Checkbox>Props
Root
| Prop | Default | Type |
|---|---|---|
value | '\'on\'' | stringThe value of checkbox input. Useful for form submission. |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg'The size of the component |
variant | 'solid' | 'outline' | 'solid' | 'subtle'The variant of the component |
as | React.ElementTypeThe underlying element to render. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | booleanWhether to remove the component's style. | |
checked | CheckedStateThe controlled checked state of the checkbox | |
defaultChecked | CheckedStateThe initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox. | |
disabled | booleanWhether the checkbox is disabled | |
form | stringThe id of the form that the checkbox belongs to. | |
id | stringThe 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 | booleanWhether the checkbox is invalid | |
name | stringThe name of the input field in a checkbox. Useful for form submission. | |
onCheckedChange | (details: CheckedChangeDetails) => voidThe callback invoked when the checked state changes. | |
readOnly | booleanWhether the checkbox is read-only | |
required | booleanWhether the checkbox is required |
Explorer
Explore the Checkbox 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
label
control
indicator
group
checkbox.recipe.ts