diff --git a/.gitignore b/.gitignore index 4e08b342d10..40ba75b1092 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ awsconfig /public/views/error.html /emails/dist /reports +.yarnrc +.yarn/ # Enterprise emails /emails/templates/enterprise_* diff --git a/packages/grafana-ui/.storybook/main.ts b/packages/grafana-ui/.storybook/main.ts index c36e7e70da6..6b9ce060a35 100644 --- a/packages/grafana-ui/.storybook/main.ts +++ b/packages/grafana-ui/.storybook/main.ts @@ -1,4 +1,9 @@ module.exports = { stories: ['../src/**/*.story.{js,jsx,ts,tsx,mdx}'], - addons: ['@storybook/addon-knobs', '@storybook/addon-actions', '@storybook/addon-docs'], + addons: [ + '@storybook/addon-knobs', + '@storybook/addon-actions', + '@storybook/addon-docs', + 'storybook-dark-mode/register', + ], }; diff --git a/packages/grafana-ui/.storybook/manager-head.html b/packages/grafana-ui/.storybook/manager-head.html new file mode 100644 index 00000000000..469d19e5541 --- /dev/null +++ b/packages/grafana-ui/.storybook/manager-head.html @@ -0,0 +1 @@ + diff --git a/packages/grafana-ui/.storybook/preview.ts b/packages/grafana-ui/.storybook/preview.ts index a14d1b11e38..4d0aaca0925 100644 --- a/packages/grafana-ui/.storybook/preview.ts +++ b/packages/grafana-ui/.storybook/preview.ts @@ -14,6 +14,7 @@ import { withPaddedStory } from '../src/utils/storybook/withPaddedStory'; import lightTheme from '../../../public/sass/grafana.light.scss'; // @ts-ignore import darkTheme from '../../../public/sass/grafana.dark.scss'; +import { GrafanaLight, GrafanaDark } from './storybookTheme'; import { configure, addDecorator, addParameters } from '@storybook/react'; import { withKnobs } from '@storybook/addon-knobs'; @@ -26,13 +27,16 @@ const handleThemeChange = (theme: any) => { lightTheme.use(); } }; - addDecorator(withTheme(handleThemeChange)); addDecorator(withKnobs); addDecorator(withPaddedStory); addParameters({ info: {}, + darkMode: { + dark: GrafanaDark, + light: GrafanaLight, + }, options: { showPanel: true, showRoots: true, diff --git a/packages/grafana-ui/.storybook/static/fav32.png b/packages/grafana-ui/.storybook/static/fav32.png new file mode 100644 index 00000000000..6f5f809d9cb Binary files /dev/null and b/packages/grafana-ui/.storybook/static/fav32.png differ diff --git a/packages/grafana-ui/.storybook/static/grafana_icon.svg b/packages/grafana-ui/.storybook/static/grafana_icon.svg new file mode 100644 index 00000000000..e91f3abdb41 --- /dev/null +++ b/packages/grafana-ui/.storybook/static/grafana_icon.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + diff --git a/packages/grafana-ui/.storybook/storybookTheme.ts b/packages/grafana-ui/.storybook/storybookTheme.ts new file mode 100644 index 00000000000..9490fe2c6db --- /dev/null +++ b/packages/grafana-ui/.storybook/storybookTheme.ts @@ -0,0 +1,49 @@ +//@ts-ignore +import { create } from '@storybook/theming/create'; +import lightTheme from '../src/themes/light'; +import darkTheme from '../src/themes/dark'; +import ThemeCommons from '../src/themes/default'; +import { GrafanaTheme } from '@grafana/data'; + +const createTheme = (theme: GrafanaTheme) => { + return create({ + base: theme.name.includes('Light') ? 'light' : 'dark', + + colorPrimary: theme.colors.brandPrimary, + colorSecondary: theme.colors.brandPrimary, + + // UI + appBg: theme.colors.bodyBg, + appContentBg: theme.colors.bodyBg, + appBorderColor: theme.colors.pageHeaderBorder, + appBorderRadius: 4, + + // Typography + fontBase: ThemeCommons.typography.fontFamily.sansSerif, + fontCode: ThemeCommons.typography.fontFamily.monospace, + + // Text colors + textColor: theme.colors.text, + textInverseColor: 'rgba(255,255,255,0.9)', + + // Toolbar default and active colors + barTextColor: theme.colors.formInputBorderActive, + barSelectedColor: theme.colors.brandPrimary, + barBg: theme.colors.bodyBg, + + // Form colors + inputBg: theme.colors.formInputBg, + inputBorder: theme.colors.formInputBorder, + inputTextColor: theme.colors.formInputText, + inputBorderRadius: 4, + + brandTitle: 'Grafana UI', + brandUrl: '/', + brandImage: '/grafana_icon.svg', + }); +}; + +const GrafanaLight = createTheme(lightTheme); +const GrafanaDark = createTheme(darkTheme); + +export { GrafanaLight, GrafanaDark }; diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 92ecc1bc585..eb3139816f5 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -18,8 +18,8 @@ "scripts": { "lint": "eslint .storybook/ src/ --ext=.js,.ts,.tsx", "typecheck": "tsc --noEmit", - "storybook": "start-storybook -p 9001 -c .storybook", - "storybook:build": "build-storybook -o ./dist/storybook -c .storybook", + "storybook": "start-storybook -p 9001 -c .storybook -s .storybook/static", + "storybook:build": "build-storybook -o ./dist/storybook -c .storybook -s .storybook/static", "clean": "rimraf ./dist ./compiled", "bundle": "rollup -c rollup.config.ts", "build": "grafana-toolkit package:build --scope=ui" @@ -92,6 +92,7 @@ "rollup-plugin-terser": "4.0.4", "rollup-plugin-typescript2": "0.19.3", "rollup-plugin-visualizer": "0.9.2", + "storybook-dark-mode": "0.3.0", "ts-loader": "6.2.1", "typescript": "3.7.2" }, diff --git a/packages/grafana-ui/src/utils/storybook/withTheme.tsx b/packages/grafana-ui/src/utils/storybook/withTheme.tsx index e004df46437..341bf70be6e 100644 --- a/packages/grafana-ui/src/utils/storybook/withTheme.tsx +++ b/packages/grafana-ui/src/utils/storybook/withTheme.tsx @@ -1,28 +1,20 @@ import React from 'react'; import { ThemeContext } from '../../themes/ThemeContext'; -import { select } from '@storybook/addon-knobs'; import { getTheme } from '../../themes/index'; import { GrafanaThemeType } from '@grafana/data'; import { RenderFunction } from '../../types'; +import { useDarkMode } from 'storybook-dark-mode'; type SassThemeChangeHandler = (theme: GrafanaThemeType) => void; const ThemableStory: React.FunctionComponent<{ handleSassThemeChange: SassThemeChangeHandler }> = ({ children, handleSassThemeChange, }) => { - const themeKnob = select( - 'Theme', - { - Light: GrafanaThemeType.Light, - Dark: GrafanaThemeType.Dark, - }, - GrafanaThemeType.Dark, - 'Theme' - ); + const theme = useDarkMode() ? GrafanaThemeType.Dark : GrafanaThemeType.Light; - handleSassThemeChange(themeKnob); + handleSassThemeChange(theme); - return {children}; + return {children}; }; // Temporary solution. When we update to Storybook V5 we will be able to pass data from decorator to story diff --git a/yarn.lock b/yarn.lock index ea54e6deb4f..612a28543ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11381,7 +11381,7 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.0.0, fast-deep-equal@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== @@ -22783,6 +22783,14 @@ storybook-chromatic@^2.2.2: tree-kill "^1.1.0" uuid "^3.3.2" +storybook-dark-mode@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/storybook-dark-mode/-/storybook-dark-mode-0.3.0.tgz#9a6ce2c55e68b2dfbd3e9af73f8c92cfcb87f23a" + integrity sha512-95uIZqncsCRdakqgO0roWn5orJixtTBIAtkDl8rrIsaEm4N2U68xodCe3VqQmCf646vmculel1sba7qgavN+Xw== + dependencies: + fast-deep-equal "^3.0.0" + memoizerific "^1.11.3" + stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"