docs: note about Storybook

This commit is contained in:
Acid Chicken (硫酸鶏) 2023-03-24 23:22:49 +09:00
parent c2d8759812
commit bd7cc6ac38
No known key found for this signature in database
GPG Key ID: 3E87B98A3F6BAB99
6 changed files with 90 additions and 47 deletions

View File

@ -203,6 +203,90 @@ niraxは、Misskeyで使用しているオリジナルのフロントエンド
vue-routerとの最大の違いは、niraxは複数のルーターが存在することを許可している点です。 vue-routerとの最大の違いは、niraxは複数のルーターが存在することを許可している点です。
これにより、アプリ内ウィンドウでブラウザとは個別にルーティングすることなどが可能になります。 これにより、アプリ内ウィンドウでブラウザとは個別にルーティングすることなどが可能になります。
## Storybook
Misskey uses [Storybook](https://storybook.js.org/) for UI development.
### Setup
```bash
cd path/to/packages/frontend
pnpm tsc -p .storybook && (node .storybook/generate.js & node .storybook/preload-locale.js & node .storybook/preload-theme.js)
```
### Run
```bash
cd path/to/packages/frontend
pnpm storybook dev
```
### Usage
When you create a new component (in this example, `MyComponent.vue`), the story file (`MyComponent.stories.ts`) will be automatically generated by the `.storybook/generate.js` script.
You can override the default story by creating a impl story file (`MyComponent.stories.impl.ts`).
```ts
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-duplicates */
import { StoryObj } from '@storybook/vue3';
import MyComponent from './MyComponent.vue';
export const Default = {
render(args) {
return {
components: {
MyComponent,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...args,
};
},
},
template: '<MyComponent v-bind="props" />',
};
},
args: {
foo: 'bar',
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkAvatar>;
```
If you want to opt-out from the automatic generation, create a `MyComponent.stories.impl.ts` file and add the following line to the file.
```ts
import MyComponent from './MyComponent.vue';
void MyComponent;
```
You can use msw to mock API requests in the storybook. Creating a `MyComponent.stories.msw.ts` file and add the following line to the file.
```ts
import { rest } from 'msw';
export const handlers = [
rest.post('/api/notes/timeline', (req, res, ctx) => {
return res(
ctx.json({
notes: [],
users: [],
hasNext: false,
})
);
}),
];
```
Don't forget to re-run the `.storybook/generate.js` script after adding, editing, or removing the above files.
## Notes ## Notes
### How to resolve conflictions occurred at pnpm-lock.yaml? ### How to resolve conflictions occurred at pnpm-lock.yaml?

View File

@ -1,7 +1,6 @@
import { resolve } from 'node:path'; import { resolve } from 'node:path';
import type { StorybookConfig } from '@storybook/vue3-vite'; import type { StorybookConfig } from '@storybook/vue3-vite';
import { mergeConfig } from 'vite'; import { mergeConfig } from 'vite';
import { getConfig } from '../vite.config';
const config = { const config = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [ addons: [
@ -22,18 +21,9 @@ const config = {
disableTelemetry: true, disableTelemetry: true,
}, },
async viteFinal(config, options) { async viteFinal(config, options) {
const { plugins, build: { rollupOptions, ...build }, ...original } = getConfig(); return mergeConfig(config, {
console.dir(config, {depth:Infinity});
console.dir(original, {depth:Infinity});
const x = mergeConfig(config, {
...original,
build,
assetsInclude: [resolve(__dirname, '../node_modules/@tabler/icons-webfont/**/*.{css,eot,ttf,woff,woff2}')], assetsInclude: [resolve(__dirname, '../node_modules/@tabler/icons-webfont/**/*.{css,eot,ttf,woff,woff2}')],
server: {
hmr: false,
},
}); });
return x;
}, },
} satisfies StorybookConfig; } satisfies StorybookConfig;
export default config; export default config;

View File

@ -0,0 +1,2 @@
import MkCaptcha from './MkCaptcha.vue';
void MkCaptcha;

View File

@ -1,34 +1,10 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */ /* eslint-disable import/no-default-export */
import { Meta, StoryObj } from '@storybook/vue3'; import { Meta } from '@storybook/vue3';
import MkCaptcha from './MkCaptcha.vue';
const meta = { const meta = {
title: 'components/MkCaptcha', title: 'components/MkCaptcha',
component: MkCaptcha, component: MkCaptcha,
} satisfies Meta<typeof MkCaptcha>; } satisfies Meta<typeof MkCaptcha>;
export const Default = {
render(args) {
return {
components: {
MkCaptcha,
},
setup() {
return {
args,
};
},
computed: {
props() {
return {
...args,
};
},
},
template: '<MkCaptcha v-bind="props" />',
};
},
parameters: {
layout: 'centered',
},
} satisfies StoryObj<typeof MkCaptcha>;
export default meta; export default meta;
import MkCaptcha from './MkCaptcha.vue';
void MkCaptcha;

View File

@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
/* eslint-disable import/no-duplicates */ /* eslint-disable import/no-duplicates */
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkAvatar from './MkAvatar.vue'; import MkAvatar from './MkAvatar.vue';

View File

@ -7,7 +7,6 @@ const meta = {
} satisfies Meta<typeof MkAvatar>; } satisfies Meta<typeof MkAvatar>;
export default meta; export default meta;
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable import/no-default-export */
/* eslint-disable import/no-duplicates */ /* eslint-disable import/no-duplicates */
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkAvatar from './MkAvatar.vue'; import MkAvatar from './MkAvatar.vue';
@ -68,13 +67,6 @@ export const ProfilePageCat = {
user: { user: {
...ProfilePage.args.user, ...ProfilePage.args.user,
isCat: true, isCat: true,
// avatarUrl: 'https://millionlive-theaterdays.idolmaster-official.jp/assets/data/webp/common/footer/icon_app.png.webp',
// avatarUrl: 'https://cdn.imastodon.net/accounts/avatars/000/144/021/original/8137afa4114ab85f.png',
// avatarUrl: 'https://avatars.githubusercontent.com/u/4439005?v=4',
// avatarUrl: 'https://avatars.githubusercontent.com/u/7973572?v=4',
// avatarUrl: 'https://avatars.githubusercontent.com/u/6533808?v=4',
// avatarUrl: 'https://avatars.githubusercontent.com/u/7106976?v=4',
avatarUrl: 'https://avatars.githubusercontent.com/u/3396686?v=4',
}, },
}, },
}; };