# 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. |