Skip to main content

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

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)}
/>

States

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>
  )
}

Props

id
string
The id of the checkbox element. Should match the label’s htmlFor if using a separate label
value
string
required
The value attribute of the checkbox when submitting a form
onChange
React.ChangeEventHandler<HTMLInputElement>
required
Callback fired when the checked state changes
checked
boolean
default:"false"
If true, the checkbox is checked
label
string
Text that appears next to the checkbox
indeterminate
boolean
default:"false"
If true, displays an indeterminate state (dash instead of checkmark)
disabled
boolean
default:"false"
If true, the checkbox is disabled and cannot be interacted with
brand
BrandTypes
Brand theme to apply (avon, natura, theBodyShop, etc.)
className
string
Optional CSS class name for custom styling
testID
string
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>
  )
}
  • Radio - For single selection from a set
  • Switch - For on/off toggles

Build docs developers (and LLMs) love