EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
Utilities·component·@astryxdesign/core

Theme

Wraps a subtree with a specific Astryx theme. For static production themes, use `astryx theme build` and import the generated CSS plus built theme object for first-paint and SSR performance. Use runtime `defineTheme()` when themes are dynamic or for prototyping. `defineTheme` accepts a `tokens` object whose keys are CSS custom property names (always prefixed with `--`). Common token names include `--color-accent`, `--color-background-surface`, `--color-background-body`, `--color-text-primary`, `--color-text-secondary`, `--radius-container`, `--spacing-1` through `--spacing-6`. Values can be a string (same for light/dark) or a `[light, dark]` tuple. Example: ```ts import {defineTheme} from '@astryxdesign/core/theme'; const myTheme = defineTheme({ name: 'ocean', tokens: { '--color-accent': ['#0077B6', '#48CAE4'], '--color-background-surface': ['#F0F8FF', '#0A1628'], '--color-text-primary': ['#0A1317', '#FFFFFF'], '--radius-container': '16px', }, }); ```

Open in Playground @astryxdesign/core/theme

Showcases and examples

4 documented examples

Theme — Distinct Themes

Two visually distinct theme providers wrapping identical content to show how Theme changes the visual treatment of child components.

Preview loads on approachPreview loads on approach
Exact source · theme-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {Theme, defineTheme} from '@astryxdesign/core/theme';
import {Card} from '@astryxdesign/core/Card';
import {Grid} from '@astryxdesign/core/Grid';
import {Section} from '@astryxdesign/core/Section';
import {Stack} from '@astryxdesign/core/Layout';
import {Heading, Text} from '@astryxdesign/core/Text';
import {Button} from '@astryxdesign/core/Button';
import {Badge} from '@astryxdesign/core/Badge';

const warmTheme = defineTheme({
  name: 'warm-docs',
  tokens: {
    '--color-accent': ['#D97706', '#FBBF24'],
    '--color-background-surface': ['#FFF7ED', '#1F1300'],
    '--color-background-card': ['#FFFBEB', '#2A1A05'],
    '--color-text-primary': ['#3B2F15', '#FEF3C7'],
    '--color-text-secondary': ['#92400E', '#FCD34D'],
    '--color-border': ['#FED7AA', '#92400E66'],
    '--radius-container': '20px',
  },
});

const forestTheme = defineTheme({
  name: 'forest-docs',
  tokens: {
    '--color-accent': ['#15803D', '#86EFAC'],
    '--color-background-surface': ['#F0FDF4', '#052E16'],
    '--color-background-card': ['#FFFFFF', '#0F3D24'],
    '--color-text-primary': ['#052E16', '#DCFCE7'],
    '--color-text-secondary': ['#166534', '#BBF7D0'],
    '--color-border': ['#BBF7D0', '#15803D66'],
    '--radius-container': '8px',
  },
});

function ThemeCard({label}: {label: string}) {
  return (
    <Card padding={4} width="100%">
      <Stack direction="vertical" gap={3}>
        <Stack direction="horizontal" gap={2} vAlign="center">
          <Heading level={4}>{label}</Heading>
          <Badge label="Active" variant="success" />
        </Stack>
        <Text type="body" color="secondary">
          The same content inherits this provider's colors, typography, radius,
          and component treatment.
        </Text>
        <Stack direction="horizontal" gap={2} wrap="wrap">
          <Button label="Primary" variant="primary" size="sm" />
          <Button label="Secondary" variant="secondary" size="sm" />
          <Button label="Ghost" variant="ghost" size="sm" />
        </Stack>
      </Stack>
    </Card>
  );
}

export default function ThemeShowcase() {
  return (
    <Section variant="muted" padding={4} maxWidth={600}>
      <Grid columns={{minWidth: 240, repeat: 'fit'}} gap={3} width="100%">
        <Theme theme={warmTheme}>
          <ThemeCard label="Warm" />
        </Theme>
        <Theme theme={forestTheme}>
          <ThemeCard label="Forest" />
        </Theme>
      </Grid>
    </Section>
  );
}

Usage

Wraps a subtree with a specific Astryx theme. For static production themes, use astryx theme build and import the generated CSS plus built theme object for first-paint and SSR performance. Use runtime defineTheme() when themes are dynamic or for prototyping.

defineTheme accepts a tokens object whose keys are CSS custom property names (always prefixed with --). Common token names include --color-accent, --color-background-surface, --color-background-body, --color-text-primary, --color-text-secondary, --radius-container, --spacing-1 through --spacing-6. Values can be a string (same for light/dark) or a [light, dark] tuple.


Example:

```ts

import {defineTheme} from '@astryxdesign/core/theme';

const myTheme = defineTheme({

name: 'ocean',

tokens: {

'--color-accent': ['#0077B6', '#48CAE4'],

'--color-background-surface': ['#F0F8FF', '#0A1628'],

'--color-text-primary': ['#0A1317', '#FFFFFF'],

'--radius-container': '16px',

},

});

```

  • Build app themes that are known ahead of time with astryx theme build, then import the generated CSS and built theme object.
  • Use runtime themes when the theme is created or edited in the browser, such as theme editors, user branding, or prototypes.
  • Token names always start with -- (e.g. --color-accent, --color-background-surface). Do not omit the prefix.
  • Default to runtime themes in SSR production apps. Component overrides inject after hydration instead of shipping as static CSS.

Typed props

PropType and behavior
themeDefinedTheme · required
Theme object to apply. Prefer built theme objects for static production themes; use runtime defineTheme() for dynamic themes.
mode'light' | 'dark' | 'system' · default 'system'
Color mode. System follows OS preference.
childrenReactNode · required
Content to render with the theme.