@tpitre/story-ui 2.0.1 โ†’ 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -6,7 +6,7 @@ import path from 'path';
6
6
  import { fileURLToPath } from 'url';
7
7
  import { setupProductionGitignore } from '../story-generator/productionGitignoreManager.js';
8
8
  import { createStoryUIConfig } from '../story-ui.config.js';
9
- import { setupCommand } from './setup.js';
9
+ import { setupCommand, cleanupDefaultStorybookComponents } from './setup.js';
10
10
  import net from 'net';
11
11
  const __filename = fileURLToPath(import.meta.url);
12
12
  const __dirname = path.dirname(__filename);
@@ -249,4 +249,12 @@ function writeConfig(config, type, filename) {
249
249
  fs.writeFileSync(outputFile, jsContent);
250
250
  }
251
251
  }
252
+ program
253
+ .command('cleanup')
254
+ .description('Remove default Storybook template files that conflict with component discovery')
255
+ .action(() => {
256
+ console.log('๐Ÿงน Cleaning up default Storybook template files...');
257
+ cleanupDefaultStorybookComponents();
258
+ console.log('โœ… Cleanup complete! Component discovery should now work properly.');
259
+ });
252
260
  program.parse(process.argv);
package/dist/cli/setup.js CHANGED
@@ -31,40 +31,129 @@ async function findAvailablePort(startPort) {
31
31
  /**
32
32
  * Clean up default Storybook template components that could conflict with design system discovery
33
33
  */
34
- function cleanupDefaultStorybookComponents() {
35
- const storiesDir = path.join(process.cwd(), 'src', 'stories');
36
- // Common default Storybook files that cause conflicts
34
+ export function cleanupDefaultStorybookComponents() {
35
+ const possibleDirs = [
36
+ path.join(process.cwd(), 'src', 'stories'),
37
+ path.join(process.cwd(), 'stories'),
38
+ path.join(process.cwd(), '.storybook', 'stories')
39
+ ];
40
+ // Comprehensive list of default Storybook files that cause conflicts
37
41
  const defaultFiles = [
38
- 'Button.stories.ts',
39
- 'Button.stories.tsx',
40
- 'Header.stories.ts',
41
- 'Header.stories.tsx',
42
- 'Page.stories.ts',
43
- 'Page.stories.tsx',
44
- 'button.css',
45
- 'header.css',
46
- 'page.css',
47
- 'Button.tsx',
48
- 'Header.tsx',
49
- 'Page.tsx'
42
+ // Component files
43
+ 'Button.stories.ts', 'Button.stories.tsx', 'Button.stories.js', 'Button.stories.jsx',
44
+ 'Header.stories.ts', 'Header.stories.tsx', 'Header.stories.js', 'Header.stories.jsx',
45
+ 'Page.stories.ts', 'Page.stories.tsx', 'Page.stories.js', 'Page.stories.jsx',
46
+ 'Introduction.stories.ts', 'Introduction.stories.tsx', 'Introduction.stories.js', 'Introduction.stories.jsx',
47
+ 'Configure.stories.ts', 'Configure.stories.tsx', 'Configure.stories.js', 'Configure.stories.jsx',
48
+ // Component implementation files
49
+ 'Button.tsx', 'Button.ts', 'Button.jsx', 'Button.js',
50
+ 'Header.tsx', 'Header.ts', 'Header.jsx', 'Header.js',
51
+ 'Page.tsx', 'Page.ts', 'Page.jsx', 'Page.js',
52
+ // CSS files
53
+ 'button.css', 'header.css', 'page.css', 'introduction.css',
54
+ // MDX files
55
+ 'Introduction.stories.mdx', 'Configure.stories.mdx'
50
56
  ];
51
57
  let cleanedFiles = 0;
52
- for (const fileName of defaultFiles) {
53
- const filePath = path.join(storiesDir, fileName);
54
- if (fs.existsSync(filePath)) {
55
- try {
56
- fs.unlinkSync(filePath);
57
- cleanedFiles++;
58
- }
59
- catch (error) {
60
- console.warn(`Could not remove ${fileName}: ${error}`);
58
+ for (const storiesDir of possibleDirs) {
59
+ if (!fs.existsSync(storiesDir))
60
+ continue;
61
+ for (const fileName of defaultFiles) {
62
+ const filePath = path.join(storiesDir, fileName);
63
+ if (fs.existsSync(filePath)) {
64
+ try {
65
+ fs.unlinkSync(filePath);
66
+ cleanedFiles++;
67
+ }
68
+ catch (error) {
69
+ console.warn(`Could not remove ${fileName}: ${error}`);
70
+ }
61
71
  }
62
72
  }
63
73
  }
64
74
  if (cleanedFiles > 0) {
65
- console.log(chalk.green(`โœ… Cleaned up ${cleanedFiles} default Storybook template files to prevent conflicts`));
75
+ console.log(chalk.green(`โœ… Cleaned up ${cleanedFiles} default Storybook template files to prevent component discovery conflicts`));
66
76
  }
67
77
  }
78
+ /**
79
+ * Set up Storybook preview file with appropriate providers for design systems
80
+ */
81
+ function setupStorybookPreview(designSystem) {
82
+ const storybookDir = path.join(process.cwd(), '.storybook');
83
+ const previewTsPath = path.join(storybookDir, 'preview.ts');
84
+ const previewTsxPath = path.join(storybookDir, 'preview.tsx');
85
+ if (!fs.existsSync(storybookDir)) {
86
+ console.log(chalk.yellow('โš ๏ธ .storybook directory not found. Please run storybook init first.'));
87
+ return;
88
+ }
89
+ const designSystemConfigs = {
90
+ chakra: {
91
+ imports: [
92
+ "import type { Preview } from '@storybook/react-vite'",
93
+ "import { ChakraProvider, defaultSystem } from '@chakra-ui/react'",
94
+ "import React from 'react'"
95
+ ],
96
+ decorator: `(Story) => (
97
+ <ChakraProvider value={defaultSystem}>
98
+ <Story />
99
+ </ChakraProvider>
100
+ )`
101
+ },
102
+ antd: {
103
+ imports: [
104
+ "import type { Preview } from '@storybook/react-vite'",
105
+ "import { ConfigProvider } from 'antd'",
106
+ "import React from 'react'"
107
+ ],
108
+ decorator: `(Story) => (
109
+ <ConfigProvider>
110
+ <Story />
111
+ </ConfigProvider>
112
+ )`
113
+ },
114
+ mantine: {
115
+ imports: [
116
+ "import type { Preview } from '@storybook/react-vite'",
117
+ "import { MantineProvider } from '@mantine/core'",
118
+ "import React from 'react'"
119
+ ],
120
+ decorator: `(Story) => (
121
+ <MantineProvider>
122
+ <Story />
123
+ </MantineProvider>
124
+ )`
125
+ }
126
+ };
127
+ const config = designSystemConfigs[designSystem];
128
+ if (!config)
129
+ return;
130
+ // Create the preview content
131
+ const previewContent = `${config.imports.join('\n')}
132
+
133
+ const preview: Preview = {
134
+ parameters: {
135
+ controls: {
136
+ matchers: {
137
+ color: /(background|color)$/i,
138
+ date: /Date$/i,
139
+ },
140
+ },
141
+ },
142
+ decorators: [
143
+ ${config.decorator},
144
+ ],
145
+ };
146
+
147
+ export default preview;
148
+ `;
149
+ // Remove existing preview.ts if it exists
150
+ if (fs.existsSync(previewTsPath)) {
151
+ fs.unlinkSync(previewTsPath);
152
+ }
153
+ // Create preview.tsx with JSX support
154
+ fs.writeFileSync(previewTsxPath, previewContent);
155
+ console.log(chalk.green(`โœ… Created .storybook/preview.tsx with ${designSystem} provider setup`));
156
+ }
68
157
  // Design system installation configurations
69
158
  const DESIGN_SYSTEM_CONFIGS = {
70
159
  antd: {
@@ -261,7 +350,27 @@ export async function setupCommand() {
261
350
  if (answers.installDesignSystem && ['antd', 'mantine', 'chakra'].includes(answers.designSystem)) {
262
351
  const installSuccess = await installDesignSystem(answers.designSystem);
263
352
  if (!installSuccess) {
264
- console.log(chalk.yellow('โš ๏ธ Installation failed but continuing with configuration...'));
353
+ console.log(chalk.red('โŒ Installation failed! Cannot continue without required dependencies.'));
354
+ console.log(chalk.yellow('Please install manually and run setup again:'));
355
+ const config = DESIGN_SYSTEM_CONFIGS[answers.designSystem];
356
+ console.log(chalk.cyan(`npm install ${config.packages.join(' ')}`));
357
+ process.exit(1);
358
+ }
359
+ }
360
+ else if (['antd', 'mantine', 'chakra'].includes(answers.designSystem)) {
361
+ // User declined installation - verify dependencies exist
362
+ const packageJsonPath = path.join(process.cwd(), 'package.json');
363
+ if (fs.existsSync(packageJsonPath)) {
364
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
365
+ const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
366
+ const config = DESIGN_SYSTEM_CONFIGS[answers.designSystem];
367
+ const missingDeps = config.packages.filter(pkg => !allDeps[pkg]);
368
+ if (missingDeps.length > 0) {
369
+ console.log(chalk.red('โŒ Required dependencies missing:'), missingDeps.join(', '));
370
+ console.log(chalk.yellow('Please install them manually:'));
371
+ console.log(chalk.cyan(`npm install ${missingDeps.join(' ')}`));
372
+ process.exit(1);
373
+ }
265
374
  }
266
375
  }
267
376
  // Generate configuration
@@ -493,6 +602,10 @@ export async function setupCommand() {
493
602
  }
494
603
  // Clean up default Storybook template components to prevent conflicts
495
604
  cleanupDefaultStorybookComponents();
605
+ // Set up Storybook preview file for design systems that require JSX
606
+ if (['chakra', 'antd', 'mantine'].includes(answers.designSystem)) {
607
+ setupStorybookPreview(answers.designSystem);
608
+ }
496
609
  // Update package.json with convenience scripts
497
610
  if (packageJson) {
498
611
  const scripts = packageJson.scripts || {};
@@ -233,14 +233,24 @@ export class DynamicPackageDiscovery {
233
233
  * Get the type of an export
234
234
  */
235
235
  getExportType(value) {
236
+ // Handle undefined/null values
237
+ if (value === undefined || value === null) {
238
+ return 'unknown';
239
+ }
236
240
  const type = typeof value;
237
241
  if (type === 'function') {
238
- // Try to distinguish between function and class
239
- const fnString = value.toString();
240
- if (fnString.startsWith('class ') || /^function [A-Z]/.test(fnString)) {
241
- return 'class';
242
+ try {
243
+ // Try to distinguish between function and class
244
+ const fnString = value.toString();
245
+ if (fnString.startsWith('class ') || /^function [A-Z]/.test(fnString)) {
246
+ return 'class';
247
+ }
248
+ return 'function';
249
+ }
250
+ catch (error) {
251
+ // Some functions might not have toString() available
252
+ return 'function';
242
253
  }
243
- return 'function';
244
254
  }
245
255
  if (type === 'object' && value !== null) {
246
256
  return 'object';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpitre/story-ui",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "description": "AI-powered Storybook story generator with dynamic component discovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",