Overview
The Checkbox component provides an accessible checkbox with support for three states (unchecked, checked, indeterminate), multiple sizes, and optional descriptions. Built on React Aria Components for full keyboard navigation and screen reader support.
Import
import { Checkbox } from 'stride-ds';
Basic Usage
import { Checkbox } from 'stride-ds';
function Example() {
return <Checkbox>Accept terms and conditions</Checkbox>;
}
Sizes
Three size options are available:
<Checkbox size="sm">Small checkbox</Checkbox>
<Checkbox size="md">Medium checkbox</Checkbox>
<Checkbox size="lg">Large checkbox</Checkbox>
With Description
Add supporting text below the main label:
<Checkbox
description="Get notified when someone mentions you in a comment or assigns you a task."
>
Enable notifications
</Checkbox>
States
Checked
<Checkbox isSelected>Checked</Checkbox>
Indeterminate
Useful for “select all” functionality:
<Checkbox isIndeterminate>Indeterminate</Checkbox>
Disabled
<Checkbox isDisabled>Disabled</Checkbox>
<Checkbox isSelected isDisabled>Disabled & Checked</Checkbox>
Props
size
'sm' | 'md' | 'lg'
default:"'md'"
Size of the checkbox.
The label text for the checkbox.
Additional description text displayed below the label.
Whether the checkbox is checked (controlled).
Whether the checkbox is initially checked (uncontrolled).
Whether the checkbox is in an indeterminate state.
Whether the checkbox is disabled.
onChange
(isSelected: boolean) => void
Handler called when the checkbox state changes.
Additional CSS classes to apply.
The value of the checkbox in a form.
The name of the checkbox in a form.
Accessibility
The Checkbox component is built with React Aria Components and provides:
- Keyboard Navigation: Space to toggle, Tab to move focus
- Focus Management: Clear focus indicators
- Screen Reader Support: Proper ARIA attributes including
aria-checked and support for indeterminate state
- Label Association: Automatic association between checkbox and label
Best Practices
-
Always provide a label via
children or use aria-label for accessibility:
<Checkbox>Enable feature</Checkbox>
// or
<Checkbox aria-label="Enable feature" />
-
Use
description for additional context:
<Checkbox description="This will enable advanced features">
Enable advanced mode
</Checkbox>
-
Use indeterminate state for nested selections:
<Checkbox isIndeterminate>Some items selected</Checkbox>
Examples
All States
<div className="flex flex-col space-y-4">
<Checkbox>Unchecked</Checkbox>
<Checkbox isSelected>Checked</Checkbox>
<Checkbox isIndeterminate>Indeterminate</Checkbox>
<Checkbox isDisabled>Disabled</Checkbox>
<Checkbox isSelected isDisabled>Disabled & Checked</Checkbox>
</div>
Indeterminate with “Select All”
import { useState } from 'react';
import { Checkbox } from 'stride-ds';
function SelectAllExample() {
const [child1, setChild1] = useState(false);
const [child2, setChild2] = useState(true);
const [child3, setChild3] = useState(false);
const childrenStates = [child1, child2, child3];
const allChecked = childrenStates.every(Boolean);
const someChecked = childrenStates.some(Boolean);
const isIndeterminate = someChecked && !allChecked;
const handleParentChange = (checked: boolean) => {
setChild1(checked);
setChild2(checked);
setChild3(checked);
};
return (
<div className="flex flex-col space-y-3">
<Checkbox
isSelected={allChecked}
isIndeterminate={isIndeterminate}
onChange={handleParentChange}
>
Select all
</Checkbox>
<div className="ml-6 flex flex-col space-y-2">
<Checkbox isSelected={child1} onChange={setChild1}>
Option 1
</Checkbox>
<Checkbox isSelected={child2} onChange={setChild2}>
Option 2
</Checkbox>
<Checkbox isSelected={child3} onChange={setChild3}>
Option 3
</Checkbox>
</div>
</div>
);
}
import { useState } from 'react';
import { Checkbox } from 'stride-ds';
function NewsletterForm() {
const [preferences, setPreferences] = useState({
newsletter: false,
updates: false,
marketing: false,
});
return (
<div className="space-y-4">
<h3 className="font-semibold">Email Preferences</h3>
<Checkbox
isSelected={preferences.newsletter}
onChange={(checked) =>
setPreferences({ ...preferences, newsletter: checked })
}
description="Receive our weekly newsletter with the latest updates"
>
Newsletter
</Checkbox>
<Checkbox
isSelected={preferences.updates}
onChange={(checked) =>
setPreferences({ ...preferences, updates: checked })
}
description="Get notified about product updates and new features"
>
Product Updates
</Checkbox>
<Checkbox
isSelected={preferences.marketing}
onChange={(checked) =>
setPreferences({ ...preferences, marketing: checked })
}
description="Receive promotional offers and marketing emails"
>
Marketing Emails
</Checkbox>
</div>
);
}
All Sizes Comparison
<div className="flex flex-col space-y-4">
<Checkbox size="sm">Small checkbox with text</Checkbox>
<Checkbox size="md">Medium checkbox with text</Checkbox>
<Checkbox size="lg">Large checkbox with text</Checkbox>
</div>
With Long Content
<Checkbox
description="By checking this box, you acknowledge that you have read and agree to our Terms of Service and Privacy Policy. This includes how we collect, use, and share your data."
>
I agree to the Terms of Service and Privacy Policy
</Checkbox>
The Checkbox component works with React Hook Form:
import { useForm, Controller } from 'react-hook-form';
import { Checkbox } from 'stride-ds';
function FormExample() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="terms"
control={control}
rules={{ required: 'You must accept the terms' }}
render={({ field }) => (
<Checkbox
isSelected={field.value}
onChange={field.onChange}
>
I accept the terms and conditions
</Checkbox>
)}
/>
</form>
);
}