diff --git a/.github/renovate.json5 b/.github/renovate.json5
index 048d88e4f6..6d6fbbd253 100644
--- a/.github/renovate.json5
+++ b/.github/renovate.json5
@@ -209,6 +209,7 @@
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-links",
+ "@storybook/addon-themes",
"@storybook/angular",
"@storybook/manager-api",
"@storybook/theming",
diff --git a/.storybook/main.ts b/.storybook/main.ts
index d98ca06ead..9583d1fc6f 100644
--- a/.storybook/main.ts
+++ b/.storybook/main.ts
@@ -29,6 +29,7 @@ const config: StorybookConfig = {
getAbsolutePath("@storybook/addon-a11y"),
getAbsolutePath("@storybook/addon-designs"),
getAbsolutePath("@storybook/addon-interactions"),
+ getAbsolutePath("@storybook/addon-themes"),
{
// @storybook/addon-docs is part of @storybook/addon-essentials
// eslint-disable-next-line storybook/no-uninstalled-addons
diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx
index 85515068b3..6bd28cfe80 100644
--- a/.storybook/preview.tsx
+++ b/.storybook/preview.tsx
@@ -1,60 +1,30 @@
import { setCompodocJson } from "@storybook/addon-docs/angular";
+import { withThemeByClassName } from "@storybook/addon-themes";
import { componentWrapperDecorator } from "@storybook/angular";
import type { Preview } from "@storybook/angular";
import docJson from "../documentation.json";
setCompodocJson(docJson);
-const decorator = componentWrapperDecorator(
- (story) => {
- return /*html*/ `
-
- ${story}
-
+const wrapperDecorator = componentWrapperDecorator((story) => {
+ return /*html*/ `
+
+ ${story}
+
`;
- },
- ({ globals }) => {
- // We need to add the theme class to the body to support body-appended content like popovers and menus
- document.body.classList.remove("theme_light");
- document.body.classList.remove("theme_dark");
-
- document.body.classList.add(`theme_${globals["theme"]}`);
-
- return { theme: `${globals["theme"]}` };
- },
-);
+});
const preview: Preview = {
- decorators: [decorator],
- globalTypes: {
- theme: {
- description: "Global theme for components",
- defaultValue: "light",
- toolbar: {
- title: "Theme",
- icon: "circlehollow",
- items: [
- {
- title: "Light",
- value: "light",
- icon: "sun",
- },
- {
- title: "Dark",
- value: "dark",
- icon: "moon",
- },
- ],
- dynamicTitle: true,
+ decorators: [
+ withThemeByClassName({
+ themes: {
+ light: "theme_light",
+ dark: "theme_dark",
},
- },
- },
+ defaultTheme: "light",
+ }),
+ wrapperDecorator,
+ ],
parameters: {
controls: {
matchers: {
@@ -69,6 +39,9 @@ const preview: Preview = {
},
},
docs: { source: { type: "dynamic", excludeDecorators: true } },
+ backgrounds: {
+ disable: true,
+ },
},
tags: ["autodocs"],
};
diff --git a/libs/components/src/drawer/drawer.stories.ts b/libs/components/src/drawer/drawer.stories.ts
index 54b4c89f4c..a524c9a7a1 100644
--- a/libs/components/src/drawer/drawer.stories.ts
+++ b/libs/components/src/drawer/drawer.stories.ts
@@ -9,10 +9,7 @@ import { ButtonModule } from "../button";
import { CalloutModule } from "../callout";
import { LayoutComponent } from "../layout";
import { mockLayoutI18n } from "../layout/mocks";
-import {
- disableBothThemeDecorator,
- positionFixedWrapperDecorator,
-} from "../stories/storybook-decorators";
+import { positionFixedWrapperDecorator } from "../stories/storybook-decorators";
import { TypographyModule } from "../typography";
import { I18nMockService } from "../utils";
@@ -30,7 +27,6 @@ export default {
},
decorators: [
positionFixedWrapperDecorator(),
- disableBothThemeDecorator,
moduleMetadata({
imports: [
RouterTestingModule,
diff --git a/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts b/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts
index 62b9398438..af3b082d1c 100644
--- a/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts
+++ b/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts
@@ -17,7 +17,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { DialogService } from "../../dialog";
import { LayoutComponent } from "../../layout";
import { I18nMockService } from "../../utils/i18n-mock.service";
-import { disableBothThemeDecorator, positionFixedWrapperDecorator } from "../storybook-decorators";
+import { positionFixedWrapperDecorator } from "../storybook-decorators";
import { DialogVirtualScrollBlockComponent } from "./components/dialog-virtual-scroll-block.component";
import { KitchenSinkForm } from "./components/kitchen-sink-form.component";
@@ -31,7 +31,6 @@ export default {
component: LayoutComponent,
decorators: [
positionFixedWrapperDecorator(),
- disableBothThemeDecorator,
moduleMetadata({
imports: [
KitchenSinkSharedModule,
diff --git a/libs/components/src/stories/storybook-decorators.ts b/libs/components/src/stories/storybook-decorators.ts
index ec0df264c7..d1146a7cd9 100644
--- a/libs/components/src/stories/storybook-decorators.ts
+++ b/libs/components/src/stories/storybook-decorators.ts
@@ -17,15 +17,3 @@ export const positionFixedWrapperDecorator = (wrapper?: (story: string) => strin
${wrapper ? wrapper(story) : story}
`,
);
-
-export const disableBothThemeDecorator = componentWrapperDecorator(
- (story) => story,
- ({ globals }) => {
- /**
- * avoid a bug with the way that we render the same component twice in the same iframe and how
- * that interacts with the router-outlet
- */
- const themeOverride = globals["theme"] === "both" ? "light" : globals["theme"];
- return { theme: themeOverride };
- },
-);
diff --git a/package-lock.json b/package-lock.json
index 5963538362..744e137009 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -91,6 +91,7 @@
"@storybook/addon-essentials": "8.5.2",
"@storybook/addon-interactions": "8.5.2",
"@storybook/addon-links": "8.5.2",
+ "@storybook/addon-themes": "^8.5.2",
"@storybook/angular": "8.5.2",
"@storybook/manager-api": "8.5.2",
"@storybook/theming": "8.5.2",
@@ -8713,6 +8714,22 @@
"storybook": "^8.5.2"
}
},
+ "node_modules/@storybook/addon-themes": {
+ "version": "8.5.2",
+ "resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.5.2.tgz",
+ "integrity": "sha512-MTJkPwXqLK2Co186EUw2wr+1CpVRMbuWsOmQvhMHeU704kQtSYKkhu/xmaExuDYMupn5xiKG0p8Pt5Ck3fEObQ==",
+ "dev": true,
+ "dependencies": {
+ "ts-dedent": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/storybook"
+ },
+ "peerDependencies": {
+ "storybook": "^8.5.2"
+ }
+ },
"node_modules/@storybook/addon-toolbars": {
"version": "8.5.2",
"resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.5.2.tgz",
diff --git a/package.json b/package.json
index 4762bad20a..e25493335b 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"@storybook/addon-essentials": "8.5.2",
"@storybook/addon-interactions": "8.5.2",
"@storybook/addon-links": "8.5.2",
+ "@storybook/addon-themes": "8.5.2",
"@storybook/angular": "8.5.2",
"@storybook/manager-api": "8.5.2",
"@storybook/theming": "8.5.2",