Styles
Write the text and effect styles into your Figma file with the Mirror Styles plugin, and keep them bound to the variables.
Figma variables hold single values, so the composite typography tokens and
the shadows reach Figma as styles instead: a text style applies a family,
weight, size, line height and letter spacing in one click, and an effect
style holds a shadow. Both are written by Mirror Styles, the plugin we ship,
whose one input is the styles.json the export writes. It makes no network
requests; everything it needs is in that file.
Everything below describes the styles built from our standard token set. A token set of your own changes where the text styles resolve from, and Custom Tokens covers that.
Generating the payload
pnpm mirror tokens
pnpm mirror figma
mirror tokens compiles the token source into .maas/tokens/, and
mirror figma reads that compiled output, so the two run in this order. The
export is written to .maas/figma/: the variable mode files, which
Variables covers, and styles.json beside them. The
text styles resolve from a typography file mirror tokens copies out of the
token source alongside the compiled tokens; if your token source has no such
file, set figma.typography to false in mirror.config.ts and the export
skips text styles.
Bindings
Import the typography collection before the first plugin run. The text styles do not copy their values: family, weight and size are bound to the typography variables, along with any letter spacing authored as an absolute length, so a bound style re-resolves through the collection’s modes, and a frame set to the small-screen mode renders every style at the small-screen scale with no second set of styles anywhere. Line height and the percentage letter spacings are written into the style as plain percentages, and a percent stays correct relative to whatever size the bound variable resolves to.
Running the plugin
Run the plugin and select or drop styles.json. It reads the document’s
local styles and variables once and compares them against the payload before
writing anything. A style the payload names and the file lacks is created, a
style whose values or bindings drifted is updated with every binding
re-asserted, and a style that already matches is left alone. Matching is by
name within each kind, and the plugin sees local styles only, so a style
subscribed from a team library is neither matched nor reported.
Two situations make the plugin skip a style rather than write it. A font
Figma does not have available skips the style, and the report names the
family and face, so either install the font or map the token’s family to one
you have through figma.fonts in mirror.config.ts. A binding that names a
variable the document lacks skips the style too, and the report says which
collection to import first; writing raw values instead would produce a style
that looks right and stops updating.
The report
The report separates a write from a no-op. It counts created, updated, unchanged and skipped styles, for text and effect styles separately. Duplicated style names are listed too (the first copy in the document is updated, the rest are left alone), and so are styles that sit under the payload’s folders but are no longer in the payload. Nothing on that last list is touched, and the plugin never renames a style or touches a variable, a collection or a node. Removing a style, like removing an orphaned variable, is done by hand in Figma.
What a re-run changes
Because the text styles are bound to the variables, a value-only token change
never needs the plugin. Updating the affected modes through Figma’s Import
mode is enough, since the styles resolve their values through the collection.
The plugin runs when the set of styles itself changes, a role added, renamed
or rebound, which is visible in the diff of styles.json.
Further reading
- Variables: the mode files, the import mechanics and the naming rules.
- Custom Tokens: text styles resolved from a typography file of your own.
- CLI: the command, and the arguments the build commands share.