flutter_checkbox 0.2.0
flutter_checkbox: ^0.2.0 copied to clipboard
Customizable Flutter checkbox widgets with tristate, tile layout, hover ring, keyboard navigation, and smooth animations.
flutter_checkbox #
A customizable checkbox widget for Flutter with tristate support, tile layout, pixel-perfect size control, and smooth animations.
Why? #
Flutter's built-in Checkbox has limitations:
- No inline label — requires wrapping with
Row+Textevery time. - Size control is indirect and unpredictable.
- Excessive default padding that's hard to remove.
- No tristate animation or tile layout out of the box.
flutter_checkbox solves these with two focused widgets.
Widgets #
FlutterCheckbox— pure checkbox graphic. Use when you need just the box.FlutterCheckboxTile— checkbox + label + tile container. Use when you need a tappable row.
Features #
- Tristate —
nullvalue renders an animated indeterminate dash with crossfade. - Extended hover area — hit/hover zone covers the full ring area, not just the box.
FlutterCheckboxTile— label, subtitle, tile background, border, shadow, animations.- Exact size control —
CheckboxStyle.sizein logical pixels,scalefor proportional resize. - Shape options —
CheckboxShape.rectangleorCheckboxShape.circle. - Hover ring — configurable padding, shape, and border radius, independent of the box.
- Keyboard navigation — Space/Enter toggles; Tab navigates focus.
- Screen reader support —
Semanticsexposes checked, mixed, enabled, and label. - Disabled state — reduced opacity, tap and keyboard ignored.
Installation #
dependencies:
flutter_checkbox:
git:
url: <your-repo-url>
Usage #
FlutterCheckbox #
FlutterCheckbox(
value: _isChecked,
onChanged: (value) => setState(() => _isChecked = value!),
)
FlutterCheckboxTile #
FlutterCheckboxTile(
value: _isChecked,
label: 'I agree to the terms',
onChanged: (value) => setState(() => _isChecked = value!),
)
Custom style #
FlutterCheckbox(
value: _isChecked,
style: CheckboxStyle(
size: 32,
activeColor: Colors.indigo,
borderRadius: 8,
borderWidth: 2.5,
),
onChanged: (value) => setState(() => _isChecked = value!),
)
Circle shape #
FlutterCheckbox(
value: _isChecked,
style: CheckboxStyle(
shape: CheckboxShape.circle,
size: 32,
activeColor: Colors.teal,
),
onChanged: (value) => setState(() => _isChecked = value!),
)
Tristate #
FlutterCheckbox(
value: _value, // bool? — null = indeterminate dash
tristate: true,
onChanged: (value) => setState(() => _value = value),
// cycles: false → true → null → false
)
Tile with subtitle and custom background #
FlutterCheckboxTile(
value: _isChecked,
label: 'Premium option',
subtitle: 'Includes all features',
selectedColor: Colors.indigo.shade50,
tileBorderRadius: BorderRadius.circular(8),
tileBorderSide: BorderSide(color: Colors.indigo.shade200),
checkboxStyle: CheckboxStyle(activeColor: Colors.indigo),
onChanged: (value) => setState(() => _isChecked = value!),
)
Checkbox at trailing edge #
FlutterCheckboxTile(
value: _isChecked,
label: 'Select item',
checkboxPosition: CheckboxPosition.end,
expandWidth: true,
onChanged: (value) => setState(() => _isChecked = value!),
)
Scale #
FlutterCheckbox(
value: _isChecked,
style: CheckboxStyle(size: 24, scale: 0.75),
onChanged: (value) => setState(() => _isChecked = value!),
)
scale proportionally resizes the box, hover ring, and hit area together.
Disabled #
FlutterCheckboxTile(
value: true,
enabled: false,
label: 'Read-only',
)
Accessibility / keyboard #
FlutterCheckbox(
value: _isChecked,
autofocus: true,
focusNode: _myFocusNode,
onChanged: (value) => setState(() => _isChecked = value!),
)
CheckboxStyle #
| Property | Type | Default | Description |
|---|---|---|---|
shape |
CheckboxShape |
rectangle |
Box shape |
size |
double |
24 |
Box width & height in logical pixels |
scale |
double |
1.0 |
Proportional scale (affects box, ring, and hit area) |
activeColor |
Color? |
ColorScheme.primary |
Checked background |
checkColor |
Color? |
Colors.white |
Checkmark / dash color |
borderColor |
Color? |
ColorScheme.outline |
Unchecked border |
inactiveColor |
Color? |
Colors.transparent |
Unchecked background |
borderWidth |
double |
2 |
Border stroke width |
borderRadius |
double |
4 |
Corner radius (rectangle only) |
checkStrokeWidth |
double |
2.5 |
Checkmark / dash stroke width |
animationDuration |
Duration |
200ms |
Check/uncheck animation |
animationCurve |
Curve |
Curves.easeInOut |
Check/uncheck curve |
morphDuration |
Duration |
150ms |
Checkmark ↔ dash crossfade |
morphCurve |
Curve |
Curves.easeInOut |
Crossfade curve |
hoverRingPadding |
double |
4 |
Space between box edge and ring edge |
hoverRingShape |
CheckboxShape? |
null (follows box) |
Ring shape override |
hoverRingBorderRadius |
double? |
null (borderRadius + 2) |
Ring corner radius override |
FlutterCheckbox #
| Property | Type | Default | Description |
|---|---|---|---|
value |
bool? |
required | Checked state. null = indeterminate |
onChanged |
ValueChanged<bool?>? |
null |
Callback. null = non-interactive |
tristate |
bool |
false |
Allow null value |
style |
CheckboxStyle |
CheckboxStyle() |
Visual style |
enabled |
bool |
true |
When false, renders at 40% opacity |
autofocus |
bool |
false |
Request focus on first build |
focusNode |
FocusNode? |
null |
External focus control |
mouseCursor |
MouseCursor? |
null |
Defaults to click / basic |
FlutterCheckboxTile #
| Property | Type | Default | Description |
|---|---|---|---|
value |
bool? |
required | Checked state |
onChanged |
ValueChanged<bool?>? |
null |
Callback |
tristate |
bool |
false |
Allow null value |
checkboxStyle |
CheckboxStyle |
CheckboxStyle() |
Checkbox style |
label |
String? |
null |
Text label |
labelWidget |
Widget? |
null |
Custom label widget |
labelStyle |
TextStyle? |
null |
Label text style |
subtitle |
String? |
null |
Secondary text below label |
subtitleWidget |
Widget? |
null |
Custom subtitle widget |
subtitleStyle |
TextStyle? |
null |
Subtitle text style |
gap |
double |
8 |
Space between checkbox and label |
checkboxPosition |
CheckboxPosition |
start |
start or end |
expandWidth |
bool |
true |
Fill available width |
padding |
EdgeInsetsGeometry? |
null |
Inner padding |
margin |
EdgeInsetsGeometry? |
null |
Outer margin |
constraints |
BoxConstraints? |
null |
Size constraints |
backgroundColor |
Color? |
null |
Default tile background |
selectedColor |
Color? |
null |
Tile background when checked |
disabledColor |
Color? |
null |
Tile background when disabled |
tileBorderRadius |
BorderRadius? |
null |
Tile corner radius |
tileBorderSide |
BorderSide? |
null |
Tile border |
tileAnimationDuration |
Duration |
200ms |
Background color transition |
tileAnimationCurve |
Curve |
Curves.easeInOut |
Background transition curve |
hoverColor |
Color? |
primary @ 8% |
Hover overlay |
splashColor |
Color? |
primary @ 12% |
Tap ripple |
highlightColor |
Color? |
null |
Held tap highlight |
focusColor |
Color? |
primary @ 12% |
Focus overlay |
elevation |
double |
0 |
Shadow elevation |
enabled |
bool |
true |
Interactive state |
autofocus |
bool |
false |
Request focus on first build |
focusNode |
FocusNode? |
null |
External focus control |
mouseCursor |
MouseCursor? |
null |
Cursor override |
Migration from 0.1.0 #
| Before | After |
|---|---|
CustomCheckbox(value, onChanged) |
FlutterCheckbox(value, onChanged) |
CustomCheckbox(value, label, onChanged) |
FlutterCheckboxTile(value, label, onChanged) |
onChanged: (bool v) => ... |
onChanged: (bool? v) => ... |
CheckboxStyle(hoverColor: ...) |
FlutterCheckboxTile(hoverColor: ...) |
Example #
Run the playground app:
cd example
flutter run
License #
MIT