chore: setup storybook

This commit is contained in:
Florian Duros 2025-06-20 14:20:26 +02:00
parent 2034f8b6bb
commit edc5e87056
No known key found for this signature in database
GPG Key ID: A5BBB4041B493F15
12 changed files with 1160 additions and 53 deletions

View File

@ -1,6 +1,11 @@
module.exports = {
plugins: ["matrix-org", "eslint-plugin-react-compiler"],
extends: ["plugin:matrix-org/babel", "plugin:matrix-org/react", "plugin:matrix-org/a11y"],
extends: [
"plugin:matrix-org/babel",
"plugin:matrix-org/react",
"plugin:matrix-org/a11y",
"plugin:storybook/recommended",
],
parserOptions: {
project: ["./tsconfig.json"],
},

3
.gitignore vendored
View File

@ -31,3 +31,6 @@ electron/pub
/index.html
# version file and tarball created by `npm pack` / `yarn pack`
/git-revision.txt
*storybook.log
storybook-static

View File

@ -0,0 +1,21 @@
import { create } from "storybook/theming";
export default create({
base: "light",
// Colors
textColor: "#1b1d22",
colorSecondary: "#111111",
// UI
appBg: "#ffffff",
appContentBg: "#ffffff",
// Toolbar
barBg: "#ffffff",
brandTitle: "Element Web",
brandUrl: "https://github.com/element-hq/element-web",
brandImage: "https://element.io/images/logo-ele-secondary.svg",
brandTarget: "_self",
});

46
.storybook/main.ts Normal file
View File

@ -0,0 +1,46 @@
import type { StorybookConfig } from "@storybook/react-webpack5";
const config: StorybookConfig = {
stories: ["../src/shared/**/*.mdx", "../src/shared/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-webpack5-compiler-swc",
"@storybook/addon-docs",
"@storybook/addon-designs",
{
name: "@storybook/addon-styling-webpack",
options: {
rules: [
{
test: /\.module.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 1,
modules: {
namedExport: false,
},
},
},
],
},
// Replaces existing CSS rules with given rule
{
test: /\.p?css$/,
exclude: /\.module.css$/,
use: ["style-loader", "css-loader"],
},
],
},
},
],
framework: "@storybook/react-webpack5",
core: {
disableTelemetry: true,
},
typescript: {
reactDocgen: "react-docgen-typescript",
},
};
export default config;

6
.storybook/manager.js Normal file
View File

@ -0,0 +1,6 @@
import { addons } from "storybook/manager-api";
import ElementTheme from "./ElementTheme";
addons.setConfig({
theme: ElementTheme,
});

3
.storybook/preview.css Normal file
View File

@ -0,0 +1,3 @@
.docs-story {
background: var(--cpd-color-bg-canvas-default);
}

56
.storybook/preview.tsx Normal file
View File

@ -0,0 +1,56 @@
import type { ArgTypes, Preview, Decorator } from "@storybook/react-webpack5";
import "../res/css/shared.pcss";
import "./preview.css";
import React, { useLayoutEffect } from "react";
export const globalTypes = {
theme: {
name: "Theme",
defaultValue: "system",
description: "Global theme for components",
toolbar: {
icon: "circlehollow",
title: "Theme",
items: [
{ title: "System", value: "system", icon: "browser" },
{ title: "Light", value: "light", icon: "sun" },
{ title: "Light (high contrast)", value: "light-hc", icon: "sun" },
{ title: "Dark", value: "dark", icon: "moon" },
{ title: "Dark (high contrast)", value: "dark-hc", icon: "moon" },
],
},
},
} satisfies ArgTypes;
const allThemesClasses = globalTypes.theme.toolbar.items.map(({ value }) => `cpd-theme-${value}`);
const ThemeSwitcher: React.FC<{
theme: string;
}> = ({ theme }) => {
useLayoutEffect(() => {
document.documentElement.classList.remove(...allThemesClasses);
if (theme !== "system") {
document.documentElement.classList.add(`cpd-theme-${theme}`);
}
return () => document.documentElement.classList.remove(...allThemesClasses);
}, [theme]);
return null;
};
const withThemeProvider: Decorator = (Story, context) => {
return (
<>
<ThemeSwitcher theme={context.globals.theme} />
<Story />
</>
);
};
const preview: Preview = {
tags: ["autodocs"],
decorators: [withThemeProvider],
};
export default preview;

8
declaration.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
declare module "*.module.css";

View File

@ -65,7 +65,9 @@
"coverage": "yarn test --coverage",
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp",
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js",
"postinstall": "patch-package"
"postinstall": "patch-package",
"storybook": "storybook dev -p 6007",
"build-storybook": "storybook build"
},
"resolutions": {
"**/pretty-format/react-is": "19.1.0",
@ -187,6 +189,11 @@
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
"@rrweb/types": "^2.0.0-alpha.18",
"@sentry/webpack-plugin": "^3.0.0",
"@storybook/addon-designs": "^10.0.1",
"@storybook/addon-docs": "^9.0.12",
"@storybook/addon-styling-webpack": "^2.0.0",
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
"@storybook/react-webpack5": "^9.0.12",
"@stylistic/eslint-plugin": "^4.0.0",
"@svgr/webpack": "^8.0.0",
"@testing-library/dom": "^10.4.0",
@ -246,6 +253,7 @@
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-storybook": "^9.0.12",
"eslint-plugin-unicorn": "^56.0.0",
"express": "^5.0.0",
"fake-indexeddb": "^6.0.0",
@ -286,6 +294,7 @@
"rimraf": "^6.0.0",
"semver": "^7.5.2",
"source-map-loader": "^5.0.0",
"storybook": "^9.0.12",
"stylelint": "^16.13.0",
"stylelint-config-standard": "^38.0.0",
"stylelint-scss": "^6.0.0",

9
res/css/shared.pcss Normal file
View File

@ -0,0 +1,9 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
@import url("@vector-im/compound-design-tokens/assets/web/css/compound-design-tokens.css") layer(compound);
@import url("@vector-im/compound-web/dist/style.css");

View File

@ -26,7 +26,8 @@
"./src/**/*.tsx",
"./test/**/*.ts",
"./test/**/*.tsx",
"./scripts/*.ts"
"./scripts/*.ts",
"./declaration.d.ts",
],
"ts-node": {
"files": true,

1040
yarn.lock

File diff suppressed because it is too large Load Diff