feat(component): add storybook (#5079)
This commit is contained in:
54
packages/frontend/component/.storybook/main.ts
Normal file
54
packages/frontend/component/.storybook/main.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { StorybookConfig } from '@storybook/react-vite';
|
||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { mergeConfig } from 'vite';
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
import { getRuntimeConfig } from '../../core/.webpack/runtime-config';
|
||||
|
||||
export default {
|
||||
stories: ['../src/ui/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
||||
addons: [
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
'@storybook/addon-mdx-gfm',
|
||||
'storybook-dark-mode',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/react-vite',
|
||||
options: {},
|
||||
},
|
||||
features: {
|
||||
storyStoreV7: true,
|
||||
},
|
||||
docs: {
|
||||
autodocs: true,
|
||||
},
|
||||
async viteFinal(config, _options) {
|
||||
return mergeConfig(config, {
|
||||
plugins: [
|
||||
vanillaExtractPlugin(),
|
||||
tsconfigPaths({
|
||||
root: fileURLToPath(new URL('../../../../', import.meta.url)),
|
||||
ignoreConfigErrors: true,
|
||||
}),
|
||||
],
|
||||
define: {
|
||||
'process.on': '(() => void 0)',
|
||||
'process.env': {},
|
||||
'process.env.COVERAGE': JSON.stringify(!!process.env.COVERAGE),
|
||||
'process.env.SHOULD_REPORT_TRACE': `${Boolean(
|
||||
process.env.SHOULD_REPORT_TRACE === 'true'
|
||||
)}`,
|
||||
'process.env.TRACE_REPORT_ENDPOINT': `"${process.env.TRACE_REPORT_ENDPOINT}"`,
|
||||
'process.env.CAPTCHA_SITE_KEY': `"${process.env.CAPTCHA_SITE_KEY}"`,
|
||||
runtimeConfig: getRuntimeConfig({
|
||||
distribution: 'browser',
|
||||
mode: 'development',
|
||||
channel: 'canary',
|
||||
coverage: false,
|
||||
}),
|
||||
},
|
||||
});
|
||||
},
|
||||
} satisfies StorybookConfig;
|
||||
27
packages/frontend/component/.storybook/preview.css.ts
Normal file
27
packages/frontend/component/.storybook/preview.css.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { darkCssVariables, lightCssVariables } from '@toeverything/theme';
|
||||
import { globalStyle } from '@vanilla-extract/css';
|
||||
|
||||
globalStyle('*', {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
});
|
||||
|
||||
globalStyle('body', {
|
||||
color: 'var(--affine-text-primary-color)',
|
||||
fontFamily: 'var(--affine-font-family)',
|
||||
fontSize: 'var(--affine-font-base)',
|
||||
lineHeight: 'var(--affine-font-height)',
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
});
|
||||
|
||||
globalStyle('html', {
|
||||
vars: lightCssVariables,
|
||||
});
|
||||
|
||||
globalStyle('html[data-theme="dark"]', {
|
||||
vars: darkCssVariables,
|
||||
});
|
||||
|
||||
globalStyle('.docs-story', {
|
||||
backgroundColor: 'var(--affine-background-primary-color)',
|
||||
});
|
||||
3
packages/frontend/component/.storybook/preview.html
Normal file
3
packages/frontend/component/.storybook/preview.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<script>
|
||||
window.global = window;
|
||||
</script>
|
||||
60
packages/frontend/component/.storybook/preview.tsx
Normal file
60
packages/frontend/component/.storybook/preview.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import './preview.css';
|
||||
import { ThemeProvider, useTheme } from 'next-themes';
|
||||
import type { ComponentType } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useDarkMode } from 'storybook-dark-mode';
|
||||
|
||||
import type { Preview } from '@storybook/react';
|
||||
import React from 'react';
|
||||
|
||||
export const parameters: Preview = {
|
||||
argTypes: {
|
||||
param: {
|
||||
table: { category: 'Group' },
|
||||
},
|
||||
},
|
||||
globalTypes: {
|
||||
theme: {
|
||||
description: 'Global theme for components',
|
||||
defaultValue: 'light',
|
||||
toolbar: {
|
||||
title: 'Theme',
|
||||
icon: 'circlehollow',
|
||||
items: ['light', 'dark'],
|
||||
dynamicTitle: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const ThemeChange = () => {
|
||||
const isDark = useDarkMode();
|
||||
const theme = useTheme();
|
||||
if (theme.resolvedTheme === 'dark' && !isDark) {
|
||||
theme.setTheme('light');
|
||||
} else if (theme.resolvedTheme === 'light' && isDark) {
|
||||
theme.setTheme('dark');
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const Component = () => {
|
||||
const isDark = useDarkMode();
|
||||
const theme = useTheme();
|
||||
useEffect(() => {
|
||||
theme.setTheme(isDark ? 'dark' : 'light');
|
||||
}, [isDark]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export const decorators = [
|
||||
(Story: ComponentType, context) => {
|
||||
return (
|
||||
<ThemeProvider themes={['dark', 'light']} enableSystem={true}>
|
||||
<ThemeChange />
|
||||
<Component />
|
||||
<Story {...context} />
|
||||
</ThemeProvider>
|
||||
);
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user