From bd27be1351c26fe798b214dfb05e70d9205f1f58 Mon Sep 17 00:00:00 2001 From: Tobias Skarhed <1438972+tskarhed@users.noreply.github.com> Date: Wed, 1 Jul 2020 11:39:46 +0200 Subject: [PATCH] Docs: Update styling docs for useStyles (#25944) --- contribute/style-guides/styling.md | 26 +++++++-- contribute/style-guides/themes.md | 92 +++++++++++++----------------- 2 files changed, 63 insertions(+), 55 deletions(-) diff --git a/contribute/style-guides/styling.md b/contribute/style-guides/styling.md index fd569459eee..4da5bbebbfc 100644 --- a/contribute/style-guides/styling.md +++ b/contribute/style-guides/styling.md @@ -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 = () => { + 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` diff --git a/contribute/style-guides/themes.md b/contribute/style-guides/themes.md index 607565fbf55..39a9a064d7f 100644 --- a/contribute/style-guides/themes.md +++ b/contribute/style-guides/themes.md @@ -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 = () => { + 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 = () => { + 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'; {theme => }; ``` -or - -```tsx -import React, { useContext } from 'react'; -import { ThemeContext } from '@grafana/ui'; - -const Foo: React.FunctionComponent = () => { - 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() 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 -}); -``` - -#### 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.