Overview
The Checkbox component enables users to make binary or multiple selections from a list of options. It provides clear visual feedback and supports indeterminate states for hierarchical selections.
import { Checkbox } from '@naturacosmeticos/natds-react'
Basic Usage
import React, { useState } from 'react'
import { Checkbox } from '@naturacosmeticos/natds-react'
function App() {
const [checked, setChecked] = useState(false)
return (
<Checkbox
id="accept-terms"
label="I accept the terms and conditions"
value="terms"
checked={checked}
onChange={() => setChecked(!checked)}
/>
)
}
With Label
<Checkbox
id="newsletter"
label="Subscribe to newsletter"
value="subscribe"
checked={subscribed}
onChange={(e) => setSubscribed(e.target.checked)}
/>
Checked and Unchecked
<Checkbox
id="option1"
label="Unchecked"
value="option1"
checked={false}
onChange={handleChange}
/>
<Checkbox
id="option2"
label="Checked"
value="option2"
checked={true}
onChange={handleChange}
/>
Indeterminate
Use the indeterminate state to represent a partial selection:
<Checkbox
id="select-all"
label="Select All"
value="all"
checked={allSelected}
indeterminate={someSelected}
onChange={handleSelectAll}
/>
Disabled
<Checkbox
id="disabled-unchecked"
label="Disabled Unchecked"
value="disabled1"
checked={false}
disabled
onChange={() => {}}
/>
<Checkbox
id="disabled-checked"
label="Disabled Checked"
value="disabled2"
checked={true}
disabled
onChange={() => {}}
/>
<Checkbox
id="disabled-indeterminate"
label="Disabled Indeterminate"
value="disabled3"
checked={true}
indeterminate
disabled
onChange={() => {}}
/>
Multiple Selection
import React, { useState } from 'react'
import { Checkbox } from '@naturacosmeticos/natds-react'
function MultiSelect() {
const [selections, setSelections] = useState({
option1: false,
option2: false,
option3: false
})
const handleChange = (key: string) => {
setSelections(prev => ({
...prev,
[key]: !prev[key]
}))
}
return (
<div>
<Checkbox
id="opt1"
label="Option 1"
value="option1"
checked={selections.option1}
onChange={() => handleChange('option1')}
/>
<Checkbox
id="opt2"
label="Option 2"
value="option2"
checked={selections.option2}
onChange={() => handleChange('option2')}
/>
<Checkbox
id="opt3"
label="Option 3"
value="option3"
checked={selections.option3}
onChange={() => handleChange('option3')}
/>
</div>
)
}
Select All Pattern
import React, { useState } from 'react'
import { Checkbox } from '@naturacosmeticos/natds-react'
function SelectAllExample() {
const [items, setItems] = useState([
{ id: 'item1', label: 'Item 1', checked: false },
{ id: 'item2', label: 'Item 2', checked: false },
{ id: 'item3', label: 'Item 3', checked: false }
])
const allChecked = items.every(item => item.checked)
const someChecked = items.some(item => item.checked) && !allChecked
const handleSelectAll = () => {
setItems(items.map(item => ({ ...item, checked: !allChecked })))
}
const handleItemChange = (id: string) => {
setItems(items.map(item =>
item.id === id ? { ...item, checked: !item.checked } : item
))
}
return (
<div>
<Checkbox
id="select-all"
label="Select All"
value="all"
checked={allChecked}
indeterminate={someChecked}
onChange={handleSelectAll}
/>
<div style={{ marginLeft: '24px' }}>
{items.map(item => (
<Checkbox
key={item.id}
id={item.id}
label={item.label}
value={item.id}
checked={item.checked}
onChange={() => handleItemChange(item.id)}
/>
))}
</div>
</div>
)
}
The id of the checkbox element. Should match the label’s htmlFor if using a separate label
The value attribute of the checkbox when submitting a form
onChange
React.ChangeEventHandler<HTMLInputElement>
required
Callback fired when the checked state changes
If true, the checkbox is checked
Text that appears next to the checkbox
If true, displays an indeterminate state (dash instead of checkmark)
If true, the checkbox is disabled and cannot be interacted with
Brand theme to apply (avon, natura, theBodyShop, etc.)
Optional CSS class name for custom styling
Optional ID for testing purposes. Defaults to ds-checkbox-{id}
Accessibility
Built-in Features
The Checkbox component includes built-in accessibility features:
- Keyboard navigation (Space to toggle)
- Focus indicators
- Proper ARIA attributes
- Label association
- Ripple effect for visual feedback
Best Practices
// Good: Clear label describing what the checkbox does
<Checkbox
id="marketing-emails"
label="Send me marketing emails"
value="marketing"
checked={acceptsMarketing}
onChange={(e) => setAcceptsMarketing(e.target.checked)}
/>
// Good: Use indeterminate for partial selections
<Checkbox
id="select-all"
label="Select all items"
value="all"
checked={allSelected}
indeterminate={someSelected}
onChange={handleSelectAll}
/>
// Good: Disable when not applicable
<Checkbox
id="premium-feature"
label="Enable premium features"
value="premium"
checked={false}
disabled={!isPremiumUser}
onChange={handleToggle}
/>
Guidelines
- Always provide a clear, descriptive label
- Use
id to associate checkbox with its label
- Group related checkboxes logically
- Provide adequate spacing between checkboxes
- Use indeterminate state for parent checkboxes in hierarchies
- Ensure sufficient contrast in all states
- Make touch targets at least 44x44px
Form Integration
import React, { useState } from 'react'
import { Checkbox } from '@naturacosmeticos/natds-react'
interface FormData {
newsletter: boolean
terms: boolean
privacy: boolean
}
function RegistrationForm() {
const [formData, setFormData] = useState<FormData>({
newsletter: false,
terms: false,
privacy: false
})
const handleChange = (field: keyof FormData) => {
setFormData(prev => ({
...prev,
[field]: !prev[field]
}))
}
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
if (!formData.terms || !formData.privacy) {
alert('Please accept the required terms')
return
}
console.log('Form submitted:', formData)
}
return (
<form onSubmit={handleSubmit}>
<Checkbox
id="newsletter"
label="Subscribe to newsletter (optional)"
value="newsletter"
checked={formData.newsletter}
onChange={() => handleChange('newsletter')}
/>
<Checkbox
id="terms"
label="I accept the Terms of Service *"
value="terms"
checked={formData.terms}
onChange={() => handleChange('terms')}
/>
<Checkbox
id="privacy"
label="I accept the Privacy Policy *"
value="privacy"
checked={formData.privacy}
onChange={() => handleChange('privacy')}
/>
<button type="submit">Register</button>
</form>
)
}
TypeScript
import { CheckboxProps } from '@naturacosmeticos/natds-react'
interface CheckboxItem {
id: string
label: string
value: string
checked: boolean
}
interface CheckboxGroupProps {
items: CheckboxItem[]
onChange: (id: string) => void
disabled?: boolean
}
const CheckboxGroup: React.FC<CheckboxGroupProps> = ({ items, onChange, disabled }) => {
return (
<div>
{items.map(item => (
<Checkbox
key={item.id}
id={item.id}
label={item.label}
value={item.value}
checked={item.checked}
disabled={disabled}
onChange={() => onChange(item.id)}
/>
))}
</div>
)
}
Related Components
- Radio - For single selection from a set
- Switch - For on/off toggles