preview.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { useEffect } 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. const withTheme: Decorator = (Story, context) => {
  18. const dark = context.globals.theme === 'dark';
  19. useEffect(() => {
  20. document.body.setAttribute('class', dark ? 'dark' : 'light');
  21. document.documentElement.setAttribute('data-theme', dark ? 'dark' : 'light');
  22. }, [dark]);
  23. return (
  24. <ConfigProvider theme={buildAntdThemeConfig(dark, false)}>
  25. <div style={{ padding: 24, minWidth: 320 }}>
  26. <Story />
  27. </div>
  28. </ConfigProvider>
  29. );
  30. };
  31. const preview: Preview = {
  32. decorators: [withTheme],
  33. globalTypes: {
  34. theme: {
  35. description: 'Ant Design theme',
  36. defaultValue: 'light',
  37. toolbar: {
  38. title: 'Theme',
  39. icon: 'circlehollow',
  40. items: [
  41. { value: 'light', title: 'Light' },
  42. { value: 'dark', title: 'Dark' },
  43. ],
  44. dynamicTitle: true,
  45. },
  46. },
  47. },
  48. parameters: {
  49. controls: {
  50. expanded: true,
  51. sort: 'requiredFirst',
  52. matchers: {
  53. color: /(background|color)$/i,
  54. date: /Date$/i,
  55. },
  56. },
  57. a11y: {
  58. test: 'error',
  59. },
  60. },
  61. };
  62. export default preview;