# WCheckbox

A utility-first checkbox component that translates Tailwind-style classes into a fully customizable checkbox widget. It sidesteps the limitations of native Flutter checkboxes by using a composable architecture of `WAnchor` and `WDiv`.

- [Basic Usage](#basic-usage)
- [Constructor](#constructor)
- [Props](#props)
- [Layout Modes](#layout-modes)
- [Event Handling](#event-handling)
- [Accessibility](#accessibility)
- [State Variants](#state-variants)
- [Styling Examples](#styling-examples)
- [All Supported Classes](#all-supported-classes)
- [Customizing Theme](#customizing-theme)
- [Related Documentation](#related-documentation)

```dart
WCheckbox(
  value: isChecked,
  onChanged: (val) => setState(() => isChecked = val),
  className: 'w-6 h-6 rounded-md border-gray-400 checked:bg-indigo-600',
)
```

## Basic Usage

The `WCheckbox` widget provides a highly flexible alternative to native Flutter checkboxes. It supports all Wind utility classes, allowing for complex styling like custom borders, focus rings, and state-based colors using the `checked:` prefix.

```dart
WCheckbox(
  value: _value,
  onChanged: (val) => setState(() => _value = val),
  className: 'w-5 h-5 rounded border-2 border-slate-300 checked:bg-blue-500 checked:border-transparent',
)
```

## Constructor

```dart
const WCheckbox({
  Key? key,
  required bool value,
  ValueChanged<bool>? onChanged,
  String? className,
  String? iconClassName,
  bool disabled = false,
  IconData? checkIcon,
  Set<String>? states,
})
```

## Props

| Prop | Type | Default | Description |
|:-----|:-----|:--------|:------------|
| `value` | `bool` | - | Whether the checkbox is currently checked. |
| `onChanged` | `ValueChanged<bool>?` | `null` | Callback triggered when the checkbox state is toggled. `null` makes the checkbox display-only, exactly like `disabled: true`. See [Accessibility](#accessibility). |
| `className` | `String?` | `null` | Wind utility classes for the checkbox container (dimensions, border, background). |
| `iconClassName` | `String?` | `null` | Utility classes applied to the check icon (e.g., `'text-white text-xs'`). |
| `disabled` | `bool` | `false` | When true, prevents interaction and applies the `disabled:` prefix styles. |
| `checkIcon` | `IconData?` | `null` | Custom icon shown when `value` is true. When `null`, the widget renders `Icons.check`. |
| `states` | `Set<String>?` | `null` | Custom state identifiers merged with built-in `checked` and `disabled` states. |

## Layout Modes

### Dimensions
Unlike some widgets that grow to fit their content, a checkbox requires explicit width (`w-{n}`) and height (`h-{n}`) classes to define its clickable area and visual size.

```dart
WCheckbox(
  value: true,
  className: 'w-4 h-4 rounded-sm', // Small checkbox
)

WCheckbox(
  value: true,
  className: 'w-8 h-8 rounded-full', // Large circular checkbox
)
```

## Event Handling

The `onChanged` callback is triggered when the user taps the checkbox. It provides the toggled boolean value.

```dart
WCheckbox(
  value: isChecked,
  onChanged: (bool newValue) {
    setState(() {
      isChecked = newValue;
    });
  },
)
```

Leaving `onChanged` null is how you render a display-only checkbox, such as a read-only summary row or a tile whose own tap drives the toggle.

## Accessibility

`WCheckbox` publishes one semantics node carrying the `checked` state, so `getByRole('checkbox')` resolves and a screen reader announces whether the box is ticked. The widget renders its check glyph as the only child, so it has no name of its own, and a `WText` sitting beside it in a row is a visible label rather than a semantic one: the two stay separate nodes. Wrap the pair in `MergeSemantics` to publish a single node carrying both the text and the checked state.

```dart
// One node, named "Accept terms", reporting checked.
MergeSemantics(
  child: WDiv(
    className: 'flex flex-row items-center gap-3',
    children: [
      WCheckbox(
        value: accepted,
        onChanged: (val) => setState(() => accepted = val),
        className: 'w-5 h-5 rounded border',
      ),
      const WText(
        'Accept terms',
        className: 'text-slate-900 dark:text-white',
      ),
    ],
  ),
)
```

A null `onChanged` is read exactly like `disabled: true`. There is no callback to run, so the checkbox attaches no gesture, publishes no tap action, reports itself as not enabled, and activates the `disabled:` prefix. That last part is visible: a display-only checkbox styled `disabled:opacity-50` renders dimmed.

```dart
// Interactive: tappable, announced as enabled.
WCheckbox(
  value: isChecked,
  onChanged: (val) => setState(() => isChecked = val),
  className: 'w-5 h-5 rounded border',
)

// Display-only: no tap action, announced as unavailable, disabled: styles apply.
const WCheckbox(
  value: true,
  className: 'w-5 h-5 rounded border disabled:opacity-50',
)
```

[WRadio](https://anilcancakir.com/wind_kit/docs/v1.6/widgets/w-radio.md) and [WSwitch](https://anilcancakir.com/wind_kit/docs/v1.6/widgets/w-switch.md) read a null callback the same way, so the three controls behave alike.

## State Variants

`WCheckbox` uses the `checked:` prefix to apply styles when the value is true. It also supports standard interaction prefixes like `hover:`, `focus:`, and `disabled:`.

```dart
WCheckbox(
  value: isChecked,
  className: 'border-gray-300 checked:bg-blue-600 checked:border-transparent hover:border-blue-400 disabled:opacity-50',
)
```

## Styling Examples

### Custom Icons and Colors
You can completely change the look of the checkbox by providing a custom icon and using background utilities.

```dart
WCheckbox(
  value: true,
  checkIcon: Icons.favorite,
  className: 'w-6 h-6 bg-pink-100 border-pink-300 checked:bg-pink-500 checked:border-transparent',
  iconClassName: 'text-white text-xs',
)
```

### Validation States
Using the `states` property allows you to apply conditional styling for errors or success states.

```dart
WCheckbox(
  value: false,
  states: {'error'},
  className: 'border-gray-300 error:border-red-500 error:ring-2 error:ring-red-100',
)
```

## All Supported Classes

| Category | Classes |
|:---------|:--------|
| Sizing | `w-{n}`, `h-{n}`, `min-w-{n}`, `aspect-square` |
| Spacing | `p-{n}`, `m-{n}` |
| Appearance | `rounded`, `border`, `bg-{color}`, `shadow` |
| States | `checked:`, `hover:`, `focus:`, `disabled:`, `error:` |
| Effects | `opacity-{n}`, `ring`, `duration-{n}`, `ease-{n}` |

## Customizing Theme

The default checked color can be controlled via the `primary` color in your `WindThemeData`.

```dart
WindThemeData(
  colors: {
    'primary': context.windColors['indigo']!,
  },
)
```

## Related Documentation

- [WFormCheckbox](https://anilcancakir.com/wind_kit/docs/v1.6/widgets/w-form-checkbox.md) - Form-integrated checkbox with label and validation.
- [WAnchor](https://anilcancakir.com/wind_kit/docs/v1.6/widgets/w-anchor.md) - The base interactive component used by WCheckbox.
- [WIcon](https://anilcancakir.com/wind_kit/docs/v1.6/widgets/w-icon.md) - Documentation for the check icon styling.
