Skip to content

Commit 451f050

Browse files
committed
chore(docs): storybook v.10 migration
1 parent 4de0f52 commit 451f050

File tree

17 files changed

+421
-373
lines changed

17 files changed

+421
-373
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import './src/register';
1+
import './src/register.js';

.storybook/custom/addons/theme-switcher/src/containers/IconButtonLabel.jsx renamed to .storybook/custom/addons/theme-switcher/src/containers/IconButtonLabel.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const IconButtonLabel = styled.div(({ theme }) => ({
55
marginLeft: 10
66
}));
77

8-
export default IconButtonLabel;
8+
export default IconButtonLabel;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { getOwner } from '../../../utilities/get-owner.js';
2+
import IconButtonLabel from './IconButtonLabel.js';
3+
import React, { useState, useEffect } from 'react';
4+
import { WithTooltip, TooltipLinkList, IconButton } from 'storybook/internal/components';
5+
import { PaintBrushIcon } from '@storybook/icons';
6+
7+
const Selector = ({ api }) => {
8+
const [availableThemes, setAvailableThemes] = useState([]);
9+
const [currentTheme, setCurrentTheme] = useState(null);
10+
const [globals, setGlobals] = useState(api.getGlobals());
11+
const [currentStory, setCurrentStory] = useState(api.getCurrentStoryData());
12+
13+
const storyProject = getOwner(currentStory);
14+
15+
// Listen for globals and story changes
16+
useEffect(() => {
17+
const onGlobalsChanged = () => {
18+
setGlobals(api.getGlobals());
19+
};
20+
21+
const onStoryChanged = () => {
22+
setCurrentStory(api.getCurrentStoryData());
23+
};
24+
25+
api.on('globalsUpdated', onGlobalsChanged);
26+
api.on('storyChanged', onStoryChanged);
27+
28+
return () => {
29+
api.off('globalsUpdated', onGlobalsChanged);
30+
api.off('storyChanged', onStoryChanged);
31+
};
32+
}, [api]);
33+
34+
useEffect(() => {
35+
if (currentStory && storyProject?.themes) {
36+
setAvailableThemes(storyProject.themes.themes || []);
37+
}
38+
}, [currentStory, storyProject]);
39+
40+
useEffect(() => {
41+
if (storyProject) {
42+
const themeKey = `${storyProject.value}-theme`;
43+
const theme = availableThemes.find((theme) => theme.value === globals?.[themeKey]);
44+
if (theme) {
45+
setCurrentTheme(theme);
46+
} else {
47+
// Set default theme if no theme is selected
48+
const defaultTheme = availableThemes.find(t => t.value === storyProject.themes?.defaultTheme);
49+
setCurrentTheme(defaultTheme || null);
50+
}
51+
}
52+
}, [availableThemes, globals, storyProject]);
53+
const RenderThemes = (onHide) => availableThemes.map(theme => {
54+
return {
55+
id: theme.value,
56+
title: theme.title,
57+
active: theme.value === currentTheme?.value,
58+
onClick: () => {
59+
const newGlobals = { ...globals, [`${storyProject?.value}-theme`]: theme.value };
60+
api.updateGlobals(newGlobals);
61+
setCurrentTheme(theme);
62+
onHide();
63+
}
64+
};
65+
});
66+
67+
return React.createElement(React.Fragment, null,
68+
React.createElement(WithTooltip, {
69+
placement: "top",
70+
trigger: "click",
71+
closeOnOutsideClick: true,
72+
tooltip: ({ onHide }) => {
73+
return React.createElement(TooltipLinkList, { links: RenderThemes(onHide) });
74+
}
75+
},
76+
React.createElement(IconButton, {
77+
disabled: availableThemes.length === 0,
78+
title: 'Theme Selector',
79+
active: !!currentTheme
80+
},
81+
React.createElement(PaintBrushIcon),
82+
currentTheme
83+
? React.createElement(IconButtonLabel, null, currentTheme?.title)
84+
: React.createElement(React.Fragment)
85+
)
86+
)
87+
);
88+
};
89+
90+
export default Selector;

.storybook/custom/addons/theme-switcher/src/containers/Selector.jsx

Lines changed: 0 additions & 63 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { addons, types } from 'storybook/manager-api';
2+
import React from 'react';
3+
import { ADDON_ID } from './constants.js';
4+
5+
addons.register(ADDON_ID, (api) => {
6+
addons.add(ADDON_ID, {
7+
title: ADDON_ID,
8+
type: types.TOOL,
9+
match: ({ viewMode }) => viewMode === 'story',
10+
render: () => {
11+
// Dynamically import Selector to avoid SSR issues
12+
const [Selector, setSelector] = React.useState(null);
13+
14+
React.useEffect(() => {
15+
import('./containers/Selector.js').then(module => {
16+
setSelector(() => module.default);
17+
});
18+
}, []);
19+
20+
if (!Selector) {
21+
return React.createElement('div', {
22+
style: { padding: '8px', fontSize: '12px', color: '#666' }
23+
}, 'Loading theme switcher...');
24+
}
25+
26+
return React.createElement(Selector, { api });
27+
}
28+
});
29+
});

.storybook/custom/addons/theme-switcher/src/register.jsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

.storybook/custom/addons/utilities/get-owner.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { sortedProjects } from './projects';
1+
import { sortedProjects } from './projects.js';
22

33
const ownersCache = new Map();
44

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import { projects } from '../../../../projects';
1+
import { projects, themes } from '../../../../projects.js';
22

3-
const sortedProjects = Object.entries(projects).map(([id, data]) => ({ id, ...data })).sort((a, b) => b.pathToPackage.length - a.pathToPackage.length);
3+
const sortedProjects = Object.entries(projects).map(([id, data]) => ({
4+
id,
5+
...data,
6+
themes: themes[id] // Add themes data to each project
7+
})).sort((a, b) => b.pathToPackage.length - a.pathToPackage.length);
48

59
export {
610
projects,
11+
themes,
712
sortedProjects,
813
};

.storybook/main.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1+
// This file has been automatically migrated to valid ESM format by Storybook.
12
import { createRequire } from "node:module";
23
import { StorybookConfig } from '@storybook/html-vite';
34
import { readFileSync } from 'fs';
45
import { mergeConfig } from 'vite';
56
import { loadCsf } from 'storybook/internal/csf-tools';
6-
import { getOwner } from './custom/addons/utilities/get-owner';
7+
import { getOwner } from './custom/addons/utilities/get-owner.js';
78
import { relative, dirname, join } from 'path';
89
import remarkGfm from 'remark-gfm';
9-
import { storybookPackages } from '../projects';
10+
import { storybookPackages } from '../projects.js';
1011
import { resolve } from 'path';
12+
import { fileURLToPath } from 'url';
1113

14+
const __filename = fileURLToPath(import.meta.url);
15+
const __dirname = dirname(__filename);
1216
const require = createRequire(import.meta.url);
1317

1418
const storiesToInclude = () => {

.storybook/manager.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { addons } from 'storybook/manager-api';
2-
import fundamentalTheme from '../packages/storybook/src/lib/fundamentals';
2+
import fundamentalTheme from '../packages/storybook/src/lib/fundamentals.js';
33

44
addons.setConfig({
55
sidebar: {

0 commit comments

Comments
 (0)