**Themes are implemented in Typescript.** That's because our goal is to share variables between Grafana Typescript code and SASS files. Theme definitions are located in `packages/grafana-ui/src/themes/[default|dark|light].ts` files. `default.ts` file holds common variables like typography and spacing definitions, while `[light|dark].ts` primarily specify colors used in themes.
**Themes are implemented in Typescript.** That's because our goal is to share variables between Grafana TypeScript and [Sass](https://sass-lang.com/) code. Theme definitions are located in the following files:
// Your component has access to the theme variables now
// Your component has access to the theme variables now
}
}
```
```
#### Using `withTheme` higher-order component (HOC)
#### Using `withTheme` higher-order component (HOC)
With this method your component will be automatically wrapped in `ThemeContext.Consumer` and provided with current theme via `theme` prop. Component used with `withTheme` must implement `Themeable` interface.
With this method your component will be automatically wrapped in `ThemeContext.Consumer` and provided with current theme via `theme` prop. Components used with `withTheme` must implement the`Themeable` interface.
```ts
```ts
import { ThemeContext, Themeable } from '@grafana/ui';
import { ThemeContext, Themeable } from '@grafana/ui';
When implementing snapshot tests for components that use the `withTheme` HOC, the snapshot will contain the entire theme object. Any change to the theme renders the snapshot outdated.
When implementing snapshot tests for components that use the `withTheme` HOC, the snapshot will contain the entire theme object. Any change to the theme renders the snapshot outdated.
@ -73,9 +83,11 @@ describe('MyComponent', () => {
});
});
```
```
### Using themes in Storybook
### Using themes in [Storybook](https://storybook.js.org/)
All stories are wrapped with `ThemeContext.Provider` using global decorator. To render `Themeable` component that's not wrapped by `withTheme` HOC you either create a new component in your story:
All stories are wrapped with `ThemeContext.Provider` using a global decorator. To render a `Themeable` component that isn't wrapped by a `withTheme` HOC, either create a new component in your story, or use the `renderComponentWithTheme` helper.
There should be very few cases where theme would be used in Angular context. For this purpose there is a function available that retrieves current theme: `import { getCurrentTheme } from app/core/utils/ConfigProvider`. Angular components should be migrated to React, or if that's not possible at the moment, styled using SASS.
There should be very few cases where a theme would be used in an Angular context. For this purpose, there is a function available that retrieves the current theme:
```ts
import { getCurrentTheme } from app/core/utils/ConfigProvider
```
Angular components should be migrated to React, or if that's not possible at the moment, styled using Sass.
## FAQ
## FAQ
### How can I modify SASS variable files?
This section provides insight into frequently-asked questions.
### How can I modify Sass variable files?
> For the following to apply you need to run `yarn dev` task.
> For the following to apply you need to run `yarn dev` task.
`[_variables|_variables.dark|_variables.light].generated.scss` files are the ones that are referenced in the main SASS files for SASS variables to be available. **These files are automatically generated and should never be modified by hand!**.
`[_variables|_variables.dark|_variables.light].generated.scss` files are the ones that are referenced in the main Sass files for Sass variables to be available. **These files are automatically generated and should never be modified by hand!**
#### If you need to modify *SASS variable value* you need to modify corresponding Typescript file that is a source of the variables:
#### If you need to modify a *Sass variable value* you need to modify the corresponding Typescript file that is the source of the variables:
### You must ensure ThemeContext provider is available in a React tree
By default all react2angular directives have `ThemeContext.Provider` ensured. But, there are cases where we create another React tree via `ReactDOM.render`. This happens in case of graph legend rendering and `ReactContainer` directive. In such cases theme consumption will fail. To make sure theme context is available in such cases, you need to wrap your rendered component with ThemeContext.Provider using `provideTheme` function:
This section describes limitations with Grafana's theming system.
### You must ensure `ThemeContext` provider is available in a React tree
By default all react2angular directives have `ThemeContext.Provider` ensured. But, there are cases where we create another React tree via `ReactDOM.render`. This happens in the case of graph legend rendering and the `ReactContainer` directive. In such cases theme consumption will fail. To make sure theme context is available in such cases, you need to wrap your rendered component with ThemeContext.Provider using the `provideTheme` function: