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
:checkedor 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
Checkboxhas rolecheckbox.- When checked,
Checkboxhasaria-checkedset totrue. - When not checked,
Checkboxhasaria-checkedset tofalse. - When partially checked,
Checkboxhasaria-checkedset tomixed.
Learn more in Accessibility.
#Composition
Checkboxuses Clickable, and is used by FormCheckbox and MenuItemCheckbox.
Learn more in Composition.
#Props
#useCheckboxState
-
stateboolean | "indeterminate" | (string | number)[]Stores the state of the checkbox. If checkboxes that share this state have defined a
valueprop, it's going to be an array.
#Checkbox
-
disabledboolean | undefinedSame as the HTML attribute.
-
focusableboolean | undefinedWhen an element is
disabled, it may still befocusable. It works similarly toreadOnlyon form elements. In this case, onlyaria-disabledwill be set. -
valuestring | number | undefinedCheckbox'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.
-
checkedboolean | undefinedCheckbox'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.
-
stateboolean | "indeterminate" | (string | number)[]Stores the state of the checkbox. If checkboxes that share this state have defined a
valueprop, it's going to be an array. -
setState(value: SetStateAction<boolean | "indeterminate...Sets
state.