A package for generating a Flutter ThemeData
from an exported design token json that is used
e.g. in this Figma plugin. It rather aims to create a Flutter Theme
based on Material 3 than creating a lot of custom widgets for each token.
Features
Right now we support generating/parsing the following:
-
ColorScheme
-
TextStyle
- Font family mapping (from Figma font name to Flutter name)
- Font weight
- Line height
- Font size
- Letter spacing
- Text decoration
-
Theme extension
- Borders
- Border radii
- Box Shadows
- Colors
- Dimensions (also with px)
- Font families
- Font weights
- Line height (only %)
- Numbers
- Opacity (also with %)
- Edge insets
- Text cases
- Text decorations
- Text styles
-
Exposing theming and extensions via a
BuildContext
extension
Getting started
- Add a
.json
file containing the tokens describing your app design. - Add a
tokenbuilder.yaml
configuration file (see example project) in yourlib
directory- Add the path leading to the json to the configuration file
- Map Figma font names to Flutter font family names in configuration file
- Add this builder to
build.yaml
targets:
$default:
builders:
design_tokens_builder:design_tokens_builder:
enabled: true
Usage
Before you can use the tokens you have to start the build runner by
executing flutter pub run build_runner build
.
After that just make sure to use one of the GeneratedTokenSet
for the selected Brightness
in
your ThemeWidget
.
return Theme(
data: GeneratedTokenSet.general.data.dark,
child
:
Container
(
)
,
);
By listening on Brightness changes you could then easily switch between themes. You could also easily change the token set.
This package also exposes the generated theme extensions by building a BuildContext
extension. You
can use the shortcut like this context.yourExtension
. We also provide shortcuts for theme related
properties like context.colorScheme
and context.textTheme
.
Additional information
Multi-theming and dark and light mode
The package can generate multiple themes based on
multiple token sets in
your token data json. Every set will be available through a GeneratedTokenSet
. This enum contains
all set pairs and
ThemeData
for light and dark themes. In order to specify the brightness of your set use Light/Dark
as a suffix in
design tokens (e.g. yourSetLight, yourSetDark). You also might have a global or core set with
universal tokens that do
not change based on the selected brightness. In that case make sure to call this set global
. It
will be recognised by
the builder and ignored when creating GeneratedTokenSets
.
Generation of Flutter ThemeData
The package allows for easy and simple generation of Flutter's ThemeData
. For doing so, you have
to have a certain
structure for your design tokens. Since this is a system token related to material 3 the tokens used
to generate Flutter's
ThemeData
should always start with sys
. If you then e.g. want to set the primary color in
Flutter's ColorScheme
you
have to add a token called sys.primary
with type color
to your json file containing all of your
tokens. primary
is
the name of ColorScheme
s primary
field. Keep in mind to exactly write the field names in camel
case so the package is
able to recognize them properly.
For text styles it works similar. Here also use sys
as the leading part of your token. To better
organize the tokens in
Token Studio we decided to split the text style naming. So if you want to generate displaySmall
text style just use a
sys.display.small
token of type typography
.
Generation of theme extensions
Theme extensions are a great way of providing custom parameters that are not defined in ThemeData
defined. In order to
create a new extension you can just use a different prefix than sys
for your tokens. Based on that
name and the type
of the tokens inside
that token group an extension will
get generated and added to the ThemeData
. So a custom set of colors
called custom
in your token json with the type color
will generate a class CustomColors
which
extends
ThemeExtension<CustomColors>
.
Example token json:
{
"light": {
// <- Token set
"sys": {
// <- Token group sys - Used for Flutter ThemeData
"primary": {
// <- Token for primary color in ColorScheme
"value": "#0000FF",
"type": "color"
},
"background": {
"value": "#FFFFFF",
"type": "color"
},
"onBackground": {
"value": "#000000",
"type": "color"
}
…
}
},
"$themes": [],
"$metadata": {
"tokenSetOrder": [
"light"
]
}
}
Using math and aliases in your tokens
Using math operations and aliases in your tokens is supported by the package.
Tokens Studio for Figma feature parity
Please also see Tokens Studio for figma documentation .
Expand table
Group | Parsable | Exposed via Extension |
---|---|---|
Sizing | ✅ | ✅ |
Spacing | ✅ | ✅ |
Color | ✅ | ✅ |
Border radius | ✅ | ✅ |
Border width | ✅ | ✅ |
Box shadow | ✅ | ✅ |
Opacity | ✅ | ✅ |
Font family | ✅ | ✅ |
Font weight | ✅ | ✅ |
Font size | ✅ | ✅ |
Line height | ✅ | ✅ |
Letter spacing | ✅ | ✅ |
Paragraph spacing | ✅ | ✅ |
Text case | ✅ | ✅ |
Text decoration | ✅ | ✅ |
Typography compositions | ✅ | ✅ |
Assets | ❌ | ❌ |
Composition | ❌ | ❌ |
Dimension | ✅ | ✅ |
Border | ✅ | ✅ |
Flutter theming
The following table shows which themes the package is able to generate.
Expand table
Properties | Supported |
---|---|
colorScheme |
✅ |
iconTheme |
❌ |
textTheme |
✅ |
appBarTheme |
❌ |
badgeTheme |
❌ |
bannerTheme |
❌ |
bottomAppBarTheme |
❌ |
bottomNavigationBarTheme |
❌ |
bottomSheetTheme |
❌ |
buttonBarTheme |
❌ |
buttonTheme |
❌ |
cardTheme |
❌ |
checkboxTheme |
❌ |
chipTheme |
❌ |
dataTableTheme |
❌ |
datePickerTheme |
❌ |
dialogTheme |
❌ |
dividerTheme |
❌ |
drawerTheme |
❌ |
dropdownMenuTheme |
❌ |
elevatedButtonTheme |
❌ |
expansionTileTheme |
❌ |
filledButtonTheme |
❌ |
floatingActionButtonTheme |
❌ |
iconButtonTheme |
❌ |
listTileTheme |
❌ |
menuBarTheme |
❌ |
menuButtonTheme |
❌ |
menuTheme |
❌ |
navigationBarTheme |
❌ |
navigationDrawerTheme |
❌ |
navigationRailTheme |
❌ |
outlinedButtonTheme |
❌ |
popupMenuTheme |
❌ |
progressIndicatorTheme |
❌ |
radioTheme |
❌ |
searchBarTheme |
❌ |
searchViewTheme |
❌ |
segmentedButtonTheme |
❌ |
sliderTheme |
❌ |
snackBarTheme |
❌ |
switchTheme |
❌ |
tabBarTheme |
❌ |
textButtonTheme |
❌ |
textSelectionTheme |
❌ |
timePickerTheme |
❌ |
toggleButtonsTheme |
❌ |
tooltipTheme |
❌ |
Future capabilities
We want to extend the package to also be able to generate/parse more material themes
like ButtonTheme
etc.
Let us know if you miss something by creating an issue or by actively contributing!
Contributing
With this open source repositories we want to create a tool that helps Flutter to integrate with more tools to streamline and simplify the design handoff experience by utilizing Flutter's API. Since this is not only a problem we face we want to share and collaborate on this software as a way to give back to the community. Any contributions are more than welcome!
See our contributing guide for more information.
Libraries
- builder_config/builder_config
- design_tokens_builder
- factory/context_extension_factory
- factory/design_tokens_factory
- factory/extension_factory
- factory/token_set_factory
- parsers/border_parser
- parsers/border_radius_parser
- parsers/box_shadow_parser
- parsers/color_parser
- parsers/design_token_parser
- parsers/dimension_parser
- parsers/font_family_parser
- parsers/font_weight_parser
- parsers/line_height_parser
- parsers/number_parser
- parsers/opacity_parser
- parsers/spacing_parser
- parsers/text_case_parser
- parsers/text_decoration_parser
- parsers/typography_parser
- utils/design_token_map_extension
- utils/string_utils
- utils/token_set_utils
- utils/transformer_utils
- utils/typography_utils