HomeBytesheetsUI TemplatesUI ToolsRoad MapsStack DiscussionByte Camp
BytesUIv0.5.3
⌘K

Theming

Every BytesUI component shares one design token system. Configure it once with ThemeProvider and control colors, variants, and per-component style overrides globally or per instance.

Overview

BytesUI ships with a centralized theme system built around 8 semantic colors (primary, secondary, tertiary, success, warning, error, neutral, info) and 4 visual variants (solid, outlined, soft, plain). Every themeable component (OtpInput, MentionTextArea, TourOverlay, and more to come) accepts `color` and `variant` props that resolve against the active theme, plus a `style` prop for instance-level slot overrides using `Bui.*` keys.

type Color =
  | 'primary'
  | 'secondary'
  | 'tertiary'
  | 'success'
  | 'warning'
  | 'error'
  | 'neutral'
  | 'info';

type Variant = 'solid' | 'outlined' | 'soft' | 'plain';

1. Wrap Your App with ThemeProvider

Add `ThemeProvider` once at the root of your application, above any BytesUI component. Choose `light` or `dark`, BytesUI's two built-in themes.

import { ThemeProvider } from '@bytesui/react';
import App from './App';

export default function Root() {
  return (
    <ThemeProvider theme="light">
      <App />
    </ThemeProvider>
  );
}

Built-in Themes

ThemeDescription
lightDefault theme. Bright surfaces with WCAG AA-compliant semantic colors. Used automatically when `theme` is omitted.
darkDedicated dark-mode surface, text, and border tokens (not simply an inverted light theme), tuned for contrast and visibility.

Colors & Variants

All 8 semantic colors and all 4 variants are available on every themed component via the `color` and `variant` props. Combine them freely — the palette resolves automatically from the active theme.

import { OtpInput } from '@bytesui/react';

const colors = ['primary', 'secondary', 'tertiary', 'success', 'warning', 'error', 'neutral', 'info'];
const variants = ['solid', 'outlined', 'soft', 'plain'];

export default function ColorVariantGrid() {
  return (
    <>
      {colors.map((color) =>
        variants.map((variant) => (
          <OtpInput key={`${color}-${variant}`} length={4} color={color} variant={variant} />
        ))
      )}
    </>
  );
}

Creating a Custom Theme

Pass a `themes` map to `ThemeProvider` to register additional named themes. A custom theme can be a full theme object, or a partial override that gets deep-merged on top of the built-in light theme.

import { ThemeProvider } from '@bytesui/react';

const customThemes = {
  corporate: {
    colors: {
      primary: {
        main: '#0f172a',
        hover: '#1e293b',
        focusBorder: '#0f172a',
        focusRing: 'rgba(15, 23, 42, 0.15)'
      }
    }
  }
};

export default function App({ children }) {
  return (
    <ThemeProvider theme="corporate" themes={customThemes} defaultTheme="light">
      {children}
    </ThemeProvider>
  );
}

Component-Level Theme Overrides

Add a `components` block to any theme to set default `color`/`variant` props and default slot style overrides for a component across your whole app. Instance-level `style` props still take precedence.

export const myTheme = {
  // ...full theme colors, surfaces, text, borders, transitions, typography
  components: {
    OtpInput: {
      defaultProps: { color: 'success', variant: 'soft' },
      styleOverrides: {
        'Bui.root': { gap: '12px' }
      }
    }
  }
};

Per-Instance Slot Styling

Every themed component accepts a `style` prop keyed by `Bui.*` slot names for one-off customization without writing separate CSS. Slot overrides always win over theme defaults.

import { OtpInput } from '@bytesui/react';

export default function SlotStylingExample() {
  return (
    <OtpInput
      length={6}
      color="secondary"
      variant="soft"
      style={{
        'Bui.root': { gap: '12px' },
        'Bui.input': { borderRadius: '10px', fontWeight: 700 },
        'Bui.placeholder': { color: '#94a3b8', opacity: 0.6 }
      }}
    />
  );
}

useTheme() Hook

Access the active theme object and helper utilities inside your own components to build custom themed UI that matches BytesUI components.

import { useTheme, resolveColorTokens, getVariantTokens } from '@bytesui/react';

export default function CustomBadge({ color = 'primary', variant = 'soft', children }) {
  const theme = useTheme();
  const palette = resolveColorTokens(theme, color, variant);
  const tokens = getVariantTokens(palette, variant);

  return (
    <span
      style={{
        background: tokens.bg,
        color: tokens.text,
        border: tokens.border ? `1px solid ${tokens.border}` : 'none',
        borderRadius: 999,
        padding: '4px 10px',
        fontFamily: theme.typography.fontFamily
      }}
    >
      {children}
    </span>
  );
}

ThemeProvider Props

PropTypeDefaultDescription
themestring"light"Name of the active theme. Built-in options: `light`, `dark`, or any key registered via `themes`.
themesRecord<string, Partial<BytesTheme>>{}Custom theme registry. Values can be a full theme object or a partial object deep-merged onto the built-in light theme.
defaultThemestring"light"Fallback theme name used if `theme` does not match any registered theme.
childrenReactNoderequiredYour application tree. Must wrap any BytesUI component that reads theme context.

Semantic Colors

ColorTypical Use
primaryMain brand color and default action color.
secondarySupporting brand accent for secondary actions.
tertiaryAdditional accent color for tags, highlights, and variety.
successPositive states, confirmations, and validation.
warningCaution states that need attention but aren't errors.
errorDestructive actions and validation failures.
neutralDefault/neutral gray for disabled or low-emphasis UI.
infoInformational messages and hints.

Variants

VariantDescription
solidFilled background using the color's `main` tone with high-contrast text.
outlinedTransparent/surface background with a colored border. The default variant.
softLight tinted background using the color's `lightest` tone with `dark` text.
plainNo background or border — colored text/icon only.

Theme Utilities & Exports

ExportDescription
ThemeProviderReact provider that supplies the active theme to all BytesUI components.
useTheme()Hook returning the active theme object.
lightTheme / darkThemeBuilt-in theme objects you can import directly for reference or to spread into a custom theme.
resolveColorTokens(theme, color, variant)Returns the full color palette object for a semantic color.
getVariantTokens(palette, variant)Extracts `{ bg, text, border }` for a specific variant from a resolved palette.
mapTokensToCSSVariables(tokens, prefix)Converts palette tokens into a `--prefix-token` CSS variable map.
generateThemeCSS(theme, prefix?)Generates a `:root { ... }` CSS string with every theme token, useful outside React.
getContrastingTextColor(hex)Returns `#ffffff` or `#000000` based on background luminance.
createComponentThemeResolver(componentName, theme)Returns a resolver function that applies `theme.components.<Name>.defaultProps` before resolving tokens.