2019-09-26 20:32:44 +02:00
# Styling Grafana
[Emotion ](https://emotion.sh/docs/introduction ) is our default-to-be approach to styling React components. It provides a way for styles to be a consequence of properties and state of a component.
2020-02-24 17:54:28 -08:00
## Usage
2019-09-26 20:32:44 +02:00
2020-02-24 17:54:28 -08:00
For styling components, use [Emotion's `css` function ](https://emotion.sh/docs/emotion#css ).
2019-09-26 20:32:44 +02:00
2022-09-23 08:22:16 +02:00
### Basic styling
2020-07-01 11:39:46 +02:00
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
2021-01-25 12:52:22 +01:00
> Please remember to put `getStyles` function at the end of the file!
2020-07-01 11:39:46 +02:00
```tsx
2023-03-14 07:38:21 -07:00
import React from 'react';
2022-09-23 08:22:16 +02:00
import { GrafanaTheme2 } from '@grafana/data ';
import { useStyles2 } from '@grafana/ui ';
2021-04-23 10:06:42 +02:00
import { css } from '@emotion/css ';
2020-07-01 11:39:46 +02:00
2023-03-14 07:38:21 -07:00
const Foo = (props: FooProps) => {
2022-09-23 08:22:16 +02:00
const styles = useStyles2(getStyles);
2021-01-25 12:52:22 +01:00
// Use styles with classNames
2021-04-23 10:06:42 +02:00
return < div className = {styles} > ...< / div > ;
2020-07-01 11:39:46 +02:00
};
2021-01-25 12:52:22 +01:00
2022-09-23 08:22:16 +02:00
const getStyles = (theme: GrafanaTheme2) =>
css({
padding: theme.spacing(1, 2), // will result in 8px 16px padding
});
2020-07-01 11:39:46 +02:00
```
2020-02-24 17:54:28 -08:00
### Styling complex components
2019-09-26 20:32:44 +02:00
2022-09-23 08:22:16 +02:00
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
2023-04-11 15:50:11 +05:30
can have your getStyles function return an object with many class names and use [Emotion's `cx` function ](https://emotion.sh/docs/@emotion/css#cx ) to compose them.
2019-10-14 12:29:10 +02:00
2021-01-25 12:52:22 +01:00
Let's say you need to style a component that has a different background depending on the `isActive` property :
2019-09-26 20:32:44 +02:00
```tsx
2022-09-23 08:22:16 +02:00
import { css, cx } from '@emotion/css ';
2023-06-20 12:31:38 +02:00
import React from 'react';
2022-09-23 08:22:16 +02:00
import { GrafanaTheme2 } from '@grafana/data ';
import { useStyles2 } from '@grafana/ui ';
2019-09-26 20:32:44 +02:00
2021-01-25 12:52:22 +01:00
interface ComponentAProps {
2021-04-23 10:06:42 +02:00
isActive: boolean;
2021-01-25 12:52:22 +01:00
}
2019-09-26 20:32:44 +02:00
2023-03-15 07:56:09 -07:00
const ComponentA = ({ isActive }: ComponentAProps) => {
2023-06-20 12:31:38 +02:00
const styles = useStyles2(getStyles);
2019-09-26 20:32:44 +02:00
return (
2022-09-23 08:22:16 +02:00
< div className = {cx(styles.wrapper, isActive & & styles . active ) } >
2019-10-14 12:29:10 +02:00
As red as you can get
< i className = {styles.icon} / >
2019-09-26 20:32:44 +02:00
< / div >
);
2020-02-24 17:54:28 -08:00
};
2021-01-25 12:52:22 +01:00
// Mind, that you can pass multiple arguments, theme included
2022-09-23 08:22:16 +02:00
const getStyles = (theme: GrafanaTheme2) => {
2021-01-25 12:52:22 +01:00
return {
2022-09-23 08:22:16 +02:00
wrapper: css({
2023-06-20 12:31:38 +02:00
background: theme.colors.background.secondary,
2022-09-23 08:22:16 +02:00
}),
active: css({
background: theme.colors.primary.main,
text: theme.colors.primary.contrastText,
2023-06-20 12:31:38 +02:00
}),
2022-09-23 08:22:16 +02:00
icon: css({
2023-06-20 12:31:38 +02:00
fontSize: theme.typography.bodySmall.fontSize,
}),
2021-01-25 12:52:22 +01:00
};
2022-09-23 08:22:16 +02:00
};
2019-09-26 20:32:44 +02:00
```
2020-02-24 17:54:28 -08:00
For more information about themes at Grafana please see the [themes guide ](./themes.md ).