Docs: Update styling docs for useStyles (#25944)

This commit is contained in:
Tobias Skarhed
2020-07-01 11:39:46 +02:00
committed by GitHub
parent d65569f5d9
commit bd27be1351
2 changed files with 63 additions and 55 deletions

View File

@@ -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`

View File

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