Skip to content

API reference

stylesheet

The stylesheet function creates a named collection of element styles using design tokens. It is returned by defineSystem and is bound to that system's token set.

Signature

TypeScript
import { stylesheet } from '@toned/systems/base'

const styles = stylesheet({
  PartName: {
    $kind: 'pressable',
    // token properties
    bgColor: 'action',
    borderRadius: 'medium',
    cursor: 'pointer',
    // escape hatch: a web-only property that no token covers
    '@platform web': { $style: { userSelect: 'none' } },
  },
})

Element Definition

Each key in the stylesheet object defines a named element. The value is an object with:

Token properties -- Any token defined in your system (bgColor, textColor, borderRadius, paddingX, etc.). Values are type-checked against the token's allowed values.

$style -- The escape hatch: portable raw fields that no token covers. Reach for a token first. An explicit platform block widens the allowed fields for that platform.

$kind -- What the part is: 'view' (the default), 'text', 'image' or 'pressable'. It selects the element or native primitive the part renders as, and limits the part to the tokens that apply to that kind. It is fixed: a state, condition or variant cannot change it.

States and conditions -- Keys such as ':hover', '@media md' and '@platform web' hold the values that apply in that state or condition. Conditions and selectors lists every key, including the earlier '@md', style and $$type spellings, which remain supported.

Multiple Elements

Stylesheets commonly define multiple elements that together describe a component's visual structure:

TypeScript
export const cardStyles = stylesheet({
  Root: {
    flexLayout: 'column',
    gap: 1,
    bgColor: 'elevated',
    borderRadius: 'large',
    borderColor: 'subtle',
    borderWidth: 'thin',
    shadow: 'small',
    padding: 3,
  },
  Title: {
    $kind: 'text',
    typography: 'heading-3',
  },
  Body: {
    $kind: 'text',
    typography: 'body-medium',
    textColor: 'subtle',
  },
})

Bound with createElements, the sheet becomes S.Root, S.Title and S.Body components. useStyles returns the same parts as prop bags to spread onto your own JSX elements.

Chaining with Variants

Call .variants() on a stylesheet to add conditional styles. See the Variants page for details.

TypeScript
import type { Variants } from '@toned/core'

const styles = stylesheet({
  Root: { bgColor: 'action' },
}).variants(($: Variants<{ size: 'm' | 's' }>) => ({
  [$.size('m')]: { Root: { paddingX: 3 } },
  [$.size('s')]: { Root: { paddingX: 2 } },
}))

Deriving a Sheet

.extend() returns a new sheet with rules merged into this one's base declarations; the original is unchanged and its variants still apply on top. See Extending and overriding for this and for overrides that win over variants.

TypeScript
const baseCard = stylesheet({
  Root: { bgColor: 'elevated', borderRadius: 'large', padding: 3 },
})

export const flatCard = baseCard.extend({
  Root: { bgColor: 'default', borderRadius: 'small' },
})

Responsive Styles

Use @media keys that name a breakpoint to apply different token values at different screen sizes:

TypeScript
const styles = stylesheet({
  Root: {
    paddingX: 2,
    '@media md': { paddingX: 4 },
    '@media lg': { paddingX: 6 },
  },
})

The inline t compatibility helper accepts the same blocks (see Media Queries), though the root-level and cross-element forms remain stylesheet-only.