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 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 { zodResolver } from "@hookform/resolvers/zod"
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.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 { zodResolver } from "@hookform/resolvers/zod"
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.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.Ref<HTMLLabelElement>
}
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 checkbox
Here's how to use the it
<Checkbox>Accept terms and conditions</Checkbox>
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' 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 |
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. |