Skip to Content
Mix 2.0 is in development! You can access the Mix 1.0 docs here.
DocsGuidesWidget Modifiers

Widget Modifiers

In Mix, a modifier is simply a method you use on a Style to add extra behavior or effects to a widget—without having to change the widget tree itself. When you use a modifier, it wraps your widget with another widget (like Transform, Padding, and so on). This lets you tweak how your widget looks or acts, all while keeping the widget tree clean and unchanged.

To make modifiers easy to identify and use, Mix follows a clear naming pattern: all modifiers start with the prefix wrap. This convention helps you quickly spot and consistently apply modifiers throughout your styles.

Understanding the Mechanics

Take the wrapOpacity method, for instance. The Container widget doesn’t inherently possess the ability to change its opacity. But, by employing a Opacity widget as a parent, we can introduce this effect.

final style = BoxStyler() .color(Colors.red) .size(100, 100) .wrapOpacity(0.4)

in this case, the Box will be wrapped with an Opacity widget with an opacity of 0.4. The final widget tree will be equivalent to:

Opacity( opacity: 0.4, child: Container(...), );

Creating a custom modifier

Mix provides a set of built-in modifiers that can be used out of the box. But you can also create your own modifiers to fit your needs.

Creating a modifier is like creating a Widget but instead of extending StatelessWidget, you extend WidgetModifier. Define the properties you want to modify and the widget you want to decorate.

final class OpacityModifier extends WidgetModifier<OpacityModifier> { final double opacity; const OpacityModifier([double? opacity]) : opacity = opacity ?? 1.0; @override OpacityModifier copyWith({double? opacity}); @override OpacityModifier lerp(OpacityModifier? other, double t); @override List<Object?> get props => [opacity]; @override Widget build(Widget child) { return Opacity(opacity: opacity, child: child); } }

The build method is the most important method in a modifier. It’s the method that will be called to build the widget tree. It’s where you define the widget tree that will be wrapped by the modifier and how it will be modified.

After creating the WidgetModifier, you need to create a Mix class for applying the modifier. This class will be used to make the modifier mergeable and resolveable.

class OpacityModifierMix extends ModifierMix<OpacityModifier> { final Prop<double>? opacity; const OpacityModifierMix.create({this.opacity}); OpacityModifierMix({double? opacity}) : this.create(opacity: Prop.maybe(opacity)); @override OpacityModifier resolve(BuildContext context); @override OpacityModifierMix merge(OpacityModifierMix? other); @override List<Object?> get props => [opacity]; }

To use your custom modifier in a style, you can use it through the .wrap method on your style. For example, if you have a BoxStyler and want to apply your custom OpacityModifierMix, you can do:

final style = BoxStyler() .color(Colors.red) .size(100, 100) .wrap(OpacityModifierMix(opacity: 0.4))