License: MIT

trio_switch

A customizable tri-state switch widget for Flutter. Allows users to select one of three states with a smooth sliding indicator animation.

Features

  • Three-state selection — tap to switch between three segments
  • Smooth animations — sliding indicator with configurable duration and curve
  • Fully customizable — colors, decorations, gradients, shadows, border radius
  • Controlled widget — parent owns state via value and onChanged
  • Haptic feedback — optional light haptic on state change
  • Disabled state — non-interactive mode with dimmed visuals
  • Per-segment disable — disable individual segments while keeping others interactive
  • Flexible icons — accepts any widget (icons, text, images)

Installation

Add trio_switch to your pubspec.yaml:

dependencies:
  trio_switch: ^1.0.0

Then run:

flutter pub get

Usage

import 'package:trio_switch/trio_switch.dart';

TrioSwitch(
  value: _selectedState,
  onChanged: (int newState) {
    setState(() => _selectedState = newState);
  },
  icons: [
    Icon(Icons.close),
    Icon(Icons.remove),
    Icon(Icons.check),
  ],
)

API Reference

Required Properties

Property Type Description
value int Currently selected state (0, 1, or 2).
onChanged ValueChanged<int> Callback when user taps a different segment.
icons List<Widget> Exactly 3 widgets displayed in each segment.

Optional Properties

Property Type Default Description
width double 200.0 Total width of the switch.
height double 48.0 Total height of the switch.
trackColor Color Colors.grey[200] Background color of the track.
trackDecoration BoxDecoration? null Full decoration for the track (overrides trackColor).
indicatorColor Color Colors.black Color of the sliding indicator.
indicatorDecoration BoxDecoration? null Full decoration for the indicator (overrides indicatorColor).
activeIconColor Color Colors.white Color applied to the active segment icon.
inactiveIconColor Color Colors.grey Color applied to inactive segment icons.
padding double 3.0 Internal padding between track edge and indicator.
borderRadius double 14.0 Border radius for track and indicator.
animationDuration Duration 300ms Duration of the sliding animation.
animationCurve Curve Curves.easeInOut Curve for the sliding animation.
disabled bool false Non-interactive with reduced opacity.
disabledStates List<bool>? null Per-segment disable. Exactly 3 booleans; true = disabled.
hapticFeedback bool true Trigger light haptic on state change.

Customization Example

TrioSwitch(
  value: _value,
  onChanged: (v) => setState(() => _value = v),
  icons: [
    Icon(Icons.sentiment_dissatisfied),
    Icon(Icons.sentiment_neutral),
    Icon(Icons.sentiment_satisfied),
  ],
  trackDecoration: BoxDecoration(
    color: Colors.deepPurple.shade50,
    borderRadius: BorderRadius.circular(20),
    border: Border.all(color: Colors.deepPurple.shade200),
  ),
  indicatorDecoration: BoxDecoration(
    gradient: LinearGradient(
      colors: [Colors.deepPurple, Colors.deepPurple.shade300],
    ),
    borderRadius: BorderRadius.circular(18),
    boxShadow: [
      BoxShadow(
        color: Colors.deepPurple.withValues(alpha: 0.3),
        blurRadius: 8,
        offset: Offset(0, 2),
      ),
    ],
  ),
  activeIconColor: Colors.white,
  inactiveIconColor: Colors.deepPurple.shade300,
  borderRadius: 20,
  height: 56,
)

Disabling Individual Segments

Use disabledStates to disable specific segments while keeping others interactive. Disabled segments appear dimmed and ignore taps.

TrioSwitch(
  value: _value,
  onChanged: (v) => setState(() => _value = v),
  icons: [
    Icon(Icons.close),
    Icon(Icons.remove),
    Icon(Icons.check),
  ],
  disabledStates: [true, false, false], // first segment disabled
)

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/my-feature)
  3. Commit your changes (git commit -am 'Add my feature')
  4. Push to the branch (git push origin feature/my-feature)
  5. Open a Pull Request

License

This project is licensed under the MIT License — see the LICENSE file for details.

Libraries

trio_switch