Migration Guide
This guide covers migrating between major versions of Mix.
1.x to 2.0
Mix 2.0 introduces a new fluent Styler API that replaces the utility-prefix pattern from v1.x. This change provides better IDE support, more intuitive method chaining, and improved type safety.
Deprecated Utilities: The global $box, $text, $icon, $flex, $stack, $image, $flexbox, and $stackbox accessors are now deprecated. Use the corresponding Styler classes directly (e.g., BoxStyler(), TextStyler()).
Breaking Changes
Style API Overhaul
The biggest change is moving from the Style() constructor with utility prefixes to dedicated Styler classes:
| v1.x Pattern | v2.0 Pattern |
|---|---|
Style($box.color.blue()) | BoxStyler().color(Colors.blue) |
Style($text.style.fontSize(16)) | TextStyler().fontSize(16) |
Style($icon.size(24)) | IconStyler().size(24) |
Style($flexbox.gap(8)) | FlexBoxStyler().spacing(8) |
Style($stack.alignment.center()) | StackBoxStyler().alignment(Alignment.center) |
Utility Prefixes Deprecated
The $box, $text, $icon, $flex, $stack, $image, $flexbox, and $stackbox utility prefixes are deprecated. Use the corresponding Styler class instead:
// v1.x
final style = Style(
$box.color.blue(),
$box.padding(16),
$box.borderRadius(8),
);
// v2.0
final style = BoxStyler()
.color(Colors.blue)
.paddingAll(16)
.borderRounded(8);Context Variants
The $on namespace is replaced with method calls directly on the Styler:
| v1.x Pattern | v2.0 Pattern |
|---|---|
$on.hover(...) | .onHovered(...) |
$on.press(...) | .onPressed(...) |
$on.focus(...) | .onFocused(...) |
$on.disabled(...) | .onDisabled(...) |
$on.dark(...) | .onDark(...) |
$on.light(...) | .onLight(...) |
// v1.x
final style = Style(
$box.color.blue(),
$on.hover($box.color.red()),
$on.dark($box.color.white()),
);
// v2.0
final style = BoxStyler()
.color(Colors.blue)
.onHovered(BoxStyler().color(Colors.red))
.onDark(BoxStyler().color(Colors.white));Widget Modifiers
The $with namespace is replaced with .wrap() method using ModifierMix classes:
| v1.x Pattern | v2.0 Pattern |
|---|---|
$with.opacity(0.5) | .wrap(OpacityModifierMix(opacity: 0.5)) |
$with.scale(2) | .scale(2) (use transform methods) |
$with.rotate(45) | .rotate(45) (use transform methods) |
Theming
MixTheme and MixThemeData are replaced with MixScope:
// v1.x
MixTheme(
data: MixThemeData(
colors: {primaryColor: Colors.blue},
),
child: MyApp(),
);
// v2.0
MixScope(
colors: {primaryColor: Colors.blue},
child: MyApp(),
);Token Usage
Token resolution syntax has changed:
// v1.x
$box.color.ref(primaryColor)
// v2.0
BoxStyler().color(primaryColor())Widget Name Changes
| v1.x Widget | v2.0 Widget |
|---|---|
StyledBox | Box |
StyledFlex | FlexBox |
StyledRow | RowBox |
StyledColumn | ColumnBox |
StyledStack | StackBox |
HBox | RowBox |
VBox | ColumnBox |
ZBox | StackBox |
New Features in 2.0
- Fluent Styler API: Chain methods for better readability
- Callable Stylers: Use
BoxStyler()...()as shorthand for creating widgets - Style.of() / Style.maybeOf(): Access resolved styles from the widget tree
- Number directives:
multiply(),add(),subtract(),divide(),clamp() - Improved animation support: Better integration with animation configs
Migration Tips
- Start with imports: Replace
Style(with the appropriate Styler class - Update utility calls: Convert
$box.property()to.property()method chains - Update variants: Replace
$on.hover()with.onHovered() - Update modifiers: Replace
$with.opacity()with.wrap(OpacityModifierMix(...)) - Update theming: Replace
MixThemewithMixScope
0.0.7 to 1.0.0
This section documents migration from legacy versions. If you’re upgrading to Mix 2.0, see the section above.
In our pursuit of API usability and efficiency, we introduced several deprecations in the latest Mix Package versions. If you encounter issues not covered by deprecation notices, please open an issue or send a PR to our deprecation file .
Deprecations
The major updates are:
Mix evolved to Style
The Mix class is now Style. Several methods in the renamed class, including withVariants, withMaybeVariants among others, are deprecated to boost performance and reduce potential confusion.
| before 1.0.0 | 1.0.0+ |
|---|---|
Mix | Style |
Mix.withVariant | Use .variant() on Styler classes |
Mix.withManyVariants | Use multiple .variant() calls |
withMaybeVariant or withMaybeVariants | removed |
Another important change is that the Style no longer contains a generic type. Therefore, in the new version, it is no longer possible.
MixContextBuilder was renamed to SpecBuilder
The MixContextBuilder was renamed to SpecBuilder to better reflect its purpose. The MixContextBuilder is now deprecated.
Widget Updates
TextMix and IconMix widgets are deprecated. Use StyledText and StyledIcon respectively.
Short Aliases
To enhance readability, short aliases and shorthand property/method names are replaced with their fully named counterparts. You can find the full list of removed aliases in the deprecations file
Modifiers
The order of modifiers was previously determined by their addition sequence. Now, we enforce a specific ordering but also allow customizable orders. This might cause behavior changes in rare cases. For details, refer to the modifiers guide.
StyledWidgets updates
The new PressableBox
To provide a more consistent way to use the gesture APIs, we developed a new widget that merges the functionalities of Box and Pressable. Thus, the new PressableBox can receive a style like a Box and also accept interactions and its variants, similar to a Pressable. For more information, see the PressableBox guide.
Keep in mind that the idea is to reserve the old Pressable for more advanced cases.
Behavior changes
Modifiers
Modifiers cannot be inherited by any children. The reason is that the abstract class Attribute has gained a new property, isInheritable, which can be set to false if you want your custom attributes to be non-inheritable, such as Modifiers.
Operators and (&) and or (|)
The operators have been redesigned to allow for concatenation and grouping, enabling the creation of conditions like (primary | secondary) & onHover.
Note: In Mix 2.0, use nested variant methods (e.g., .onHovered().onDark()) instead of the & and | operators.
StyledWidgets and Modifiers
Several StyledWidgets now allow receiving modifiers’ attributes, including StyledIcon, StyledFlex, and StyledText. Additionally, when a modifier is not applied to a Style, a RenderWidgetModifiers will not be present in the widget tree. This simplification makes the widget easier to debug.
Theming
The MixTheme feature has been improved and now offers a better API. It can be applied to main attributes using the method .of, as shown in the following code:
const primaryColor = ColorToken('primary');
final theme = MixThemeData(
colors: {
primaryColor: Colors.blue,
},
);
// ... body method ...
MixTheme(
data: theme,
Box(
key: key,
style: Style(
$box.color.ref(primaryColor),
),
)
)The use of $ (Deprecated in 2.0)
Note: The $ prefix utilities described below are deprecated in Mix 2.0. If you’re migrating to Mix 2.0, use the Styler classes directly (e.g., BoxStyler() instead of $box). See the 1.x to 2.0 migration section above.
In version 1.0.0, the $ symbol was introduced to access the API from the Mix package. This made it easier to identify the utilities provided by Mix. For example, to access the box namespace, you would use $box.
| Before 1.0.0 | 1.0.0+ | 2.0+ (Recommended) |
|---|---|---|
box | $box | BoxStyler() |
text | $text | TextStyler() |
icon | $icon | IconStyler() |
image | $image | ImageStyler() |
flex | $flex | FlexStyler() |
flexbox | $flexbox | FlexBoxStyler() |
stack | $stack | StackStyler() |
stackbox | $stackbox | StackBoxStyler() |
The Namespaces $on and $with (Deprecated in 2.0)
Deprecated: In Mix 2.0, use the direct methods on Styler classes instead:
$on.hover()→.onHovered()$with.opacity()→.wrap(OpacityModifierMix())
Two namespaces were added in 1.0.0: $on and $with. The $on namespace was used to access ContextVariants, and $with was used for modifiers.
// v1.x syntax (deprecated)
PressableBox(
onPress: () {},
style: Style(
$box.width(200),
$box.height(200),
$box.color.blue(),
$with.scale(2), // <-- Modifier
$with.opacity(0.5),
$on.hover( // <-- ContextVariant
$box.color.red(),
),
$on.press(
$box.color.green(),
),
),
child: Box(),
)
// v2.0 syntax (recommended)
PressableBox(
onPress: () {},
child: Box(
style: BoxStyler()
.width(200)
.height(200)
.color(Colors.blue)
.scale(2)
.wrap(OpacityModifierMix(opacity: 0.5))
.onHovered(BoxStyler().color(Colors.red))
.onPressed(BoxStyler().color(Colors.green)),
),
)