ThemeProvider Component

The ThemeProvider component applies StyleX theme variables to the document root element, enabling consistent theming across your entire application. It manages theme lifecycle and cleanup automatically.

Usage

Basic Usage

Wrap your application with ThemeProvider to apply the default root styles:

Content with default theme

import { ThemeProvider } from "@228-co/reef/components";

<ThemeProvider>
  <App />
</ThemeProvider>

Custom Color Theme

Override the default colors by passing a colors theme created with stylex.createTheme:

import * as stylex from "@stylexjs/stylex";
import { ThemeProvider } from "@228-co/reef/components";
import { themeColors } from "@228-co/reef/themes";

const customColors = stylex.createTheme(themeColors, {
  danger500: "#ff0000",
  primary500: "#0000ff",
  // ... other color overrides
});

<ThemeProvider theme={{ colors: customColors }}>
  <App />
</ThemeProvider>

Custom Sizing Theme

Override font sizes and spacing with a custom sizing theme:

import * as stylex from "@stylexjs/stylex";
import { ThemeProvider } from "@228-co/reef/components";
import { themeSizing } from "@228-co/reef/themes";

const customSizing = stylex.createTheme(themeSizing, {
  font1: "1.125rem",
  spaceM: "1.25rem",
  // ... other sizing overrides
});

<ThemeProvider theme={{ sizing: customSizing }}>
  <App />
</ThemeProvider>

Custom Details Theme

Override component-specific styling details like padding, border radius, and animation timing:

import * as stylex from "@stylexjs/stylex";
import { ThemeProvider } from "@228-co/reef/components";
import { themeDetails } from "@228-co/reef/themes";

const customDetails = stylex.createTheme(themeDetails, {
  containerPadding: "16px",
  containerBaseBorderRadius: "12px",
  buttonBorderRadius: "4px",
  // ... other detail overrides
});

<ThemeProvider theme={{ details: customDetails }}>
  <App />
</ThemeProvider>

Combined Theme

Combine multiple theme overrides for complete customization:

<ThemeProvider
  theme={{
    colors: customColors,
    sizing: customSizing,
    details: customDetails,
  }}
>
  <App />
</ThemeProvider>

Additional Styles

Apply additional StyleX styles to the document root element:

const rootStyles = stylex.create({
  custom: {
    fontFamily: "'Inter', sans-serif",
  },
});

<ThemeProvider style={rootStyles.custom}>
  <App />
</ThemeProvider>

Props

NameTypeDefaultDescription
childrenJSX.Element

Content to render within the themed context

theme{ colors?: Theme<themeColors>; details?: Theme<themeDetails>; sizing?: Theme<themeSizing> }undefined

Theme object containing optional color, detail, and sizing theme overrides

styleStyleXStylesundefined

Additional StyleX styles to apply to the root element

Theme Object Properties

The theme prop accepts an object with these optional properties:

NameTypeDescription
colorsstylex.Theme<typeof themeColors>

Color theme override. Defines status colors (danger, warning, info, success), primary, secondary, background, and neutral color scales (0-1000).

detailsstylex.Theme<typeof themeDetails>

Detail theme override. Controls padding, border radius, border width, animation timing, and component-specific styling variables.

sizingstylex.Theme<typeof themeSizing>

Sizing theme override. Defines font sizes (font0-font5) and spacing scales (spaceXS, spaceS, spaceM, spaceL).

Theme Variables

Color Variables (themeColors)

Color variables follow a scale from 0-1000, with 500 being the base color:

danger0-1000 - Red color scale for error states

warning0-1000 - Yellow color scale for warning states

info0-1000 - Blue color scale for informational states

success0-1000 - Green color scale for success states

primary0-1000 - Primary text color (dark/light mode aware)

secondary0-1000 - Secondary color scale

background0-1000 - Background color scale (dark/light mode aware)

neutral0-1000 - Neutral gray color scale

Sizing Variables (themeSizing)

font0-font5 - Responsive font sizes using clamp()

spaceXS - Extra small spacing (0.25rem)

spaceS - Small spacing (responsive)

spaceM - Medium spacing (responsive)

spaceL - Large spacing (responsive)

spaceText - Spacing for text elements

spaceHeading - Spacing for heading elements

Detail Variables (themeDetails)

containerPadding - Default container padding

containerBaseBorderRadius - Base border radius for containers

containerBorderWidth - Container border width

buttonBorderRadius - Button border radius

animationLoadingTime - Loading animation duration

animationFadeTime - Fade animation duration

gap - Default gap between elements

How It Works

ThemeProvider applies themes to the document's root HTML element rather than a wrapper div. This approach allows theme CSS variables to be used throughout the entire application, including in other theme definitions.

1. On mount, it captures the initial className and style of the document root

2. It applies the combined theme classes using stylex.props()

3. When the theme prop changes, it reactively updates the root element

4. On unmount, it restores the original className and style values

Dark Mode Support

The default theme variables include dark mode support using CSS media queries. Colors like primary and background automatically switch based on the user's system preference:

// From theme.stylex.ts
const DARK = "@media (prefers-color-scheme: dark)";

primary500: { default: Lampblack[500], [DARK]: White[500] },
background500: { default: FishBelly[500], [DARK]: CeremonialBlack[500] },

You can override this behavior by providing your own theme with custom dark mode values or static values that ignore the system preference.