# 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 | `-` | - | | `theme` | `ThemeConfig` | Yes | `-` | - | | `className` | `string` | No | `-` | - | | `display` | `grid \| ruby \| table \| block \| inline \| inherit \| none \| inline-block \| flex \| inline-flex \| inline-grid \| contents \| flow-root \| revert \| list-item \| string & {} \| -moz-initial \| initial \| revert-layer \| unset \| run-in \| -ms-flexbox \| -ms-grid \| -webkit-flex \| flow \| ruby-base \| ruby-base-container \| ruby-text \| ruby-text-container \| table-caption \| table-cell \| table-column \| table-column-group \| table-footer-group \| table-header-group \| table-row \| table-row-group \| -ms-inline-flexbox \| -ms-inline-grid \| -webkit-inline-flex \| inline-list-item \| inline-table` | No | `-` | - | | `motionFeatures` | `FeatureBundle \| LazyFeatureBundle` | No | `-` | - | | `style` | `CSSProperties` | No | `-` | - |