CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-stitches--react

React implementation of Stitches CSS-in-JS library with type-safe styling and variants

Pending
Overview
Eval results
Files

theme-management.mddocs/

Theme Management

Create and manage design tokens with type-safe theme references and dynamic theme switching. The theme system provides a structured approach to managing colors, spacing, typography, and other design tokens across your application.

Capabilities

Create Theme

Creates theme objects for design token management with optional naming.

/**
 * Creates a theme object with design tokens
 * @param theme - Object containing design token scales
 * @returns Theme object with className, selector, and token properties
 */
function createTheme(theme: ThemeObject): string & ThemeTokens & ThemeMetadata;

/**
 * Creates a named theme object with design tokens
 * @param name - Theme name for CSS class generation
 * @param theme - Object containing design token scales
 * @returns Named theme object with className, selector, and token properties
 */
function createTheme(name: string, theme: ThemeObject): string & ThemeTokens & ThemeMetadata;

interface ThemeObject {
  colors?: { [token: string]: string };
  space?: { [token: string]: string };
  fontSizes?: { [token: string]: string };
  fonts?: { [token: string]: string };
  fontWeights?: { [token: string]: string | number };
  lineHeights?: { [token: string]: string | number };
  letterSpacings?: { [token: string]: string };
  sizes?: { [token: string]: string };
  borderWidths?: { [token: string]: string };
  borderStyles?: { [token: string]: string };
  radii?: { [token: string]: string };
  shadows?: { [token: string]: string };
  zIndices?: { [token: string]: number };
  transitions?: { [token: string]: string };
}

interface ThemeMetadata {
  /** CSS class name for applying this theme */
  className: string;
  /** CSS selector for targeting this theme */
  selector: string;
}

Usage Examples:

import { createTheme } from "@stitches/react";

// Create default theme
const lightTheme = createTheme({
  colors: {
    primary: 'blue',
    secondary: 'gray',
    background: 'white',
    text: 'black',
    success: 'green',
    warning: 'orange',
    danger: 'red'
  },
  space: {
    1: '4px',
    2: '8px',
    3: '12px',
    4: '16px',
    5: '24px',
    6: '32px'
  },
  fontSizes: {
    xs: '12px',
    sm: '14px',
    md: '16px',
    lg: '18px',
    xl: '20px',
    '2xl': '24px'
  },
  fonts: {
    sans: 'system-ui, sans-serif',
    mono: 'Monaco, monospace'
  }
});

// Create named theme variant
const darkTheme = createTheme('dark', {
  colors: {
    primary: 'lightblue',
    secondary: 'lightgray',
    background: '#1a1a1a',
    text: 'white',
    success: 'lightgreen',
    warning: 'yellow',
    danger: 'lightcoral'
  }
});

// Apply theme to document or container
document.body.className = darkTheme;
// or
<div className={darkTheme}>
  <App />
</div>

Theme Tokens

Access theme tokens with type-safe references and auto-completion.

interface ThemeTokens {
  [scale: string]: {
    [token: string]: ThemeToken;
  };
}

interface ThemeToken {
  /** The token value */
  value: string;
  /** CSS custom property name */
  variable: string;
  /** Scale name this token belongs to */
  scale: string;
  /** Token name within the scale */
  token: string;
}

Usage Examples:

const theme = createTheme({
  colors: {
    primary: 'blue',
    secondary: 'gray'
  },
  space: {
    sm: '8px',
    md: '16px',
    lg: '24px'
  }
});

// Access theme tokens
console.log(theme.colors.primary.value); // 'blue'
console.log(theme.colors.primary.variable); // '--colors-primary'
console.log(theme.space.md.value); // '16px'

// Use tokens in styles with $ prefix
const Button = styled('button', {
  backgroundColor: '$colors$primary',
  padding: '$space$md',
  color: '$colors$secondary'
});

// Or use in CSS function
const cardStyles = css({
  backgroundColor: '$colors$background',
  padding: '$space$lg',
  borderRadius: '$radii$md'
});

Default Theme Map

Map CSS properties to theme scales for automatic token resolution.

interface DefaultThemeMap {
  // Spacing properties
  gap: 'space';
  margin: 'space';
  padding: 'space';
  top: 'space';
  right: 'space';
  bottom: 'space';
  left: 'space';
  
  // Color properties
  color: 'colors';
  backgroundColor: 'colors';
  borderColor: 'colors';
  
  // Typography properties
  fontSize: 'fontSizes';
  fontFamily: 'fonts';
  fontWeight: 'fontWeights';
  lineHeight: 'lineHeights';
  letterSpacing: 'letterSpacings';
  
  // Size properties
  width: 'sizes';
  height: 'sizes';
  minWidth: 'sizes';
  maxWidth: 'sizes';
  
  // Border properties
  borderWidth: 'borderWidths';
  borderRadius: 'radii';
  
  // Shadow and effects
  boxShadow: 'shadows';
  zIndex: 'zIndices';
  transition: 'transitions';
}

const defaultThemeMap: DefaultThemeMap;

Usage Examples:

// Theme map allows shorthand token references
const Button = styled('button', {
  // These automatically map to theme scales via defaultThemeMap
  fontSize: '$md',        // Maps to $fontSizes$md
  padding: '$lg',         // Maps to $space$lg  
  backgroundColor: '$primary', // Maps to $colors$primary
  borderRadius: '$sm'     // Maps to $radii$sm
});

// Custom theme map configuration
const { styled } = createStitches({
  themeMap: {
    ...defaultThemeMap,
    // Custom mappings
    opacity: 'opacity',
    transform: 'transforms'
  },
  theme: {
    opacity: {
      low: '0.5',
      high: '0.9'
    },
    transforms: {
      scale: 'scale(1.1)',
      rotate: 'rotate(45deg)'
    }
  }
});

Dynamic Theme Switching

Switch between themes dynamically at runtime.

Usage Examples:

import { useState } from 'react';

const lightTheme = createTheme({
  colors: {
    background: 'white',
    text: 'black',
    primary: 'blue'
  }
});

const darkTheme = createTheme('dark', {
  colors: {
    background: '#1a1a1a',
    text: 'white', 
    primary: 'lightblue'
  }
});

function ThemeProvider({ children }) {
  const [isDark, setIsDark] = useState(false);
  const currentTheme = isDark ? darkTheme : lightTheme;
  
  return (
    <div className={currentTheme}>
      <button onClick={() => setIsDark(!isDark)}>
        Switch to {isDark ? 'Light' : 'Dark'} Theme
      </button>
      {children}
    </div>
  );
}

Theme Inheritance

Extend existing themes with additional or overridden tokens.

Usage Examples:

const baseTheme = createTheme({
  colors: {
    primary: 'blue',
    secondary: 'gray',
    background: 'white'
  },
  space: {
    sm: '8px',
    md: '16px',
    lg: '24px'
  }
});

// Extend with additional tokens
const extendedTheme = createTheme('extended', {
  colors: {
    ...baseTheme.colors,
    tertiary: 'green',      // Add new color
    primary: 'darkblue'     // Override existing color
  },
  space: {
    ...baseTheme.space,
    xl: '32px',             // Add new spacing
    xxl: '48px'
  },
  // Add completely new scale
  fontSizes: {
    sm: '14px',
    md: '16px',
    lg: '18px'
  }
});

CSS Custom Properties

Themes generate CSS custom properties for external integration.

Usage Examples:

const theme = createTheme({
  colors: {
    primary: 'blue',
    secondary: 'gray'
  },
  space: {
    md: '16px',
    lg: '24px'
  }
});

// CSS custom properties are automatically generated:
// --colors-primary: blue;
// --colors-secondary: gray;
// --space-md: 16px;
// --space-lg: 24px;

// Use in regular CSS
const regularCSS = `
  .my-component {
    background-color: var(--colors-primary);
    padding: var(--space-lg);
  }
`;

// Or in CSS-in-JS
const Component = styled('div', {
  backgroundColor: 'var(--colors-primary)',
  padding: 'var(--space-lg)'
});

Server-Side Rendering

Handle theme application during server-side rendering.

Usage Examples:

// On the server
import { getCssText } from "@stitches/react";

const theme = createTheme({
  colors: { primary: 'blue' }
});

// Apply theme class to HTML
const html = `
  <html>
    <head>
      <style>${getCssText()}</style>
    </head>
    <body class="${theme}">
      <div id="root">${renderToString(<App />)}</div>
    </body>
  </html>
`;

// On the client - hydration will work correctly
ReactDOM.hydrate(<App />, document.getElementById('root'));

Type Safety

// Theme token type with scale and token information
interface ThemeToken<Token, Value, Scale, Prefix> {
  /** Token name prefixed for CSS custom property */
  readonly [Symbol.toPrimitive]: () => string;
  /** Scale this token belongs to */
  scale: Scale;
  /** Token name within the scale */
  token: Token;
  /** Token value */
  value: Value;
  /** CSS custom property variable name */
  variable: string;
}

// Type-safe theme value references
type ScaleValue<Scale, Config = null> = 
  Config extends null
    ? { readonly [K in $$ScaleValue]: Scale }
    : Scale extends keyof Config['theme']
      ? `$${string & keyof Config['theme'][Scale]}`
      : never;

// Property value with theme support
type PropertyValue<Property extends keyof CSSProperties, Config = null> = 
  Config extends null 
    ? { readonly [K in $$PropertyValue]: Property }
    : CSS<Config['media'], Config['theme'], Config['themeMap'], Config['utils']>[Property];

Usage Examples:

// Type-safe theme token access
const theme = createTheme({
  colors: {
    primary: 'blue',
    secondary: 'gray'
  }
});

// TypeScript ensures token exists
const Button = styled('button', {
  backgroundColor: '$colors$primary', // ✓ Valid
  // backgroundColor: '$colors$invalid', // ✗ TypeScript error
});

// Extract theme type for other uses
type MyTheme = typeof theme;
type ColorTokens = keyof MyTheme['colors']; // 'primary' | 'secondary'

Install with Tessl CLI

npx tessl i tessl/npm-stitches--react

docs

animations.md

configuration.md

css-classes.md

global-styles.md

index.md

styled-components.md

theme-management.md

tile.json