cherrypick/packages/frontend/.storybook/preview.ts
Acid Chicken (硫酸鶏) 38d0b62167
build(#10336): Storybook & Chromatic & msw (#10365)
* build(#10336): init

* fix(#10336): invalid name conversion

* build(#10336): load locales and vite config

* refactor(#10336): remove unused imports

* build(#10336): separate definitions and generated codes

* refactor(#10336): remove hatches

* refactor(#10336): module semantics

* refactor(#10336): remove unused common preferences

* fix: typo

* build(#10336): mock assets

* build(#10336): impl `SatisfiesExpression`

* build(#10336): control themes

* refactor(#10336): semantics

* build(#10336): make .storybook as an individual TypeScript project

* style(#10336): use single quote

* build(#10336): avoid intrinsic component names

* chore: suppress linter

* style: typing

* build(#10336): update dependencies

* docs: note about Storybook

* build(#10336): sync

* build(#10336): full reload server on change

* chore: use defaultStore instead

* build(#10336): show popups on Story

* refactor(#10336): remove redundant div

* docs: fix

* build(#10336): interactions

* build(#10336): add an interaction test for `<MkA/>`

* build(#10336): bump storybook

* docs(#10336): mention to pre-build misskey-js

* build(#10336): write stories for `MkAcct`

* build(#10336): write stories for `MkAd`

* build(#10336): fix missing type definition

* build(#10336): use `toHaveTextContent`

* build(#10336): write some stories

* build(#10336): hide internal args

* build(#10336): generate `components/global` stories only

* build(#10336): write stories for `MkMisskeyFlavoredMarkdown`

* fix: conflict errors

* build(#10336): subcomponents on sidebar

* refactor: restore `SatisfiesExpression`

* docs(#10336): note development status

* build(#10336): use chokidar-cli

* docs(#10336): note chokidar-cli mode

* chore(#10336): untrack generated stories files

* fix: pointer handling

* build(#10336): finalize

* chore: add static option to `MkLoading`

* refactor(#10336): bind to local args

* fix: missing case

* revert: restore `SatisfiesExpression`

This reverts commit f246699f38.

* build(#10336): make storybook buildable

* build(#10336): staticify assets

* build(#10336): staticified directory structure

* build(#10336): normalize path for Windows

* ci(#10336): create actions

* build(#10336): ignore tsc errors

* build(#10336): ignore tsc errors

* build(#10336): missing dependencies

* build(#10336): missing dependencies

* build(#10336): use fast-glob

* fix: invalid lockfile

* ci(#10336): increase heap size

* build(#10336): use unpkg for storybook tabler icons

* build(#10336): use unpkg for storybook twemojis

* build(#10336): disable `ProfilePageCat`

* build(#10336): blur `MkA` before interaction ends

* ci(#10336): stabilize

* ci(#10336): fetch-depth

* build(#10336): isChromatic

* ci(#10336): notify on changes

* ci(#10336): fix typo

* ci(#10336): missing working directory

* ci(#10336): skip build

* ci(#10336): fix path

* build(#10336): fails on Windows

* build(#10336): available on Windows

* ci(#10336): disable animation on chromatic

* ci(#10336): add static option to `PageHeader.tabs`

* chore: void

* ci(#10336): change parameters

* docs(#10336): update CONTRIBUTING

* docs(#10336): note about meta overriding and etc.

* ci(#10336): use Chromatic for checks

* ci(#10336): use `pull_request` instead of `pull_request_target` for now

* ci(#10336): use `exitOnceUploaded`

* ci(#10336): reuse built storybook

* ci(#10336): back to `pull_request_target`

* chore: unused dependencies

* style(#10336): reduce prettier indents

* style: note about `TSSatisfiesExpression`
2023-04-04 09:38:34 +09:00

114 lines
2.8 KiB
TypeScript

import { addons } from '@storybook/addons';
import { FORCE_REMOUNT } from '@storybook/core-events';
import { type Preview, setup } from '@storybook/vue3';
import isChromatic from 'chromatic/isChromatic';
import { initialize, mswDecorator } from 'msw-storybook-addon';
import locale from './locale';
import { commonHandlers, onUnhandledRequest } from './mocks';
import themes from './themes';
import '../src/style.scss';
const appInitialized = Symbol();
let moduleInitialized = false;
let unobserve = () => {};
let misskeyOS = null;
function loadTheme(applyTheme: typeof import('../src/scripts/theme')['applyTheme']) {
unobserve();
const theme = themes[document.documentElement.dataset.misskeyTheme];
if (theme) {
applyTheme(themes[document.documentElement.dataset.misskeyTheme]);
} else if (isChromatic()) {
applyTheme(themes['l-light']);
}
const observer = new MutationObserver((entries) => {
for (const entry of entries) {
if (entry.attributeName === 'data-misskey-theme') {
const target = entry.target as HTMLElement;
const theme = themes[target.dataset.misskeyTheme];
if (theme) {
applyTheme(themes[target.dataset.misskeyTheme]);
} else {
target.removeAttribute('style');
}
}
}
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-misskey-theme'],
});
unobserve = () => observer.disconnect();
}
initialize({
onUnhandledRequest,
});
localStorage.setItem("locale", JSON.stringify(locale));
queueMicrotask(() => {
Promise.all([
import('../src/components'),
import('../src/directives'),
import('../src/widgets'),
import('../src/scripts/theme'),
import('../src/store'),
import('../src/os'),
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }, { defaultStore }, os]) => {
setup((app) => {
moduleInitialized = true;
if (app[appInitialized]) {
return;
}
app[appInitialized] = true;
loadTheme(applyTheme);
components(app);
directives(app);
widgets(app);
misskeyOS = os;
if (isChromatic()) {
defaultStore.set('animation', false);
}
});
});
});
const preview = {
decorators: [
(Story, context) => {
const story = Story();
if (!moduleInitialized) {
const channel = addons.getChannel();
(globalThis.requestIdleCallback || setTimeout)(() => {
channel.emit(FORCE_REMOUNT, { storyId: context.id });
});
}
return story;
},
mswDecorator,
(Story, context) => {
return {
setup() {
return {
context,
popups: misskeyOS.popups,
};
},
template:
'<component :is="popup.component" v-for="popup in popups" :key="popup.id" v-bind="popup.props" v-on="popup.events"/>' +
'<story />',
};
},
],
parameters: {
controls: {
exclude: /^__/,
},
msw: {
handlers: commonHandlers,
},
},
} satisfies Preview;
export default preview;