# Checkbox Component Usage
## Overview
The checkbox component provides accessible, styled checkboxes for form inputs. It supports multiple states including checked, unchecked, indeterminate, and disabled. Checkboxes can be used standalone or combined with labels and descriptions.
## HTML Structure
### Basic Checkbox
```html
<input type="checkbox" class="input">
```
### Checkbox with Label
```html
<label class="label gap-3">
<input type="checkbox" class="input">
Accept terms and conditions
</label>
```
### Checkbox with Description
```html
<div class="items-top flex gap-3">
<input type="checkbox" id="terms" class="input">
<div class="grid gap-1.5 leading-none">
<label for="terms" class="label">Accept terms and conditions</label>
<p class="text-muted-foreground text-sm">You agree to our Terms of Service and Privacy Policy.</p>
</div>
</div>
```
## States
### Checked State
```html
<input type="checkbox" class="input" checked>
```
### Disabled State
```html
<input type="checkbox" class="input" disabled>
<input type="checkbox" class="input" checked disabled>
```
### Invalid State
```html
<input type="checkbox" class="input" aria-invalid="true">
```
### Indeterminate State (via JavaScript)
```html
<input type="checkbox" class="input" id="parent-checkbox">
<script>
document.getElementById('parent-checkbox').indeterminate = true;
</script>
```
## Implementation Examples
### Checkbox Group
```html
<fieldset class="grid gap-4">
<legend class="label mb-2">Select your interests:</legend>
<label class="label gap-3">
<input type="checkbox" class="input" name="interests" value="technology">
Technology
</label>
<label class="label gap-3">
<input type="checkbox" class="input" name="interests" value="design">
Design
</label>
<label class="label gap-3">
<input type="checkbox" class="input" name="interests" value="business">
Business
</label>
</fieldset>
```
### Terms and Conditions
```html
<form class="form grid gap-4">
<div class="items-top flex gap-3">
<input type="checkbox" id="terms" class="input" required>
<div class="grid gap-1.5 leading-none">
<label for="terms" class="label">
Accept terms and conditions
</label>
<p class="text-muted-foreground text-sm">
You agree to our <a href="#" class="underline underline-offset-4 hover:text-primary">Terms of Service</a> and <a href="#" class="underline underline-offset-4 hover:text-primary">Privacy Policy</a>.
</p>
</div>
</div>
<button type="submit" class="btn">Continue</button>
</form>
```
### Notification Preferences
```html
<form class="form space-y-6">
<h3 class="text-lg font-medium">Notification Preferences</h3>
<div class="space-y-4">
<div class="items-top flex gap-3">
<input type="checkbox" id="email-notifications" class="input" checked>
<div class="grid gap-1.5 leading-none">
<label for="email-notifications" class="label">Email notifications</label>
<p class="text-muted-foreground text-sm">Receive emails about your account activity.</p>
</div>
</div>
<div class="items-top flex gap-3">
<input type="checkbox" id="marketing" class="input">
<div class="grid gap-1.5 leading-none">
<label for="marketing" class="label">Marketing emails</label>
<p class="text-muted-foreground text-sm">Receive emails about new features and updates.</p>
</div>
</div>
<div class="items-top flex gap-3">
<input type="checkbox" id="sms" class="input">
<div class="grid gap-1.5 leading-none">
<label for="sms" class="label">SMS notifications</label>
<p class="text-muted-foreground text-sm">Receive text messages for urgent alerts.</p>
</div>
</div>
</div>
<button type="submit" class="btn">Save Preferences</button>
</form>
```
### Select All Pattern
```html
<div class="space-y-4">
<label class="label gap-3 font-medium">
<input type="checkbox" id="select-all" class="input">
Select All
</label>
<div class="ml-6 space-y-2">
<label class="label gap-3">
<input type="checkbox" class="item-checkbox input">
Item 1
</label>
<label class="label gap-3">
<input type="checkbox" class="item-checkbox input">
Item 2
</label>
<label class="label gap-3">
<input type="checkbox" class="item-checkbox input">
Item 3
</label>
</div>
</div>
<script>
const selectAll = document.getElementById('select-all');
const items = document.querySelectorAll('.item-checkbox');
selectAll.addEventListener('change', function() {
items.forEach(item => item.checked = this.checked);
});
items.forEach(item => {
item.addEventListener('change', function() {
const checkedCount = document.querySelectorAll('.item-checkbox:checked').length;
selectAll.checked = checkedCount === items.length;
selectAll.indeterminate = checkedCount > 0 && checkedCount < items.length;
});
});
</script>
```
## Form Integration
### Using with Form Class
```html
<form class="form grid gap-4">
<label class="label gap-3">
<input type="checkbox" name="subscribe">
Subscribe to newsletter
</label>
<button type="submit" class="btn">Submit</button>
</form>
```
When using the `form` class on a parent element, the checkbox styling is automatically applied without needing the `input` class.
## Accessibility Guidelines
### Required Attributes
- Always use `<label>` elements or `aria-label` for checkbox identification
- Use `aria-describedby` to link to description text
- Use `aria-invalid="true"` for error states
- Group related checkboxes with `<fieldset>` and `<legend>`
### Example with Full Accessibility
```html
<fieldset>
<legend class="label mb-2" id="permissions-label">Permissions</legend>
<div class="space-y-2" role="group" aria-labelledby="permissions-label">
<div class="items-top flex gap-3">
<input
type="checkbox"
id="read"
class="input"
aria-describedby="read-desc"
>
<div class="grid gap-1 leading-none">
<label for="read" class="label">Read</label>
<p id="read-desc" class="text-muted-foreground text-sm">View content and data</p>
</div>
</div>
<div class="items-top flex gap-3">
<input
type="checkbox"
id="write"
class="input"
aria-describedby="write-desc"
>
<div class="grid gap-1 leading-none">
<label for="write" class="label">Write</label>
<p id="write-desc" class="text-muted-foreground text-sm">Create and modify content</p>
</div>
</div>
</div>
</fieldset>
```
## Best Practices
### When to Use Checkboxes
- Multiple selections from a list
- Binary yes/no decisions
- Enabling/disabling features
- Terms acceptance
### Visual Guidelines
- Align checkboxes vertically for easier scanning
- Use descriptions for complex options
- Group related checkboxes together
- Maintain consistent spacing
### Label Guidelines
- Keep labels concise and clear
- Use sentence case
- Place label after the checkbox (for left-to-right languages)
- Ensure adequate click/touch target size
### Error Handling
```html
<div class="items-top flex gap-3">
<input
type="checkbox"
id="terms"
class="input"
aria-invalid="true"
aria-describedby="terms-error"
required
>
<div class="grid gap-1 leading-none">
<label for="terms" class="label">Accept terms</label>
<p id="terms-error" class="text-destructive text-sm">You must accept the terms to continue</p>
</div>
</div>
```
## JavaScript Integration
### Form Validation
```javascript
const form = document.querySelector('form');
const checkbox = document.querySelector('#terms');
form.addEventListener('submit', function(e) {
if (!checkbox.checked) {
e.preventDefault();
checkbox.setAttribute('aria-invalid', 'true');
// Show error message
}
});
```
### Toggle All Items
```javascript
function toggleAll(parentCheckbox, childSelector) {
const children = document.querySelectorAll(childSelector);
children.forEach(child => {
child.checked = parentCheckbox.checked;
});
}
function updateParent(parentId, childSelector) {
const parent = document.getElementById(parentId);
const children = document.querySelectorAll(childSelector);
const checked = document.querySelectorAll(`${childSelector}:checked`);
parent.checked = checked.length === children.length;
parent.indeterminate = checked.length > 0 && checked.length < children.length;
}
```