Files
letro-authentication-service/frontend/.storybook/preview.tsx
2025-11-19 13:38:36 +01:00

153 lines
3.5 KiB
TypeScript

// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
import type { Decorator, Preview } from "@storybook/react-vite";
import { TooltipProvider } from "@vector-im/compound-web";
import { initialize, mswLoader } from "msw-storybook-addon";
import { useEffect, useLayoutEffect } from "react";
import { I18nextProvider } from "react-i18next";
import "../src/entrypoints/shared.css";
import i18n, { setupI18n } from "../src/i18n";
import { DummyRouter } from "../src/test-utils/router";
import { handlers } from "../tests/mocks/handlers";
import localazyMetadata from "./locales";
initialize(
{
onUnhandledRequest: "bypass",
serviceWorker: {
url: "./mockServiceWorker.js",
},
},
handlers,
);
setupI18n();
const allThemesClasses = [
"cpd-theme-light",
"cpd-theme-light-hc",
"cpd-theme-dark",
"cpd-theme-dark-hc",
];
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 LocaleSwitcher: React.FC<{
locale: string;
}> = ({ locale }) => {
useEffect(() => {
i18n.changeLanguage(locale);
}, [locale]);
return null;
};
const withI18nProvider: Decorator = (Story, context) => {
return (
<>
<LocaleSwitcher locale={context.globals.locale} />
<I18nextProvider i18n={i18n}>
<Story />
</I18nextProvider>
</>
);
};
const withDummyRouter: Decorator = (Story, _context) => {
return (
<DummyRouter>
<Story />
</DummyRouter>
);
};
const withTooltipProvider: Decorator = (Story, _context) => {
return (
<TooltipProvider>
<Story />
</TooltipProvider>
);
};
const preview: Preview = {
loaders: [mswLoader],
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
decorators: [
withI18nProvider,
withThemeProvider,
withDummyRouter,
withTooltipProvider,
],
globalTypes: {
theme: {
name: "Theme",
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" },
],
},
},
locale: {
name: "Locale",
description: "Locale for the app",
toolbar: {
title: "Language",
icon: "globe",
items: localazyMetadata.languages.map(
({ language, localizedName, name }) => ({
title: `${localizedName} (${name})`,
value: language,
}),
),
},
},
},
initialGlobals: {
locale: localazyMetadata.baseLocale,
theme: "system",
},
tags: ["autodocs"],
};
export default preview;