feat(storybook): improve code (#3786)

This commit is contained in:
Alex Yang 2023-08-16 15:07:55 -05:00 committed by GitHub
parent 64656c3c98
commit 1e5a4a6849
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 63 additions and 128 deletions

View File

@ -34,5 +34,5 @@ jobs:
with:
workingDir: apps/storybook
buildScriptName: build
onlyStoryNames: 'Preview/**'
onlyChanged: true
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}

View File

@ -5,6 +5,7 @@ import { mergeConfig } from 'vite';
import tsconfigPaths from 'vite-tsconfig-paths';
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
import { getRuntimeConfig } from '../../core/.webpack/runtime-config';
import turbosnap from 'vite-plugin-turbosnap';
runCli(
{
@ -33,7 +34,7 @@ export default {
framework: {
name: '@storybook/react-vite',
},
async viteFinal(config, _) {
async viteFinal(config, { configType }) {
return mergeConfig(config, {
assetsInclude: ['**/*.md'],
plugins: [
@ -41,6 +42,9 @@ export default {
tsconfigPaths({
root: fileURLToPath(new URL('../../../', import.meta.url)),
}),
configType === 'PRODUCTION'
? turbosnap({ rootDir: config.root ?? process.cwd() })
: null,
],
define: {
'process.env': {},

View File

@ -4,12 +4,12 @@ import '@affine/component/theme/theme.css';
import '@toeverything/components/style.css';
import { createI18n } from '@affine/i18n';
import { ThemeProvider, useTheme } from 'next-themes';
import type { ComponentType } from 'react';
import { useEffect } from 'react';
import { useDarkMode } from 'storybook-dark-mode';
import { setup } from '@affine/core/bootstrap/setup';
import { AffineContext } from '@affine/component/context';
import { use } from 'foxact/use';
import useSWR from 'swr';
import type { Decorator } from '@storybook/react';
const setupPromise = setup();
@ -24,38 +24,42 @@ export const parameters = {
},
};
const createI18nDecorator = () => {
const i18n = createI18n();
const withI18n = (Story: any, context: any) => {
const locale = context.globals.locale;
useEffect(() => {
i18n.changeLanguage(locale);
}, [locale]);
return <Story {...context} />;
};
return withI18n;
const i18n = createI18n();
const withI18n: Decorator = (Story, context) => {
const locale = context.globals.locale;
useSWR(
locale,
async () => {
await i18n.changeLanguage(locale);
},
{
suspense: true,
}
);
return <Story {...context} />;
};
const Component = () => {
const ThemeChange = () => {
const isDark = useDarkMode();
const theme = useTheme();
useEffect(() => {
theme.setTheme(isDark ? 'dark' : 'light');
}, [isDark]);
if (theme.resolvedTheme === 'dark' && !isDark) {
theme.setTheme('light');
} else if (theme.resolvedTheme === 'light' && isDark) {
theme.setTheme('dark');
}
return null;
};
export const decorators = [
(Story: ComponentType) => {
use(setupPromise);
return (
<ThemeProvider>
<AffineContext>
<Component />
<Story />
</AffineContext>
</ThemeProvider>
);
},
createI18nDecorator(),
];
const withContextDecorator: Decorator = (Story, context) => {
use(setupPromise);
return (
<ThemeProvider>
<AffineContext>
<ThemeChange />
<Story {...context} />
</AffineContext>
</ThemeProvider>
);
};
export const decorators = [withContextDecorator, withI18n];

View File

@ -41,7 +41,8 @@
"chromatic": "^6.22.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"storybook-addon-react-router-v6": "^2.0.4"
"storybook-addon-react-router-v6": "^2.0.4",
"vite-plugin-turbosnap": "^1.0.2"
},
"peerDependencies": {
"@blocksuite/blocks": "*",

View File

@ -1,92 +0,0 @@
/* deepscan-disable USELESS_ARROW_FUNC_BIND */
import { BlockHubWrapper } from '@affine/component/block-hub';
import type { EditorProps } from '@affine/component/block-suite-editor';
import { BlockSuiteEditor } from '@affine/component/block-suite-editor';
import { rootBlockHubAtom } from '@affine/workspace/atom';
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
import type { EditorContainer } from '@blocksuite/editor';
import type { Page } from '@blocksuite/store';
import { createMemoryStorage, Schema, Workspace } from '@blocksuite/store';
import { expect } from '@storybook/jest';
import type { Meta, StoryFn } from '@storybook/react';
import { use } from 'foxact/use';
const schema = new Schema();
schema.register(AffineSchemas).register(__unstableSchemas);
const blockSuiteWorkspace = new Workspace({
id: 'test',
blobStorages: [createMemoryStorage],
schema,
});
async function initPage(page: Page) {
await page.waitForLoaded();
// Add page block and surface block at root level
const pageBlockId = page.addBlock('affine:page', {
title: new page.Text('Hello, world!'),
});
page.addBlock('affine:surface', {}, pageBlockId);
const frameId = page.addBlock('affine:note', {}, pageBlockId);
page.addBlock(
'affine:paragraph',
{
text: new page.Text('This is a paragraph.'),
},
frameId
);
page.resetHistory();
}
const page = blockSuiteWorkspace.createPage('page0');
type BlockSuiteMeta = Meta<typeof BlockSuiteEditor>;
export default {
title: 'BlockSuite/Editor',
component: BlockSuiteEditor,
} satisfies BlockSuiteMeta;
const Template: StoryFn<EditorProps> = (props: Partial<EditorProps>) => {
if (!page.loaded) {
use(initPage(page));
}
return (
<div
style={{
height: '100vh',
width: '100vw',
overflow: 'auto',
}}
>
<BlockSuiteEditor onInit={initPage} page={page} mode="page" {...props} />
<BlockHubWrapper
style={{
position: 'absolute',
right: 12,
bottom: 12,
}}
blockHubAtom={rootBlockHubAtom}
/>
</div>
);
};
export const Empty = Template.bind({});
Empty.play = async ({ canvasElement }) => {
await new Promise<void>(resolve => {
setTimeout(() => resolve(), 500);
});
const editorContainer = canvasElement.querySelector(
'[data-testid="editor-page0"]'
) as HTMLDivElement;
expect(editorContainer).not.toBeNull();
const editor = editorContainer.querySelector(
'editor-container'
) as EditorContainer;
expect(editor).not.toBeNull();
};
Empty.args = {
mode: 'page',
};

View File

@ -24,6 +24,9 @@ const FakeApp = () => {
export default {
title: 'Preview/Core',
parameters: {
chromatic: { disableSnapshot: false },
},
};
export const Index: StoryFn = () => {

View File

@ -1,11 +1,14 @@
import { AFFiNEDatePicker } from '@affine/component/date-picker';
import type { StoryFn } from '@storybook/react';
import type { Meta, StoryFn } from '@storybook/react';
import { useState } from 'react';
export default {
title: 'AFFiNE/AFFiNEDatePicker',
component: AFFiNEDatePicker,
};
parameters: {
chromatic: { disableSnapshot: true },
},
} satisfies Meta;
export const Default: StoryFn = () => {
const [value, setValue] = useState<string>(new Date().toString());

View File

@ -2,11 +2,12 @@
import { toast } from '@affine/component';
import { ImportPage } from '@affine/component/import-page';
import type { StoryFn } from '@storybook/react';
import type { Meta } from '@storybook/react';
export default {
title: 'AFFiNE/ImportPage',
component: ImportPage,
};
} satisfies Meta;
const Template: StoryFn<typeof ImportPage> = args => <ImportPage {...args} />;

View File

@ -13,6 +13,9 @@ import { userEvent } from '@storybook/testing-library';
export default {
title: 'AFFiNE/PageList',
component: PageList,
parameters: {
chromatic: { disableSnapshot: true },
},
};
export const AffineOperationCell: StoryFn<OperationCellProps> = ({

View File

@ -727,6 +727,7 @@ __metadata:
storybook: ^7.3.1
storybook-addon-react-router-v6: ^2.0.4
storybook-dark-mode: ^3.0.1
vite-plugin-turbosnap: ^1.0.2
wait-on: ^7.0.1
peerDependencies:
"@blocksuite/blocks": "*"
@ -32465,6 +32466,13 @@ __metadata:
languageName: node
linkType: hard
"vite-plugin-turbosnap@npm:^1.0.2":
version: 1.0.2
resolution: "vite-plugin-turbosnap@npm:1.0.2"
checksum: c5da204cd9fa0dbf8a5f3c151681057da0f8cec3acbec94bdc04e525d410d85bd87c46b73498ba20c487fe61a68b1486b0f88bc51fec48d7053d1f3597411231
languageName: node
linkType: hard
"vite-tsconfig-paths@npm:^4.2.0":
version: 4.2.0
resolution: "vite-tsconfig-paths@npm:4.2.0"