build(#10336): control themes
This commit is contained in:
parent
bdbbb92ff6
commit
0ac4d744fd
7 changed files with 843 additions and 195 deletions
8
packages/frontend/.storybook/.gitignore
vendored
8
packages/frontend/.storybook/.gitignore
vendored
|
@ -1,8 +1,8 @@
|
|||
# (cd .; pnpm tsc --jsx react --jsxFactory h ./generate.tsx && node ./generate.js)
|
||||
# (cd path/to/frontend; pnpm tsc --jsx react --jsxFactory h .storybook/generate.tsx && node .storybook/generate.js)
|
||||
/generate.js
|
||||
# (cd .; pnpm tsc ./preload-locale.ts && node ./preload-locale.js)
|
||||
# (cd path/to/frontend; pnpm tsc .storybook/preload-locale.ts && node .storybook/preload-locale.js)
|
||||
/preload-locale.js
|
||||
/locale.ts
|
||||
# (cd .; pnpm tsc ./preload-theme.ts && node ./preload-theme.js)
|
||||
# (cd path/to/frontend; pnpm tsc .storybook/preload-theme.ts && node .storybook/preload-theme.js)
|
||||
/preload-theme.js
|
||||
/theme.ts
|
||||
/themes.ts
|
||||
|
|
|
@ -8,6 +8,7 @@ const config = {
|
|||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
'@storybook/addon-interactions',
|
||||
'../node_modules/storybook-addon-misskey-theme',
|
||||
],
|
||||
framework: {
|
||||
name: '@storybook/vue3-vite',
|
||||
|
|
|
@ -2,19 +2,35 @@ import { readFile, writeFile } from 'node:fs/promises';
|
|||
import { resolve } from 'node:path';
|
||||
import * as JSON5 from 'json5';
|
||||
|
||||
Promise.all([
|
||||
readFile(resolve(__dirname, '../src/themes/_light.json5'), 'utf8'),
|
||||
readFile(resolve(__dirname, '../src/themes/l-light.json5'), 'utf8'),
|
||||
]).then((sources) => {
|
||||
const base = JSON5.parse(sources[0]);
|
||||
const theme = JSON5.parse(sources[1]);
|
||||
const keys = [
|
||||
'_dark',
|
||||
'_light',
|
||||
'l-light',
|
||||
'l-coffee',
|
||||
'l-apricot',
|
||||
'l-rainy',
|
||||
'l-botanical',
|
||||
'l-vivid',
|
||||
'l-cherry',
|
||||
'l-sushi',
|
||||
'l-u0',
|
||||
'd-dark',
|
||||
'd-persimmon',
|
||||
'd-astro',
|
||||
'd-future',
|
||||
'd-botanical',
|
||||
'd-green-lime',
|
||||
'd-green-orange',
|
||||
'd-cherry',
|
||||
'd-ice',
|
||||
'd-u0',
|
||||
]
|
||||
|
||||
Promise.all(keys.map((key) => readFile(resolve(__dirname, `../src/themes/${key}.json5`), 'utf8'))).then((sources) => {
|
||||
writeFile(
|
||||
resolve(__dirname, './theme.ts'),
|
||||
resolve(__dirname, './themes.ts'),
|
||||
`export default ${JSON.stringify(
|
||||
Object.assign(theme, {
|
||||
base: undefined,
|
||||
props: Object.assign(base.props, theme.props),
|
||||
}),
|
||||
Object.fromEntries(sources.map((source, i) => [keys[i], JSON5.parse(source)])),
|
||||
undefined,
|
||||
2,
|
||||
)} as const;`,
|
||||
|
|
|
@ -1,30 +1,75 @@
|
|||
import { type Preview, setup } from '@storybook/vue3';
|
||||
import { addons } from '@storybook/addons';
|
||||
import { FORCE_REMOUNT } from '@storybook/core-events';
|
||||
import { type Preview, forceReRender, setup } from '@storybook/vue3';
|
||||
import { initialize, mswDecorator } from 'msw-storybook-addon';
|
||||
import locale from './locale';
|
||||
import { commonHandlers, onUnhandledRequest } from './mocks';
|
||||
import theme from './theme';
|
||||
import themes from './themes';
|
||||
import '../src/style.scss';
|
||||
|
||||
let initialized = false;
|
||||
let unobserve = () => {};
|
||||
|
||||
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]);
|
||||
}
|
||||
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));
|
||||
Promise.all([
|
||||
import('../src/components'),
|
||||
import('../src/directives'),
|
||||
import('../src/widgets'),
|
||||
import('../src/scripts/theme').then(({ applyTheme }) => applyTheme(theme)),
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }]) => {
|
||||
setup((app) => {
|
||||
components(app);
|
||||
directives(app);
|
||||
widgets(app);
|
||||
queueMicrotask(() => {
|
||||
Promise.all([
|
||||
import('../src/components'),
|
||||
import('../src/directives'),
|
||||
import('../src/widgets'),
|
||||
import('../src/scripts/theme'),
|
||||
]).then(([{ default: components }, { default: directives }, { default: widgets }, { applyTheme }]) => {
|
||||
setup((app) => {
|
||||
initialized = true;
|
||||
loadTheme(applyTheme);
|
||||
components(app);
|
||||
directives(app);
|
||||
widgets(app);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const preview = {
|
||||
decorators: [
|
||||
mswDecorator,
|
||||
(Story, context) => {
|
||||
const story = Story();
|
||||
if (!initialized) {
|
||||
const channel = addons.getChannel();
|
||||
requestIdleCallback(() => {
|
||||
channel.emit(FORCE_REMOUNT, { storyId: context.id });
|
||||
});
|
||||
}
|
||||
return story;
|
||||
}
|
||||
],
|
||||
parameters: {
|
||||
msw: {
|
||||
|
|
|
@ -75,10 +75,16 @@
|
|||
"@storybook/addon-essentials": "^7.0.0-rc.4",
|
||||
"@storybook/addon-interactions": "^7.0.0-rc.4",
|
||||
"@storybook/addon-links": "^7.0.0-rc.4",
|
||||
"@storybook/addons": "7.0.0-rc.5",
|
||||
"@storybook/blocks": "^7.0.0-rc.4",
|
||||
"@storybook/manager-api": "7.0.0-rc.4",
|
||||
"@storybook/core-events": "^7.0.0-rc.4",
|
||||
"@storybook/manager-api": "^7.0.0-rc.4",
|
||||
"@storybook/preview-api": "^7.0.0-rc.4",
|
||||
"@storybook/react": "^7.0.0-rc.4",
|
||||
"@storybook/react-vite": "^7.0.0-rc.4",
|
||||
"@storybook/testing-library": "^0.0.14-next.1",
|
||||
"@storybook/theming": "7.0.0-rc.4",
|
||||
"@storybook/theming": "^7.0.0-rc.4",
|
||||
"@storybook/types": "^7.0.0-rc.4",
|
||||
"@storybook/vue3": "^7.0.0-rc.4",
|
||||
"@storybook/vue3-vite": "^7.0.0-rc.4",
|
||||
"@testing-library/vue": "^6.6.1",
|
||||
|
@ -114,6 +120,7 @@
|
|||
"react-dom": "^18.2.0",
|
||||
"start-server-and-test": "2.0.0",
|
||||
"storybook": "^7.0.0-rc.4",
|
||||
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
|
||||
"summaly": "github:misskey-dev/summaly",
|
||||
"vitest": "^0.29.2",
|
||||
"vitest-fetch-mock": "^0.2.2",
|
||||
|
|
|
@ -3,7 +3,6 @@ export class I18n<T extends Record<string, any>> {
|
|||
|
||||
constructor(locale: T) {
|
||||
this.ts = locale;
|
||||
console.log(this);
|
||||
|
||||
//#region BIND
|
||||
this.t = this.t.bind(this);
|
||||
|
|
910
pnpm-lock.yaml
910
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue