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"