1
0

preview.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import { useLayoutEffect } from 'react';
  2. import type { Decorator, Preview } from '@storybook/react-vite';
  3. import { ConfigProvider } from 'antd';
  4. import i18next from 'i18next';
  5. import { initReactI18next } from 'react-i18next';
  6. import { buildAntdThemeConfig } from '@/hooks/useTheme';
  7. import enUS from '../../internal/web/translation/en-US.json';
  8. if (!i18next.isInitialized) {
  9. void i18next.use(initReactI18next).init({
  10. lng: 'en-US',
  11. fallbackLng: 'en-US',
  12. resources: { 'en-US': { translation: enUS } },
  13. interpolation: { escapeValue: false, prefix: '{', suffix: '}' },
  14. returnNull: false,
  15. });
  16. }
  17. export const withTheme: Decorator = (Story, context) => {
  18. const dark = context.globals.theme === 'dark';
  19. useLayoutEffect(() => {
  20. document.body.classList.remove('dark', 'light');
  21. document.body.classList.add(dark ? 'dark' : 'light');
  22. document.documentElement.removeAttribute('data-theme');
  23. }, [dark]);
  24. return (
  25. <ConfigProvider theme={buildAntdThemeConfig(dark, false)}>
  26. <div style={{ padding: 24, minWidth: 320 }}>
  27. <Story />
  28. </div>
  29. </ConfigProvider>
  30. );
  31. };
  32. const preview: Preview = {
  33. decorators: [withTheme],
  34. globalTypes: {
  35. theme: {
  36. description: 'Ant Design theme',
  37. defaultValue: 'light',
  38. toolbar: {
  39. title: 'Theme',
  40. icon: 'circlehollow',
  41. items: [
  42. { value: 'light', title: 'Light' },
  43. { value: 'dark', title: 'Dark' },
  44. ],
  45. dynamicTitle: true,
  46. },
  47. },
  48. },
  49. parameters: {
  50. controls: {
  51. expanded: true,
  52. sort: 'requiredFirst',
  53. matchers: {
  54. color: /(background|color)$/i,
  55. date: /Date$/i,
  56. },
  57. },
  58. a11y: {
  59. test: 'error',
  60. },
  61. },
  62. };
  63. export default preview;