Dynamic Styling
Mix lets you define state-aware styles in one place instead of scattering conditional logic throughout your widget tree. Styles automatically adapt to hover, press, disabled, dark mode, and other contexts.
Understanding Variants
Let’s look at a simple example: suppose you want a Box to change its color when hovered. With Mix, you can achieve this by simply adding .onHovered(...) to your style definition.
import 'package:flutter/material.dart';
import 'package:mix/mix.dart';
final style = BoxStyler()
.color(Colors.red)
.height(100)
.width(100)
.borderRounded(10)
.onHovered(BoxStyler().color(Colors.blue));Mix automatically merges the hovered style with the base style—you only define what changes.
Composing Styles with Variants
When you define a style, it is expected to be reused in multiple places. With Mix, you can easily reuse styles even when a variant was defined inside it.
final styleA = BoxStyler()
.color(Colors.red)
.height(100)
.width(100)
.borderRounded(10)
.onHovered(
BoxStyler()
.color(Colors.blue)
.width(200)
);
final styleB = styleA.onHovered(BoxStyler().color(Colors.green));In this example, styleB will have the same style as styleA, but when the widget is hovered it has a different color and maintains the width equal to 200. So the final style when hovered will be:
BoxStyler()
.color(Colors.green)
.height(100)
.width(200)
.borderRounded(10);Nesting Variants
There are cases where you want to combine multiple variants to achieve a specific style. For example, you want to apply a variant when the widget is hovered and want different colors for dark mode and light mode. With Mix, you can achieve this by simply nesting the variants.
final hoverStyle = BoxStyler()
.onDark(BoxStyler().color(Colors.blue))
.onLight(BoxStyler().color(Colors.green));
final style = BoxStyler()
.color(Colors.red)
.height(100)
.width(100)
.borderRounded(10)
.onHovered(hoverStyle);Built-in Variants
Built-in Variant Methods
Below is a list of all built-in variant methods available on stylers (e.g., BoxStyler, TextStyler). Each method allows you to apply a style based on a specific state, platform, breakpoint, or context.
| Method | Description |
|---|---|
onHovered(style) | Applies style when the widget is hovered |
onPressed(style) | Applies style when the widget is pressed |
onFocused(style) | Applies style when the widget is focused |
onDisabled(style) | Applies style when the widget is disabled |
onEnabled(style) | Applies style when the widget is enabled (not disabled) |
onDark(style) | Applies style in dark mode |
onLight(style) | Applies style in light mode |
onPortrait(style) | Applies style in portrait orientation |
onLandscape(style) | Applies style in landscape orientation |
onBreakpoint(breakpoint, style) | Applies style for a custom breakpoint |
onMobile(style) | Applies style on mobile devices |
onTablet(style) | Applies style on tablets |
onDesktop(style) | Applies style on desktops |
onLtr(style) | Applies style for left-to-right text direction |
onRtl(style) | Applies style for right-to-left text direction |
onIos(style) | Applies style on iOS |
onAndroid(style) | Applies style on Android |
onMacos(style) | Applies style on macOS |
onWindows(style) | Applies style on Windows |
onLinux(style) | Applies style on Linux |
onFuchsia(style) | Applies style on Fuchsia |
onWeb(style) | Applies style on web |
onNot(contextVariant, style) | Applies style when the given context variant is not active |
onBuilder((context) => style) | Applies a style based on a custom function using BuildContext |