mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Docs: Update styling docs for useStyles (#25944)
This commit is contained in:
@@ -23,6 +23,27 @@ const ComponentA = () => (
|
||||
);
|
||||
```
|
||||
|
||||
### Styling with theme
|
||||
|
||||
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
import { css } from 'emotion';
|
||||
|
||||
const getComponentStyles = (theme: GrafanaTheme) => css`
|
||||
padding: ${theme.spacing.md};
|
||||
`;
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const styles = useStyles(getComponentsStyles);
|
||||
|
||||
// Use styles with className
|
||||
};
|
||||
```
|
||||
|
||||
### Styling complex components
|
||||
|
||||
In more complex cases, especially when you need to style multiple DOM elements in one component, or when using styles that depend on properties and/or state, you should create a helper function that returns an object of styles. This function should also be wrapped in the `stylesFactory` helper function, which will provide basic memoization.
|
||||
@@ -36,10 +57,7 @@ import { GrafanaTheme } from '@grafana/data';
|
||||
import { selectThemeVariant, stylesFactory, useTheme } from '@grafana/ui';
|
||||
|
||||
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
||||
const backgroundColor = selectThemeVariant(
|
||||
{ light: theme.colors.red, dark: theme.colors.blue },
|
||||
theme.type
|
||||
);
|
||||
const backgroundColor = selectThemeVariant({ light: theme.colors.red, dark: theme.colors.blue }, theme.type);
|
||||
|
||||
return {
|
||||
wrapper: css`
|
||||
|
||||
@@ -18,6 +18,40 @@ This section provides usage guidelines.
|
||||
|
||||
Here's how to use Grafana themes in React components.
|
||||
|
||||
#### useStyles hook
|
||||
|
||||
`useStyles` memoizes the function and provides access to the theme.
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { GrafanaTheme } from '@grafana/data';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
import { css } from 'emotion';
|
||||
|
||||
const getComponentStyles = (theme: GrafanaTheme) => css`
|
||||
padding: ${theme.spacing.md};
|
||||
`;
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const styles = useStyles(getComponentsStyles);
|
||||
|
||||
// Use styles with className
|
||||
};
|
||||
```
|
||||
|
||||
#### Get the theme object
|
||||
|
||||
```tsx
|
||||
import React, { FC } from 'react';
|
||||
import { useTheme } from '@grafana/ui';
|
||||
|
||||
const Foo: FC<FooProps> = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
// Your component has access to the theme variables now
|
||||
};
|
||||
```
|
||||
|
||||
#### Using `ThemeContext` directly
|
||||
|
||||
```tsx
|
||||
@@ -26,19 +60,6 @@ import { ThemeContext } from '@grafana/ui';
|
||||
<ThemeContext.Consumer>{theme => <Foo theme={theme} />}</ThemeContext.Consumer>;
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```tsx
|
||||
import React, { useContext } from 'react';
|
||||
import { ThemeContext } from '@grafana/ui';
|
||||
|
||||
const Foo: React.FunctionComponent<FooProps> = () => {
|
||||
const theme = useContext(ThemeContext);
|
||||
|
||||
// Your component has access to the theme variables now
|
||||
}
|
||||
```
|
||||
|
||||
#### 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. Components used with `withTheme` must implement the `Themeable` interface.
|
||||
@@ -76,6 +97,7 @@ describe('MyComponent', () => {
|
||||
restoreThemeContext();
|
||||
});
|
||||
|
||||
|
||||
it('renders correctly', () => {
|
||||
const wrapper = mount(<MyComponent />)
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
@@ -83,62 +105,30 @@ describe('MyComponent', () => {
|
||||
});
|
||||
```
|
||||
|
||||
### Using themes in [Storybook](https://storybook.js.org/)
|
||||
|
||||
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.
|
||||
|
||||
#### Create a new component:
|
||||
|
||||
```tsx
|
||||
// Foo.story.tsx
|
||||
const FooWithTheme = withTheme(Foo);
|
||||
|
||||
FooStories.add('Story' () => {
|
||||
return <FooWithTheme />
|
||||
});
|
||||
```
|
||||
|
||||
#### Use `renderComponentWithTheme` helper:
|
||||
|
||||
```tsx
|
||||
// Bar.story.tsx
|
||||
|
||||
BarStories.add('Story' () => {
|
||||
return renderComponentWithTheme(Bar, /* pass props here */)
|
||||
});
|
||||
```
|
||||
|
||||
### Using themes in Angular code
|
||||
|
||||
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
|
||||
|
||||
This section provides insight into frequently-asked questions.
|
||||
|
||||
### How can I modify Sass variable files?
|
||||
|
||||
**If possible, migrate styles to Emotion**
|
||||
|
||||
> 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!**
|
||||
|
||||
#### If you need to modify a *Sass variable value* you need to modify the corresponding Typescript file that is the 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:
|
||||
|
||||
- `_variables.generated.scss` - modify `grafana-ui/src/themes/default.ts`
|
||||
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/light.ts`
|
||||
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/dark.ts`
|
||||
|
||||
#### If you need to *add new variable* to Sass variables you need to modify corresponding template file:
|
||||
#### If you need to _add new variable_ to Sass variables you need to modify corresponding template file:
|
||||
|
||||
- `_variables.generated.scss` - modify `grafana-ui/src/themes/_variables.scss.tmpl.ts`
|
||||
- `_variables.light.generated.scss` - modify `grafana-ui/src/themes/_variables.light.scss.tmpl.ts`
|
||||
- `_variables.dark.generated.scss` - modify `grafana-ui/src/themes/_variables.dark.scss.tmpl.ts`
|
||||
|
||||
|
||||
## Limitations
|
||||
|
||||
This section describes limitations with Grafana's theming system.
|
||||
|
||||
Reference in New Issue
Block a user