diff --git a/contribute/style-guides/frontend.md b/contribute/style-guides/frontend.md
index c4691401ad7..dc0fc6e4427 100644
--- a/contribute/style-guides/frontend.md
+++ b/contribute/style-guides/frontend.md
@@ -166,17 +166,22 @@ interface ModalState {
##### Emotion class names
```typescript
-const getStyles = = () => ({
+const getStyles = (theme: GrafanaTheme2) => ({
// bad
ElementWrapper: css`...`,
// bad
- ["element-wrapper"]: css`...`,
+ ['element-wrapper']: css`...`,
// good
- elementWrapper: css`...`,
+ elementWrapper: css({
+ padding: theme.spacing(1, 2),
+ background: theme.colors.background.secondary,
+ }),
});
```
+Use hook useStyles2(getStyles) to memoize the styles generation and try to avoid passing props to the the getStyles function and instead compose classes using emotion cx function.
+
#### Use `ALL_CAPS` for constants.
```typescript
diff --git a/contribute/style-guides/styling.md b/contribute/style-guides/styling.md
index 550f5d3b69a..e6c9ab63a57 100644
--- a/contribute/style-guides/styling.md
+++ b/contribute/style-guides/styling.md
@@ -4,26 +4,9 @@
## 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 = () => (
-
- As red as you can get
-
-);
-```
-
-### Styling with theme
+### Basic styling
To access the theme in your styles, use the `useStyles` hook. It provides basic memoization and access to the theme object.
@@ -31,33 +14,35 @@ To access the theme in your styles, use the `useStyles` hook. It provides basic
```tsx
import React, { FC } from 'react';
-import { GrafanaTheme } from '@grafana/data';
-import { useStyles } from '@grafana/ui';
+import { GrafanaTheme2 } from '@grafana/data';
+import { useStyles2 } from '@grafana/ui';
import { css } from '@emotion/css';
const Foo: FC = () => {
- const styles = useStyles(getStyles);
+ const styles = useStyles2(getStyles);
// Use styles with classNames
return ...
;
};
-const getStyles = (theme: GrafanaTheme) => css`
- padding: ${theme.spacing.md};
-`;
+const getStyles = (theme: GrafanaTheme2) =>
+ css({
+ padding: theme.spacing(1, 2), // will result in 8px 16px padding
+ });
```
### 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.
+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
+can have your getStyles function return an object with many class names and use [Emotion's `cx` function](https://emotion.sh/docs/emotion#cx) to compose them.
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';
+import { css, cx } from '@emotion/css';
+import { GrafanaTheme2 } from '@grafana/data';
+import { useStyles2 } from '@grafana/ui';
interface ComponentAProps {
isActive: boolean;
@@ -65,10 +50,10 @@ interface ComponentAProps {
const ComponentA: React.FC = ({ isActive }) => {
const theme = useTheme();
- const styles = getStyles(theme, isActive);
+ const styles = useStyles2(theme);
return (
-
+
As red as you can get
@@ -76,42 +61,20 @@ const ComponentA: React.FC
= ({ isActive }) => {
};
// 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;
-
+const getStyles = (theme: GrafanaTheme2) => {
return {
- wrapper: css`
- background: ${backgroundColor};
- `,
- icon: css`
- font-size: ${theme.typography.size.sm};
- `,
+ wrapper: css({
+ background: theme.colors.background.secondary;
+ }),
+ active: css({
+ background: theme.colors.primary.main,
+ text: theme.colors.primary.contrastText,
+ },
+ icon: css({
+ fontSize: theme.typography.bodySmall.fontSize;
+ })
};
-});
+};
```
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;
-}
-
-function ComponentA({ className }: Props) {
- const finalClassName = cx(
- className,
- css`
- background: red;
- `
- );
-
- return As red as you can ge
;
-}
-```