mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-12-23 02:21:49 +03:00
feat(storybook): improve code (#3786)
This commit is contained in:
parent
64656c3c98
commit
1e5a4a6849
2
.github/workflows/publish-storybook.yml
vendored
2
.github/workflows/publish-storybook.yml
vendored
@ -34,5 +34,5 @@ jobs:
|
||||
with:
|
||||
workingDir: apps/storybook
|
||||
buildScriptName: build
|
||||
onlyStoryNames: 'Preview/**'
|
||||
onlyChanged: true
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
|
@ -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': {},
|
||||
|
@ -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];
|
||||
|
@ -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": "*",
|
||||
|
@ -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',
|
||||
};
|
@ -24,6 +24,9 @@ const FakeApp = () => {
|
||||
|
||||
export default {
|
||||
title: 'Preview/Core',
|
||||
parameters: {
|
||||
chromatic: { disableSnapshot: false },
|
||||
},
|
||||
};
|
||||
|
||||
export const Index: StoryFn = () => {
|
||||
|
@ -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());
|
||||
|
@ -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} />;
|
||||
|
||||
|
@ -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> = ({
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user