Skip to content

HyCheckbox

A form-associated tri-state checkbox component that supports unchecked, checked, and indeterminate states. Provides comprehensive form integration via the ElementInternals API, accessibility features, and customizable styling.

Key Behavioral Model

This checkbox implements a clear separation between user interactions and programmatic control:

  • Limited to 2 states: Only toggle between uncheckedchecked

  • Never access indeterminate: Indeterminate state is invisible to users

  • Standard behavior: Follows native HTML checkbox conventions

  • Predictable UX: Users get consistent toggle behavior regardless of settings

  • Full 3-state access: Can set unchecked, checked, or indeterminate

  • Method-controlled: Use setState(), setIndeterminate(), toggle(), etc.

  • Flexible behavior: Respects allowIndeterminate setting for methods like toggle()

  • Event tracking: All changes include reason field ('user' | 'programmatic')

Form Integration

This component implements the Form-Associated Custom Elements API, allowing it to participate in form submission just like native checkboxes. The checkbox's value will be included in FormData when checked and the form is submitted. Indeterminate state is treated as unchecked for form purposes.

Keyboard Navigation

  • Space key: Toggles between uncheckedchecked (standard behavior)
  • Tab: Moves focus to/from the checkbox
  • Enter: No effect (standard checkbox behavior - doesn't change state)
  • Indeterminate access: Only via programmatic methods like setState('indeterminate', 'programmatic')

State Management Philosophy

The component treats indeterminate as a display-only state for users:

  • Users see it visually but can't directly set it
  • User interactions "exit" indeterminate by going to checked first
  • Applications control indeterminate programmatically for complex UI patterns
  • Clear event tracking helps distinguish user intent from application logic

Common Use Cases

Examples

Simple Two-State Preferences

html
<form>
  <hy-checkbox
    name="notifications"
    value="enabled"
    label="Enable notifications"
    allow-indeterminate="false"
  >
  </hy-checkbox>
  <button type="submit">Save</button>
</form>

Form Validation with Required Fields

html
<form>
  <hy-checkbox
    name="terms"
    value="accepted"
    label="I accept the terms"
    required
    variant="error"
    allow-indeterminate="false"
  >
  </hy-checkbox>
  <button type="submit">Submit</button>
</form>

Event Handling


## Events

- **change** - Fired when state changes. Detail: { state: CheckboxState, checked: boolean, indeterminate: boolean, value: string, reason: StateChangeReason }
- **input** - Standard form input event

## Slots

- **top-label** - Content above the checkbox
- **help-text** - Content below the checkbox

## Methods

### willUpdate()

Generates unique IDs before the first render to prevent update-after-update warnings.
IDs are generated client-side only to prevent SSR/client hydration mismatches.

Built with Lit. Documented with VitePress.