2019-09-26 13:32:44 -05: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 19:54:28 -06:00
## Usage
2019-09-26 13:32:44 -05:00
2020-02-24 19:54:28 -06:00
### Basic styling
2019-09-26 13:32:44 -05:00
2020-02-24 19:54:28 -06:00
For styling components, use [Emotion's `css` function ](https://emotion.sh/docs/emotion#css ).
2019-09-26 13:32:44 -05:00
```tsx
2020-02-24 19:54:28 -06:00
import React from 'react';
2021-04-23 03:06:42 -05:00
import { css } from '@emotion/css';
2020-02-24 19:54:28 -06:00
const ComponentA = () => (
< div
className={css`
background: red;
`}
>
As red as you can get
< / div >
);
2019-09-26 13:32:44 -05:00
```
2020-07-01 04:39:46 -05:00
### Styling with theme
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
2021-01-25 05:52:22 -06:00
> Please remember to put `getStyles` function at the end of the file!
2020-07-01 04:39:46 -05:00
```tsx
import React, { FC } from 'react';
import { GrafanaTheme } from '@grafana/data';
import { useStyles } from '@grafana/ui';
2021-04-23 03:06:42 -05:00
import { css } from '@emotion/css';
2020-07-01 04:39:46 -05:00
const Foo: FC< FooProps > = () => {
2021-01-25 05:52:22 -06:00
const styles = useStyles(getStyles);
// Use styles with classNames
2021-04-23 03:06:42 -05:00
return < div className = {styles} > ...< / div > ;
2020-07-01 04:39:46 -05:00
};
2021-01-25 05:52:22 -06:00
const getStyles = (theme: GrafanaTheme) => css`
padding: ${theme.spacing.md};
`;
2020-07-01 04:39:46 -05:00
```
2020-02-24 19:54:28 -06:00
### Styling complex components
2019-09-26 13:32:44 -05:00
2020-02-24 19:54:28 -06: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 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.
2019-10-14 05:29:10 -05:00
2021-01-25 05:52:22 -06:00
Let's say you need to style a component that has a different background depending on the `isActive` property :
2019-09-26 13:32:44 -05:00
```tsx
2020-02-24 19:54:28 -06:00
import React from 'react';
2021-04-23 03:06:42 -05:00
import { css } from '@emotion/css';
2020-02-24 19:54:28 -06:00
import { GrafanaTheme } from '@grafana/data';
import { selectThemeVariant, stylesFactory, useTheme } from '@grafana/ui';
2019-09-26 13:32:44 -05:00
2021-01-25 05:52:22 -06:00
interface ComponentAProps {
2021-04-23 03:06:42 -05:00
isActive: boolean;
2021-01-25 05:52:22 -06:00
}
2019-09-26 13:32:44 -05:00
2021-04-23 03:06:42 -05:00
const ComponentA: React.FC< ComponentAProps > = ({ isActive }) => {
2019-09-26 13:32:44 -05:00
const theme = useTheme();
2021-01-25 05:52:22 -06:00
const styles = getStyles(theme, isActive);
2019-09-26 13:32:44 -05:00
return (
< div className = {styles.wrapper} >
2019-10-14 05:29:10 -05:00
As red as you can get
< i className = {styles.icon} / >
2019-09-26 13:32:44 -05:00
< / div >
);
2020-02-24 19:54:28 -06:00
};
2021-01-25 05:52:22 -06:00
// Mind, that you can pass multiple arguments, theme included
const getStyles = stylesFactory((theme: GrafanaTheme, isActive: boolean) => {
const backgroundColor = isActive ? theme.colors.red : theme.colors.blue;
return {
wrapper: css`
background: ${backgroundColor};
`,
icon: css`
font-size: ${theme.typography.size.sm};
`,
};
});
2019-09-26 13:32:44 -05:00
```
2020-02-24 19:54:28 -06:00
For more information about themes at Grafana please see the [themes guide ](./themes.md ).
2019-09-26 13:32:44 -05:00
2020-02-24 19:54:28 -06:00
### Composing class names
2019-09-26 13:32:44 -05:00
2020-02-24 19:54:28 -06:00
For class composition, use [Emotion's `cx` function ](https://emotion.sh/docs/emotion#cx ).
2019-09-26 13:32:44 -05:00
```tsx
2020-02-24 19:54:28 -06:00
import React from 'react';
2021-04-23 03:06:42 -05:00
import { css, cx } from '@emotion/css';
2019-09-26 13:32:44 -05:00
interface Props {
className?: string;
}
2022-08-24 15:54:34 -05:00
function ComponentA({ className }: Props) {
2019-09-26 13:32:44 -05:00
const finalClassName = cx(
className,
2020-02-24 19:54:28 -06:00
css`
background: red;
`
2019-09-26 13:32:44 -05:00
);
2020-02-24 19:54:28 -06:00
return < div className = {finalClassName} > As red as you can ge< / div > ;
2022-08-24 15:54:34 -05:00
}
2019-09-26 13:32:44 -05:00
```