Skip to main content

Checkbox

A checkbox component for binary choices with support for validation, helper text, and group management

Checkbox

The Checkbox component provides an accessible way to present binary choices to users. It supports validation states, helper text, and can be grouped together for multiple selections. The component uses typography tokens for consistent text rendering and includes comprehensive keyboard support.

Basic Checkbox

Click to toggle checkbox state

You can unsubscribe at any time

Current State:

Single: Unchecked
Notifications: Enabled

API Reference

Props

PropTypeDefaultDescription
idstringrequiredUnique identifier for the checkbox
namestringidForm field name
labelstringrequiredCheckbox label text
checkedbooleanfalseChecked state (bindable)
valuestring''Value when submitted in a form
requiredbooleanfalseWhether field is required
disabledbooleanfalseDisables the checkbox
errorstring \| nullnullError message to display
helperstring-Helper text below checkbox

Usage Examples

Basic Checkbox

<script>
  import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
  
  let acceptTerms = $state(false);
</script>

<Checkbox
  id="terms"
  label="I accept the terms and conditions"
  bind:checked={acceptTerms}
/>

With Helper Text

<script>
  import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
  
  let subscribe = $state(false);
</script>

<Checkbox
  id="newsletter"
  label="Subscribe to newsletter"
  bind:checked={subscribe}
  helper="You can unsubscribe at any time"
/>

Checkbox Group

<script>
  import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
  
  let preferences = $state({
    email: true,
    sms: false,
    push: false
  });
</script>

<fieldset>
  <legend>Notification Preferences</legend>
  
  <Checkbox
    id="pref-email"
    label="Email notifications"
    bind:checked={preferences.email}
  />
  
  <Checkbox
    id="pref-sms"
    label="SMS notifications"
    bind:checked={preferences.sms}
  />
  
  <Checkbox
    id="pref-push"
    label="Push notifications"
    bind:checked={preferences.push}
  />
</fieldset>

With Validation

<script>
  import Checkbox from '$lib/shared/components/forms/Checkbox.svelte';
  
  let agreed = $state(false);
  let error = $state(null);
  
  function validate() {
    if (!agreed) {
      error = 'You must agree to continue';
    } else {
      error = null;
    }
  }
</script>

<Checkbox
  id="agreement"
  label="I agree to the privacy policy"
  bind:checked={agreed}
  error={error}
  required
  onchange={validate}
/>

Typography System

The Checkbox component uses design system typography tokens:

Applied Tokens

/* Label Text */
--typography-body-size
--typography-body-color
--typography-body-weight

/* Helper Text */
--typography-caption-size
--typography-muted-color
--typography-caption-weight

/* Error Text */
--typography-caption-size
--error (semantic color)
--typography-caption-weight

Styling

Visual Design

The checkbox uses a custom appearance with:

  • Size: 1.25rem (20px) square
  • Border: 2px solid with theme-aware colors
  • Check mark: SVG icon or CSS pseudo-element
  • Border radius: Small radius for subtle rounding

States

  • Unchecked: Empty box with border
  • Checked: Filled with primary color and check mark
  • Disabled: Reduced opacity and cursor change
  • Error: Red border color with error message
  • Focus: Focus ring for keyboard navigation

CSS Classes

  • .field-checkbox - Base checkbox styles
  • .field-choice-label - Label container
  • .field-error - Error state modifier
  • .field-error-message - Error message styling
  • .field-hint - Helper text styling

Accessibility

The Checkbox component includes comprehensive accessibility features:

ARIA Support

  • aria-required - Indicates required fields
  • aria-invalid - Communicates error states
  • aria-describedby - Links helper and error text
  • role="alert" - Error messages announced to screen readers

Keyboard Interaction

  • Space - Toggle checkbox state
  • Tab - Navigate between checkboxes
  • Shift+Tab - Navigate backwards

Label Association

  • Clicking the label toggles the checkbox
  • Proper for/id linking
  • Labels wrap the input for larger click target

Patterns

Multiple Selection

Use checkboxes when users can select multiple options:

<div class="checkbox-group">
  <h3>Select features:</h3>
  <Checkbox id="feat1" label="Feature A" />
  <Checkbox id="feat2" label="Feature B" />
  <Checkbox id="feat3" label="Feature C" />
</div>

Required Fields

For required checkboxes (like terms acceptance):

<Checkbox
  id="terms"
  label="I accept the terms and conditions"
  required
  error={!accepted ? "Required" : null}
/>

Indeterminate State

For parent checkboxes controlling groups:

<script>
  let allSelected = $state(false);
  let items = $state([false, false, false]);
  
  $effect(() => {
    const selected = items.filter(Boolean).length;
    // Handle indeterminate state logic
  });
</script>

Best Practices

  1. Clear labels - Use descriptive, action-oriented labels
  2. Group related options - Use fieldsets for logical grouping
  3. Default to unchecked - Unless there’s a strong reason otherwise
  4. Validate on submit - Don’t show errors before interaction
  5. Provide context - Use helper text for complex options
  6. Size click targets - Ensure adequate touch/click area

Common Use Cases

  • Terms acceptance - Legal agreements and policies
  • Preferences - User settings and notifications
  • Feature selection - Multiple choice options
  • Filters - Search and listing refinements
  • Bulk actions - Select multiple items for operations