Dynamic Styling
Traditionally, making your widgets react to different states—like being pressed, hovered, disabled, or adapting to dark mode—means scattering conditional logic and style changes throughout your widget tree. This quickly becomes verbose and hard to maintain, as you end up writing a lot of boilerplate just to update colors, borders, or other properties based on the widget’s state or context. Mix streamlines this process by letting you define context-aware variants in a single place, so your styles automatically adapt to any situation without cluttering your UI code.
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.
final style = BoxStyler()
.color(Colors.red)
.height(100)
.width(100)
.borderRounded(10)
.onHovered(BoxStyler().color(Colors.blue));
Note that wasn’t necessary to define the height, width, and border radius. Mix will automatically merge the style inside the .onHovered(...)
method with the previous style. Making your code less verbose, much easier to read and maintain.
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 |
onSelected(style) | Applies style when the widget is selected |
onError(style) | Applies style when the widget is in an error state |
onScrolledUnder(style) | Applies style when the widget is scrolled under |
onDragged(style) | Applies style when the widget is being dragged |
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 |