Skip to main content

Checkbox

The Checkbox component provides a flexible checkbox input with multiple visual variants, sizes, labels, and disabled state. It is accessible and easy to customize via classes.

Overview

  • Variants: basic, rounded, outline, outline-text
  • Sizes: sm, md, lg
  • Label support
  • Controlled and uncontrolled usage
  • Disabled state
  • Accessible and keyboard friendly

Basic Usage

import { Checkbox } from '@/components/atoms'

function MyComponent() {
const [checked, setChecked] = useState(false)

return (
<Checkbox
label='Basic Checkbox'
checked={checked}
onChange={() => setChecked((v) => !v)}
/>
)
}

Props

PropTypeDefaultDescription
checkedboolean-Controlled checked state
defaultCheckedboolean-Uncontrolled initial state
onChangefunction-Change handler (not called when disabled)
labelstring''Optional label text
classNamestring''Additional classes for root label
variantstring'basic'Visual style: basic, rounded, outline, outline-text
sizestring'md'Size: sm, md, lg
disabledbooleanfalseDisable interaction and adjust styles
...propsany-Spread to the underlying input[type="checkbox"]

Variants

Basic

<Checkbox label='Basic Checkbox' />

Rounded

<Checkbox label='Rounded Checkbox' variant='rounded' />

Outline

<Checkbox label='Outline Checkbox' variant='outline' />

Outline with Text Color

<Checkbox label='Outline Text Checkbox' variant='outline-text' />

Sizes

<div className='flex gap-4'>
<Checkbox label='Small' size='sm' />
<Checkbox label='Medium' size='md' />
<Checkbox label='Large' size='lg' />
</div>

Disabled

<Checkbox label='Disabled Checkbox' disabled />

Examples (from CheckboxPage)

Basic Checkbox

<Checkbox
label='Basic Checkbox'
checked={checked.basic}
onChange={() => setChecked((c) => ({ ...c, basic: !c.basic }))}
/>

Rounded Checkbox

<Checkbox
label='Rounded Checkbox'
variant='rounded'
checked={checked.rounded}
onChange={() => setChecked((c) => ({ ...c, rounded: !c.rounded }))}
/>

Outline Checkbox

<Checkbox
label='Outline Checkbox'
variant='outline'
checked={checked.outline}
onChange={() => setChecked((c) => ({ ...c, outline: !c.outline }))}
/>

Outline Text Checkbox

<Checkbox
label='Outline Text Checkbox'
variant='outline-text'
checked={checked.outlineText}
onChange={() => setChecked((c) => ({ ...c, outlineText: !c.outlineText }))}
/>

Checkbox Sizes

<div className='flex gap-4'>
<Checkbox label='Small' size='sm' />
<Checkbox label='Medium' size='md' />
<Checkbox label='Large' size='lg' />
</div>

Checkbox Disabled

<Checkbox label='Disabled Checkbox' checked={false} disabled />

Styling

Root element is a label.checkbox. Important classes:

  • Root: .checkbox (+ composed variants and sizes)
    • Variants: .checkbox-rounded, .checkbox-outline, .checkbox-outline-text
    • Sizes: .checkbox-sm, .checkbox-md, .checkbox-lg
    • Disabled: .disabled
  • Hidden native input: input[type='checkbox']
  • Visual box: .checkbox-custom
    • Checked state styled via input:checked + .checkbox-custom
  • Label text: .checkbox-label

Key style behaviors:

  • Basic: white box with slate border; checked turns blue with checkmark SVG
  • Rounded: .checkbox-rounded makes circular
  • Outline: transparent background with blue border
  • Outline-text: like outline, plus blue label text
  • Disabled: reduced opacity and not-allowed cursor

Accessibility

  • Uses native input[type='checkbox'] for semantics
  • Click target is the label; supports keyboard and screen readers
  • Disabled state prevents interaction and handler calls
  • Ensure descriptive label for clarity

Best Practices

  • Prefer controlled checked + onChange for synced state
  • Use defaultChecked only for simple uncontrolled usage
  • Keep labels concise and descriptive
  • Choose outline-text to hint selection via color where appropriate
  • Test focus/keyboard flows and contrast
  • Switch - Alternative toggle UI
  • Radio - Single-selection inputs
  • Button - Action triggers