mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-22 19:53:48 +08:00
fix(storybook): remove storybook testing (#6595)
remove tests/storybook @affine/components storybook still exists
This commit is contained in:
@@ -54,7 +54,6 @@ const allPackages = [
|
|||||||
'packages/common/theme',
|
'packages/common/theme',
|
||||||
'packages/common/y-indexeddb',
|
'packages/common/y-indexeddb',
|
||||||
'tools/cli',
|
'tools/cli',
|
||||||
'tests/storybook',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
name: Publish Storybook
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max-old-space-size=4096
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- canary
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- canary
|
|
||||||
paths-ignore:
|
|
||||||
- README.md
|
|
||||||
- .github/**
|
|
||||||
- packages/backend/server
|
|
||||||
- packages/frontend/electron
|
|
||||||
- '!.github/workflows/publish-storybook.yml'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-storybook:
|
|
||||||
name: Publish Storybook
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
|
||||||
# This is required to fetch all commits for chromatic
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: ./.github/actions/setup-node
|
|
||||||
with:
|
|
||||||
electron-install: false
|
|
||||||
- uses: chromaui/action-next@v1
|
|
||||||
with:
|
|
||||||
workingDir: tests/storybook
|
|
||||||
buildScriptName: build
|
|
||||||
exitOnceUploaded: true
|
|
||||||
onlyChanged: false
|
|
||||||
diagnostics: true
|
|
||||||
env:
|
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
|
||||||
NODE_OPTIONS: ${{ env.NODE_OPTIONS }}
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: chromatic-build-artifacts-${{ github.run_id }}
|
|
||||||
path: |
|
|
||||||
chromatic-diagnostics.json
|
|
||||||
**/build-storybook.log
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
name: Publish UI Storybook
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max-old-space-size=4096
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- canary
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- canary
|
|
||||||
paths-ignore:
|
|
||||||
- README.md
|
|
||||||
- .github/**
|
|
||||||
- packages/backend/server
|
|
||||||
- packages/frontend/electron
|
|
||||||
- '!.github/workflows/publish-storybook.yml'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
publish-ui-storybook:
|
|
||||||
name: Publish UI Storybook
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
|
||||||
# This is required to fetch all commits for chromatic
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: ./.github/actions/setup-node
|
|
||||||
with:
|
|
||||||
electron-install: false
|
|
||||||
- uses: chromaui/action-next@v1
|
|
||||||
with:
|
|
||||||
workingDir: packages/frontend/component
|
|
||||||
buildScriptName: build:storybook
|
|
||||||
exitOnceUploaded: true
|
|
||||||
onlyChanged: false
|
|
||||||
diagnostics: true
|
|
||||||
env:
|
|
||||||
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_UI_PROJECT_TOKEN }}
|
|
||||||
NODE_OPTIONS: ${{ env.NODE_OPTIONS }}
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
if: always()
|
|
||||||
with:
|
|
||||||
name: chromatic-build-artifacts-${{ github.run_id }}
|
|
||||||
path: |
|
|
||||||
chromatic-diagnostics.json
|
|
||||||
**/build-storybook.log
|
|
||||||
@@ -112,7 +112,7 @@ If you have questions, you are welcome to contact us. One of the best places to
|
|||||||
|
|
||||||
| Name | | |
|
| Name | | |
|
||||||
| -------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| -------------------------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| [@affine/component](packages/frontend/component) | AFFiNE Component Resources | [](https://affine-storybook.vercel.app/) |
|
| [@affine/component](packages/frontend/component) | AFFiNE Component Resources |  |
|
||||||
| [@toeverything/y-indexeddb](packages/common/y-indexeddb) | IndexedDB database adapter for Yjs | [](https://www.npmjs.com/package/@toeverything/y-indexeddb) |
|
| [@toeverything/y-indexeddb](packages/common/y-indexeddb) | IndexedDB database adapter for Yjs | [](https://www.npmjs.com/package/@toeverything/y-indexeddb) |
|
||||||
| [@toeverything/theme](packages/common/theme) | AFFiNE theme | [](https://www.npmjs.com/package/@toeverything/theme) |
|
| [@toeverything/theme](packages/common/theme) | AFFiNE theme | [](https://www.npmjs.com/package/@toeverything/theme) |
|
||||||
|
|
||||||
|
|||||||
@@ -54,12 +54,6 @@ yarn dev
|
|||||||
|
|
||||||
See [building desktop client app](../building-desktop-client-app.md).
|
See [building desktop client app](../building-desktop-client-app.md).
|
||||||
|
|
||||||
### `@affine/storybook`
|
|
||||||
|
|
||||||
```shell
|
|
||||||
yarn workspace @affine/storybook storybook
|
|
||||||
```
|
|
||||||
|
|
||||||
## What's next?
|
## What's next?
|
||||||
|
|
||||||
- [Behind the code](./behind-the-code.md)
|
- [Behind the code](./behind-the-code.md)
|
||||||
|
|||||||
@@ -22,9 +22,7 @@
|
|||||||
"build": "yarn nx build @affine/web",
|
"build": "yarn nx build @affine/web",
|
||||||
"build:electron": "yarn nx build @affine/electron",
|
"build:electron": "yarn nx build @affine/electron",
|
||||||
"build:storage": "yarn nx run-many -t build -p @affine/storage",
|
"build:storage": "yarn nx run-many -t build -p @affine/storage",
|
||||||
"build:storybook": "yarn nx build @affine/storybook",
|
|
||||||
"start:web-static": "yarn workspace @affine/web static-server",
|
"start:web-static": "yarn workspace @affine/web static-server",
|
||||||
"start:storybook": "yarn exec serve tests/storybook/storybook-static -l 6006",
|
|
||||||
"serve:test-static": "yarn exec serve tests/fixtures --cors -p 8081",
|
"serve:test-static": "yarn exec serve tests/fixtures --cors -p 8081",
|
||||||
"lint:eslint": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" eslint . --ext .js,mjs,.ts,.tsx --cache",
|
"lint:eslint": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" eslint . --ext .js,mjs,.ts,.tsx --cache",
|
||||||
"lint:eslint:fix": "yarn lint:eslint --fix",
|
"lint:eslint:fix": "yarn lint:eslint --fix",
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
import { runCli } from '@magic-works/i18n-codegen';
|
|
||||||
import type { StorybookConfig } from '@storybook/react-vite';
|
|
||||||
import { fileURLToPath } from 'node:url';
|
|
||||||
import { mergeConfig, type InlineConfig } from 'vite';
|
|
||||||
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
|
|
||||||
import { getRuntimeConfig } from '@affine/cli/src/webpack/runtime-config';
|
|
||||||
|
|
||||||
runCli(
|
|
||||||
{
|
|
||||||
config: fileURLToPath(
|
|
||||||
new URL('../../../.i18n-codegen.json', import.meta.url)
|
|
||||||
),
|
|
||||||
watch: false,
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
console.error(error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export default {
|
|
||||||
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
|
|
||||||
staticDirs: ['../../../packages/frontend/core/public'],
|
|
||||||
addons: [
|
|
||||||
'@storybook/addon-links',
|
|
||||||
'@storybook/addon-essentials',
|
|
||||||
'@storybook/addon-interactions',
|
|
||||||
'storybook-dark-mode',
|
|
||||||
'storybook-addon-react-router-v6',
|
|
||||||
],
|
|
||||||
framework: {
|
|
||||||
name: '@storybook/react-vite',
|
|
||||||
},
|
|
||||||
async viteFinal(config, _options) {
|
|
||||||
const runtimeConfig = getRuntimeConfig({
|
|
||||||
distribution: 'browser',
|
|
||||||
mode: 'development',
|
|
||||||
channel: 'canary',
|
|
||||||
coverage: false,
|
|
||||||
});
|
|
||||||
// disable for storybook build
|
|
||||||
runtimeConfig.enableCloud = false;
|
|
||||||
return mergeConfig<InlineConfig, InlineConfig>(config, {
|
|
||||||
assetsInclude: ['**/*.md', '**/*.zip'],
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
// workaround for https://github.com/vitejs/vite/issues/9731
|
|
||||||
// it seems vite does not resolve self reference correctly?
|
|
||||||
'@affine/core': fileURLToPath(
|
|
||||||
new URL('../../../packages/frontend/core/src', import.meta.url)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
esbuild: {
|
|
||||||
target: 'ES2022',
|
|
||||||
},
|
|
||||||
plugins: [vanillaExtractPlugin()],
|
|
||||||
define: {
|
|
||||||
'process.on': 'undefined',
|
|
||||||
'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: runtimeConfig,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
} as StorybookConfig;
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
import 'core-js/modules/esnext.symbol.async-dispose';
|
|
||||||
import 'core-js/modules/esnext.symbol.dispose';
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<script>
|
|
||||||
window.global = window;
|
|
||||||
</script>
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
import './polyfill';
|
|
||||||
import '@affine/component/theme/global.css';
|
|
||||||
import '@affine/component/theme/theme.css';
|
|
||||||
import '@affine/core/bootstrap/preload';
|
|
||||||
import { createI18n } from '@affine/i18n';
|
|
||||||
import { ThemeProvider, useTheme } from 'next-themes';
|
|
||||||
import { useDarkMode } from 'storybook-dark-mode';
|
|
||||||
import { AffineContext } from '@affine/component/context';
|
|
||||||
import useSWR from 'swr';
|
|
||||||
import type { Decorator } from '@storybook/react';
|
|
||||||
import {
|
|
||||||
FrameworkRoot,
|
|
||||||
FrameworkScope,
|
|
||||||
GlobalContextService,
|
|
||||||
LifecycleService,
|
|
||||||
WorkspacesService,
|
|
||||||
_setCurrentStore,
|
|
||||||
configureTestingInfraModules,
|
|
||||||
useLiveData,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import { setupGlobal, type Environment } from '@affine/env/global';
|
|
||||||
|
|
||||||
import type { Preview } from '@storybook/react';
|
|
||||||
import { useLayoutEffect, useMemo, useRef } from 'react';
|
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
|
||||||
import { Framework } from '@toeverything/infra';
|
|
||||||
import { configureCommonModules } from '@affine/core/modules';
|
|
||||||
import { createStore } from 'jotai';
|
|
||||||
|
|
||||||
setupGlobal();
|
|
||||||
export const parameters = {
|
|
||||||
backgrounds: { disable: true },
|
|
||||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
|
||||||
controls: {
|
|
||||||
matchers: {
|
|
||||||
color: /(background|color)$/i,
|
|
||||||
date: /Date$/,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
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 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
localStorage.clear();
|
|
||||||
|
|
||||||
// do not show onboarding for storybook
|
|
||||||
window.localStorage.setItem('app_config', '{"onBoarding":false}');
|
|
||||||
window.localStorage.setItem('dismissAiOnboarding', 'true');
|
|
||||||
window.localStorage.setItem('dismissAiOnboardingEdgeless', 'true');
|
|
||||||
window.localStorage.setItem('dismissAiOnboardingLocal', 'true');
|
|
||||||
|
|
||||||
const framework = new Framework();
|
|
||||||
|
|
||||||
configureCommonModules(framework);
|
|
||||||
configureTestingInfraModules(framework);
|
|
||||||
|
|
||||||
const frameworkProvider = framework.provider();
|
|
||||||
|
|
||||||
frameworkProvider.get(LifecycleService).applicationStart();
|
|
||||||
const globalContextService = frameworkProvider.get(GlobalContextService);
|
|
||||||
|
|
||||||
const store = createStore();
|
|
||||||
_setCurrentStore(store);
|
|
||||||
|
|
||||||
frameworkProvider
|
|
||||||
.get(WorkspacesService)
|
|
||||||
.create(WorkspaceFlavour.LOCAL, async w => {
|
|
||||||
w.meta.setName('test-workspace');
|
|
||||||
w.meta.writeVersion(w);
|
|
||||||
})
|
|
||||||
.then(meta => {
|
|
||||||
globalContextService.globalContext.workspaceId.set(meta.id);
|
|
||||||
});
|
|
||||||
|
|
||||||
const withContextDecorator: Decorator = (Story, context) => {
|
|
||||||
const workspaceId = useLiveData(
|
|
||||||
globalContextService.globalContext.workspaceId.$
|
|
||||||
);
|
|
||||||
|
|
||||||
const { workspace } =
|
|
||||||
useMemo(() => {
|
|
||||||
if (!workspaceId) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return frameworkProvider.get(WorkspacesService).open({
|
|
||||||
metadata: { flavour: WorkspaceFlavour.LOCAL, id: workspaceId },
|
|
||||||
});
|
|
||||||
}, []) ?? {};
|
|
||||||
|
|
||||||
if (!workspace) {
|
|
||||||
return <>loading..</>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FrameworkRoot framework={frameworkProvider}>
|
|
||||||
<FrameworkScope scope={workspace.scope}>
|
|
||||||
<ThemeProvider>
|
|
||||||
<AffineContext store={store}>
|
|
||||||
<ThemeChange />
|
|
||||||
<Story {...context} />
|
|
||||||
</AffineContext>
|
|
||||||
</ThemeProvider>
|
|
||||||
</FrameworkScope>
|
|
||||||
</FrameworkRoot>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const platforms = ['web', 'desktop-macos', 'desktop-windows'] as const;
|
|
||||||
|
|
||||||
const withPlatformSelectionDecorator: Decorator = (Story, context) => {
|
|
||||||
const setupCounterRef = useRef(0);
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (setupCounterRef.current++ === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (context.globals.platform) {
|
|
||||||
case 'desktop-macos':
|
|
||||||
environment = {
|
|
||||||
...environment,
|
|
||||||
isBrowser: true,
|
|
||||||
isDesktop: true,
|
|
||||||
isMacOs: true,
|
|
||||||
isWindows: false,
|
|
||||||
} as Environment;
|
|
||||||
break;
|
|
||||||
case 'desktop-windows':
|
|
||||||
environment = {
|
|
||||||
...environment,
|
|
||||||
isBrowser: true,
|
|
||||||
isDesktop: true,
|
|
||||||
isMacOs: false,
|
|
||||||
isWindows: true,
|
|
||||||
} as Environment;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
globalThis.$AFFINE_SETUP = false;
|
|
||||||
setupGlobal();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, [context.globals.platform]);
|
|
||||||
|
|
||||||
return <Story key={context.globals.platform} {...context} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const decorators = [
|
|
||||||
withContextDecorator,
|
|
||||||
withI18n,
|
|
||||||
withPlatformSelectionDecorator,
|
|
||||||
];
|
|
||||||
|
|
||||||
const preview: Preview = {
|
|
||||||
decorators,
|
|
||||||
globalTypes: {
|
|
||||||
platform: {
|
|
||||||
description: 'Rendering platform target',
|
|
||||||
defaultValue: 'web',
|
|
||||||
toolbar: {
|
|
||||||
// The label to show for this toolbar item
|
|
||||||
title: 'platform',
|
|
||||||
// Array of plain string values or MenuItem shape (see below)
|
|
||||||
items: platforms,
|
|
||||||
// Change title based on selected value
|
|
||||||
dynamicTitle: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default preview;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
# Storybook
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@affine/storybook",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"dev": "storybook dev -p 6006",
|
|
||||||
"build": "storybook build",
|
|
||||||
"test": "test-storybook"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@affine/cli": "workspace:*",
|
|
||||||
"@affine/component": "workspace:*",
|
|
||||||
"@affine/i18n": "workspace:*",
|
|
||||||
"@dnd-kit/sortable": "^8.0.0",
|
|
||||||
"@storybook/jest": "^0.2.3",
|
|
||||||
"@storybook/testing-library": "^0.2.2",
|
|
||||||
"foxact": "^0.2.33",
|
|
||||||
"jotai": "^2.8.0",
|
|
||||||
"lodash-es": "^4.17.21",
|
|
||||||
"nanoid": "^5.0.7",
|
|
||||||
"react-router-dom": "^6.22.3",
|
|
||||||
"ses": "^1.4.1",
|
|
||||||
"storybook-addon-react-router-v6": "^2.0.15"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@blocksuite/block-std": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@blocksuite/blocks": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@blocksuite/global": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@blocksuite/icons": "2.1.46",
|
|
||||||
"@blocksuite/inline": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@blocksuite/presets": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@blocksuite/store": "0.14.0-canary-202404151235-655ec84",
|
|
||||||
"@storybook/addon-actions": "^7.6.17",
|
|
||||||
"@storybook/addon-essentials": "^7.6.17",
|
|
||||||
"@storybook/addon-interactions": "^7.6.17",
|
|
||||||
"@storybook/addon-links": "^7.6.17",
|
|
||||||
"@storybook/addon-storysource": "^7.6.17",
|
|
||||||
"@storybook/blocks": "^7.6.17",
|
|
||||||
"@storybook/builder-vite": "^7.6.17",
|
|
||||||
"@storybook/react": "^7.6.17",
|
|
||||||
"@storybook/react-vite": "^7.6.17",
|
|
||||||
"@storybook/test-runner": "^0.17.0",
|
|
||||||
"@vanilla-extract/esbuild-plugin": "^2.3.5",
|
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
|
||||||
"chromatic": "^11.3.0",
|
|
||||||
"concurrently": "^8.2.2",
|
|
||||||
"jest-mock": "^29.7.0",
|
|
||||||
"react": "18.2.0",
|
|
||||||
"react-dom": "18.2.0",
|
|
||||||
"serve": "^14.2.1",
|
|
||||||
"storybook": "^7.6.17",
|
|
||||||
"storybook-dark-mode": "^3.0.3",
|
|
||||||
"storybook-mock-date-decorator": "^1.0.2",
|
|
||||||
"wait-on": "^7.2.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@blocksuite/blocks": "*",
|
|
||||||
"@blocksuite/global": "*",
|
|
||||||
"@blocksuite/icons": "2.1.34",
|
|
||||||
"@blocksuite/presets": "*",
|
|
||||||
"@blocksuite/store": "*"
|
|
||||||
},
|
|
||||||
"version": "0.14.0"
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@affine/storybook",
|
|
||||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
|
||||||
"targets": {
|
|
||||||
"build": {
|
|
||||||
"executor": "nx:run-script",
|
|
||||||
"dependsOn": ["^build"],
|
|
||||||
"inputs": [
|
|
||||||
"default",
|
|
||||||
"^production",
|
|
||||||
"{projectRoot}/.storybook/**/*",
|
|
||||||
"{workspaceRoot}/packages/frontend/components/src/**/*",
|
|
||||||
"{workspaceRoot}/packages/frontend/core/src/**/*",
|
|
||||||
"{workspaceRoot}/packages/common/infra/**/*",
|
|
||||||
{
|
|
||||||
"runtime": "node -v"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "BUILD_TYPE"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "PERFSEE_TOKEN"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "SENTRY_ORG"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "SENTRY_PROJECT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "SENTRY_AUTH_TOKEN"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "SENTRY_DSN"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "DISTRIBUTION"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"env": "COVERAGE"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"options": {
|
|
||||||
"script": "build"
|
|
||||||
},
|
|
||||||
"outputs": ["{projectRoot}/storybook-static"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
import { BrowserWarning, LocalDemoTips } from '@affine/component/affine-banner';
|
|
||||||
import type { StoryFn } from '@storybook/react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/Banner',
|
|
||||||
component: BrowserWarning,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Default: StoryFn = () => {
|
|
||||||
const [closed, setIsClosed] = useState(true);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<BrowserWarning
|
|
||||||
message={<span>test</span>}
|
|
||||||
show={closed}
|
|
||||||
onClose={() => {
|
|
||||||
setIsClosed(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Download: StoryFn = () => {
|
|
||||||
const [, setIsClosed] = useState(true);
|
|
||||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<LocalDemoTips
|
|
||||||
isLoggedIn={isLoggedIn}
|
|
||||||
onLogin={() => setIsLoggedIn(true)}
|
|
||||||
onEnableCloud={() => {}}
|
|
||||||
onClose={() => {
|
|
||||||
setIsClosed(false);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
import {
|
|
||||||
AddPageButton,
|
|
||||||
AppSidebar,
|
|
||||||
AppSidebarFallback,
|
|
||||||
appSidebarOpenAtom,
|
|
||||||
CategoryDivider,
|
|
||||||
MenuLinkItem,
|
|
||||||
navHeaderStyle,
|
|
||||||
QuickSearchInput,
|
|
||||||
SidebarContainer,
|
|
||||||
SidebarScrollableContainer,
|
|
||||||
SidebarSwitch,
|
|
||||||
} from '@affine/core/components/app-sidebar';
|
|
||||||
import { DeleteTemporarilyIcon, SettingsIcon } from '@blocksuite/icons';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { useAtom } from 'jotai';
|
|
||||||
import type { PropsWithChildren } from 'react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/AppSidebar',
|
|
||||||
component: AppSidebar,
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
const Container = ({ children }: PropsWithChildren) => (
|
|
||||||
<MemoryRouter>
|
|
||||||
<main
|
|
||||||
style={{
|
|
||||||
position: 'relative',
|
|
||||||
width: '100vw',
|
|
||||||
height: 'calc(100vh - 40px)',
|
|
||||||
overflow: 'hidden',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
</MemoryRouter>
|
|
||||||
);
|
|
||||||
const Main = () => {
|
|
||||||
const [open] = useAtom(appSidebarOpenAtom);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<div className={navHeaderStyle}>
|
|
||||||
<SidebarSwitch show={!open} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Default: StoryFn = () => {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<AppSidebar />
|
|
||||||
<Main />
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Fallback = () => {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<AppSidebarFallback />
|
|
||||||
<Main />
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const WithItems: StoryFn = () => {
|
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<AppSidebar>
|
|
||||||
<SidebarContainer>
|
|
||||||
<QuickSearchInput />
|
|
||||||
<div style={{ height: '20px' }} />
|
|
||||||
<MenuLinkItem
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Settings
|
|
||||||
</MenuLinkItem>
|
|
||||||
<MenuLinkItem
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Settings
|
|
||||||
</MenuLinkItem>
|
|
||||||
<MenuLinkItem
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Settings
|
|
||||||
</MenuLinkItem>
|
|
||||||
</SidebarContainer>
|
|
||||||
|
|
||||||
<SidebarScrollableContainer>
|
|
||||||
<CategoryDivider label="Favorites" />
|
|
||||||
<MenuLinkItem
|
|
||||||
collapsed={collapsed}
|
|
||||||
onCollapsedChange={setCollapsed}
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Collapsible Item
|
|
||||||
</MenuLinkItem>
|
|
||||||
<MenuLinkItem
|
|
||||||
collapsed={!collapsed}
|
|
||||||
onCollapsedChange={setCollapsed}
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Collapsible Item
|
|
||||||
</MenuLinkItem>
|
|
||||||
<MenuLinkItem
|
|
||||||
icon={<SettingsIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Settings
|
|
||||||
</MenuLinkItem>
|
|
||||||
|
|
||||||
<CategoryDivider label="Others" />
|
|
||||||
<MenuLinkItem
|
|
||||||
icon={<DeleteTemporarilyIcon />}
|
|
||||||
to="/test"
|
|
||||||
onClick={() => alert('opened')}
|
|
||||||
>
|
|
||||||
Trash
|
|
||||||
</MenuLinkItem>
|
|
||||||
</SidebarScrollableContainer>
|
|
||||||
<SidebarContainer>
|
|
||||||
<AddPageButton />
|
|
||||||
</SidebarContainer>
|
|
||||||
</AppSidebar>
|
|
||||||
<Main />
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import type { AddPageButtonProps } from '@affine/core/components/app-sidebar';
|
|
||||||
import { AppUpdaterButton } from '@affine/core/components/app-sidebar';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import type { PropsWithChildren } from 'react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/AppUpdaterButton',
|
|
||||||
component: AppUpdaterButton,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof AppUpdaterButton>;
|
|
||||||
|
|
||||||
const Container = ({ children }: PropsWithChildren) => (
|
|
||||||
<main
|
|
||||||
style={{
|
|
||||||
position: 'relative',
|
|
||||||
width: '320px',
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'row',
|
|
||||||
backgroundColor: '#eee',
|
|
||||||
padding: '16px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const Default: StoryFn<AddPageButtonProps> = props => {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<AppUpdaterButton {...props} />
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Default.args = {
|
|
||||||
appQuitting: false,
|
|
||||||
updateReady: true,
|
|
||||||
updateAvailable: {
|
|
||||||
version: '1.0.0-beta.1',
|
|
||||||
allowAutoUpdate: true,
|
|
||||||
},
|
|
||||||
downloadProgress: 42,
|
|
||||||
changelogUnread: true,
|
|
||||||
autoDownload: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Updated: StoryFn<AddPageButtonProps> = props => {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<AppUpdaterButton {...props} updateAvailable={null} />
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Updated.args = {
|
|
||||||
changelogUnread: true,
|
|
||||||
};
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import { BlockSuiteEditor } from '@affine/core/components/blocksuite/block-suite-editor';
|
|
||||||
import { AffineSchemas } from '@blocksuite/blocks/schemas';
|
|
||||||
import { DocCollection, Schema } from '@blocksuite/store';
|
|
||||||
import type { StoryFn } from '@storybook/react';
|
|
||||||
import { initEmptyPage } from '@toeverything/infra';
|
|
||||||
|
|
||||||
const schema = new Schema();
|
|
||||||
schema.register(AffineSchemas);
|
|
||||||
|
|
||||||
async function createAndInitPage(
|
|
||||||
docCollection: DocCollection,
|
|
||||||
title: string,
|
|
||||||
preview: string
|
|
||||||
) {
|
|
||||||
const doc = docCollection.createDoc();
|
|
||||||
initEmptyPage(doc, title);
|
|
||||||
doc.getBlockByFlavour('affine:paragraph').at(0)?.text?.insert(preview, 0);
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/BlocksuiteEditor/DocEditor',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DocEditor: StoryFn<typeof BlockSuiteEditor> = (_, { loaded }) => {
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100vh' }}>
|
|
||||||
<BlockSuiteEditor mode="page" page={loaded.page} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
DocEditor.loaders = [
|
|
||||||
async () => {
|
|
||||||
const docCollection = new DocCollection({
|
|
||||||
id: 'test-workspace-id',
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
docCollection.doc.emit('sync', [true, docCollection.doc]);
|
|
||||||
docCollection.meta.setProperties({
|
|
||||||
tags: {
|
|
||||||
options: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 1',
|
|
||||||
'Hello World from page 1'
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
page,
|
|
||||||
workspace: docCollection,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import { toast } from '@affine/component';
|
|
||||||
import { BlockCard } from '@affine/component/card/block-card';
|
|
||||||
import { WorkspaceCard } from '@affine/component/card/workspace-card';
|
|
||||||
import { Tooltip } from '@affine/component/ui/tooltip';
|
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
|
||||||
import {
|
|
||||||
EdgelessIcon,
|
|
||||||
ExportToHtmlIcon,
|
|
||||||
HelpIcon,
|
|
||||||
PageIcon,
|
|
||||||
} from '@blocksuite/icons';
|
|
||||||
import type { Meta } from '@storybook/react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/Card',
|
|
||||||
component: WorkspaceCard,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
export const AffineWorkspaceCard = () => {
|
|
||||||
return (
|
|
||||||
<WorkspaceCard
|
|
||||||
meta={{
|
|
||||||
id: 'blocksuite-local',
|
|
||||||
flavour: WorkspaceFlavour.LOCAL,
|
|
||||||
}}
|
|
||||||
onClick={() => {}}
|
|
||||||
onSettingClick={() => {}}
|
|
||||||
currentWorkspaceId={null}
|
|
||||||
isOwner={true}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AffineBlockCard = () => {
|
|
||||||
return (
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
|
||||||
<BlockCard title={'New Page'} onClick={() => toast('clicked')} />
|
|
||||||
<BlockCard
|
|
||||||
title={'New Page'}
|
|
||||||
desc={'Write with a blank page'}
|
|
||||||
right={<PageIcon width={20} height={20} />}
|
|
||||||
onClick={() => toast('clicked page')}
|
|
||||||
/>
|
|
||||||
<BlockCard
|
|
||||||
title={'New Edgeless'}
|
|
||||||
desc={'Draw with a blank whiteboard'}
|
|
||||||
left={<PageIcon width={20} height={20} />}
|
|
||||||
right={<EdgelessIcon width={20} height={20} />}
|
|
||||||
onClick={() => toast('clicked edgeless')}
|
|
||||||
/>
|
|
||||||
<BlockCard
|
|
||||||
left={<ExportToHtmlIcon width={20} height={20} />}
|
|
||||||
title="HTML"
|
|
||||||
disabled
|
|
||||||
right={
|
|
||||||
<Tooltip content={'Learn how to Import pages into AFFiNE.'}>
|
|
||||||
<HelpIcon />
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
onClick={() => toast('click HTML')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import { Checkbox } from '@affine/component';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/Checkbox',
|
|
||||||
component: Checkbox,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof Checkbox>;
|
|
||||||
|
|
||||||
export const Basic: StoryFn<typeof Checkbox> = props => {
|
|
||||||
const [checked, setChecked] = useState(props.checked);
|
|
||||||
const handleChange = (
|
|
||||||
_event: React.ChangeEvent<HTMLInputElement>,
|
|
||||||
checked: boolean
|
|
||||||
) => {
|
|
||||||
setChecked(checked);
|
|
||||||
props.onChange?.(_event, checked);
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
gap: '1rem',
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Checkbox
|
|
||||||
style={{ fontSize: 14 }}
|
|
||||||
{...props}
|
|
||||||
checked={checked}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
style={{ fontSize: 16 }}
|
|
||||||
{...props}
|
|
||||||
checked={checked}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
style={{ fontSize: 18 }}
|
|
||||||
{...props}
|
|
||||||
checked={checked}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
<Checkbox
|
|
||||||
style={{ fontSize: 24 }}
|
|
||||||
{...props}
|
|
||||||
checked={checked}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Basic.args = {
|
|
||||||
checked: true,
|
|
||||||
disabled: false,
|
|
||||||
indeterminate: false,
|
|
||||||
onChange: console.log,
|
|
||||||
};
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
import { NavigateContext, topLevelRoutes } from '@affine/core/router';
|
|
||||||
import { assertExists } from '@blocksuite/global/utils';
|
|
||||||
import type { StoryFn } from '@storybook/react';
|
|
||||||
import { screen, userEvent, waitFor, within } from '@storybook/testing-library';
|
|
||||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
|
||||||
import {
|
|
||||||
reactRouterOutlets,
|
|
||||||
reactRouterParameters,
|
|
||||||
withRouter,
|
|
||||||
} from 'storybook-addon-react-router-v6';
|
|
||||||
import { mockDateDecorator } from 'storybook-mock-date-decorator';
|
|
||||||
|
|
||||||
const FakeApp = () => {
|
|
||||||
const location = useLocation();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
// fixme: `key` is a hack to force the storybook to re-render the outlet
|
|
||||||
return (
|
|
||||||
<NavigateContext.Provider value={navigate}>
|
|
||||||
<Outlet key={location.pathname} />
|
|
||||||
</NavigateContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Preview/Core',
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: false },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Index: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
Index.decorators = [withRouter];
|
|
||||||
Index.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(
|
|
||||||
topLevelRoutes[0].children /* skip root wrapper */
|
|
||||||
),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SettingPage: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
SettingPage.play = async ({ canvasElement, step }) => {
|
|
||||||
const canvas = within(canvasElement);
|
|
||||||
await waitFor(
|
|
||||||
async () => {
|
|
||||||
assertExists(
|
|
||||||
document.body.querySelector(
|
|
||||||
'[data-testid="slider-bar-workspace-setting-button"]'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 10000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await step('click setting modal button', async () => {
|
|
||||||
await userEvent.click(
|
|
||||||
canvas.getByTestId('slider-bar-workspace-setting-button')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await waitFor(async () => {
|
|
||||||
assertExists(
|
|
||||||
document.body.querySelector('[data-testid="language-menu-button"]')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Menu button may have "pointer-events: none" style, await 100ms to avoid this weird situation.
|
|
||||||
await new Promise(resolve => window.setTimeout(resolve, 100));
|
|
||||||
|
|
||||||
await step('click language menu button', async () => {
|
|
||||||
await userEvent.click(
|
|
||||||
document.body.querySelector(
|
|
||||||
'[data-testid="language-menu-button"]'
|
|
||||||
) as HTMLElement
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
SettingPage.decorators = [withRouter];
|
|
||||||
SettingPage.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const NotFoundPage: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
NotFoundPage.decorators = [withRouter];
|
|
||||||
NotFoundPage.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
location: {
|
|
||||||
path: '/404',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const WorkspaceList: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
WorkspaceList.play = async ({ canvasElement }) => {
|
|
||||||
const canvas = within(canvasElement);
|
|
||||||
// click current-workspace
|
|
||||||
const currentWorkspace = await waitFor(
|
|
||||||
() => {
|
|
||||||
assertExists(canvas.getByTestId('current-workspace'));
|
|
||||||
return canvas.getByTestId('current-workspace');
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 5000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// todo: figure out why userEvent cannot click this element?
|
|
||||||
// await userEvent.click(currentWorkspace);
|
|
||||||
currentWorkspace.click();
|
|
||||||
};
|
|
||||||
WorkspaceList.decorators = [withRouter];
|
|
||||||
WorkspaceList.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
location: {
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SearchPage: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
SearchPage.play = async ({ canvasElement }) => {
|
|
||||||
const canvas = within(canvasElement);
|
|
||||||
await waitFor(
|
|
||||||
async () => {
|
|
||||||
assertExists(
|
|
||||||
document.body.querySelector(
|
|
||||||
'[data-testid="slider-bar-quick-search-button"]'
|
|
||||||
)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 3000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await userEvent.click(canvas.getByTestId('slider-bar-quick-search-button'));
|
|
||||||
await waitFor(
|
|
||||||
() => {
|
|
||||||
assertExists(screen.getByTestId('cmdk-quick-search'));
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 3000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
SearchPage.decorators = [withRouter];
|
|
||||||
SearchPage.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
location: {
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ImportPage: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
ImportPage.play = async ({ canvasElement }) => {
|
|
||||||
const canvas = within(canvasElement);
|
|
||||||
await waitFor(
|
|
||||||
async () => {
|
|
||||||
assertExists(
|
|
||||||
document.body.querySelector('[data-testid="sidebar-new-page-button"]')
|
|
||||||
);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
timeout: 10000,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await userEvent.click(canvas.getByTestId('sidebar-new-page-button'));
|
|
||||||
await waitFor(() => {
|
|
||||||
assertExists(canvasElement.querySelector('v-line'));
|
|
||||||
});
|
|
||||||
await waitFor(() => {
|
|
||||||
assertExists(
|
|
||||||
canvasElement.querySelector('[data-testid="header-dropDownButton"]')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await userEvent.click(canvas.getByTestId('header-dropDownButton'));
|
|
||||||
await waitFor(() => {
|
|
||||||
assertExists(
|
|
||||||
document.body.querySelector('[data-testid="editor-option-menu-import"]')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
await userEvent.click(screen.getByTestId('editor-option-menu-import'));
|
|
||||||
};
|
|
||||||
ImportPage.decorators = [withRouter, mockDateDecorator];
|
|
||||||
ImportPage.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
location: {
|
|
||||||
path: '/',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
date: new Date('Mon, 25 Mar 2024 08:39:07 GMT'),
|
|
||||||
};
|
|
||||||
|
|
||||||
export const OpenAppPage: StoryFn = () => {
|
|
||||||
return <FakeApp />;
|
|
||||||
};
|
|
||||||
OpenAppPage.decorators = [withRouter];
|
|
||||||
OpenAppPage.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
location: {
|
|
||||||
path: '/open-app/url',
|
|
||||||
searchParams: {
|
|
||||||
url: 'affine-beta://foo-bar.com',
|
|
||||||
open: 'false',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import { BlockSuiteEditor } from '@affine/core/components/blocksuite/block-suite-editor';
|
|
||||||
import { ImagePreviewModal } from '@affine/core/components/image-preview';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import type { Doc } from '@toeverything/infra';
|
|
||||||
import {
|
|
||||||
DocsService,
|
|
||||||
FrameworkScope,
|
|
||||||
initEmptyPage,
|
|
||||||
useService,
|
|
||||||
WorkspaceService,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { createPortal } from 'react-dom';
|
|
||||||
import { mockDateDecorator } from 'storybook-mock-date-decorator';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Component/ImagePreviewModal',
|
|
||||||
component: ImagePreviewModal,
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
export const Default: StoryFn = () => {
|
|
||||||
const workspace = useService(WorkspaceService).workspace;
|
|
||||||
const docsService = useService(DocsService);
|
|
||||||
|
|
||||||
const [doc, setDoc] = useState<Doc | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const bsDoc = workspace.docCollection.createDoc({ id: 'page0' });
|
|
||||||
initEmptyPage(bsDoc);
|
|
||||||
|
|
||||||
const { doc, release } = docsService.open(bsDoc.meta!.id);
|
|
||||||
|
|
||||||
fetch(new URL('@affine-test/fixtures/large-image.png', import.meta.url))
|
|
||||||
.then(res => res.arrayBuffer())
|
|
||||||
.then(async buffer => {
|
|
||||||
const id = await workspace.docCollection.blob.set(
|
|
||||||
new Blob([buffer], { type: 'image/png' })
|
|
||||||
);
|
|
||||||
const frameId = bsDoc.getBlockByFlavour('affine:note')[0].id;
|
|
||||||
bsDoc.addBlock(
|
|
||||||
'affine:paragraph',
|
|
||||||
{
|
|
||||||
text: new bsDoc.Text(
|
|
||||||
'Please double click the image to preview it.'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
frameId
|
|
||||||
);
|
|
||||||
bsDoc.addBlock(
|
|
||||||
'affine:image',
|
|
||||||
{
|
|
||||||
sourceId: id,
|
|
||||||
},
|
|
||||||
frameId
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error('Failed to load large-image.png', err);
|
|
||||||
});
|
|
||||||
setDoc(doc);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
release();
|
|
||||||
};
|
|
||||||
}, [docsService, workspace]);
|
|
||||||
|
|
||||||
if (!doc) {
|
|
||||||
return <div />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FrameworkScope scope={doc.scope}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100vh',
|
|
||||||
width: '100vw',
|
|
||||||
overflow: 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<BlockSuiteEditor mode="page" page={doc.blockSuiteDoc} />
|
|
||||||
{createPortal(
|
|
||||||
<ImagePreviewModal
|
|
||||||
pageId={doc.id}
|
|
||||||
docCollection={doc.blockSuiteDoc.collection}
|
|
||||||
/>,
|
|
||||||
document.body
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</FrameworkScope>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Default.decorators = [mockDateDecorator];
|
|
||||||
Default.parameters = {
|
|
||||||
date: new Date('Mon, 25 Mar 2024 08:39:07 GMT'),
|
|
||||||
};
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
/* deepscan-disable USELESS_ARROW_FUNC_BIND */
|
|
||||||
import { toast } from '@affine/component';
|
|
||||||
import { ImportPage } from '@affine/component/import-page';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/ImportPage',
|
|
||||||
component: ImportPage,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
const Template: StoryFn<typeof ImportPage> = args => <ImportPage {...args} />;
|
|
||||||
|
|
||||||
export const Basic = Template.bind(undefined);
|
|
||||||
Basic.args = {
|
|
||||||
importHtml: () => toast('Click importHtml'),
|
|
||||||
importMarkdown: () => toast('Click importMarkdown'),
|
|
||||||
importNotion: () => toast('Click importNotion'),
|
|
||||||
onClose: () => toast('Click onClose'),
|
|
||||||
};
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { Input } from '@affine/component';
|
|
||||||
import { expect } from '@storybook/jest';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { userEvent, within } from '@storybook/testing-library';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/Input',
|
|
||||||
component: Input,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof Input>;
|
|
||||||
|
|
||||||
export const Basic: StoryFn<typeof Input> = () => {
|
|
||||||
return <Input data-testid="test-input" defaultValue="test" />;
|
|
||||||
};
|
|
||||||
|
|
||||||
Basic.play = async ({ canvasElement }) => {
|
|
||||||
const element = within(canvasElement);
|
|
||||||
const item = element.getByTestId('test-input') as HTMLInputElement;
|
|
||||||
expect(item).toBeTruthy();
|
|
||||||
expect(item.value).toBe('test');
|
|
||||||
await userEvent.clear(item);
|
|
||||||
await userEvent.type(item, 'test 2');
|
|
||||||
expect(item.value).toBe('test 2');
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DynamicHeight: StoryFn<typeof Input> = () => {
|
|
||||||
return <Input style={{ width: '200px' }} data-testid="test-input" />;
|
|
||||||
};
|
|
||||||
|
|
||||||
DynamicHeight.play = async ({ canvasElement }) => {
|
|
||||||
const element = within(canvasElement);
|
|
||||||
const item = element.getByTestId('test-input') as HTMLInputElement;
|
|
||||||
expect(item).toBeTruthy();
|
|
||||||
// FIXME: the following is not correct
|
|
||||||
// expect(item.getBoundingClientRect().width).toBe(200);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const NoBorder: StoryFn<typeof Input> = () => {
|
|
||||||
return <Input noBorder={true} data-testid="test-input" />;
|
|
||||||
};
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import { Meta } from '@storybook/blocks';
|
|
||||||
|
|
||||||
<Meta title="Introduction" />
|
|
||||||
|
|
||||||
# AFFiNE UI Storybook
|
|
||||||
|
|
||||||
This is a UI component dev environment for AFFiNE UI.
|
|
||||||
It allows you to browse the AFFiNE UI components,
|
|
||||||
view the different states of each component,
|
|
||||||
and interactively develop and test components.
|
|
||||||
|
|
||||||
## Bug Reporting
|
|
||||||
|
|
||||||
If you find a bug, please file an issue on [GitHub](https://github.com/toeverything/AFFiNE/issues)
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
We welcome contributions from the community! [Get started here](https://github.com/toeverything/AFFiNE/blob/canary/docs/BUILDING.md)
|
|
||||||
@@ -1,249 +0,0 @@
|
|||||||
import {
|
|
||||||
expandNotificationCenterAtom,
|
|
||||||
NotificationCenter,
|
|
||||||
pushNotificationAtom,
|
|
||||||
} from '@affine/component/notification-center';
|
|
||||||
import type { Meta } from '@storybook/react';
|
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/NotificationCenter',
|
|
||||||
component: NotificationCenter,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof NotificationCenter>;
|
|
||||||
|
|
||||||
let id = 0;
|
|
||||||
const image = (
|
|
||||||
<video autoPlay muted loop>
|
|
||||||
<source
|
|
||||||
src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
|
|
||||||
type="video/mp4"
|
|
||||||
/>
|
|
||||||
</video>
|
|
||||||
);
|
|
||||||
export const Basic = () => {
|
|
||||||
const push = useSetAtom(pushNotificationAtom);
|
|
||||||
const expand = useAtomValue(expandNotificationCenterAtom);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div>{expand ? 'expanded' : 'collapsed'}</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: `${key} message`,
|
|
||||||
timeout: 3000,
|
|
||||||
progressingBar: true,
|
|
||||||
action: async () => {
|
|
||||||
console.log('undo');
|
|
||||||
},
|
|
||||||
type: 'info',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Push timeout notification
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: `${key} message`,
|
|
||||||
type: 'info',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Push notification with no timeout
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'info',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Push notification with no message
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'success',
|
|
||||||
theme: 'light',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
light success
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'success',
|
|
||||||
theme: 'dark',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
dark success
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'info',
|
|
||||||
theme: 'light',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
light info
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'info',
|
|
||||||
theme: 'dark',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
dark info
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'warning',
|
|
||||||
theme: 'light',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
light warning
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'warning',
|
|
||||||
theme: 'dark',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
dark warning
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'error',
|
|
||||||
theme: 'light',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
light error
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: ``,
|
|
||||||
type: 'error',
|
|
||||||
theme: 'dark',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
dark error
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
key: `${key}`,
|
|
||||||
title: `${key} title`,
|
|
||||||
message: `gif test`,
|
|
||||||
type: 'info',
|
|
||||||
multimedia: image,
|
|
||||||
timeout: 3000,
|
|
||||||
action: async () => {
|
|
||||||
console.log('undo');
|
|
||||||
},
|
|
||||||
progressingBar: true,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
gif
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
const key = id++;
|
|
||||||
push({
|
|
||||||
title: `${key} title`,
|
|
||||||
type: 'info',
|
|
||||||
theme: 'default',
|
|
||||||
timeout: 3000,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
default message
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<NotificationCenter />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import type { Input } from '@affine/component';
|
|
||||||
import { Onboarding } from '@affine/core/components/affine/onboarding/onboarding';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'Preview/Onboarding',
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof Input>;
|
|
||||||
|
|
||||||
export const Preview: StoryFn<typeof Onboarding> = () => {
|
|
||||||
return <Onboarding />;
|
|
||||||
};
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import { PageDetailSkeleton } from '@affine/component/page-detail-skeleton';
|
|
||||||
import type { Meta } from '@storybook/react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/PageDetailSkeleton',
|
|
||||||
component: PageDetailSkeleton,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<typeof PageDetailSkeleton>;
|
|
||||||
|
|
||||||
export const Basic = () => {
|
|
||||||
return <PageDetailSkeleton />;
|
|
||||||
};
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
import { PagePropertiesTable } from '@affine/core/components/affine/page-properties';
|
|
||||||
import { AffineSchemas } from '@blocksuite/blocks/schemas';
|
|
||||||
import { DocCollection, Schema } from '@blocksuite/store';
|
|
||||||
import type { StoryFn } from '@storybook/react';
|
|
||||||
import { initEmptyPage } from '@toeverything/infra';
|
|
||||||
|
|
||||||
const schema = new Schema();
|
|
||||||
schema.register(AffineSchemas);
|
|
||||||
|
|
||||||
async function createAndInitPage(
|
|
||||||
docCollection: DocCollection,
|
|
||||||
title: string,
|
|
||||||
preview: string
|
|
||||||
) {
|
|
||||||
const page = docCollection.createDoc();
|
|
||||||
initEmptyPage(page, title);
|
|
||||||
page.getBlockByFlavour('affine:paragraph').at(0)?.text?.insert(preview, 0);
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/PageInfoProperties',
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PageInfoProperties: StoryFn<typeof PagePropertiesTable> = (
|
|
||||||
_,
|
|
||||||
{ loaded }
|
|
||||||
) => {
|
|
||||||
return (
|
|
||||||
<div style={{ height: '100vh' }}>
|
|
||||||
<PagePropertiesTable page={loaded.page} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
PageInfoProperties.loaders = [
|
|
||||||
async () => {
|
|
||||||
const docCollection = new DocCollection({
|
|
||||||
id: 'test-workspace-id',
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
docCollection.doc.emit('sync', [true, docCollection.doc]);
|
|
||||||
docCollection.meta.setProperties({
|
|
||||||
tags: {
|
|
||||||
options: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const page = await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 1',
|
|
||||||
'Hello World from page 1'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (page.meta) {
|
|
||||||
page.meta.updatedDate = Date.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
page,
|
|
||||||
workspace: docCollection,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,349 +0,0 @@
|
|||||||
import { toast } from '@affine/component';
|
|
||||||
import type {
|
|
||||||
ListItem,
|
|
||||||
ListProps,
|
|
||||||
PageListItemProps,
|
|
||||||
PageOperationCellProps,
|
|
||||||
PageTagsProps,
|
|
||||||
} from '@affine/core/components/page-list';
|
|
||||||
import {
|
|
||||||
FloatingToolbar,
|
|
||||||
List,
|
|
||||||
ListScrollContainer,
|
|
||||||
NewPageButton,
|
|
||||||
PageListItem,
|
|
||||||
PageOperationCell,
|
|
||||||
PageTags,
|
|
||||||
} from '@affine/core/components/page-list';
|
|
||||||
import { topLevelRoutes } from '@affine/core/router';
|
|
||||||
import { AffineSchemas } from '@blocksuite/blocks/schemas';
|
|
||||||
import { PageIcon, TagsIcon } from '@blocksuite/icons';
|
|
||||||
import { DocCollection, Schema } from '@blocksuite/store';
|
|
||||||
import { expect } from '@storybook/jest';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { userEvent } from '@storybook/testing-library';
|
|
||||||
import { initEmptyPage } from '@toeverything/infra';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import {
|
|
||||||
reactRouterOutlets,
|
|
||||||
reactRouterParameters,
|
|
||||||
withRouter,
|
|
||||||
} from 'storybook-addon-react-router-v6';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/PageList',
|
|
||||||
parameters: {
|
|
||||||
layout: 'fullscreen',
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
export const AffineOperationCell: StoryFn<PageOperationCellProps> = ({
|
|
||||||
...props
|
|
||||||
}) => <PageOperationCell {...props} />;
|
|
||||||
|
|
||||||
AffineOperationCell.args = {
|
|
||||||
page: {
|
|
||||||
id: '123',
|
|
||||||
title: 'Test Page Title',
|
|
||||||
tags: ['tag1', 'tag2'],
|
|
||||||
createDate: new Date('2021-01-01').getTime(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
AffineOperationCell.parameters = {
|
|
||||||
reactRouter: reactRouterParameters({
|
|
||||||
routing: reactRouterOutlets(topLevelRoutes),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
AffineOperationCell.play = async ({ canvasElement }) => {
|
|
||||||
{
|
|
||||||
const button = canvasElement.querySelector(
|
|
||||||
'[data-testid="page-list-operation-button"]'
|
|
||||||
) as HTMLButtonElement;
|
|
||||||
expect(button).not.toBeNull();
|
|
||||||
await userEvent.click(button);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AffineNewPageButton: StoryFn<typeof NewPageButton> = ({
|
|
||||||
...props
|
|
||||||
}) => <NewPageButton {...props} />;
|
|
||||||
AffineNewPageButton.args = {
|
|
||||||
createNewPage: () => toast('Create new page'),
|
|
||||||
createNewEdgeless: () => toast('Create new edgeless'),
|
|
||||||
};
|
|
||||||
|
|
||||||
AffineNewPageButton.play = async ({ canvasElement }) => {
|
|
||||||
const button = canvasElement.querySelector('button') as HTMLButtonElement;
|
|
||||||
expect(button).not.toBeNull();
|
|
||||||
const dropdown = button.querySelector('svg') as SVGSVGElement;
|
|
||||||
expect(dropdown).not.toBeNull();
|
|
||||||
await userEvent.click(dropdown);
|
|
||||||
};
|
|
||||||
|
|
||||||
const testTags = [
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-cccc',
|
|
||||||
value: 'cccccccccccccccc',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-a',
|
|
||||||
value: 'a',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-b',
|
|
||||||
value: 'b',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-c',
|
|
||||||
value: 'c',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-d',
|
|
||||||
value: 'd',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-0',
|
|
||||||
value: 'foo',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'pink',
|
|
||||||
id: 'test-tag-id-1',
|
|
||||||
value: 'bar',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'purple',
|
|
||||||
id: 'test-tag-id-2',
|
|
||||||
value: 'foobar',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'black',
|
|
||||||
id: 'test-tag-id-3',
|
|
||||||
value: 'affine',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'orange',
|
|
||||||
id: 'test-tag-id-4',
|
|
||||||
value: 'blocksuite',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'yellow',
|
|
||||||
id: 'test-tag-id-5',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'green',
|
|
||||||
id: 'test-tag-id-6',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'blue',
|
|
||||||
id: 'test-tag-id-7',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'indigo',
|
|
||||||
id: 'test-tag-id-8',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'teal',
|
|
||||||
id: 'test-tag-id-9',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'cyan',
|
|
||||||
id: 'test-tag-id-10',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'gray',
|
|
||||||
id: 'test-tag-id-11',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
color: 'red',
|
|
||||||
id: 'test-tag-id-12',
|
|
||||||
value: 'toeverything',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const PageListItemComponent: StoryFn<PageListItemProps> = props => (
|
|
||||||
<PageListItem {...props}></PageListItem>
|
|
||||||
);
|
|
||||||
|
|
||||||
PageListItemComponent.args = {
|
|
||||||
pageId: 'test-page-id',
|
|
||||||
title: 'Test Page Title',
|
|
||||||
preview:
|
|
||||||
'this is page preview and it is very long and will be truncated because it is too long and it is very long and will be truncated because it is too long',
|
|
||||||
icon: <PageIcon />,
|
|
||||||
to: '/hello',
|
|
||||||
selectable: true,
|
|
||||||
createDate: new Date('2021-01-01'),
|
|
||||||
updatedDate: new Date('2023-08-15'),
|
|
||||||
draggable: true,
|
|
||||||
tags: testTags,
|
|
||||||
selected: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
PageListItemComponent.decorators = [withRouter];
|
|
||||||
|
|
||||||
export const ListItemTags: StoryFn<PageTagsProps> = props => (
|
|
||||||
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
||||||
<div style={{ width: '300px' }}>
|
|
||||||
<PageTags {...props}></PageTags>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
ListItemTags.args = {
|
|
||||||
// FIXME: this is a hack to make the storybook work
|
|
||||||
// tags: testTags,
|
|
||||||
hoverExpandDirection: 'left',
|
|
||||||
widthOnHover: 600,
|
|
||||||
maxItems: 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const PageListStory: StoryFn<ListProps<ListItem>> = (
|
|
||||||
props,
|
|
||||||
{ loaded }
|
|
||||||
) => {
|
|
||||||
return (
|
|
||||||
<ListScrollContainer
|
|
||||||
style={{
|
|
||||||
height: '100vh',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<List {...props} {...loaded}></List>
|
|
||||||
</ListScrollContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
PageListStory.args = {
|
|
||||||
groupBy: [
|
|
||||||
{
|
|
||||||
id: 'all',
|
|
||||||
label: count => `All Pages (${count})`,
|
|
||||||
match: () => true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
PageListStory.argTypes = {
|
|
||||||
selectable: {
|
|
||||||
control: 'radio',
|
|
||||||
options: [true, 'toggle', false],
|
|
||||||
},
|
|
||||||
hideHeader: {
|
|
||||||
type: 'boolean',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
async function createAndInitPage(
|
|
||||||
docCollection: DocCollection,
|
|
||||||
title: string,
|
|
||||||
preview: string
|
|
||||||
) {
|
|
||||||
const doc = docCollection.createDoc();
|
|
||||||
initEmptyPage(doc, title);
|
|
||||||
doc.getBlockByFlavour('affine:paragraph').at(0)?.text?.insert(preview, 0);
|
|
||||||
return doc;
|
|
||||||
}
|
|
||||||
|
|
||||||
PageListStory.loaders = [
|
|
||||||
async () => {
|
|
||||||
const schema = new Schema();
|
|
||||||
schema.register(AffineSchemas);
|
|
||||||
const docCollection = new DocCollection({
|
|
||||||
id: 'test-workspace-id',
|
|
||||||
schema,
|
|
||||||
});
|
|
||||||
|
|
||||||
docCollection.meta.setProperties({
|
|
||||||
tags: {
|
|
||||||
options: structuredClone(testTags),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const page1 = await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 1',
|
|
||||||
'Hello World from page 1'
|
|
||||||
);
|
|
||||||
const page2 = await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 2',
|
|
||||||
'Hello World from page 2'
|
|
||||||
);
|
|
||||||
const page3 = await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 3',
|
|
||||||
'Hello World from page 3Hello World from page 3Hello World from page 3Hello World from page 3Hello World from page 3'
|
|
||||||
);
|
|
||||||
|
|
||||||
await createAndInitPage(
|
|
||||||
docCollection,
|
|
||||||
'This is page 4',
|
|
||||||
'Hello World from page 3Hello World from page 3Hello World from page 3Hello World from page 3Hello World from page 3'
|
|
||||||
);
|
|
||||||
|
|
||||||
page1.meta!.createDate = new Date('2021-01-01').getTime();
|
|
||||||
page2.meta!.createDate = page2.meta!.createDate - 3600 * 1000 * 24;
|
|
||||||
page3.meta!.createDate = page3.meta!.createDate - 3600 * 1000 * 24 * 7;
|
|
||||||
|
|
||||||
docCollection.meta.docMetas[3].tags = testTags.slice(0, 3).map(t => t.id);
|
|
||||||
docCollection.meta.docMetas[2].tags = testTags.slice(0, 12).map(t => t.id);
|
|
||||||
|
|
||||||
return {
|
|
||||||
blockSuiteWorkspace: docCollection,
|
|
||||||
pages: docCollection.meta.docs,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export const FloatingToolbarStory: StoryFn<typeof FloatingToolbar> = props => {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '100vh',
|
|
||||||
overflow: 'auto',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
border: '1px solid black',
|
|
||||||
padding: '10px',
|
|
||||||
}}
|
|
||||||
onClick={() => setOpen(o => !o)}
|
|
||||||
>
|
|
||||||
{open ? 'hide' : 'show'}
|
|
||||||
</button>
|
|
||||||
<FloatingToolbar
|
|
||||||
style={{ position: 'fixed', bottom: '20px', width: '100%' }}
|
|
||||||
{...props}
|
|
||||||
open={open}
|
|
||||||
>
|
|
||||||
<FloatingToolbar.Item>10 Selected</FloatingToolbar.Item>
|
|
||||||
<FloatingToolbar.Separator />
|
|
||||||
<FloatingToolbar.Button
|
|
||||||
icon={<TagsIcon />}
|
|
||||||
label="Add Tags"
|
|
||||||
onClick={console.log}
|
|
||||||
/>
|
|
||||||
<FloatingToolbar.Button
|
|
||||||
icon={<TagsIcon />}
|
|
||||||
label="Add Tags"
|
|
||||||
onClick={console.log}
|
|
||||||
/>
|
|
||||||
</FloatingToolbar>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
import {
|
|
||||||
registerAffineCreationCommands,
|
|
||||||
registerAffineLayoutCommands,
|
|
||||||
registerAffineSettingsCommands,
|
|
||||||
} from '@affine/core/commands';
|
|
||||||
import { CMDKQuickSearchModal } from '@affine/core/components/pure/cmdk';
|
|
||||||
import { HighlightLabel } from '@affine/core/components/pure/cmdk/highlight';
|
|
||||||
import { useAFFiNEI18N } from '@affine/i18n/hooks';
|
|
||||||
import type { Doc } from '@blocksuite/store';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { useStore } from 'jotai';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
import { withRouter } from 'storybook-addon-react-router-v6';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/QuickSearch',
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
const createMockedPage = () => {
|
|
||||||
return {
|
|
||||||
id: 'test-page',
|
|
||||||
waitForLoaded: () => Promise.resolve(),
|
|
||||||
} as any as Doc;
|
|
||||||
};
|
|
||||||
|
|
||||||
function useRegisterCommands() {
|
|
||||||
const t = useAFFiNEI18N();
|
|
||||||
const store = useStore();
|
|
||||||
useEffect(() => {
|
|
||||||
const unsubs = [
|
|
||||||
registerAffineSettingsCommands({
|
|
||||||
t,
|
|
||||||
store,
|
|
||||||
theme: {
|
|
||||||
setTheme: () => {},
|
|
||||||
theme: 'auto',
|
|
||||||
themes: ['auto', 'dark', 'light'],
|
|
||||||
},
|
|
||||||
languageHelper: {
|
|
||||||
onLanguageChange: () => {},
|
|
||||||
languagesList: [
|
|
||||||
{
|
|
||||||
tag: 'en',
|
|
||||||
name: 'English',
|
|
||||||
originalName: 'English',
|
|
||||||
Completeness: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tag: 'zh-Hans',
|
|
||||||
name: 'Simplified Chinese',
|
|
||||||
originalName: '简体中文',
|
|
||||||
Completeness: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
currentLanguage: undefined,
|
|
||||||
},
|
|
||||||
editor: null,
|
|
||||||
}),
|
|
||||||
registerAffineCreationCommands({
|
|
||||||
t,
|
|
||||||
store,
|
|
||||||
pageHelper: {
|
|
||||||
createEdgeless: createMockedPage,
|
|
||||||
createPage: createMockedPage,
|
|
||||||
importFile: () => Promise.resolve(),
|
|
||||||
isPreferredEdgeless: () => false,
|
|
||||||
createLinkedPage: createMockedPage,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
registerAffineLayoutCommands({
|
|
||||||
t,
|
|
||||||
store,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
unsubs.forEach(unsub => unsub());
|
|
||||||
};
|
|
||||||
}, [store, t]);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CMDKStoryWithCommands: StoryFn = () => {
|
|
||||||
useRegisterCommands();
|
|
||||||
|
|
||||||
return <CMDKQuickSearchModal open />;
|
|
||||||
};
|
|
||||||
|
|
||||||
CMDKStoryWithCommands.decorators = [withRouter];
|
|
||||||
|
|
||||||
export const HighlightStory: StoryFn = () => {
|
|
||||||
const [query, setQuery] = useState('');
|
|
||||||
const label = {
|
|
||||||
title: 'title',
|
|
||||||
};
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<input value={query} onChange={e => setQuery(e.target.value)} />
|
|
||||||
<HighlightLabel label={label} highlight={query} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import { Button } from '@affine/component/ui/button';
|
|
||||||
import { CMDKContainer, CMDKModal } from '@affine/core/components/pure/cmdk';
|
|
||||||
import { useCMDKCommandGroups } from '@affine/core/components/pure/cmdk/data-hooks';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import { useState } from 'react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/QuickSearch',
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
export const CMDKModalStory: StoryFn = () => {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [counter, setCounter] = useState(0);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Button onClick={() => setOpen(true)}>Open Modal</Button>
|
|
||||||
<CMDKModal key={counter} open={open} onOpenChange={setOpen}>
|
|
||||||
<Button onClick={() => setCounter(c => c + 1)}>
|
|
||||||
Trigger new modal
|
|
||||||
</Button>
|
|
||||||
</CMDKModal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CMDKPanelStory: StoryFn = () => {
|
|
||||||
const [query, setQuery] = useState('');
|
|
||||||
const groups = useCMDKCommandGroups();
|
|
||||||
return (
|
|
||||||
<CMDKModal open>
|
|
||||||
<CMDKContainer
|
|
||||||
open
|
|
||||||
query={query}
|
|
||||||
onQueryChange={setQuery}
|
|
||||||
groups={groups}
|
|
||||||
/>
|
|
||||||
</CMDKModal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
import { toast } from '@affine/component';
|
|
||||||
import { PublicLinkDisableModal } from '@affine/component/disable-public-link';
|
|
||||||
import { ShareMenu } from '@affine/core/components/affine/share-page-modal/share-menu';
|
|
||||||
import { WorkspaceFlavour } from '@affine/env/workspace';
|
|
||||||
import type { Doc } from '@blocksuite/store';
|
|
||||||
import { expect } from '@storybook/jest';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
import {
|
|
||||||
initEmptyPage,
|
|
||||||
useService,
|
|
||||||
WorkspaceService,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
import { nanoid } from 'nanoid';
|
|
||||||
import { useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/ShareMenu',
|
|
||||||
component: ShareMenu,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
async function unimplemented() {
|
|
||||||
toast('work in progress');
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Basic: StoryFn = () => {
|
|
||||||
const workspace = useService(WorkspaceService).workspace;
|
|
||||||
|
|
||||||
const [page, setPage] = useState<Doc | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const page = workspace.docCollection.createDoc({ id: nanoid() });
|
|
||||||
initEmptyPage(page);
|
|
||||||
|
|
||||||
setPage(page);
|
|
||||||
}, [workspace]);
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
return <div></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ShareMenu
|
|
||||||
currentPage={page}
|
|
||||||
workspaceMetadata={workspace}
|
|
||||||
onEnableAffineCloud={unimplemented}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Basic.play = async ({ canvasElement }) => {
|
|
||||||
{
|
|
||||||
const button = canvasElement.querySelector(
|
|
||||||
'[data-testid="share-menu-button"]'
|
|
||||||
) as HTMLButtonElement;
|
|
||||||
expect(button).not.toBeNull();
|
|
||||||
button.click();
|
|
||||||
}
|
|
||||||
await new Promise(resolve => window.setTimeout(resolve, 100));
|
|
||||||
{
|
|
||||||
const button = canvasElement.querySelector(
|
|
||||||
'[data-testid="share-menu-enable-affine-cloud-button"]'
|
|
||||||
);
|
|
||||||
expect(button).not.toBeNull();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AffineBasic: StoryFn = () => {
|
|
||||||
const workspace = useService(WorkspaceService).workspace;
|
|
||||||
|
|
||||||
const [page, setPage] = useState<Doc | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const page = workspace.docCollection.createDoc({ id: nanoid() });
|
|
||||||
initEmptyPage(page);
|
|
||||||
|
|
||||||
setPage(page);
|
|
||||||
}, [workspace]);
|
|
||||||
|
|
||||||
if (!page) {
|
|
||||||
return <div></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ShareMenu
|
|
||||||
currentPage={page}
|
|
||||||
workspaceMetadata={{
|
|
||||||
...workspace.meta,
|
|
||||||
flavour: WorkspaceFlavour.AFFINE_CLOUD,
|
|
||||||
}}
|
|
||||||
onEnableAffineCloud={unimplemented}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const DisableModal: StoryFn = () => {
|
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div onClick={() => setOpen(!open)}>Disable Public Link</div>
|
|
||||||
<PublicLinkDisableModal
|
|
||||||
open={open}
|
|
||||||
onConfirm={() => {
|
|
||||||
toast('Disabled');
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
onOpenChange={setOpen}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/* deepscan-disable USELESS_ARROW_FUNC_BIND */
|
|
||||||
import { Switch } from '@affine/component';
|
|
||||||
import type { Meta, StoryFn } from '@storybook/react';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/Switch',
|
|
||||||
component: Switch,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta;
|
|
||||||
|
|
||||||
export const Basic: StoryFn = () => {
|
|
||||||
return <Switch>Switch</Switch>;
|
|
||||||
};
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import type { WorkspaceListProps } from '@affine/component/workspace-list';
|
|
||||||
import { WorkspaceList } from '@affine/component/workspace-list';
|
|
||||||
import type { Meta } from '@storybook/react';
|
|
||||||
import {
|
|
||||||
useLiveData,
|
|
||||||
useService,
|
|
||||||
WorkspacesService,
|
|
||||||
} from '@toeverything/infra';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
title: 'AFFiNE/WorkspaceList',
|
|
||||||
component: WorkspaceList,
|
|
||||||
parameters: {
|
|
||||||
chromatic: { disableSnapshot: true },
|
|
||||||
},
|
|
||||||
} satisfies Meta<WorkspaceListProps>;
|
|
||||||
|
|
||||||
export const Default = () => {
|
|
||||||
const list = useLiveData(useService(WorkspacesService).list.workspaces$);
|
|
||||||
return (
|
|
||||||
<WorkspaceList
|
|
||||||
currentWorkspaceId={null}
|
|
||||||
items={list}
|
|
||||||
onClick={() => {}}
|
|
||||||
onSettingClick={() => {}}
|
|
||||||
onDragEnd={_ => {}}
|
|
||||||
useWorkspaceAvatar={() => undefined}
|
|
||||||
useWorkspaceName={() => undefined}
|
|
||||||
useIsWorkspaceOwner={() => false}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"include": ["./src/**/*", "./.storybook/**/*"],
|
|
||||||
"compilerOptions": {
|
|
||||||
// Workaround for storybook build
|
|
||||||
"baseUrl": "../..",
|
|
||||||
"composite": true,
|
|
||||||
"noEmit": false,
|
|
||||||
"outDir": "lib"
|
|
||||||
},
|
|
||||||
"references": [
|
|
||||||
{
|
|
||||||
"path": "../../packages/frontend/core"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../packages/frontend/component"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../tools/cli"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../packages/common/env"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../packages/common/infra"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "./tsconfig.node.json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"composite": true,
|
|
||||||
"module": "ESNext",
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"noEmit": false,
|
|
||||||
"outDir": "lib/.storybook"
|
|
||||||
},
|
|
||||||
"include": [".storybook"],
|
|
||||||
"exclude": ["lib"],
|
|
||||||
"references": [
|
|
||||||
{ "path": "../../packages/frontend/core" },
|
|
||||||
{ "path": "../../packages/frontend/i18n" },
|
|
||||||
{
|
|
||||||
"path": "../../packages/common/env"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "../../packages/frontend/core/tsconfig.node.json"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -126,9 +126,6 @@
|
|||||||
{
|
{
|
||||||
"path": "./tests/kit"
|
"path": "./tests/kit"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "./tests/storybook"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "./tests/affine-local"
|
"path": "./tests/affine-local"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -764,61 +764,6 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@affine/storybook@workspace:tests/storybook":
|
|
||||||
version: 0.0.0-use.local
|
|
||||||
resolution: "@affine/storybook@workspace:tests/storybook"
|
|
||||||
dependencies:
|
|
||||||
"@affine/cli": "workspace:*"
|
|
||||||
"@affine/component": "workspace:*"
|
|
||||||
"@affine/i18n": "workspace:*"
|
|
||||||
"@blocksuite/block-std": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@blocksuite/blocks": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@blocksuite/global": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@blocksuite/icons": "npm:2.1.46"
|
|
||||||
"@blocksuite/inline": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@blocksuite/presets": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@blocksuite/store": "npm:0.14.0-canary-202404151235-655ec84"
|
|
||||||
"@dnd-kit/sortable": "npm:^8.0.0"
|
|
||||||
"@storybook/addon-actions": "npm:^7.6.17"
|
|
||||||
"@storybook/addon-essentials": "npm:^7.6.17"
|
|
||||||
"@storybook/addon-interactions": "npm:^7.6.17"
|
|
||||||
"@storybook/addon-links": "npm:^7.6.17"
|
|
||||||
"@storybook/addon-storysource": "npm:^7.6.17"
|
|
||||||
"@storybook/blocks": "npm:^7.6.17"
|
|
||||||
"@storybook/builder-vite": "npm:^7.6.17"
|
|
||||||
"@storybook/jest": "npm:^0.2.3"
|
|
||||||
"@storybook/react": "npm:^7.6.17"
|
|
||||||
"@storybook/react-vite": "npm:^7.6.17"
|
|
||||||
"@storybook/test-runner": "npm:^0.17.0"
|
|
||||||
"@storybook/testing-library": "npm:^0.2.2"
|
|
||||||
"@vanilla-extract/esbuild-plugin": "npm:^2.3.5"
|
|
||||||
"@vitejs/plugin-react": "npm:^4.2.1"
|
|
||||||
chromatic: "npm:^11.3.0"
|
|
||||||
concurrently: "npm:^8.2.2"
|
|
||||||
foxact: "npm:^0.2.33"
|
|
||||||
jest-mock: "npm:^29.7.0"
|
|
||||||
jotai: "npm:^2.8.0"
|
|
||||||
lodash-es: "npm:^4.17.21"
|
|
||||||
nanoid: "npm:^5.0.7"
|
|
||||||
react: "npm:18.2.0"
|
|
||||||
react-dom: "npm:18.2.0"
|
|
||||||
react-router-dom: "npm:^6.22.3"
|
|
||||||
serve: "npm:^14.2.1"
|
|
||||||
ses: "npm:^1.4.1"
|
|
||||||
storybook: "npm:^7.6.17"
|
|
||||||
storybook-addon-react-router-v6: "npm:^2.0.15"
|
|
||||||
storybook-dark-mode: "npm:^3.0.3"
|
|
||||||
storybook-mock-date-decorator: "npm:^1.0.2"
|
|
||||||
wait-on: "npm:^7.2.0"
|
|
||||||
peerDependencies:
|
|
||||||
"@blocksuite/blocks": "*"
|
|
||||||
"@blocksuite/global": "*"
|
|
||||||
"@blocksuite/icons": 2.1.34
|
|
||||||
"@blocksuite/presets": "*"
|
|
||||||
"@blocksuite/store": "*"
|
|
||||||
languageName: unknown
|
|
||||||
linkType: soft
|
|
||||||
|
|
||||||
"@affine/templates@workspace:*, @affine/templates@workspace:packages/frontend/templates":
|
"@affine/templates@workspace:*, @affine/templates@workspace:packages/frontend/templates":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@affine/templates@workspace:packages/frontend/templates"
|
resolution: "@affine/templates@workspace:packages/frontend/templates"
|
||||||
@@ -2245,7 +2190,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.14.0, @babel/core@npm:^7.18.5, @babel/core@npm:^7.18.9, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.5, @babel/core@npm:^7.22.9, @babel/core@npm:^7.23.0, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.5, @babel/core@npm:^7.23.9, @babel/core@npm:^7.7.5":
|
"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.14.0, @babel/core@npm:^7.18.5, @babel/core@npm:^7.18.9, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.5, @babel/core@npm:^7.22.9, @babel/core@npm:^7.23.0, @babel/core@npm:^7.23.2, @babel/core@npm:^7.23.9, @babel/core@npm:^7.7.5":
|
||||||
version: 7.24.3
|
version: 7.24.3
|
||||||
resolution: "@babel/core@npm:7.24.3"
|
resolution: "@babel/core@npm:7.24.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3368,7 +3313,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/plugin-transform-react-jsx-self@npm:^7.18.6, @babel/plugin-transform-react-jsx-self@npm:^7.23.3":
|
"@babel/plugin-transform-react-jsx-self@npm:^7.18.6":
|
||||||
version: 7.23.3
|
version: 7.23.3
|
||||||
resolution: "@babel/plugin-transform-react-jsx-self@npm:7.23.3"
|
resolution: "@babel/plugin-transform-react-jsx-self@npm:7.23.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3379,7 +3324,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/plugin-transform-react-jsx-source@npm:^7.19.6, @babel/plugin-transform-react-jsx-source@npm:^7.23.3":
|
"@babel/plugin-transform-react-jsx-source@npm:^7.19.6":
|
||||||
version: 7.23.3
|
version: 7.23.3
|
||||||
resolution: "@babel/plugin-transform-react-jsx-source@npm:7.23.3"
|
resolution: "@babel/plugin-transform-react-jsx-source@npm:7.23.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3714,7 +3659,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2":
|
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.16.7, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.6, @babel/runtime@npm:^7.22.6, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2":
|
||||||
version: 7.23.9
|
version: 7.23.9
|
||||||
resolution: "@babel/runtime@npm:7.23.9"
|
resolution: "@babel/runtime@npm:7.23.9"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -14437,7 +14382,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14, @types/babel__core@npm:^7.18.0, @types/babel__core@npm:^7.20.5":
|
"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14, @types/babel__core@npm:^7.18.0":
|
||||||
version: 7.20.5
|
version: 7.20.5
|
||||||
resolution: "@types/babel__core@npm:7.20.5"
|
resolution: "@types/babel__core@npm:7.20.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -15747,20 +15692,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@vanilla-extract/esbuild-plugin@npm:^2.3.5":
|
|
||||||
version: 2.3.5
|
|
||||||
resolution: "@vanilla-extract/esbuild-plugin@npm:2.3.5"
|
|
||||||
dependencies:
|
|
||||||
"@vanilla-extract/integration": "npm:^7.0.0"
|
|
||||||
peerDependencies:
|
|
||||||
esbuild: ">=0.17.6"
|
|
||||||
peerDependenciesMeta:
|
|
||||||
esbuild:
|
|
||||||
optional: true
|
|
||||||
checksum: 10/5ef46dc86a3121a2f1bfa6758511cc16a1dda434d6faa0d4cae278bcd83c9d1f577abc476dfa75442ffcadd477af30d58ce1f3582ddf4ba2198eecff828cada6
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@vanilla-extract/integration@npm:^7.0.0, @vanilla-extract/integration@npm:^7.1.2":
|
"@vanilla-extract/integration@npm:^7.0.0, @vanilla-extract/integration@npm:^7.1.2":
|
||||||
version: 7.1.2
|
version: 7.1.2
|
||||||
resolution: "@vanilla-extract/integration@npm:7.1.2"
|
resolution: "@vanilla-extract/integration@npm:7.1.2"
|
||||||
@@ -15862,21 +15793,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@vitejs/plugin-react@npm:^4.2.1":
|
|
||||||
version: 4.2.1
|
|
||||||
resolution: "@vitejs/plugin-react@npm:4.2.1"
|
|
||||||
dependencies:
|
|
||||||
"@babel/core": "npm:^7.23.5"
|
|
||||||
"@babel/plugin-transform-react-jsx-self": "npm:^7.23.3"
|
|
||||||
"@babel/plugin-transform-react-jsx-source": "npm:^7.23.3"
|
|
||||||
"@types/babel__core": "npm:^7.20.5"
|
|
||||||
react-refresh: "npm:^0.14.0"
|
|
||||||
peerDependencies:
|
|
||||||
vite: ^4.2.0 || ^5.0.0
|
|
||||||
checksum: 10/d7fa6dacd3c246bcee482ff4b7037b2978b6ca002b79780ad4921e91ae4bc85ab234cfb94f8d4d825fed8488a0acdda2ff02b47c27b3055187c0727b18fc725e
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@vitest/coverage-istanbul@npm:1.4.0":
|
"@vitest/coverage-istanbul@npm:1.4.0":
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
resolution: "@vitest/coverage-istanbul@npm:1.4.0"
|
resolution: "@vitest/coverage-istanbul@npm:1.4.0"
|
||||||
@@ -18446,25 +18362,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"chromatic@npm:^11.3.0":
|
|
||||||
version: 11.3.0
|
|
||||||
resolution: "chromatic@npm:11.3.0"
|
|
||||||
peerDependencies:
|
|
||||||
"@chromatic-com/cypress": ^0.*.* || ^1.0.0
|
|
||||||
"@chromatic-com/playwright": ^0.*.* || ^1.0.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
"@chromatic-com/cypress":
|
|
||||||
optional: true
|
|
||||||
"@chromatic-com/playwright":
|
|
||||||
optional: true
|
|
||||||
bin:
|
|
||||||
chroma: dist/bin.js
|
|
||||||
chromatic: dist/bin.js
|
|
||||||
chromatic-cli: dist/bin.js
|
|
||||||
checksum: 10/fd8d0678c93bebe45cf087496a8b4c44967d06003bc26f18d7b5ce25db00962efd7fbb700f098f3196f1d65b037050ca785da0e07bfc1766ed81b2f9bbbad23f
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"chrome-trace-event@npm:^1.0.2, chrome-trace-event@npm:^1.0.3":
|
"chrome-trace-event@npm:^1.0.2, chrome-trace-event@npm:^1.0.3":
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
resolution: "chrome-trace-event@npm:1.0.3"
|
resolution: "chrome-trace-event@npm:1.0.3"
|
||||||
@@ -19023,13 +18920,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"compare-versions@npm:^6.0.0":
|
|
||||||
version: 6.1.0
|
|
||||||
resolution: "compare-versions@npm:6.1.0"
|
|
||||||
checksum: 10/20f349e7f8ad784704c68265f4e660e2abbe2c3d5c75793184fccb85f0c5c0263260e01fdd4488376f6b74b0f069e16c9684463f7316b075716fb1581eb36b77
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"component-emitter@npm:^1.3.0":
|
"component-emitter@npm:^1.3.0":
|
||||||
version: 1.3.1
|
version: 1.3.1
|
||||||
resolution: "component-emitter@npm:1.3.1"
|
resolution: "component-emitter@npm:1.3.1"
|
||||||
@@ -19103,26 +18993,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"concurrently@npm:^8.2.2":
|
|
||||||
version: 8.2.2
|
|
||||||
resolution: "concurrently@npm:8.2.2"
|
|
||||||
dependencies:
|
|
||||||
chalk: "npm:^4.1.2"
|
|
||||||
date-fns: "npm:^2.30.0"
|
|
||||||
lodash: "npm:^4.17.21"
|
|
||||||
rxjs: "npm:^7.8.1"
|
|
||||||
shell-quote: "npm:^1.8.1"
|
|
||||||
spawn-command: "npm:0.0.2"
|
|
||||||
supports-color: "npm:^8.1.1"
|
|
||||||
tree-kill: "npm:^1.2.2"
|
|
||||||
yargs: "npm:^17.7.2"
|
|
||||||
bin:
|
|
||||||
conc: dist/bin/concurrently.js
|
|
||||||
concurrently: dist/bin/concurrently.js
|
|
||||||
checksum: 10/dcb1aa69d9c611a7bda9d4fc0fe1e388f971d1744acec7e0d52dffa2ef55743f1266ec9292f414c5789b9f61734b3fce772bd005d4de9564a949fb121b97bae1
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"config-file-ts@npm:^0.2.4":
|
"config-file-ts@npm:^0.2.4":
|
||||||
version: 0.2.6
|
version: 0.2.6
|
||||||
resolution: "config-file-ts@npm:0.2.6"
|
resolution: "config-file-ts@npm:0.2.6"
|
||||||
@@ -19842,15 +19712,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"date-fns@npm:^2.30.0":
|
|
||||||
version: 2.30.0
|
|
||||||
resolution: "date-fns@npm:2.30.0"
|
|
||||||
dependencies:
|
|
||||||
"@babel/runtime": "npm:^7.21.0"
|
|
||||||
checksum: 10/70b3e8ea7aaaaeaa2cd80bd889622a4bcb5d8028b4de9162cbcda359db06e16ff6e9309e54eead5341e71031818497f19aaf9839c87d1aba1e27bb4796e758a9
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"date-fns@npm:^3.6.0":
|
"date-fns@npm:^3.6.0":
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
resolution: "date-fns@npm:3.6.0"
|
resolution: "date-fns@npm:3.6.0"
|
||||||
@@ -29012,13 +28873,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"mockdate@npm:^3.0.5":
|
|
||||||
version: 3.0.5
|
|
||||||
resolution: "mockdate@npm:3.0.5"
|
|
||||||
checksum: 10/ff74f43f56a12e1339e838aee623e37b6e4c378173905697f2a006a5c581eea9c71da54fcea76c27e7e744422e49395c668932bf09e67f024841240ffef91fd2
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"modern-ahocorasick@npm:^1.0.0":
|
"modern-ahocorasick@npm:^1.0.0":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "modern-ahocorasick@npm:1.0.1"
|
resolution: "modern-ahocorasick@npm:1.0.1"
|
||||||
@@ -31864,15 +31718,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"react-inspector@npm:6.0.2":
|
|
||||||
version: 6.0.2
|
|
||||||
resolution: "react-inspector@npm:6.0.2"
|
|
||||||
peerDependencies:
|
|
||||||
react: ^16.8.4 || ^17.0.0 || ^18.0.0
|
|
||||||
checksum: 10/5d23ad0f6f920458abd4c01af1b3cbdbe8846c254762fd6cfff4df119c54e08dd98ce8e91acacafb8173c19f07de2066df5b8e6cb19425751c1929a2620cbe77
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"react-is@npm:18.1.0":
|
"react-is@npm:18.1.0":
|
||||||
version: 18.1.0
|
version: 18.1.0
|
||||||
resolution: "react-is@npm:18.1.0"
|
resolution: "react-is@npm:18.1.0"
|
||||||
@@ -33873,13 +33718,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"spawn-command@npm:0.0.2":
|
|
||||||
version: 0.0.2
|
|
||||||
resolution: "spawn-command@npm:0.0.2"
|
|
||||||
checksum: 10/f13e8c3c63abd4a0b52fb567eba5f7940d480c5ed3ec61781d38a1850f179b1196c39e6efa2bbd301f82c1bf1cd7807abc8fbd8fc8e44bcaa3975a124c0d1657
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"spawn-wrap@npm:^2.0.0":
|
"spawn-wrap@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "spawn-wrap@npm:2.0.0"
|
resolution: "spawn-wrap@npm:2.0.0"
|
||||||
@@ -34134,32 +33972,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"storybook-addon-react-router-v6@npm:^2.0.15":
|
|
||||||
version: 2.0.15
|
|
||||||
resolution: "storybook-addon-react-router-v6@npm:2.0.15"
|
|
||||||
dependencies:
|
|
||||||
compare-versions: "npm:^6.0.0"
|
|
||||||
react-inspector: "npm:6.0.2"
|
|
||||||
peerDependencies:
|
|
||||||
"@storybook/blocks": ^7.0.0
|
|
||||||
"@storybook/channels": ^7.0.0
|
|
||||||
"@storybook/components": ^7.0.0
|
|
||||||
"@storybook/core-events": ^7.0.0
|
|
||||||
"@storybook/manager-api": ^7.0.0
|
|
||||||
"@storybook/preview-api": ^7.0.0
|
|
||||||
"@storybook/theming": ^7.0.0
|
|
||||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
|
||||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
|
|
||||||
react-router-dom: ^6.4.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
react:
|
|
||||||
optional: true
|
|
||||||
react-dom:
|
|
||||||
optional: true
|
|
||||||
checksum: 10/a6fbebd0f9b44b2866920c61d40e591adf6dc1fcd058814f349a78cded41c239e8f08448edec747b660476d55c44623caadef2b2de90321279debe60bafba4b9
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"storybook-dark-mode@npm:^3.0.3":
|
"storybook-dark-mode@npm:^3.0.3":
|
||||||
version: 3.0.3
|
version: 3.0.3
|
||||||
resolution: "storybook-dark-mode@npm:3.0.3"
|
resolution: "storybook-dark-mode@npm:3.0.3"
|
||||||
@@ -34184,17 +33996,6 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"storybook-mock-date-decorator@npm:^1.0.2":
|
|
||||||
version: 1.0.2
|
|
||||||
resolution: "storybook-mock-date-decorator@npm:1.0.2"
|
|
||||||
dependencies:
|
|
||||||
mockdate: "npm:^3.0.5"
|
|
||||||
peerDependencies:
|
|
||||||
"@storybook/addons": ">=6"
|
|
||||||
checksum: 10/c8e8b6966b58bd830c4837e6940328b9d32776c216bfcbc9f55bb38c5c192ab511670ff77505577737589bf83a7ad98538da1e62a2aa9c628e42e5998f2f6147
|
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"storybook@npm:^7.6.17":
|
"storybook@npm:^7.6.17":
|
||||||
version: 7.6.17
|
version: 7.6.17
|
||||||
resolution: "storybook@npm:7.6.17"
|
resolution: "storybook@npm:7.6.17"
|
||||||
@@ -34650,7 +34451,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1, supports-color@npm:~8.1.1":
|
"supports-color@npm:^8.0.0, supports-color@npm:~8.1.1":
|
||||||
version: 8.1.1
|
version: 8.1.1
|
||||||
resolution: "supports-color@npm:8.1.1"
|
resolution: "supports-color@npm:8.1.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -36735,7 +36536,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"wait-on@npm:^7.0.0, wait-on@npm:^7.2.0":
|
"wait-on@npm:^7.0.0":
|
||||||
version: 7.2.0
|
version: 7.2.0
|
||||||
resolution: "wait-on@npm:7.2.0"
|
resolution: "wait-on@npm:7.2.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user