diff --git a/packages/canon/.storybook/main.ts b/packages/canon/.storybook/main.ts
index 3020ade96e..262862c657 100644
--- a/packages/canon/.storybook/main.ts
+++ b/packages/canon/.storybook/main.ts
@@ -15,7 +15,6 @@ const config: StorybookConfig = {
getAbsolutePath('@storybook/addon-webpack5-compiler-swc'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@storybook/addon-interactions'),
- getAbsolutePath('@storybook/addon-themes'),
],
framework: {
name: getAbsolutePath('@storybook/react-webpack5'),
diff --git a/packages/canon/.storybook/preview.tsx b/packages/canon/.storybook/preview.tsx
index 516f554e12..645b328cb2 100644
--- a/packages/canon/.storybook/preview.tsx
+++ b/packages/canon/.storybook/preview.tsx
@@ -1,6 +1,6 @@
-import React from 'react';
-import type { Preview, ReactRenderer } from '@storybook/react';
-import { withThemeByDataAttribute } from '@storybook/addon-themes';
+import React, { useEffect } from 'react';
+import type { Decorator, Preview, ReactRenderer } from '@storybook/react';
+import { useGlobals } from '@storybook/preview-api';
// Default Backstage theme
import '../src/css/styles.css';
@@ -8,7 +8,67 @@ import '../src/css/styles.css';
// Custom themes
import './themes/spotify.css';
+export const withThemes: Decorator = StoryFn => {
+ const [globals] = useGlobals();
+ const selectedTheme = globals.themeMode || 'light';
+ const selectedThemeName = globals.themeName || 'default';
+
+ useEffect(() => {
+ const htmlElement = document.documentElement;
+
+ // Remove any existing theme data attributes
+ htmlElement.removeAttribute('data-theme');
+ htmlElement.removeAttribute('data-theme-name');
+
+ // Add the selected theme data attribute
+ htmlElement.setAttribute('data-theme', selectedTheme);
+ htmlElement.setAttribute('data-theme-name', selectedThemeName);
+
+ // Cleanup on unmount
+ return () => {
+ htmlElement.removeAttribute('data-theme');
+ htmlElement.removeAttribute('data-theme-name');
+ };
+ }, [selectedTheme, selectedThemeName]);
+
+ return ;
+};
+
const preview: Preview = {
+ globalTypes: {
+ themeMode: {
+ name: 'Theme Mode',
+ description: 'Global theme mode for components',
+ defaultValue: 'light',
+ toolbar: {
+ icon: 'circlehollow',
+ items: [
+ { value: 'light', icon: 'circlehollow', title: 'Light' },
+ { value: 'dark', icon: 'circle', title: 'Dark' },
+ ],
+ showName: true,
+ dynamicTitle: true,
+ },
+ },
+ themeName: {
+ name: 'Theme Name',
+ description: 'Global theme name for components',
+ defaultValue: 'default',
+ toolbar: {
+ icon: 'paintbrush',
+ items: [
+ { value: 'default', title: 'Default (Backstage)' },
+ { value: 'spotify', title: 'Spotify' },
+ ],
+ showName: true,
+ dynamicTitle: true,
+ },
+ },
+ },
+ initialGlobals: {
+ themeMode: 'light',
+ themeName: 'default',
+ },
parameters: {
controls: {
matchers: {
@@ -73,15 +133,7 @@ const preview: Preview = {
},
},
decorators: [
- withThemeByDataAttribute({
- themes: {
- ['Backstage Light']: 'light',
- ['Backstage Dark']: 'dark',
- ['Spotify Light']: 'spotify-light',
- ['Spotify Dark']: 'spotify-dark',
- },
- defaultTheme: 'Backstage Light',
- }),
+ withThemes,
Story => {
document.body.style.backgroundColor = 'var(--canon-bg)';
diff --git a/packages/canon/.storybook/themes/spotify.css b/packages/canon/.storybook/themes/spotify.css
index b912bb5ea0..74c7138a21 100644
--- a/packages/canon/.storybook/themes/spotify.css
+++ b/packages/canon/.storybook/themes/spotify.css
@@ -22,7 +22,7 @@
format('woff');
}
-[data-theme='spotify-dark'] {
+[data-theme='dark'][data-theme-name='spotify'] {
--canon-font-text: CircularSp, CircularSp-Arab, CircularSp-Hebr,
CircularSp-Cyrl, CircularSp-Grek, CircularSp-Deva;
--canon-font-title: CircularSpTitle, CircularSp-Arab, CircularSp-Hebr,
diff --git a/packages/canon/package.json b/packages/canon/package.json
index eb6165aa8c..2def886f3b 100644
--- a/packages/canon/package.json
+++ b/packages/canon/package.json
@@ -52,7 +52,6 @@
"@storybook/addon-essentials": "^8.6.12",
"@storybook/addon-interactions": "^8.6.12",
"@storybook/addon-styling-webpack": "^1.0.1",
- "@storybook/addon-themes": "^8.6.12",
"@storybook/addon-webpack5-compiler-swc": "^3.0.0",
"@storybook/blocks": "^8.6.12",
"@storybook/react": "^8.6.12",
diff --git a/yarn.lock b/yarn.lock
index a27446148e..42a7845f09 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3799,7 +3799,6 @@ __metadata:
"@storybook/addon-essentials": "npm:^8.6.12"
"@storybook/addon-interactions": "npm:^8.6.12"
"@storybook/addon-styling-webpack": "npm:^1.0.1"
- "@storybook/addon-themes": "npm:^8.6.12"
"@storybook/addon-webpack5-compiler-swc": "npm:^3.0.0"
"@storybook/blocks": "npm:^8.6.12"
"@storybook/react": "npm:^8.6.12"
@@ -19755,17 +19754,6 @@ __metadata:
languageName: node
linkType: hard
-"@storybook/addon-themes@npm:^8.6.12":
- version: 8.6.12
- resolution: "@storybook/addon-themes@npm:8.6.12"
- dependencies:
- ts-dedent: "npm:^2.0.0"
- peerDependencies:
- storybook: ^8.6.12
- checksum: 10/2df945accd7c0546785f71e2adc4ed68d71a057bc54aaef53f16ce8fcbc5a494380d60f9dd58520fe7d93b021a1b09e3d73553766d4bf2a1d07a3d731132b939
- languageName: node
- linkType: hard
-
"@storybook/addon-toolbars@npm:8.6.12":
version: 8.6.12
resolution: "@storybook/addon-toolbars@npm:8.6.12"