# ThemeProvider
Provides the theme context to all child components, and automatically generates CSS Variables for dynamic theming.
## Import
```tsx
import { ThemeProvider } from '@coinbase/cds-web'
```
## Examples
import { defaultTheme } from '@coinbase/cds-web/themes/defaultTheme';
import { createThemeCssVars } from '@coinbase/cds-web/core/createThemeCssVars';
import { JSONCodeBlock } from '@site/src/components/page/JSONCodeBlock';
### ThemeProvider component
The ThemeProvider provides the theme context to all child components, and automatically generates CSS Variables for dynamic theming.
You must pass the `theme` prop to configure the theme, and the `activeColorScheme` prop to set light or dark mode.
```tsx
import { ThemeProvider } from '@coinbase/cds-web/system/ThemeProvider';
import { defaultTheme } from '@coinbase/cds-web/themes/defaultTheme';
const App = () => (
{/* Your app components */}
);
```
:::tip
Changing the `activeColorScheme` automatically updates the values returned from the `useTheme` hook and from CSS Variables.
:::
### `useTheme` hook
The `useTheme` hook provides access to the current `theme` and `activeColorScheme`.
The `color` and `spectrum` objects automatically change based on the `activeColorScheme`.
[See the `useTheme` docs here →](/hooks/useTheme)
```jsx
const theme = useTheme();
theme.activeColorScheme; // "light" or "dark"
theme.spectrum; // Resolves to lightSpectrum or darkSpectrum, depends on activeColorScheme
theme.color; // Resolves to lightColor or darkColor, depends on activeColorScheme
theme.color.bgPrimary; // "rgb(0,82,255)" or "rgb(87,139,250)", depends on activeColorScheme
theme.space[2]; // 16
theme.borderRadius[200]; // 8
theme.fontSize.display3; // "2.5rem"
```
:::tip
For best performance, prefer to use CSS Variables instead of the `useTheme` hook whenever possible.
:::
### ThemeProvider CSS Variables
CSS Variables are created for every value in the theme.
For best performance, prefer to use CSS Variables instead of the `useTheme` hook whenever possible.
```jsx
const theme = useTheme();
theme.color.bgPrimary; // --color-bgPrimary
theme.lightColor.bgPrimary; // --lightColor-bgPrimary
theme.darkColor.bgPrimary; // --darkColor-bgPrimary
theme.spectrum.blue10; // --blue10
theme.lightSpectrum.blue10; // --light-blue10
theme.darkSpectrum.blue10; // --dark-blue10
theme.space[2]; // --space-2
theme.space[0.25]; // --space-0_25
theme.borderRadius[400]; // --borderRadius-400
theme.fontSize.body; // --fontSize-body
```
You can see all the CSS Variables for the `defaultTheme` below.
### ThemeProvider classnames
The ThemeProvider renders with CSS classnames based on the `activeColorScheme` and the theme's `id`.
This allows you to style components based on the `activeColorScheme` or the theme's `id`.
```jsx
// Renders with a .cds-default class and a .light class
```
### Nested themes
ThemeProviders can be nested to create theme overrides for specific sections.
```jsx
{/* Default theme in light color scheme */}
{/* Custom theme in dark color scheme */}
```
When nesting, you may want to override specific color values from the current theme. Overrides must be conditionally applied because we don't enforce that a theme has both light and dark colors defined.
```jsx
// Override parts of the parent theme
const theme = useTheme();
const customTheme = {
...theme,
...(theme.lightColor &&
theme.lightSpectrum && {
lightColor: {
...theme.lightColor,
bg: `rgb(${theme.lightSpectrum.orange50})`,
bgPrimary: `rgb(${theme.lightSpectrum.red20})`,
bgSecondary: `rgb(${theme.lightSpectrum.blue50})`,
},
}),
...(theme.darkColor &&
theme.darkSpectrum && {
darkColor: {
...theme.darkColor,
bg: `rgb(${theme.darkSpectrum.orange50})`,
bgPrimary: `rgb(${theme.darkSpectrum.red20})`,
bgSecondary: `rgb(${theme.darkSpectrum.blue50})`,
},
}),
} as const satisfies Theme;
```
### Theme inheritence
Nested ThemeProviders do not automatically inherit the theme from their parent provider. You can manually inherit the theme with the `useTheme` hook.
```jsx
const Example = () => {
// Pass the parent theme down to another ThemeProvider
const theme = useTheme();
return (
{children}
);
};
```
### InvertedThemeProvider component
The InvertedThemeProvider automatically inherits from its parent theme and flips the `activeColorScheme` to the opposite value.
```jsx live
{/* Default theme in light color scheme */}
{/* Default theme in inverse (dark) color scheme */}
```
## Props
| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `activeColorScheme` | `light \| dark` | Yes | `-` | The currently active color scheme for the parent ThemeProvider, either light or dark. |
| `avatarSize` | `{ s: number; m: number; l: number; xl: number; xxl: number; xxxl: number; }` | Yes | `-` | The avatar size values. |
| `borderRadius` | `{ 0: number; 100: number; 200: number; 300: number; 400: number; 500: number; 600: number; 700: number; 800: number; 900: number; 1000: number; }` | Yes | `-` | The border radius values. |
| `borderWidth` | `{ 0: number; 100: number; 200: number; 300: number; 400: number; 500: number; }` | Yes | `-` | The border width values. |
| `color` | `{ currentColor: Color; fg: Color; fgMuted: Color; fgInverse: Color; fgPrimary: Color; fgWarning: Color; fgPositive: Color; fgNegative: Color; bg: Color; bgAlternate: Color; bgInverse: Color; bgOverlay: Color; bgElevation1: Color; bgElevation2: Color; bgPrimary: Color; bgPrimaryWash: Color; bgSecondary: Color; bgTertiary: Color; bgSecondaryWash: Color; bgNegative: Color; bgNegativeWash: Color; bgPositive: Color; bgPositiveWash: Color; bgWarning: Color; bgWarningWash: Color; bgLine: Color; bgLineHeavy: Color; bgLineInverse: Color; bgLinePrimary: Color; bgLinePrimarySubtle: Color; accentSubtleRed: Color; accentBoldRed: Color; accentSubtleGreen: Color; accentBoldGreen: Color; accentSubtleBlue: Color; accentBoldBlue: Color; accentSubtlePurple: Color; accentBoldPurple: Color; accentSubtleYellow: Color; accentBoldYellow: Color; accentSubtleGray: Color; accentBoldGray: Color; transparent: Color; }` | Yes | `-` | The light or dark color palette, as appropriate based on the activeColorScheme. |
| `controlSize` | `{ checkboxSize: number; radioSize: number; switchWidth: number; switchHeight: number; switchThumbSize: number; tileSize: number; }` | Yes | `-` | The control size values. |
| `fontFamily` | `{ body: FontFamily; caption: FontFamily; display1: FontFamily; display2: FontFamily; display3: FontFamily; title1: FontFamily; title2: FontFamily; title3: FontFamily; title4: FontFamily; headline: FontFamily; label1: FontFamily; label2: FontFamily; legal: FontFamily; }` | Yes | `-` | The font family values. |
| `fontSize` | `{ body: FontSize<0 \| (string & {})>; caption: FontSize<0 \| (string & {})>; display1: FontSize<0 \| (string & {})>; display2: FontSize<0 \| (string & {})>; display3: FontSize<0 \| (string & {})>; title1: FontSize<0 \| (string & {})>; title2: FontSize<0 \| (string & {})>; title3: FontSize<0 \| (string & {})>; title4: FontSize<0 \| (string & {})>; headline: FontSize<0 \| (string & {})>; label1: FontSize<0 \| (string & {})>; label2: FontSize<0 \| (string & {})>; legal: FontSize<0 \| (string & {})>; }` | Yes | `-` | The font size values. |
| `fontWeight` | `{ body: FontWeight; caption: FontWeight; display1: FontWeight; display2: FontWeight; display3: FontWeight; title1: FontWeight; title2: FontWeight; title3: FontWeight; title4: FontWeight; headline: FontWeight; label1: FontWeight; label2: FontWeight; legal: FontWeight; }` | Yes | `-` | The font weight values. |
| `iconSize` | `{ s: number; xs: number; m: number; l: number; }` | Yes | `-` | The icon size values. |
| `lineHeight` | `{ body: LineHeight<0 \| (string & {})>; caption: LineHeight<0 \| (string & {})>; display1: LineHeight<0 \| (string & {})>; display2: LineHeight<0 \| (string & {})>; display3: LineHeight<0 \| (string & {})>; title1: LineHeight<0 \| (string & {})>; title2: LineHeight<0 \| (string & {})>; title3: LineHeight<0 \| (string & {})>; title4: LineHeight<0 \| (string & {})>; headline: LineHeight<0 \| (string & {})>; label1: LineHeight<0 \| (string & {})>; label2: LineHeight<0 \| (string & {})>; legal: LineHeight<0 \| (string & {})>; }` | Yes | `-` | The line height values. |
| `shadow` | `{ elevation1: BoxShadow; elevation2: BoxShadow; }` | Yes | `-` | The shadow values. |
| `space` | `{ 0: number; 5: number; 10: number; 0.25: number; 0.5: number; 0.75: number; 1: number; 1.5: number; 2: number; 3: number; 4: number; 6: number; 7: number; 8: number; 9: number; }` | Yes | `-` | The space values, used for margin and padding. |
| `spectrum` | `{ blue0: string; blue100: string; blue5: string; blue10: string; blue15: string; blue20: string; blue30: string; blue40: string; blue50: string; blue60: string; blue70: string; blue80: string; blue90: string; green0: string; green100: string; green5: string; green10: string; green15: string; green20: string; green30: string; green40: string; green50: string; green60: string; green70: string; green80: string; green90: string; orange0: string; orange100: string; orange5: string; orange10: string; orange15: string; orange20: string; orange30: string; orange40: string; orange50: string; orange60: string; orange70: string; orange80: string; orange90: string; yellow0: string; yellow100: string; yellow5: string; yellow10: string; yellow15: string; yellow20: string; yellow30: string; yellow40: string; yellow50: string; yellow60: string; yellow70: string; yellow80: string; yellow90: string; gray0: string; gray100: string; gray5: string; gray10: string; gray15: string; gray20: string; gray30: string; gray40: string; gray50: string; gray60: string; gray70: string; gray80: string; gray90: string; indigo0: string; indigo100: string; indigo5: string; indigo10: string; indigo15: string; indigo20: string; indigo30: string; indigo40: string; indigo50: string; indigo60: string; indigo70: string; indigo80: string; indigo90: string; pink0: string; pink100: string; pink5: string; pink10: string; pink15: string; pink20: string; pink30: string; pink40: string; pink50: string; pink60: string; pink70: string; pink80: string; pink90: string; purple0: string; purple100: string; purple5: string; purple10: string; purple15: string; purple20: string; purple30: string; purple40: string; purple50: string; purple60: string; purple70: string; purple80: string; purple90: string; red0: string; red100: string; red5: string; red10: string; red15: string; red20: string; red30: string; red40: string; red50: string; red60: string; red70: string; red80: string; red90: string; teal0: string; teal100: string; teal5: string; teal10: string; teal15: string; teal20: string; teal30: string; teal40: string; teal50: string; teal60: string; teal70: string; teal80: string; teal90: string; chartreuse0: string; chartreuse100: string; chartreuse5: string; chartreuse10: string; chartreuse15: string; chartreuse20: string; chartreuse30: string; chartreuse40: string; chartreuse50: string; chartreuse60: string; chartreuse70: string; chartreuse80: string; chartreuse90: string; }` | Yes | `-` | The light or dark spectrum color values, as appropriate based on the activeColorScheme. |
| `textTransform` | `{ body: TextTransform; caption: TextTransform; display1: TextTransform; display2: TextTransform; display3: TextTransform; title1: TextTransform; title2: TextTransform; title3: TextTransform; title4: TextTransform; headline: TextTransform; label1: TextTransform; label2: TextTransform; legal: TextTransform; }` | Yes | `-` | The text transform values. |
| `darkColor` | `{ currentColor: Color; fg: Color; fgMuted: Color; fgInverse: Color; fgPrimary: Color; fgWarning: Color; fgPositive: Color; fgNegative: Color; bg: Color; bgAlternate: Color; bgInverse: Color; bgOverlay: Color; bgElevation1: Color; bgElevation2: Color; bgPrimary: Color; bgPrimaryWash: Color; bgSecondary: Color; bgTertiary: Color; bgSecondaryWash: Color; bgNegative: Color; bgNegativeWash: Color; bgPositive: Color; bgPositiveWash: Color; bgWarning: Color; bgWarningWash: Color; bgLine: Color; bgLineHeavy: Color; bgLineInverse: Color; bgLinePrimary: Color; bgLinePrimarySubtle: Color; accentSubtleRed: Color; accentBoldRed: Color; accentSubtleGreen: Color; accentBoldGreen: Color; accentSubtleBlue: Color; accentBoldBlue: Color; accentSubtlePurple: Color; accentBoldPurple: Color; accentSubtleYellow: Color; accentBoldYellow: Color; accentSubtleGray: Color; accentBoldGray: Color; transparent: Color; }` | No | `-` | The dark color palette. |
| `darkSpectrum` | `{ blue0: string; blue100: string; blue5: string; blue10: string; blue15: string; blue20: string; blue30: string; blue40: string; blue50: string; blue60: string; blue70: string; blue80: string; blue90: string; green0: string; green100: string; green5: string; green10: string; green15: string; green20: string; green30: string; green40: string; green50: string; green60: string; green70: string; green80: string; green90: string; orange0: string; orange100: string; orange5: string; orange10: string; orange15: string; orange20: string; orange30: string; orange40: string; orange50: string; orange60: string; orange70: string; orange80: string; orange90: string; yellow0: string; yellow100: string; yellow5: string; yellow10: string; yellow15: string; yellow20: string; yellow30: string; yellow40: string; yellow50: string; yellow60: string; yellow70: string; yellow80: string; yellow90: string; gray0: string; gray100: string; gray5: string; gray10: string; gray15: string; gray20: string; gray30: string; gray40: string; gray50: string; gray60: string; gray70: string; gray80: string; gray90: string; indigo0: string; indigo100: string; indigo5: string; indigo10: string; indigo15: string; indigo20: string; indigo30: string; indigo40: string; indigo50: string; indigo60: string; indigo70: string; indigo80: string; indigo90: string; pink0: string; pink100: string; pink5: string; pink10: string; pink15: string; pink20: string; pink30: string; pink40: string; pink50: string; pink60: string; pink70: string; pink80: string; pink90: string; purple0: string; purple100: string; purple5: string; purple10: string; purple15: string; purple20: string; purple30: string; purple40: string; purple50: string; purple60: string; purple70: string; purple80: string; purple90: string; red0: string; red100: string; red5: string; red10: string; red15: string; red20: string; red30: string; red40: string; red50: string; red60: string; red70: string; red80: string; red90: string; teal0: string; teal100: string; teal5: string; teal10: string; teal15: string; teal20: string; teal30: string; teal40: string; teal50: string; teal60: string; teal70: string; teal80: string; teal90: string; chartreuse0: string; chartreuse100: string; chartreuse5: string; chartreuse10: string; chartreuse15: string; chartreuse20: string; chartreuse30: string; chartreuse40: string; chartreuse50: string; chartreuse60: string; chartreuse70: string; chartreuse80: string; chartreuse90: string; }` | No | `-` | The dark spectrum color values. |
| `fontFamilyMono` | `{ body: FontFamily; caption: FontFamily; display1: FontFamily; display2: FontFamily; display3: FontFamily; title1: FontFamily; title2: FontFamily; title3: FontFamily; title4: FontFamily; headline: FontFamily; label1: FontFamily; label2: FontFamily; legal: FontFamily; }` | No | `-` | The font family values for monospace fonts. |
| `id` | `string` | No | `-` | A unique identifier for the theme. Must be a valid CSS class name. |
| `lightColor` | `{ currentColor: Color; fg: Color; fgMuted: Color; fgInverse: Color; fgPrimary: Color; fgWarning: Color; fgPositive: Color; fgNegative: Color; bg: Color; bgAlternate: Color; bgInverse: Color; bgOverlay: Color; bgElevation1: Color; bgElevation2: Color; bgPrimary: Color; bgPrimaryWash: Color; bgSecondary: Color; bgTertiary: Color; bgSecondaryWash: Color; bgNegative: Color; bgNegativeWash: Color; bgPositive: Color; bgPositiveWash: Color; bgWarning: Color; bgWarningWash: Color; bgLine: Color; bgLineHeavy: Color; bgLineInverse: Color; bgLinePrimary: Color; bgLinePrimarySubtle: Color; accentSubtleRed: Color; accentBoldRed: Color; accentSubtleGreen: Color; accentBoldGreen: Color; accentSubtleBlue: Color; accentBoldBlue: Color; accentSubtlePurple: Color; accentBoldPurple: Color; accentSubtleYellow: Color; accentBoldYellow: Color; accentSubtleGray: Color; accentBoldGray: Color; transparent: Color; }` | No | `-` | The light color palette. |
| `lightSpectrum` | `{ blue0: string; blue100: string; blue5: string; blue10: string; blue15: string; blue20: string; blue30: string; blue40: string; blue50: string; blue60: string; blue70: string; blue80: string; blue90: string; green0: string; green100: string; green5: string; green10: string; green15: string; green20: string; green30: string; green40: string; green50: string; green60: string; green70: string; green80: string; green90: string; orange0: string; orange100: string; orange5: string; orange10: string; orange15: string; orange20: string; orange30: string; orange40: string; orange50: string; orange60: string; orange70: string; orange80: string; orange90: string; yellow0: string; yellow100: string; yellow5: string; yellow10: string; yellow15: string; yellow20: string; yellow30: string; yellow40: string; yellow50: string; yellow60: string; yellow70: string; yellow80: string; yellow90: string; gray0: string; gray100: string; gray5: string; gray10: string; gray15: string; gray20: string; gray30: string; gray40: string; gray50: string; gray60: string; gray70: string; gray80: string; gray90: string; indigo0: string; indigo100: string; indigo5: string; indigo10: string; indigo15: string; indigo20: string; indigo30: string; indigo40: string; indigo50: string; indigo60: string; indigo70: string; indigo80: string; indigo90: string; pink0: string; pink100: string; pink5: string; pink10: string; pink15: string; pink20: string; pink30: string; pink40: string; pink50: string; pink60: string; pink70: string; pink80: string; pink90: string; purple0: string; purple100: string; purple5: string; purple10: string; purple15: string; purple20: string; purple30: string; purple40: string; purple50: string; purple60: string; purple70: string; purple80: string; purple90: string; red0: string; red100: string; red5: string; red10: string; red15: string; red20: string; red30: string; red40: string; red50: string; red60: string; red70: string; red80: string; red90: string; teal0: string; teal100: string; teal5: string; teal10: string; teal15: string; teal20: string; teal30: string; teal40: string; teal50: string; teal60: string; teal70: string; teal80: string; teal90: string; chartreuse0: string; chartreuse100: string; chartreuse5: string; chartreuse10: string; chartreuse15: string; chartreuse20: string; chartreuse30: string; chartreuse40: string; chartreuse50: string; chartreuse60: string; chartreuse70: string; chartreuse80: string; chartreuse90: string; }` | No | `-` | The light spectrum color values. |