Why the current Design Tokens implementation is not complete #852
tilucasoli
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
The current Design Tokens implementation is functional for several common paths, but it is not complete yet.
The main gap is that token references and token resolution are mixed in ways that can look like concrete values but are just sentinel values relying on
noSuchMethod.Problem statement
The Design Tokens feature should allow any value to become tokenizable while preserving type safety and predictable resolution behavior.
Today, sentinel values and final resolution exist only inside Mix—tokens resolve correctly when used within Mix’s styling flow. If a user uses tokens in plain Flutter widgets (e.g. by following suggested call methods from the documentation), resolution may not happen there and the API may not behave as expected, leading to confusion and integration risks.
What is working today
MixToken<T>and specialized token types are available.MixScope.BuildContext.MixToken<T>extensions use thecall()method that applies a sentinel value first, then resolution happens later in the style pipeline. This flow only works for predefined types (e.g. those handled ingetReferenceValue:Color,double,Radius,Shadow,BoxShadow,TextStyle,Breakpoint,BorderSide,FontWeight,Duration,List<Shadow>,List<BoxShadow>). Custom or otherTare not given proper ref types and do not get the same sentinel-then-resolve behavior.Why the implementation is not complete
1. The goal is broader than what is currently covered
The goal of Design Tokens is to make any kind of value tokenizable, not only a fixed subset of value types.
Resolution via
BuildContextworks well in the current code. The limitation is that thecall()method onMixToken(which returns ref/sentinel values for the style pipeline) only works for known built-in token types; custom or other value types do not get the same treatment.2. Resolution depends on
BuildContext, but styles are often created in places where it is not availableAny token can be resolved using
BuildContext, but styles are frequently declared in places whereBuildContextis not available yet (for example, static style declarations, shared constants, or builder-independent layers).3.
MixToken.call()can suggest a final value when it is actually a temporary referenceSome classes extending
MixTokenexposecall()returning aRef-like value. This is useful internally, but the API can give the impression that the returned object is already the final concrete value.In reality, it is a temporary placeholder that must be resolved later.
This becomes problematic in two common scenarios:
copyWithor value transformations can run on unresolved placeholders, causing invalid behavior or runtime errors.Impact
copyWith, arithmetic, merges) can behave incorrectly before resolution.useToken(...)as a possible solution (and its problems)One possible solution is an API like:
Upside: It gives a clear, ergonomic way to build styles from resolved token values (e.g. “when this token is X, apply this style”), which can simplify token-aware styling.
Problems: If implemented on top of
ContextVariant, it can alter the order of style application and not respect the override order. To be safe, resolution would need to happen inline at the same declaration position (order-preserving), not as a variant layer with different merge timing—which may constrain or complicate the implementation.Beta Was this translation helpful? Give feedback.
All reactions