or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

components.mdhooks-utilities.mdindex.mdstyling-system.mdtheming.md
tile.json

hooks-utilities.mddocs/

Hooks and Utilities

Theme UI provides hooks for accessing theme context and color mode state, along with utility functions for theme manipulation, object access, and style generation. These tools enable advanced theme integration and programmatic theme usage outside of React components.

Capabilities

Theme Context Hook

The useThemeUI hook provides access to the complete theme context including the theme object and color mode state.

/**
 * Access the complete Theme UI context
 * @returns Object containing theme, colorMode, and setColorMode
 */
function useThemeUI(): ThemeUIContextValue;

interface ThemeUIContextValue {
  /** Current theme object */
  theme: Theme;
  /** Current color mode name */
  colorMode?: string;
  /** Function to change color mode */
  setColorMode?: (mode: string) => void;
}

Usage Examples:

import { useThemeUI } from 'theme-ui'

function ThemeInspector() {
  const { theme, colorMode, setColorMode } = useThemeUI()
  
  return (
    <div>
      <h3>Current Theme</h3>
      <p>Color Mode: {colorMode}</p>
      <p>Primary Color: {theme.colors?.primary}</p>
      <p>Font Sizes: {JSON.stringify(theme.fontSizes)}</p>
      
      <button onClick={() => setColorMode?.(colorMode === 'light' ? 'dark' : 'light')}>
        Toggle Mode
      </button>
    </div>
  )
}

// Access specific theme values
function ThemedComponent() {
  const { theme } = useThemeUI()
  const primaryColor = theme.colors?.primary || '#007acc'
  const largeFontSize = theme.fontSizes?.[4] || '24px'
  
  return (
    <div style={{ 
      color: primaryColor, 
      fontSize: largeFontSize 
    }}>
      Programmatically styled
    </div>
  )
}

Color Mode Hook

The useColorMode hook provides direct access to color mode state management.

/**
 * Get and set the current color mode
 * @returns Tuple of [currentMode, setMode] similar to useState
 */
function useColorMode(): [string, (mode: string) => void];

Usage Examples:

import { useColorMode } from 'theme-ui'

function ColorModeToggle() {
  const [colorMode, setColorMode] = useColorMode()
  
  const toggleMode = () => {
    setColorMode(colorMode === 'light' ? 'dark' : 'light')
  }
  
  return (
    <button onClick={toggleMode}>
      {colorMode === 'light' ? 'πŸŒ™' : 'β˜€οΈ'} 
      Switch to {colorMode === 'light' ? 'dark' : 'light'} mode
    </button>
  )
}

function MultiModeToggle() {
  const [colorMode, setColorMode] = useColorMode()
  const modes = ['light', 'dark', 'sepia']
  
  const nextMode = () => {
    const currentIndex = modes.indexOf(colorMode)
    const nextIndex = (currentIndex + 1) % modes.length
    setColorMode(modes[nextIndex])
  }
  
  return (
    <button onClick={nextMode}>
      Current: {colorMode} (click for next)
    </button>
  )
}

// Conditional rendering based on color mode
function ModeSpecificContent() {
  const [colorMode] = useColorMode()
  
  if (colorMode === 'dark') {
    return <div>πŸŒ™ Dark mode content</div>
  }
  
  return <div>β˜€οΈ Light mode content</div>
}

CSS Utility Function

The css function converts theme-aware style objects to CSS for use with other styling solutions.

/**
 * Convert theme-aware styles to CSS function
 * @param styles - Style object with theme references and responsive values
 * @returns Function that accepts theme and returns CSS object
 */
function css(styles: ThemeUIStyleObject): (theme: Theme) => CSSObject;

interface ThemeUIStyleObject {
  [property: string]: ResponsiveStyleValue<any>;
}

interface CSSObject {
  [property: string]: any;
}

Usage Examples:

import { css } from 'theme-ui'
import styled from '@emotion/styled'

// Create CSS function from theme-aware styles
const buttonStyles = css({
  bg: 'primary',
  color: 'white',
  fontSize: 2,
  px: 4,
  py: 2,
  border: 'none',
  borderRadius: 'default',
  cursor: 'pointer',
  '&:hover': {
    bg: 'secondary'
  },
  '&:disabled': {
    opacity: 0.5,
    cursor: 'not-allowed'
  }
})

// Use with emotion/styled-components
const StyledButton = styled.button(buttonStyles)

// Use with CSS-in-JS libraries
import { useTheme } from '@emotion/react'

function CustomComponent() {
  const theme = useTheme()
  const styles = css({
    display: 'flex',
    alignItems: 'center',
    gap: 2,
    p: 3,
    bg: 'background',
    border: '1px solid',
    borderColor: 'muted',
    borderRadius: 'md'
  })(theme)
  
  return <div style={styles}>Custom styled component</div>
}

// Generate responsive CSS
const responsiveStyles = css({
  fontSize: [2, 3, 4],        // 14px, 16px, 20px
  padding: [2, 3, 4],         // 8px, 16px, 32px
  display: ['block', 'flex'], // block on mobile, flex on tablet+
  flexDirection: [null, 'column', 'row'] // column on tablet, row on desktop
})

Get Utility Function

The get function safely accesses nested object properties using dot notation with fallback support.

/**
 * Get nested values from objects using dot notation
 * @param object - Object to search in
 * @param key - Dot-notation key path (e.g., 'colors.primary', 'fontSizes.3')
 * @param fallback - Fallback value if key path not found
 * @returns Retrieved value or fallback
 */
function get(object: object, key: string, fallback?: any): any;

Usage Examples:

import { get, useThemeUI } from 'theme-ui'

function ComponentWithThemeAccess() {
  const { theme } = useThemeUI()
  
  // Safe theme value access with fallbacks
  const primaryColor = get(theme, 'colors.primary', '#007acc')
  const fontSize3 = get(theme, 'fontSizes.3', '16px')
  const buttonPadding = get(theme, 'space.3', '16px')
  const borderRadius = get(theme, 'radii.default', '4px')
  
  // Access deeply nested values
  const buttonVariant = get(theme, 'buttons.primary.backgroundColor', primaryColor)
  const shadowLarge = get(theme, 'shadows.lg', '0 10px 25px rgba(0,0,0,0.15)')
  
  // Array access by index
  const breakpointMd = get(theme, 'breakpoints.1', '52em')
  const spacingLg = get(theme, 'space.4', '32px')
  
  return (
    <div
      style={{
        color: primaryColor,
        fontSize: fontSize3,
        padding: buttonPadding,
        borderRadius: borderRadius,
        boxShadow: shadowLarge
      }}
    >
      Safely accessing theme values
    </div>
  )
}

// Helper function for theme access
function useThemeValue(path: string, fallback?: any) {
  const { theme } = useThemeUI()
  return get(theme, path, fallback)
}

function ComponentWithHelper() {
  const primaryColor = useThemeValue('colors.primary', '#000')
  const largeFontSize = useThemeValue('fontSizes.4', '20px')
  
  return (
    <h2 style={{ color: primaryColor, fontSize: largeFontSize }}>
      Using theme helper
    </h2>
  )
}

Merge Utility Function

The merge function deeply merges objects, useful for extending themes and combining configuration objects.

/**
 * Deep merge two objects with Theme UI-specific logic
 * @param target - Base object to merge into
 * @param source - Source object to merge from
 * @returns New merged object
 */
function merge(target: object, source: object): object;

Usage Examples:

import { merge } from 'theme-ui'

// Extend base theme
const baseTheme = {
  colors: {
    text: '#000',
    background: '#fff',
    primary: '#007acc'
  },
  fonts: {
    body: 'system-ui, sans-serif'
  },
  fontSizes: [12, 14, 16, 20, 24, 32]
}

const darkTheme = merge(baseTheme, {
  colors: {
    text: '#fff',
    background: '#111',
    secondary: '#ff6b6b' // Added new color
  },
  // fonts and fontSizes inherited from baseTheme
})

// Extend component variants
const baseButtons = {
  primary: {
    bg: 'primary',
    color: 'white'
  }
}

const extendedButtons = merge(baseButtons, {
  primary: {
    borderRadius: 'full', // Extends existing primary variant
    fontWeight: 'bold'
  },
  secondary: {               // Adds new variant
    bg: 'secondary',
    color: 'white'
  }
})

// Theme composition
const createTheme = (overrides = {}) => {
  const defaultTheme = {
    colors: {
      primary: '#007acc',
      secondary: '#ff6b6b'
    },
    space: [0, 4, 8, 16, 32, 64]
  }
  
  return merge(defaultTheme, overrides)
}

const customTheme = createTheme({
  colors: {
    primary: '#9c27b0', // Override primary
    accent: '#ffa726'   // Add new color
  },
  radii: {              // Add new scale
    sm: 2,
    md: 4,
    lg: 8
  }
})

Advanced Theme Context

The __ThemeUIContext provides direct access to the React context for advanced use cases.

/**
 * Direct access to Theme UI React context (advanced usage)
 */
const __ThemeUIContext: React.Context<ThemeUIContextValue>;

/**
 * Enhanced createElement function with theme awareness
 * @param type - Element type or component
 * @param props - Element props
 * @param children - Child elements
 * @returns JSX element with theme processing
 */
function createElement(type: any, props?: any, ...children: any[]): JSX.Element;

Usage Examples:

import { __ThemeUIContext, createElement } from 'theme-ui'
import { useContext } from 'react'

// Direct context access (advanced)
function AdvancedThemeComponent() {
  const context = useContext(__ThemeUIContext)
  
  if (!context) {
    throw new Error('Component must be used within ThemeUIProvider')
  }
  
  const { theme, colorMode, setColorMode } = context
  
  return (
    <div>
      <p>Advanced theme access</p>
      <pre>{JSON.stringify(theme.colors, null, 2)}</pre>
    </div>
  )
}

// Custom createElement usage
function CustomComponent({ sx, ...props }) {
  return createElement('div', {
    ...props,
    sx: {
      p: 3,
      bg: 'background',
      color: 'text',
      ...sx
    }
  })
}

Theme Validation Utilities

Utility functions for validating and debugging theme configuration.

/**
 * Validate theme object structure
 * @param theme - Theme object to validate
 * @returns Validation result with errors/warnings
 */
interface ThemeValidationResult {
  valid: boolean;
  errors: string[];
  warnings: string[];
}

// Note: These are conceptual - actual validation would be implementation-specific
function validateTheme(theme: Theme): ThemeValidationResult;
function debugTheme(theme: Theme): void;

Usage Examples:

// Theme debugging in development
import { useThemeUI } from 'theme-ui'

function ThemeDebugger() {
  const { theme } = useThemeUI()
  
  // Log theme structure in development
  React.useEffect(() => {
    if (process.env.NODE_ENV === 'development') {
      console.group('Theme UI Debug')
      console.log('Theme object:', theme)
      console.log('Available colors:', Object.keys(theme.colors || {}))
      console.log('Font sizes:', theme.fontSizes)
      console.log('Spacing scale:', theme.space)
      console.groupEnd()
    }
  }, [theme])
  
  return null
}

Types

interface ThemeUIContextValue {
  theme: Theme;
  colorMode?: string;
  setColorMode?: (mode: string) => void;
}

interface Theme {
  colors?: ColorTheme;
  fonts?: { [key: string]: string };
  fontSizes?: (string | number)[] | { [key: string]: string | number };
  fontWeights?: { [key: string]: string | number };
  lineHeights?: { [key: string]: string | number };
  space?: (string | number)[] | { [key: string]: string | number };
  sizes?: { [key: string]: string | number };
  radii?: { [key: string]: string | number };
  shadows?: { [key: string]: string };
  breakpoints?: Breakpoints;
  zIndices?: { [key: string]: number };
  styles?: ThemeStyles;
  [componentName: string]: any;
}

interface ColorTheme {
  [colorName: string]: string;
  modes?: {
    [modeName: string]: {
      [colorName: string]: string;
    };
  };
}

interface ThemeUIStyleObject {
  [property: string]: ResponsiveStyleValue<any>;
}

type ResponsiveStyleValue<T> = T | Array<T | null | undefined>;

interface CSSObject {
  [property: string]: any;
}

interface Breakpoints extends Array<string> {
  [key: string]: string;
}

interface ThemeStyles {
  root?: ThemeUIStyleObject;
  [element: string]: ThemeUIStyleObject | undefined;
}

interface ThemeValidationResult {
  valid: boolean;
  errors: string[];
  warnings: string[];
}