1- import { type ComponentType , type PropsWithChildren , useMemo } from 'react' ;
1+ import { type ComponentType , type PropsWithChildren , useMemo , useState } from 'react' ;
22import { type Control , DocsContainer , type DocsContainerProps } from '@storybook/addon-docs/blocks' ;
33import type { Preview , ReactRenderer } from '@storybook/react-vite' ;
4- import { App as AntdApp , ConfigProvider as AntdConfigProvider , theme } from 'antd' ;
4+ import { App as AntdApp , ConfigProvider as AntdConfigProvider , theme as antThemes } from 'antd' ;
55import enUS from 'antd/es/locale/en_US' ;
66import zhCN from 'antd/es/locale/zh_CN' ;
77import { FORCE_RE_RENDER } from 'storybook/internal/core-events' ;
@@ -10,14 +10,37 @@ import { addons, useStoryContext } from 'storybook/preview-api';
1010import { themes } from 'storybook/theming' ;
1111import ConfigProvider from '../src/components/ConfigProvider' ;
1212import { useRefValue } from '../src/hooks' ;
13- import storyI18n from './locales' ;
13+ import type { Langs } from '../src/locales' ;
14+ import storyI18n , { storyT } from './locales' ;
15+ import { getGlobalValueFromUrl } from './utils/global' ;
1416import { inferControlFromDocgenType , standardizeJsDocDefaultValue } from './utils/jsdoc' ;
1517
1618// import './preview.css';
1719
20+ const themeFromUrl = getGlobalValueFromUrl ( 'backgrounds.value' ) ;
21+ const langFromUrl = getGlobalValueFromUrl ( 'lang' ) ;
1822const isPreferDark = window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ;
1923
2024const preview : Preview = {
25+ initialGlobals : {
26+ lang : 'en-US' ,
27+ backgrounds : {
28+ value : themeFromUrl ?? ( isPreferDark ? 'dark' : 'light' ) ,
29+ grid : false ,
30+ } ,
31+ } ,
32+ globalTypes : {
33+ lang : {
34+ description : 'Internationalization locale' ,
35+ toolbar : {
36+ icon : 'globe' ,
37+ items : [
38+ { value : 'en-US' , right : '🇺🇸' , title : 'English' } ,
39+ { value : 'zh-CN' , right : '🇨🇳' , title : '中文' } ,
40+ ] ,
41+ } ,
42+ } ,
43+ } ,
2144 parameters : {
2245 controls : {
2346 expanded : true ,
@@ -28,14 +51,15 @@ const preview: Preview = {
2851 } ,
2952 backgrounds : {
3053 options : {
31- light : { name : 'Light ' , value : '#ffffff' } ,
32- dark : { name : 'Dark ' , value : '#2c2c2c' } ,
54+ light : { value : '#ffffff ' , name : storyT ( 'storybook.stories.Backgrounds.light' ) } ,
55+ dark : { value : '#2c2c2c ' , name : storyT ( 'storybook.stories.Backgrounds.dark' ) } ,
3356 } ,
3457 } ,
3558 docs : {
3659 container : ( props : PropsWithChildren < DocsContainerProps > ) => {
37- const bgValue = ( props . context as unknown as StoryContext < ReactRenderer > ) ?. globals ?. backgrounds ?. value ;
38- const isDark = bgValue ? bgValue === 'dark' : isPreferDark ;
60+ const globalValue = ( props . context as unknown as StoryContext < ReactRenderer > ) ?. globals ?. backgrounds ?. value ;
61+ const theme = globalValue ?? themeFromUrl ;
62+ const isDark = theme ? theme === 'dark' : isPreferDark ;
3963 return < DocsContainer { ...props } theme = { isDark ? themes . dark : themes . light } /> ;
4064 } ,
4165 extractComponentDescription : (
@@ -48,31 +72,27 @@ const preview: Preview = {
4872 } ,
4973 } ,
5074 } ,
51- globalTypes : {
52- lang : {
53- description : 'Internationalization locale' ,
54- toolbar : {
55- icon : 'globe' ,
56- items : [
57- { value : 'en-US' , right : '🇺🇸' , title : 'English' } ,
58- { value : 'zh-CN' , right : '🇨🇳' , title : '中文' } ,
59- ] ,
60- } ,
61- } ,
62- } ,
63- initialGlobals : {
64- lang : 'en-US' ,
65- backgrounds : { value : isPreferDark ? 'dark' : 'light' } ,
66- } ,
6775 tags : [ 'autodocs' ] ,
6876 decorators : [
6977 ( Story , context ) => {
70- const bgValue = context . globals ?. backgrounds ?. value ;
71- const lang = context . globals . lang ?? 'en-US' ;
78+ const themeFromGlobal = context . globals ?. backgrounds ?. value ;
79+ const theme : string | undefined = themeFromGlobal ?? themeFromUrl ;
80+ const lang : Langs | undefined = context . globals . lang ?? langFromUrl ?? 'en-US' ;
7281 const antdLocale = lang === 'zh-CN' ? zhCN : enUS ;
7382 const { viewMode } = useStoryContext ( ) ;
7483 const viewModeRef = useRefValue ( viewMode ) ;
84+ const [ prevTheme , setPrevTheme ] = useState ( themeFromGlobal ) ;
85+ const isDark = theme === 'dark' || ( ! theme && isPreferDark ) ;
86+
87+ // Reload the page if the theme changes.
88+ useMemo ( ( ) => {
89+ if ( themeFromGlobal !== prevTheme ) {
90+ setPrevTheme ( themeFromGlobal ) ;
91+ ( window . top ?? window . parent ?? window ) . location . reload ( ) ;
92+ }
93+ } , [ themeFromGlobal , prevTheme ] ) ;
7594
95+ // Reload the page if the language changes.
7696 useMemo ( ( ) => {
7797 if ( storyI18n . language !== lang ) {
7898 storyI18n . changeLanguage ( lang ) . then ( ( ) => {
@@ -88,7 +108,7 @@ const preview: Preview = {
88108 return (
89109 < AntdConfigProvider
90110 locale = { antdLocale }
91- theme = { { algorithm : bgValue === 'dark' ? theme . darkAlgorithm : theme . defaultAlgorithm } }
111+ theme = { { algorithm : isDark ? antThemes . darkAlgorithm : antThemes . defaultAlgorithm } }
92112 >
93113 < AntdApp >
94114 < ConfigProvider lang = { lang } >
0 commit comments