Tokens
Foundations

Tokens

Color, space, type, radius, and shadow values in Onset are named tokens exported from the library.

All tokens are available from @solarius/onset/tokens. You can also import them directly from @solarius/onset; the main entry re-exports everything the tokens module exposes.

Color math

Dependency-free color conversion utilities. The scale generator in Palettes is built on these.

hexToRgb(hex: string)

Converts a hex string ("#7366ff") to an [r, g, b] tuple. Handles 3- and 6-digit hex.

rgbToHex(r, g, b)

Converts [r, g, b] channel values back to a 6-digit hex string. Channels are clamped to 0–255.

hexToHsl(hex: string)

Converts a hex color to an { h, s, l } object with h in degrees (0–360) and s, l as percentages (0–100).

hslToHex(h, s, l)

Converts HSL values back to a hex string. The inverse of hexToHsl.

hslToRgb(h, s, l)

Converts HSL to an [r, g, b] tuple, useful when you need intermediate RGB channels for blending or alpha compositing.

hexToRgba(hex: string, alpha: number)

Converts a hex color to an rgba() string with the given alpha channel. Used throughout the palette builder for transparent foreground steps.

mix(a: string, b: string, amount: number)

Mixes two hex colors in RGB space. amount = 0 gives pure a; amount = 1 gives pure b. Intermediate values produce a linear blend between the two.

Palettes

The palette layer turns a single base color and mode into the complete surface, text, accent, and status color set.

buildPalette(baseColorHex, mode?)

Produces a SemanticPalette object containing every named color the library uses: bg, surfaceLow through surfaceHighest, border, borderStrong, fg through fgFaint, primary, primaryHover, bright, ok, warn, err, and the 12-step neutral and accent scales. Status colors (ok, warn, err) are fixed per mode and not derived from the base color.

Custom paletteTSX
import { buildPalette } from "@solarius/onset/tokens";

// Get every color for a teal dark-mode theme
const palette1 = buildPalette("#0abab5", "dark");
console.log(palette1.bg); // surface 3 — the default app bg
console.log(palette1.primary); // accent step 9 — primary action color
console.log(palette1.ok); // fixed status green

// Light-mode variant
const palette2 = buildPalette("#0abab5", "light");

generateAccentScale(hex, mode?)

Generates a 12-step accent ramp from a single hex. Step 9 is the base color unmodified; surrounding steps adjust lightness and saturation according to a fixed per-mode curve. Returns an AccentScale object with numeric keys 1–12.

generateNeutralScale(hex, mode?)

Generates a 12-step neutral ramp tinted by the hue of the given color. Only the hue is used: saturation and lightness follow a fixed per-mode curve calibrated against the reference console. Returns a NeutralScale object with numeric keys 1–12.

Radius

Every corner radius in Onset is a multiple of a single base value. Changing the base changes every corner radius.

DEFAULT_RADIUS_BASE

The default base radius is 8 (px).

generateRadiusScale(basePx)

Returns a RadiusScale with keys none, xs, sm, md, lg, xl, full. Each step is a multiple of the base:

Radius scaleTSX
import {
  generateRadiusScale,
  DEFAULT_RADIUS_BASE,
} from "@solarius/onset/tokens";

const scale = generateRadiusScale(DEFAULT_RADIUS_BASE);
// {
//   none: "0px",
//   xs: "4px",       // base × 0.5
//   sm: "6px",       // base × 0.75
//   md: "8px",       // base × 1
//   lg: "10px",      // base × 1.25
//   xl: "16px",      // base × 2
//   full: "9999px",  // pill / circle
// }

Spacing

A 2px-based spacing scale. The reference console uses dense paddings of 2–18px throughout.

The spacing constant is an object mapping step names to pixel values:

Spacing scaleTSX
import { spacing } from "@solarius/onset/tokens";

// { 0: "0px", px: "1px", 0.5: "2px", 1: "4px", 1.5: "6px",
//   2: "8px", 2.5: "10px", 3: "12px", 3.5: "14px", 4: "16px",
//   5: "20px", 6: "24px", 7: "28px", 8: "32px", 9: "36px",
//   10: "40px", 12: "48px", 14: "56px", 16: "64px",
//   20: "80px", 24: "96px", 32: "128px" }

Steps are exposed as --m-space-* CSS variables. Fractional step names use underscores: --m-space-0_5.

Spacing steps multiply their numeric key by one base unit. ThemeProvider.spacingBase changes the base. generateSpacingScale creates a scale; the exported spacing uses the default base of 4.

Generating a scaleTSX
import {
  generateSpacingScale,
  DEFAULT_SPACING_BASE,
} from "@solarius/onset/tokens";

generateSpacingScale(3); // tighter: space-2 is 6px
generateSpacingScale(6); // roomier: space-2 is 12px

DEFAULT_SPACING_BASE; // 4

Motion

Three duration-and-easing pairs rather than a general-purpose scale. Each token carries its easing as well as its duration, so a transition shorthand reads transition: opacity var(--m-transition-fast).

TransitionsTSX
import { transition } from "@solarius/onset/tokens";

// {
//   fast:    "0.1s ease",   // fades and color shifts: opacity, chart marks
//   control: "0.12s ease",  // a control acknowledging a press: buttons, inputs
//   slow:    "0.3s ease",   // something travelling a distance: drawers, collapse
// }

Exposed as --m-transition-fast, --m-transition-control and --m-transition-slow. Setting them to 0s linear on a theme root turns the library's animation off wholesale. Component CSS also honours prefers-reduced-motion on its own; this is the manual override for consumers who need it off regardless of the OS setting.

Typography

Typography tokens use role-based names. Font sizes derive from one base size. See fontSizeBase in Theming.

fontFamily

Font familiesTSX
import { fontFamily } from "@solarius/onset/tokens";

// {
//   sans: '"IBM Plex Sans", "Segoe UI", Arial, sans-serif',
//   mono: '"IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace',
// }

DEFAULT_FONT_SIZE_BASE

The default base text size is 13 (px). Body copy renders at md, a half-step above it.

generateFontSizeScale(basePx)

Returns a FontSizeScale with keys nano, micro, 2xs, xs, sm, base, md, lg, xl, 2xl, 3xl, 4xl, display. Each step holds a fixed proportion to the base and is rounded to the nearest half-pixel:

fontSize

The scale at the default base. It is a plain object, fixed at import time; components read the --m-font-size-* variables instead, which lets fontSizeBase retheme them at runtime.

Font sizesTSX
import { fontSize } from "@solarius/onset/tokens";

// {
//   nano: "10px",     micro: "10.5px",  "2xs": "11px",
//   xs: "12px",       sm: "12.5px",     base: "13px",
//   md: "13.5px",     lg: "14px",       xl: "15.5px",
//   "2xl": "16.5px",  "3xl": "17.5px",  "4xl": "19px",
//   display: "23.5px",
// }

fontWeight

Font weightsTSX
import { fontWeight } from "@solarius/onset/tokens";

// {
//   regular: "400",
//   medium: "500",
//   semibold: "600",
// }

lineHeight

Line heightsTSX
import { lineHeight } from "@solarius/onset/tokens";

// {
//   tight: "1",
//   snug: "1.3",
//   normal: "1.5",
//   relaxed: "1.65",
// }

letterSpacing

Letter spacingTSX
import { letterSpacing } from "@solarius/onset/tokens";

// {
//   tight: "-0.01em",
//   normal: "0",
//   wide: "0.04em",
//   wider: "0.06em",
// }

Shadows & z-index

shadow

Elevation-based box shadows with three levels. Components read these via --m-shadow-sm, --m-shadow-md, --m-shadow-lg.

ShadowsTSX
import { shadow } from "@solarius/onset/tokens";

// {
//   none: "none",
//   sm: "0 1px 3px rgba(0, 0, 0, 0.3)",
//   md: "0 4px 16px rgba(0, 0, 0, 0.5)",
//   lg: "0 8px 32px rgba(0, 0, 0, 0.55)",
// }

zIndex

Named z-index scale for consistent layering across components. Exposed as --m-z-base, --m-z-sticky, etc.

zIndexTSX
import { zIndex } from "@solarius/onset/tokens";

// {
//   base: 0,      sticky: 1,
//   overlay: 4,   toast: 6,
//   hud: 50,      menu: 60,
// }

Tone

A semantic status scale shared by every component that displays status. See Tone for the full API.

TONES

The canonical list: ["neutral", "primary", "info", "ok", "warn", "err"].

TONE_ALIASES

Maps common alternative spellings to canonical tones: "success" → "ok", "warning" → "warn", "danger" → "err", "default" → "neutral", and more.

resolveTone(tone, fallback?)

Normalizes any accepted tone spelling to a canonical Tone. Falls back to "neutral" when the input doesn’t match a known tone or alias.

toneVars(tone)

Returns a style object of --m-tone-* variables for a single tone. Prefer the data-m-tone attribute on components that own their root element; use this when you need to spread tone variables onto something else.

Control sizing

ControlSize

The ControlSize type is "sm" | "md" | "lg". Every bordered input control (Input, Select, NumberInput, Autocomplete, TokenField) accepts a size prop of this type.

controlSize

A record mapping each size to its metrics: height, paddingX, gap, fontSize, radius. These are emitted as CSS variables (--m-control-height-sm, etc.) so they’re theme-overridable.

Control metricsTSX
import { controlSize } from "@solarius/onset/tokens";

// sm: { height: "24px", paddingX: "7px", gap: "4px", … }
// md: { height: "28px", paddingX: "var(--m-space-2)", … }
// lg: { height: "34px", paddingX: "var(--m-space-2_5)", … }

controlCssVars()

Generates the flat --m-control-* CSS variable map for all three sizes. Called by themeToCssVars; you rarely need to call it directly.

focusCssVars()

Generates --m-focus-* variables for the global focus ring style. Two forms are emitted: --m-focus-outline (an outline, clipped by overflow-hidden ancestors) and --m-focus-ring / --m-focus-ring-inset (box-shadow rings that survive clipping). These are token-driven so products can restyle focus globally.

Theme

The theme layer ties everything together into a single --m-* variable map that ThemeProvider writes onto the DOM. See Theming for how to use it.

ThemeConfig

The resolved configuration includes baseColor, radiusBase, fontSizeBase, spacingBase, mode, and the fonts sans/mono family stacks.

DEFAULT_THEME

The reference config: dark mode, #7366ff base color, 8px radius, 13px text, 4px spacing, and the IBM Plex family stacks.

resolveTheme(config?)

Accepts a partial ThemeConfig (merged with defaults) and returns a ResolvedTheme containing the full palette, radius scale, and config. Does not require a mounted provider.

themeToCssVars(resolved)

Flattens a ResolvedTheme into a --m-* CSS variable map: the function that produces every visual token the component library reads. ThemeProvider calls it internally and writes the result onto the DOM.

Server-side theme resolutionTSX
import { resolveTheme, themeToCssVars } from "@solarius/onset/tokens";

// Resolve without mounting a Provider — useful in SSR / build scripts
const resolved = resolveTheme({ baseColor: "#e74c3c", mode: "light" });
const vars = themeToCssVars(resolved);
// vars is a flat Record<string, string> of --m-* custom properties