mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* refactor(loginpage): migrate custom button styles to use Button component * refactor(certificationkey): prefer grafana-ui form elements over html elements and classnames * refactor(axisselector): prefer grafana-ui Button component over html button element * refactor(input-datasource): replace use of btn class with grafana-ui components * chore(grafana-ui): delete deprecated ToggleButtonGroup component * refactor: replace btn and cta-form__close class usage with IconButton * chore(closebutton): post master merge use v2 theme * refactor(permissionlist): remove usage of .btn classname * Wip * docs(styling): update styling and theme docs import paths * refactor(alerting): remote btn classnames from TestRuleResult * refactor(apikeys): prefer grafana-ui Button components over btn classNames * refactor(folders): prefer grafana-ui Button components over btn classNames * refactor(teams): prefer grafana-ui Button components over btn classNames * refactor(datasources): prefer grafana-ui Button components over btn classNames * refactor: prefer grafana-ui Button components over btn classNames * Minor style tweak to service buttons * test: update snapshots related to button changes * chore(input-datasource): remove unused import declaration * refactor(loginservicebuttons): rename theme.palette to theme.colors Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
118 lines
3.0 KiB
Markdown
118 lines
3.0 KiB
Markdown
# 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.
|
|
|
|
## Usage
|
|
|
|
### Basic styling
|
|
|
|
For styling components, use [Emotion's `css` function](https://emotion.sh/docs/emotion#css).
|
|
|
|
```tsx
|
|
import React from 'react';
|
|
import { css } from '@emotion/css';
|
|
|
|
const ComponentA = () => (
|
|
<div
|
|
className={css`
|
|
background: red;
|
|
`}
|
|
>
|
|
As red as you can get
|
|
</div>
|
|
);
|
|
```
|
|
|
|
### Styling with theme
|
|
|
|
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
|
|
|
|
> Please remember to put `getStyles` function at the end of the file!
|
|
|
|
```tsx
|
|
import React, { FC } from 'react';
|
|
import { GrafanaTheme } from '@grafana/data';
|
|
import { useStyles } from '@grafana/ui';
|
|
import { css } from '@emotion/css';
|
|
|
|
const Foo: FC<FooProps> = () => {
|
|
const styles = useStyles(getStyles);
|
|
|
|
// Use styles with classNames
|
|
return <div className={styles}>...</div>;
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme) => css`
|
|
padding: ${theme.spacing.md};
|
|
`;
|
|
```
|
|
|
|
### 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.
|
|
|
|
Let's say you need to style a component that has a different background depending on the `isActive` property :
|
|
|
|
```tsx
|
|
import React from 'react';
|
|
import { css } from '@emotion/css';
|
|
import { GrafanaTheme } from '@grafana/data';
|
|
import { selectThemeVariant, stylesFactory, useTheme } from '@grafana/ui';
|
|
|
|
interface ComponentAProps {
|
|
isActive: boolean;
|
|
}
|
|
|
|
const ComponentA: React.FC<ComponentAProps> = ({ isActive }) => {
|
|
const theme = useTheme();
|
|
const styles = getStyles(theme, isActive);
|
|
|
|
return (
|
|
<div className={styles.wrapper}>
|
|
As red as you can get
|
|
<i className={styles.icon} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// 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};
|
|
`,
|
|
};
|
|
});
|
|
```
|
|
|
|
For more information about themes at Grafana please see the [themes guide](./themes.md).
|
|
|
|
### Composing class names
|
|
|
|
For class composition, use [Emotion's `cx` function](https://emotion.sh/docs/emotion#cx).
|
|
|
|
```tsx
|
|
import React from 'react';
|
|
import { css, cx } from '@emotion/css';
|
|
|
|
interface Props {
|
|
className?: string;
|
|
}
|
|
|
|
const ComponentA: React.FC<Props> = ({ className }) => {
|
|
const finalClassName = cx(
|
|
className,
|
|
css`
|
|
background: red;
|
|
`
|
|
);
|
|
|
|
return <div className={finalClassName}>As red as you can ge</div>;
|
|
};
|
|
```
|