Checkbox
Accessible Checkbox
component that follows the WAI-ARIA Checkbox Pattern, which means you'll have a working dual or tri-state toggle button regardless of the type of the underlying element. By default, it renders the native <input type="checkbox">
.
#Installation
npm install reakit
Learn more in Get started.
#Usage
It receives the same props as controlled inputs, such as checked
and onChange
:
import React from "react"; import { Checkbox } from "reakit/Checkbox"; function Example() { const [checked, setChecked] = React.useState(false); const toggle = () => setChecked(!checked); return ( <label> <Checkbox checked={checked} onChange={toggle} /> Checkbox </label> ); }
#Rendering as a different element
You can render Checkbox
as any component. Reakit will ensure that it's accessible by adding proper ARIA attributes and event handlers.
When styling, instead of using
:checked
or the[checked]
selector, you will have to use[aria-checked="true"]
to select non-native checked checkboxes.
import React from "react"; import { Checkbox } from "reakit/Checkbox"; import { Button } from "reakit/Button"; function Example() { const [checked, setChecked] = React.useState(false); const toggle = () => setChecked(!checked); return ( <Checkbox as={Button} checked={checked} onChange={toggle}> {checked ? "Uncheck" : "Check"} </Checkbox> ); }
#useCheckboxState
For convenience and consistency with the other components, Reakit provides a useCheckboxState
that already implements the state logic for you:
import { useCheckboxState, Checkbox } from "reakit/Checkbox"; function Example() { const checkbox = useCheckboxState({ state: true }); return ( <label> <Checkbox {...checkbox} /> Checkbox </label> ); }
#Multiple checkboxes
Oftentimes we need to render multiple checkboxes and store the checked values in an array. It can be easily done with Reakit:
import { useCheckboxState, Checkbox } from "reakit/Checkbox"; function Example() { const checkbox = useCheckboxState({ state: [] }); return ( <> <div>Choices: {checkbox.state.join(", ")}</div> <label> <Checkbox {...checkbox} value="apple" /> Apple </label> <label> <Checkbox {...checkbox} value="orange" /> Orange </label> <label> <Checkbox {...checkbox} value="watermelon" /> Watermelon </label> </> ); }
#Indeterminate or mixed state
You can programmatically set checkbox value as indeterminate
:
import React from "react"; import { Checkbox, useCheckboxState } from "reakit/Checkbox"; function useTreeState({ values }) { const group = useCheckboxState(); const items = useCheckboxState(); // updates items when group is toggled React.useEffect(() => { if (group.state === true) { items.setState(values); } else if (group.state === false) { items.setState([]); } }, [group.state]); // updates group when items is toggled React.useEffect(() => { if (items.state.length === values.length) { group.setState(true); } else if (items.state.length) { group.setState("indeterminate"); } else { group.setState(false); } }, [items.state]); return { group, items }; } function Example() { const values = ["Apple", "Orange", "Watermelon"]; const { group, items } = useTreeState({ values }); return ( <ul> <li> <label> <Checkbox {...group} /> Fruits </label> </li> <ul> {values.map((value, i) => ( <li key={i}> <label> <Checkbox {...items} value={value} /> {value} </label> </li> ))} </ul> </ul> ); }
#Styling
Reakit components are un-styled by default. Each component returns a single HTML element that accepts all HTML props, including className
and style
.
The example below uses Emotion. But these styles can be reproduced using static CSS and other CSS-in-JS libraries, such as styled-components.
import * as React from "react"; import { Checkbox } from "reakit/Checkbox"; import { css } from "emotion"; const labelStyle = css` display: flex; align-items: center; `; const checkboxStyle = css` appearance: none; border: 1px solid #a860ff; border-radius: 4px; outline: none; cursor: pointer; width: 20px; height: 20px; display: flex; justify-content: center; align-items: center; margin-right: 5px; &:after { content: "✔"; display: none; color: white; font-size: 70%; } &:checked { background-color: #6a50ee; border: 2px solid #a860ff; &:after { display: block; } } `; function Example() { const [checked, setChecked] = React.useState(false); const toggle = () => setChecked(!checked); return ( <label className={labelStyle}> <Checkbox checked={checked} onChange={toggle} className={checkboxStyle} /> Checkbox </label> ); }
#Accessibility
Checkbox
has rolecheckbox
.- When checked,
Checkbox
hasaria-checked
set totrue
. - When not checked,
Checkbox
hasaria-checked
set tofalse
. - When partially checked,
Checkbox
hasaria-checked
set tomixed
.
Learn more in Accessibility.
#Composition
Checkbox
uses Clickable, and is used by FormCheckbox and MenuItemCheckbox.
Learn more in Composition.
#Props
#useCheckboxState
-
state
boolean | "indeterminate" | (string | number)[]
Stores the state of the checkbox. If checkboxes that share this state have defined a
value
prop, it's going to be an array.
#Checkbox
-
disabled
boolean | undefined
Same as the HTML attribute.
-
focusable
boolean | undefined
When an element is
disabled
, it may still befocusable
. It works similarly toreadOnly
on form elements. In this case, onlyaria-disabled
will be set. -
value
string | number | undefined
Checkbox's value is going to be used when multiple checkboxes share the same state. Checking a checkbox with value will add it to the state array.
-
checked
boolean | undefined
Checkbox's checked state. If present, it's used instead of
state
.
2 state props
These props are returned by the state hook. You can spread them into this component (
{...state}
) or pass them separately. You can also provide these props from your own state logic.
-
state
boolean | "indeterminate" | (string | number)[]
Stores the state of the checkbox. If checkboxes that share this state have defined a
value
prop, it's going to be an array. -
setState
(value: SetStateAction<boolean | "indeterminate...
Sets
state
.