Files
letro-authentication-service/frontend/.storybook/preview.tsx
Quentin Gliech 77bc13fe70 Full-page stories
2024-11-15 09:51:16 +01:00

129 lines
2.8 KiB
TypeScript

// Copyright 2024 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
import type {
ArgTypes,
Decorator,
Parameters,
Preview,
} from "@storybook/react";
import { TooltipProvider } from "@vector-im/compound-web";
import { initialize, mswLoader } from "msw-storybook-addon";
import { useLayoutEffect } from "react";
import "../src/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",
},
handlers,
);
setupI18n();
export const parameters: Parameters = {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};
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 withDummyRouter: Decorator = (Story, _context) => {
return (
<DummyRouter>
<Story />
</DummyRouter>
);
};
const withTooltipProvider: Decorator = (Story, _context) => {
return (
<TooltipProvider>
<Story />
</TooltipProvider>
);
};
export const decorators: Decorator[] = [
withThemeProvider,
withDummyRouter,
withTooltipProvider,
];
const locales = Object.fromEntries(
localazyMetadata.languages.map(({ language, name, localizedName }) => [
language,
`${localizedName} (${name})`,
]),
);
const preview: Preview = {
initialGlobals: {
locale: localazyMetadata.baseLocale,
locales,
},
parameters: {
i18n,
},
loaders: [mswLoader],
};
export default preview;