Design Tokens
Introduction
Design tokens are the core of any design system. They are the smallest pieces of a design system that define the visual properties of a UI. These properties can include colors, typography, spacing, and more. Design tokens are used to maintain consistency across an application and make it easier to update the design system. As Mix is a solution for styling and is used for building design systems, it also supports design tokens.
Getting Started
Mix has built-in support for design tokens. The tokens are used to define the visual properties in key-value pairs, where the key is a class that extends MixToken
and the value is the actual value of the token.
// 1. declare the token
final $primary = ColorToken('primary'); // ColorToken is a class that extends MixToken<Color>
// 2. define the token value
MixScope(
colors: {
$primary: Colors.lightBlue,
},
child: ...
);
// 3. Use the token in a style
final style = BoxStyler()
.color($primary()) // Use the call method to pass the token value to the style
.size(100, 100);
MixScope
In the same way we use Theme
and ThemeData
in Flutter, Mix has MixScope
. It is a widget that wraps the application and provides the design tokens values to all its child widgets.
MixScope(
colors: {
$primary: Colors.blue,
},
)
Creating a custom token
Mix provides a set of built-in tokens. But you can also create your own tokens to fit your needs. To create a custom token, you need to extend the MixToken
class. For the next example, we will create a custom token for a EdgeInsetsGeometry
.
class EdgeInsetsGeometryToken extends MixToken<EdgeInsetsGeometry> {
const EdgeInsetsGeometryToken(super.name);
@override
EdgeInsetsGeometryRef call() => EdgeInsetsGeometryRef(Prop.token(this));
}
The call
method of your custom token returns an EdgeInsetsGeometryRef
, which acts as a reference to the token’s value. This reference extends type Prop<EdgeInsetsGeometry>
, making it fully compatible with any Mix API that accepts this type. For example, you can directly use it with the padding
parameter of BoxStyler.create(padding: Prop<EdgeInsetsGeometry>)
to apply our custom token.
final style = BoxStyler()
.color(Colors.red)
.size(100, 100)
.merge(BoxStyler.create(padding: $spacing()));