Build beautiful apps
Start

Theme

FlexiUI provides a powerful, flexible theming system built on top of Tailwind CSS. This guide covers the complete theme architecture, available tokens, and how to customize every aspect of your design system.

Overview

The FlexiUI theme system is built on three key principles:

  • Design Tokens - Semantic values for colors, spacing, typography, etc.
  • Tailwind Integration - Full compatibility with Tailwind CSS theming
  • Type Safety - Complete TypeScript support for theme customization

Theme Architecture

FlexiUI themes are configured through the Tailwind plugin:

// tailwind.config.ts
import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [
    flexiui({
      themes: {
        light: {
          // Light theme configuration
        },
        dark: {
          // Dark theme configuration
        },
      },
    }),
  ],
}

Default Theme

FlexiUI comes with a carefully crafted default theme that works out of the box. No configuration is required to get started:

import { FlexiUIProvider } from '@flexi-ui/system'
 
function App() {
  return (
    <FlexiUIProvider>
      {/* Your app with default theme */}
    </FlexiUIProvider>
  )
}

The default theme includes:

  • Semantic colors - primary, secondary, success, warning, danger
  • Neutral colors - background, foreground, default, content
  • Component-specific - divider, focus, overlay, disabled
  • Responsive spacing - Consistent spacing scale
  • Typography - Font families, sizes, and weights
  • Border radius - Consistent radius values

Theme Structure

Complete Theme Object

Here's the complete structure of a FlexiUI theme:

{
  colors: {
    // Brand colors
    primary: {
      50: '#eff6ff',
      100: '#dbeafe',
      200: '#bfdbfe',
      300: '#93c5fd',
      400: '#60a5fa',
      500: '#3b82f6',
      600: '#2563eb',
      700: '#1d4ed8',
      800: '#1e40af',
      900: '#1e3a8a',
      DEFAULT: '#3b82f6',
      foreground: '#ffffff',
    },
    secondary: {
      // Similar structure
      DEFAULT: '#7928ca',
      foreground: '#ffffff',
    },
 
    // Semantic colors
    success: {
      DEFAULT: '#0cce6b',
      foreground: '#ffffff',
    },
    warning: {
      DEFAULT: '#ffc107',
      foreground: '#000000',
    },
    danger: {
      DEFAULT: '#f31260',
      foreground: '#ffffff',
    },
 
    // Layout colors
    background: '#ffffff',
    foreground: '#11181c',
 
    // Neutral colors
    default: {
      100: '#f4f4f5',
      200: '#e4e4e7',
      300: '#d4d4d8',
      400: '#a1a1aa',
      500: '#71717a',
      600: '#52525b',
      700: '#3f3f46',
      800: '#27272a',
      900: '#18181b',
      DEFAULT: '#e4e4e7',
      foreground: '#11181c',
    },
 
    // Component-specific
    content1: '#ffffff',
    content2: '#f4f4f5',
    content3: '#e4e4e7',
    content4: '#d4d4d8',
 
    divider: '#e4e4e7',
    focus: '#3b82f6',
    overlay: 'rgba(0, 0, 0, 0.5)',
  },
 
  layout: {
    dividerWeight: '1px',
    disabledOpacity: '0.5',
    fontSize: {
      tiny: '0.75rem',
      small: '0.875rem',
      medium: '1rem',
      large: '1.125rem',
    },
    lineHeight: {
      tiny: '1rem',
      small: '1.25rem',
      medium: '1.5rem',
      large: '1.75rem',
    },
    radius: {
      small: '0.5rem',
      medium: '0.75rem',
      large: '1rem',
    },
  },
 
  borderWidth: {
    small: '1px',
    medium: '2px',
    large: '3px',
  },
}

Colors

Semantic Colors

FlexiUI provides semantic color tokens for common UI patterns:

{
  colors: {
    primary: {
      DEFAULT: '#0070f3',
      foreground: '#ffffff',
    },
    secondary: {
      DEFAULT: '#7928ca',
      foreground: '#ffffff',
    },
    success: {
      DEFAULT: '#0cce6b',
      foreground: '#ffffff',
    },
    warning: {
      DEFAULT: '#ffc107',
      foreground: '#000000',
    },
    danger: {
      DEFAULT: '#f31260',
      foreground: '#ffffff',
    },
  },
}

Each semantic color includes:

  • DEFAULT - The main color value
  • foreground - Text color to use on this background

Color Scales

For more granular control, define full color scales:

{
  colors: {
    primary: {
      50: '#eff6ff',
      100: '#dbeafe',
      200: '#bfdbfe',
      300: '#93c5fd',
      400: '#60a5fa',
      500: '#3b82f6',  // Base color
      600: '#2563eb',
      700: '#1d4ed8',
      800: '#1e40af',
      900: '#1e3a8a',
      DEFAULT: '#3b82f6',
      foreground: '#ffffff',
    },
  },
}

Layout Colors

Background and foreground colors for the overall layout:

{
  colors: {
    background: '#ffffff',
    foreground: '#11181c',
  },
}

Content Colors

For layered content with different background levels:

{
  colors: {
    content1: '#ffffff',  // Highest level
    content2: '#f4f4f5',  // Second level
    content3: '#e4e4e7',  // Third level
    content4: '#d4d4d8',  // Lowest level
  },
}

Component Colors

Special colors for specific UI elements:

{
  colors: {
    divider: '#e4e4e7',
    focus: '#3b82f6',
    overlay: 'rgba(0, 0, 0, 0.5)',
  },
}

Typography

Font Families

Configure font families for different contexts:

{
  typography: {
    fontFamily: {
      sans: 'Inter, system-ui, -apple-system, sans-serif',
      mono: 'Fira Code, Monaco, Courier New, monospace',
    },
  },
}

Font Sizes

The theme includes predefined font sizes:

{
  layout: {
    fontSize: {
      tiny: '0.75rem',    // 12px
      small: '0.875rem',  // 14px
      medium: '1rem',     // 16px
      large: '1.125rem',  // 18px
    },
  },
}

Line Heights

Corresponding line heights for each font size:

{
  layout: {
    lineHeight: {
      tiny: '1rem',      // 16px
      small: '1.25rem',  // 20px
      medium: '1.5rem',  // 24px
      large: '1.75rem',  // 28px
    },
  },
}

Spacing & Layout

Enhanced Spacing System

FlexiUI includes a comprehensive spacing scale for consistent layouts:

{
  layout: {
    spacing: {
      xs: '0.25rem',   // 4px
      sm: '0.5rem',    // 8px
      md: '0.75rem',   // 12px
      lg: '1rem',      // 16px
      xl: '1.5rem',    // 24px
      '2xl': '2rem',   // 32px
      '3xl': '3rem',   // 48px
      '4xl': '4rem',   // 64px
    },
  },
}

Border Radius

Consistent border radius values:

{
  layout: {
    radius: {
      small: '0.5rem',   // 8px
      medium: '0.75rem', // 12px
      large: '1rem',     // 16px
    },
  },
}

Border Width

Border width tokens:

{
  borderWidth: {
    small: '1px',
    medium: '2px',
    large: '3px',
  },
}

Divider

Divider styling:

{
  layout: {
    dividerWeight: '1px',
  },
}

Opacity

Disabled element opacity:

{
  layout: {
    disabledOpacity: '0.5',
  },
}

Customization Examples

Basic Customization

Override specific colors:

// tailwind.config.ts
import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [
    flexiui({
      themes: {
        light: {
          colors: {
            primary: {
              DEFAULT: '#ff0080',
              foreground: '#ffffff',
            },
            focus: '#ff0080',
          },
        },
      },
    }),
  ],
}

Complete Custom Theme

Create a full custom theme:

// tailwind.config.ts
import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [
    flexiui({
      themes: {
        'my-brand': {
          colors: {
            primary: {
              DEFAULT: '#ff0080',
              foreground: '#ffffff',
            },
            secondary: {
              DEFAULT: '#7928ca',
              foreground: '#ffffff',
            },
            success: {
              DEFAULT: '#17c964',
              foreground: '#ffffff',
            },
            warning: {
              DEFAULT: '#f5a524',
              foreground: '#000000',
            },
            danger: {
              DEFAULT: '#f31260',
              foreground: '#ffffff',
            },
            background: '#ffffff',
            foreground: '#11181c',
            focus: '#ff0080',
          },
          layout: {
            radius: {
              small: '0.25rem',
              medium: '0.5rem',
              large: '0.75rem',
            },
          },
        },
      },
    }),
  ],
}

Then use your custom theme:

<FlexiUIProvider theme="my-brand">
  {/* Your app */}
</FlexiUIProvider>

Extending the Default Theme

Extend rather than replace:

import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [
    flexiui({
      themes: {
        light: {
          extend: 'light', // Extend default light theme
          colors: {
            // Only override what you need
            primary: {
              DEFAULT: '#0070f3',
              foreground: '#ffffff',
            },
          },
        },
      },
    }),
  ],
}

Multi-Theme Setup

Defining Multiple Themes

Create light and dark variations:

import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [
    flexiui({
      themes: {
        light: {
          colors: {
            background: '#ffffff',
            foreground: '#000000',
            primary: {
              DEFAULT: '#0070f3',
              foreground: '#ffffff',
            },
          },
        },
        dark: {
          colors: {
            background: '#000000',
            foreground: '#ffffff',
            primary: {
              DEFAULT: '#3291ff',
              foreground: '#000000',
            },
          },
        },
      },
    }),
  ],
}

Switching Themes

Switch themes at runtime:

'use client'
 
import { useState } from 'react'
import { FlexiUIProvider } from '@flexi-ui/system'
 
function App() {
  const [theme, setTheme] = useState<'light' | 'dark'>('light')
 
  return (
    <FlexiUIProvider theme={theme}>
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Toggle theme
      </button>
      {/* Your app */}
    </FlexiUIProvider>
  )
}

Using Theme Values

With useTheme Hook

Access theme values in components:

import { useTheme } from '@flexi-ui/system'
 
function MyComponent() {
  const { theme } = useTheme()
 
  return (
    <div style={{ color: theme.colors.primary.DEFAULT }}>
      Themed content
    </div>
  )
}

With Tailwind Classes

Use theme colors in Tailwind classes:

<div className="bg-primary text-primary-foreground">
  Primary background with foreground text
</div>
 
<div className="bg-secondary-500 text-white">
  Secondary-500 background
</div>

With CSS Variables

Access as CSS variables:

.my-custom-class {
  background-color: var(--flexi-colors-primary);
  color: var(--flexi-colors-primary-foreground);
  border-radius: var(--flexi-radius-medium);
}

Tailwind Integration

Accessing in Tailwind Config

Use theme values in your Tailwind config:

import { flexiui } from '@flexi-ui/theme'
 
export default {
  theme: {
    extend: {
      colors: {
        brand: '#ff0080', // Custom color
      },
    },
  },
  plugins: [
    flexiui({
      themes: {
        light: {
          colors: {
            // FlexiUI theme colors
            primary: {
              DEFAULT: '#0070f3',
              foreground: '#ffffff',
            },
          },
        },
      },
    }),
  ],
}

Extending Tailwind Theme

Combine FlexiUI theme with Tailwind customizations:

export default {
  theme: {
    extend: {
      // Additional spacing
      spacing: {
        '128': '32rem',
      },
      // Additional breakpoints
      screens: {
        '3xl': '1920px',
      },
    },
  },
  plugins: [flexiui()],
}

Component-Specific Theming

Some components accept theme overrides:

import { Button } from '@flexi-ui/button'
 
<Button
  color="primary"
  className="custom-styles"
>
  Themed button
</Button>

CSS Variables Output

FlexiUI automatically generates CSS variables:

:root {
  --flexi-colors-primary: #0070f3;
  --flexi-colors-primary-foreground: #ffffff;
  --flexi-colors-secondary: #7928ca;
  --flexi-colors-background: #ffffff;
  --flexi-colors-foreground: #11181c;
  --flexi-radius-small: 0.5rem;
  --flexi-radius-medium: 0.75rem;
  --flexi-radius-large: 1rem;
  /* ...and many more */
}

Best Practices

1. Use Semantic Colors

Prefer semantic colors over specific values:

// Good - semantic
<Button color="primary">Submit</Button>
 
// Avoid - specific
<Button className="bg-blue-500">Submit</Button>

2. Maintain Contrast

Ensure proper contrast between background and foreground:

{
  colors: {
    primary: {
      DEFAULT: '#0070f3',
      foreground: '#ffffff',  // High contrast
    },
  },
}

3. Use Consistent Spacing

Stick to the theme's spacing scale:

// Good - uses theme values
<div className="p-4 gap-2">
 
// Avoid - arbitrary values
<div className="p-[13px] gap-[7px]">

4. Define Complete Themes

When creating dark mode, define all required colors:

{
  themes: {
    dark: {
      colors: {
        background: '#000000',
        foreground: '#ffffff',
        primary: { /* ... */ },
        secondary: { /* ... */ },
        // Define all semantic colors
      },
    },
  },
}

5. Test in Both Themes

Always test components in all defined themes:

<FlexiUIProvider theme="light">
  <MyComponent /> {/* Test in light */}
</FlexiUIProvider>
 
<FlexiUIProvider theme="dark">
  <MyComponent /> {/* Test in dark */}
</FlexiUIProvider>

Troubleshooting

Colors Not Applying

Problem: Custom theme colors not showing up.

Solution: Ensure the theme is properly configured:

// Correct
export default {
  plugins: [
    flexiui({
      themes: {
        light: {
          colors: {
            primary: {
              DEFAULT: '#0070f3',
              foreground: '#ffffff',
            },
          },
        },
      },
    }),
  ],
}

CSS Variables Not Available

Problem: CSS variables not accessible.

Solution: Make sure FlexiUI plugin is loaded:

// tailwind.config.ts
import { flexiui } from '@flexi-ui/theme'
 
export default {
  plugins: [flexiui()], // Plugin must be included
}

Theme Not Switching

Problem: Theme prop not changing the active theme.

Solution: Ensure provider is at the root:

// Correct
<FlexiUIProvider theme={activeTheme}>
  <App />
</FlexiUIProvider>
 
// Won't work - provider inside app
<App>
  <FlexiUIProvider theme={activeTheme}>
    {/* ... */}
  </FlexiUIProvider>
</App>

TypeScript Errors

Problem: TypeScript complaining about theme values.

Solution: Ensure proper types are imported:

import type { FlexiUITheme } from '@flexi-ui/theme'
 
const customTheme: FlexiUITheme = {
  colors: {
    // TypeScript will validate
  },
}

Token Reference

Color Tokens

  • primary - Primary brand color
  • secondary - Secondary brand color
  • success - Success state color
  • warning - Warning state color
  • danger - Danger/error state color
  • background - Page background
  • foreground - Default text color
  • default - Default neutral color
  • content1-4 - Content layer backgrounds
  • focus - Focus indicator color
  • divider - Divider line color
  • overlay - Modal/overlay background

Layout Tokens

  • fontSize.tiny|small|medium|large - Text sizes
  • lineHeight.tiny|small|medium|large - Line heights
  • radius.small|medium|large - Border radius values
  • dividerWeight - Divider thickness
  • disabledOpacity - Disabled element opacity

Border Tokens

  • borderWidth.small|medium|large - Border widths

Migration from Other Libraries

From Chakra UI

// Chakra theme
{
  colors: {
    brand: {
      500: '#0070f3',
    },
  },
}
 
// FlexiUI equivalent
{
  colors: {
    primary: {
      DEFAULT: '#0070f3',
      foreground: '#ffffff',
    },
  },
}

From Material-UI

// MUI theme
{
  palette: {
    primary: {
      main: '#0070f3',
    },
  },
}
 
// FlexiUI equivalent
{
  colors: {
    primary: {
      DEFAULT: '#0070f3',
      foreground: '#ffffff',
    },
  },
}

Theme Presets

FlexiUI includes pre-built theme presets for quick starts:

import { flexiui } from '@flexi-ui/theme'
import { createConfigFromPreset } from '@flexi-ui/theme/presets'
 
// Use a preset
const plugin = flexiui(createConfigFromPreset('modern'))

Available presets:

  • Modern - Clean, contemporary design with vibrant colors
  • Minimal - Clean, minimal design with subtle colors
  • Vibrant - Bold, colorful design with high contrast

Learn more in the Theme Presets guide.

Theme Generators

Generate themes programmatically from colors:

import { generateConfigFromColor } from '@flexi-ui/theme'
 
// Generate from brand color
const config = generateConfigFromColor('#006FEE', {
  defaultTheme: 'light'
})
 
const plugin = flexiui(config)

Learn more in the Theme Generators guide.

Next Steps

Now that you understand the theme system, explore: