summaryrefslogtreecommitdiffstats
path: root/.storybook
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-22 17:39:39 +0200
committerArmand Philippot <git@armandphilippot.com>2022-05-22 17:39:39 +0200
commit3ed7f185e82c0cc87c63b75dc8cddfecc5c608ce (patch)
treeb1b314cec900ebb3f671269f6fc9560242e90a0a /.storybook
parent321dae4a47594af83269fa560b375965d7f35763 (diff)
chore(storybook): use custom themes and add dark mode support
Diffstat (limited to '.storybook')
-rw-r--r--.storybook/main.js1
-rw-r--r--.storybook/manager.js6
-rw-r--r--.storybook/overrides/docs-container.js36
-rw-r--r--.storybook/preview.js40
-rw-r--r--.storybook/themes/common.js8
-rw-r--r--.storybook/themes/dark.js37
-rw-r--r--.storybook/themes/light.js36
7 files changed, 162 insertions, 2 deletions
diff --git a/.storybook/main.js b/.storybook/main.js
index bedbd0e..477b09e 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -11,6 +11,7 @@ const storybookConfig = {
'@storybook/addon-essentials',
'@storybook/addon-interactions',
'storybook-addon-next',
+ 'storybook-dark-mode',
],
framework: '@storybook/react',
core: {
diff --git a/.storybook/manager.js b/.storybook/manager.js
new file mode 100644
index 0000000..945c246
--- /dev/null
+++ b/.storybook/manager.js
@@ -0,0 +1,6 @@
+import { addons } from '@storybook/addons';
+import light from './themes/light';
+
+addons.setConfig({
+ theme: light,
+});
diff --git a/.storybook/overrides/docs-container.js b/.storybook/overrides/docs-container.js
new file mode 100644
index 0000000..f539986
--- /dev/null
+++ b/.storybook/overrides/docs-container.js
@@ -0,0 +1,36 @@
+import { DocsContainer as BaseContainer } from '@storybook/addon-docs/blocks';
+import { useDarkMode } from 'storybook-dark-mode';
+import dark from '../themes/dark';
+import light from '../themes/light';
+
+/**
+ * Custom Docs Container to support dark theme.
+ *
+ * @see https://github.com/hipstersmoothie/storybook-dark-mode/issues/127#issuecomment-1070524402
+ */
+export const DocsContainer = ({ children, context }) => {
+ const isDark = useDarkMode();
+
+ return (
+ <BaseContainer
+ context={{
+ ...context,
+ storyById: (id) => {
+ const storyContext = context.storyById(id);
+ return {
+ ...storyContext,
+ parameters: {
+ ...storyContext?.parameters,
+ docs: {
+ ...storyContext?.parameters?.docs,
+ theme: isDark ? dark : light,
+ },
+ },
+ };
+ },
+ }}
+ >
+ {children}
+ </BaseContainer>
+ );
+};
diff --git a/.storybook/preview.js b/.storybook/preview.js
index e30927b..9df7514 100644
--- a/.storybook/preview.js
+++ b/.storybook/preview.js
@@ -1,6 +1,12 @@
-import '@styles/globals.scss';
import * as NextImage from 'next/image';
+import { ThemeProvider, useTheme } from 'next-themes';
+import { useEffect } from 'react';
import { IntlProvider } from 'react-intl';
+import { useDarkMode } from 'storybook-dark-mode';
+import { DocsContainer } from './overrides/docs-container';
+import dark from './themes/dark';
+import light from './themes/light';
+import '@styles/globals.scss';
const OriginalNextImage = NextImage.default;
@@ -27,12 +33,42 @@ export const parameters = {
date: /Date$/,
},
},
+ darkMode: {
+ // Override the default dark theme
+ dark: { ...dark },
+ // Override the default light theme
+ light: { ...light },
+ stylePreview: true,
+ },
+ docs: {
+ container: DocsContainer,
+ },
+};
+
+// Create a component that listens for theme change.
+export const ThemeWrapper = (props) => {
+ const { setTheme } = useTheme();
+ const theme = useDarkMode() ? 'dark' : 'light';
+
+ useEffect(() => {
+ setTheme(theme);
+ }, [theme, setTheme]);
+
+ return <>{props.children}</>;
};
export const decorators = [
(Story) => (
<IntlProvider locale="en">
- <Story />
+ <ThemeProvider
+ defaultTheme="system"
+ enableColorScheme={true}
+ enableSystem={true}
+ >
+ <ThemeWrapper>
+ <Story />
+ </ThemeWrapper>
+ </ThemeProvider>
</IntlProvider>
),
];
diff --git a/.storybook/themes/common.js b/.storybook/themes/common.js
new file mode 100644
index 0000000..17619c2
--- /dev/null
+++ b/.storybook/themes/common.js
@@ -0,0 +1,8 @@
+export const brand = {
+ title: 'Design system',
+};
+
+export const fontFamilies = {
+ mono: '"Cousine", "Liberation Mono", "DejaVu Sans Mono", "Courier New", monospace',
+ primary: '"Inter", "Liberation Sans", Arial, sans-serif',
+};
diff --git a/.storybook/themes/dark.js b/.storybook/themes/dark.js
new file mode 100644
index 0000000..e23703b
--- /dev/null
+++ b/.storybook/themes/dark.js
@@ -0,0 +1,37 @@
+import { create } from '@storybook/theming';
+import { brand, fontFamilies } from './common';
+
+const colors = {
+ black: 'hsl(208, 25%, 11%)',
+ blackBright: 'hsl(208, 21%, 15%)',
+ blue: 'hsl(200, 50%, 68%)',
+ blueBright: 'hsl(200, 55%, 70%)',
+ grey: 'hsl(208, 10%, 70%)',
+ greyDark: 'hsl(208, 20%, 25%)',
+ greyDarker: 'hsl(208, 18%, 20%)',
+ white: 'hsl(208, 25%, 92%)',
+ whiteDark: 'hsl(206, 20%, 93%)',
+};
+
+export default create({
+ base: 'dark',
+ brandTitle: brand.title,
+ colorPrimary: colors.blue,
+ colorSecondary: colors.blueBright,
+ appBg: colors.black,
+ appContentBg: colors.black,
+ appBorderColor: colors.greyDark,
+ appBorderRadius: 3,
+ fontBase: fontFamilies.primary,
+ fontCode: fontFamilies.mono,
+ textColor: colors.white,
+ textInverseColor: colors.black,
+ textMutedColor: colors.grey,
+ barTextColor: colors.white,
+ barSelectedColor: colors.blueBright,
+ barBg: colors.blackBright,
+ inputBg: colors.greyDarker,
+ inputBorder: colors.greyDark,
+ inputTextColor: colors.white,
+ inputBorderRadius: 0,
+});
diff --git a/.storybook/themes/light.js b/.storybook/themes/light.js
new file mode 100644
index 0000000..d445272
--- /dev/null
+++ b/.storybook/themes/light.js
@@ -0,0 +1,36 @@
+import { create } from '@storybook/theming';
+import { brand, fontFamilies } from './common';
+
+const colors = {
+ black: 'hsl(207, 47%, 11%)',
+ blue: 'hsl(206, 75%, 31%)',
+ blueBright: 'hsl(206, 77%, 36%)',
+ grey: 'hsl(206, 15%, 80%)',
+ greyBright: 'hsl(206, 20%, 86%)',
+ greyDark: 'hsl(206, 30%, 30%)',
+ white: 'hsl(206, 15%, 97%)',
+ whiteDark: 'hsl(206, 20%, 93%)',
+};
+
+export default create({
+ base: 'light',
+ brandTitle: brand.title,
+ colorPrimary: colors.blue,
+ colorSecondary: colors.blueBright,
+ appBg: colors.white,
+ appContentBg: colors.white,
+ appBorderColor: colors.grey,
+ appBorderRadius: 3,
+ fontBase: fontFamilies.primary,
+ fontCode: fontFamilies.mono,
+ textColor: colors.black,
+ textInverseColor: colors.white,
+ textMutedColor: colors.greyDark,
+ barTextColor: colors.black,
+ barSelectedColor: colors.blueBright,
+ barBg: colors.whiteDark,
+ inputBg: colors.greyBright,
+ inputBorder: colors.grey,
+ inputTextColor: colors.black,
+ inputBorderRadius: 0,
+});