Files
AppFlowy-Web/.storybook/main.ts
Nathan 67bf9ea607 refactor(storybook): consolidate configuration and eliminate code duplication
## Summary
Reviewed and refactored all Storybook stories to use shared utilities,
eliminating ~200 lines of duplicate code while ensuring stories use
current theme, config, and styles consistently.

## Changes

### New Shared Utilities (.storybook/)
- **argTypes.ts**: Shared argTypes definitions (hostname, subscription, etc.)
- **decorators.tsx**: Reusable decorators (context providers, hostname mocking)
- **mocks.ts**: Shared mock context values (AFConfig, AppContext)

### Refactored Story Files
- HomePageSetting.stories.tsx: Now uses shared utilities
- UpgradeBanner.stories.tsx: Reduced from ~195 to ~80 lines
- UpgradePlan.stories.tsx: Reduced from ~180 to ~95 lines
- TextColor.stories.tsx: Uses shared argTypes
- RecordNotFound.stories.tsx: Reduced from ~235 to ~170 lines

### Configuration Updates
- **main.ts**: Added MUI optimizeDeps for proper theme support, removed deprecated buildStoriesJson
- **GUIDE.md**: Comprehensive documentation with examples and best practices
- **tsconfig.web.json**: Explicitly exclude .storybook/ from production builds

### Lint Fixes & Improvements
- **ApproveRequestPage.tsx**: Added missing blank line (lint fix)
- **subscription.ts**: Fixed type casting to avoid @typescript-eslint/no-explicit-any
- **AppTheme.tsx**: Changed to named imports (better practice)

## Benefits
-  Zero code duplication across stories
-  Consistent theme, config, and styles across all stories
-  Better maintainability (change once, apply everywhere)
-  Improved type safety with shared utilities
-  Comprehensive documentation for future story development
-  Storybook files guaranteed excluded from production builds

## Testing
- All linting passes (pnpm run lint)
- Storybook configuration verified to not be included in production builds
- Multiple layers of protection ensure isolation from main application

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-16 14:48:48 +08:00

87 lines
2.4 KiB
TypeScript

import type { StorybookConfig } from '@storybook/react-vite';
import path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@chromatic-com/storybook',
'@storybook/addon-docs',
'@storybook/addon-onboarding',
'@storybook/addon-a11y',
'@storybook/addon-vitest',
],
framework: {
name: '@storybook/react-vite',
options: {},
},
typescript: {
reactDocgen: 'react-docgen-typescript',
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
propFilter: (prop) => {
if (prop.parent) {
return !prop.parent.fileName.includes('node_modules');
}
return true;
},
shouldRemoveUndefinedFromOptional: true,
},
},
async viteFinal(config) {
if (config.resolve) {
const existingAlias = Array.isArray(config.resolve.alias)
? config.resolve.alias
: config.resolve.alias
? Object.entries(config.resolve.alias).map(([find, replacement]) => ({
find,
replacement: replacement as string,
}))
: [];
config.resolve.alias = [
...existingAlias,
{ find: 'src/', replacement: path.resolve(__dirname, '../src/') },
{ find: '@/', replacement: path.resolve(__dirname, '../src/') },
];
}
// Ensure CSS processing is enabled
// PostCSS config is automatically picked up from postcss.config.cjs
// Vite/Storybook will automatically process CSS/SCSS files
if (!config.css) {
config.css = {};
}
config.css.modules = config.css.modules || {};
// Ensure Material-UI is properly optimized for Storybook
if (!config.optimizeDeps) {
config.optimizeDeps = {};
}
config.optimizeDeps.include = [
...(config.optimizeDeps.include || []),
'@mui/material/styles',
'@mui/material/styles/createTheme',
'@emotion/react',
'@emotion/styled',
];
// Ensure proper module resolution for MUI v6
if (!config.resolve) {
config.resolve = {};
}
if (!config.resolve.dedupe) {
config.resolve.dedupe = [];
}
if (!config.resolve.dedupe.includes('@mui/material')) {
config.resolve.dedupe.push('@mui/material');
}
return config;
},
};
export default config;