@wayflyer/flyui-tokens
v11.15.0
Published
`@wayflyer/flyui-tokens` turns the canonical design tokens that live in Figma into:
Readme
FlyUI Tokens
@wayflyer/flyui-tokens turns the canonical design tokens that live in Figma into:
- Hashed CSS bundles with custom properties (per theme) that can be loaded in any product.
- TypeScript-friendly
themeobjects that expose the same values for runtime logic. - A canonical
validCssCustomPropertieslist that powers lint rules and keeps ad‑hoc CSS vars out of our apps. - A
themeManifestthat maps theme keys to the hashed CSS filenames we publish to/fly-assets/themes.
System overview
- The
supernovadirectory contains JSON snapshots that are synced from Figma via the Supernova service. Never edit these by hand, rerun the sync instead. This is done from here (run theStyled Dictionarypipeline to open a PR). scripts/build-tokens.mtsis the single build script that ingests the JSON, and transforms it into CSS and TS artifacts for the consuming apps.pnpm generate-tokens(declared inpackage.json) runs the build script, formats the generated TS, and is invoked beforepnpm build.- Generated files land in
src/build(for consumption inside the package) andpublic/themes(hashed CSS that other apps fetch from the CDN).
Data flow
flowchart TB
Figma[Figma variables] -->|Supernova sync| SupernovaJSON[packages/flyui-tokens/src/supernova/*.json]
SupernovaJSON --> buildScript[scripts/build-tokens.mts]
buildScript --> cssLocal[src/build/*.css]
buildScript --> tsTheme[src/build/theme.ts]
buildScript --> manifest[src/build/theme-manifest.ts]
cssHashed --> CDN["CDN: /fly-assets/themes"]
tsTheme --> npmDist["flyui-tokens exports"]Repository layout
| Path | Purpose |
| --- | --- |
| src/supernova/{wayflyer,light,dark}/*.json | Raw design tokens from Supernova sync (colors, dimensions, typography). |
| src/scripts/build-tokens.mts | The end-to-end build pipeline described below. |
| src/extended-theme.ts | Extra palette + layout defaults that do not exist in Figma. |
| src/build/* | Generated CSS, theme.ts, and theme-manifest.ts. |
Running the build
pnpm nx build flyui-tokensThat command runs tsx ./src/scripts/build-tokens.mts and then formats any generated TypeScript so diffs stay readable.
The pnpm build script depends on this, so publishing always ships fresh tokens.
build-tokens.mts in detail
The script performs the following high-level steps:
- Read synced JSON –
color.json,dimension.json, andstring.json(from thewayflyerdirectory) contain both Wayflyer and white-label primitives. The script selects the correct primitive set per brand/theme. - Resolve references – tokens often reference one another (
{palette.color.grey.50}). TheresolveReferencehelper walks the JSON hierarchy, swaps primitive types where needed, and ensures the final value is a concrete CSS value. - Flatten categories – colors (
processColors), sizes (processDimensions), typography (processTypography), and font sizes (processFontSize) are flattened into CSS custom properties and mirrored TypeScript paths. Spacing tokens are validated to guarantee they aren * 4px(plus the special0-5/1-5steps). The build fails fast if Supernova drifts from these rules, which keeps the source of truth clean. - Inject derived tokens – certain values are not in Figma: global breakpoints, focus/blur/shadow effects, CTA defaults, line heights, and the
extendedThemepalette/defaults. These are appended after the Supernova data. - Generate CSS – tokens are sorted into sensible sections (
defaults, spacing, other tokens, extended palette) and written tosrc/build/*.css. The helpercopyToPublicThemeshashes each CSS file, cleans up old versions inpublic/themes, and updates an in-memory manifest so apps can look up/fly-assets/themes/<theme>.<hash>.css. - Generate TypeScript – all token paths are assembled into a deeply nested
tokensobject plus literal string types. The same pass emitsvalidCssCustomProperties, which contains every custom property name (without the--prefix) alongside a few hardcoded wildcard patterns (e.g.,app-*,scoped-*,grid-*). - Write the manifest –
theme-manifest.tsexports aThemeManifestobject with aschemaVersionand astylesmap of{ [themeKey]: "/fly-assets/themes/<hashed>.css" }. This is what apps load at runtime when swapping themes.
Token categories
- Palette tokens – built from
palette.mapped, plus top-levelbg/contentsections if needed. Alias references are resolved so white-label builds can reuse Wayflyer primitives automatically. - Sizes – includes spacing, radius, stroke, blur, and hard-coded breakpoints. Special-case spacing keys (
0-5,1-5) are added, and both CSS and TypeScript representations keep numeric ordering intact. - Typography – includes font families, weights (converted to numeric values), line heights, and aliases. When secondary typefaces are missing, they fall back to the primary definition.
- Extended palette + defaults –
extended-theme.tshouses data like chart colors and layout defaults that are not managed in Figma yet. These are treated like any other CSS var so downstream apps can reference them consistently.
ESLint integration
The exported validCssCustomProperties list is consumed inside @wayflyer/eslint-plugin rules so only sanctioned CSS custom properties are used. For example, packages/flyui/eslint.config.mjs extends the @wayflyer/allowed-css-variables rule with the allowlist:
import { validCssCustomProperties } from "@wayflyer/flyui-tokens";
export default {
rules: {
"@wayflyer/allowed-css-variables": [
"error",
{
allowlist: [...validCssCustomProperties, "disclosure-panel-height"],
},
],
},
};Outputs & consumption
CSS assets
Local development can import the un-hashed CSS directly:
import "@wayflyer/flyui-tokens/wayflyer-theme.css";Production apps should prefer the hashed files referenced by
themeManifestso they get CDN cache-busting OR re-bundle and hash the un-hashed CSS themeselves.import { themeManifest } from "@wayflyer/flyui-tokens"; const link = document.createElement("link"); link.rel = "stylesheet"; link.href = themeManifest.whiteLabel; // e.g. /fly-assets/themes/whiteLabel.ab12cd34.css document.head.appendChild(link);
JavaScript / TypeScript API
import {
theme,
themeManifest,
validCssCustomProperties,
applyThemeOverrides,
fetchThemeOverrides,
getThemeFlags,
type Theme,
type ThemeOverrides,
} from "@wayflyer/flyui-tokens";
const Card = styled.div`
background: var(--palette-bg-surface-default);
padding: var(--sizes-spacing-4);
border-radius: var(--defaults-borderRadius);
`;
const nextBreakpoint = theme.sizes.breakpoint.lg; // "1280px"Theme override utilities
The package exports utility functions for applying runtime theme overrides:
import {
applyThemeOverrides,
fetchThemeOverrides,
getThemeFlags,
type ThemeOverrides,
} from "@wayflyer/flyui-tokens";
// Fetch theme overrides for a partner
const overrides = await fetchThemeOverrides({ partnerId: "partner-id" });
// Apply overrides to the document root (returns an undo function)
const undo = applyThemeOverrides(overrides);
// Later, revert the changes
undo();
// Or apply to a specific element
const undo = applyThemeOverrides(overrides, document.querySelector(".container"));
// Read current theme flags from CSS custom properties
const flags = getThemeFlags({ rootElement: document.documentElement });
// Returns: { cta: { content: "default", surface: "brand" } }applyThemeOverrides– Applies theme overrides (brand colors, border radius, fonts, CTA styles) to CSS custom properties on a given element. Returns a function that can undo all changes.fetchThemeOverrides– Fetches theme override JSON from the CDN for a given partner ID. Accepts{ partnerId, onError? }options object.getThemeFlags– Reads current theme flags (e.g., CTA content/surface settings) from CSS custom properties on a root element.
Lint rule usage
All repos that use @wayflyer/eslint-plugin can wire in the allowlist exactly as FlyUI does:
import { validCssCustomProperties } from "@wayflyer/flyui-tokens";
const allowlist = [...validCssCustomProperties, "disclosure-panel-height"];Updating tokens
- Change Figma – update the canonical variable in Figma.
- Sync via Supernova – run the Supernova job so the JSON snapshots under
src/supernovaare refreshed. - Regenerate – run
pnpm nx build flyui-tokensto rebuild CSS/TS artifacts. The script will fail if validations (e.g., spacing) are violated. - Commit – include the updated JSON, generated CSS/TS, and any new hashed theme files or manifest changes. Never edit generated files manually.
By keeping this loop tight we ensure every consumer of @wayflyer/flyui-tokens (FlyUI, FlyUI Dataviz, app-shells, etc.) receives a predictable, lint-enforced set of design tokens.
