@tpitre/story-ui 2.0.1 โ 2.1.1
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,130 @@ 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
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
'Button.stories.tsx',
|
|
40
|
-
'Header.stories.ts',
|
|
41
|
-
'
|
|
42
|
-
'
|
|
43
|
-
'
|
|
44
|
-
|
|
45
|
-
'
|
|
46
|
-
'
|
|
47
|
-
'
|
|
48
|
-
|
|
49
|
-
'
|
|
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
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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 '@mantine/core/styles.css'",
|
|
119
|
+
"import React from 'react'"
|
|
120
|
+
],
|
|
121
|
+
decorator: `(Story) => (
|
|
122
|
+
<MantineProvider>
|
|
123
|
+
<Story />
|
|
124
|
+
</MantineProvider>
|
|
125
|
+
)`
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const config = designSystemConfigs[designSystem];
|
|
129
|
+
if (!config)
|
|
130
|
+
return;
|
|
131
|
+
// Create the preview content
|
|
132
|
+
const previewContent = `${config.imports.join('\n')}
|
|
133
|
+
|
|
134
|
+
const preview: Preview = {
|
|
135
|
+
parameters: {
|
|
136
|
+
controls: {
|
|
137
|
+
matchers: {
|
|
138
|
+
color: /(background|color)$/i,
|
|
139
|
+
date: /Date$/i,
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
decorators: [
|
|
144
|
+
${config.decorator},
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default preview;
|
|
149
|
+
`;
|
|
150
|
+
// Remove existing preview.ts if it exists
|
|
151
|
+
if (fs.existsSync(previewTsPath)) {
|
|
152
|
+
fs.unlinkSync(previewTsPath);
|
|
153
|
+
}
|
|
154
|
+
// Create preview.tsx with JSX support
|
|
155
|
+
fs.writeFileSync(previewTsxPath, previewContent);
|
|
156
|
+
console.log(chalk.green(`โ
Created .storybook/preview.tsx with ${designSystem} provider setup`));
|
|
157
|
+
}
|
|
68
158
|
// Design system installation configurations
|
|
69
159
|
const DESIGN_SYSTEM_CONFIGS = {
|
|
70
160
|
antd: {
|
|
@@ -112,11 +202,56 @@ async function installDesignSystem(systemKey) {
|
|
|
112
202
|
try {
|
|
113
203
|
console.log(chalk.gray(`Running: ${installCommand}`));
|
|
114
204
|
execSync(installCommand, { stdio: 'inherit' });
|
|
205
|
+
// Verify installation was successful by re-checking package.json
|
|
206
|
+
const updatedPackageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'));
|
|
207
|
+
const updatedDeps = { ...updatedPackageJson.dependencies, ...updatedPackageJson.devDependencies };
|
|
208
|
+
const stillMissingPackages = config.packages.filter(pkg => !updatedDeps[pkg]);
|
|
209
|
+
if (stillMissingPackages.length > 0) {
|
|
210
|
+
throw new Error(`Installation failed: packages still missing: ${stillMissingPackages.join(', ')}`);
|
|
211
|
+
}
|
|
115
212
|
console.log(chalk.green(`โ
${config.name} installed successfully!`));
|
|
116
213
|
if (config.additionalSetup) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
214
|
+
// Try to automatically add CSS import for Mantine
|
|
215
|
+
if (systemKey === 'mantine') {
|
|
216
|
+
const cssFiles = [
|
|
217
|
+
path.join(process.cwd(), 'src', 'index.css'),
|
|
218
|
+
path.join(process.cwd(), 'src', 'main.css'),
|
|
219
|
+
path.join(process.cwd(), 'src', 'App.css')
|
|
220
|
+
];
|
|
221
|
+
let cssAdded = false;
|
|
222
|
+
for (const cssFile of cssFiles) {
|
|
223
|
+
if (fs.existsSync(cssFile)) {
|
|
224
|
+
try {
|
|
225
|
+
const cssContent = fs.readFileSync(cssFile, 'utf-8');
|
|
226
|
+
if (!cssContent.includes('@mantine/core/styles.css')) {
|
|
227
|
+
const newContent = `@import "@mantine/core/styles.css";\n\n${cssContent}`;
|
|
228
|
+
fs.writeFileSync(cssFile, newContent);
|
|
229
|
+
console.log(chalk.green(`โ
Added Mantine CSS import to ${path.relative(process.cwd(), cssFile)}`));
|
|
230
|
+
cssAdded = true;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
console.log(chalk.blue(`โน๏ธ Mantine CSS already imported in ${path.relative(process.cwd(), cssFile)}`));
|
|
235
|
+
cssAdded = true;
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.warn(chalk.yellow(`โ ๏ธ Could not modify ${cssFile}:`, error));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (!cssAdded) {
|
|
245
|
+
console.log(chalk.blue('\n๐ Manual setup required:'));
|
|
246
|
+
console.log(chalk.gray(`Add this import to your main CSS file:`));
|
|
247
|
+
console.log(chalk.cyan(`${config.additionalSetup}`));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
console.log(chalk.blue('\n๐ Additional setup required:'));
|
|
252
|
+
console.log(chalk.gray(`Add this import to your main CSS/index file:`));
|
|
253
|
+
console.log(chalk.cyan(`${config.additionalSetup}`));
|
|
254
|
+
}
|
|
120
255
|
}
|
|
121
256
|
return true;
|
|
122
257
|
}
|
|
@@ -261,7 +396,27 @@ export async function setupCommand() {
|
|
|
261
396
|
if (answers.installDesignSystem && ['antd', 'mantine', 'chakra'].includes(answers.designSystem)) {
|
|
262
397
|
const installSuccess = await installDesignSystem(answers.designSystem);
|
|
263
398
|
if (!installSuccess) {
|
|
264
|
-
console.log(chalk.
|
|
399
|
+
console.log(chalk.red('โ Installation failed! Cannot continue without required dependencies.'));
|
|
400
|
+
console.log(chalk.yellow('Please install manually and run setup again:'));
|
|
401
|
+
const config = DESIGN_SYSTEM_CONFIGS[answers.designSystem];
|
|
402
|
+
console.log(chalk.cyan(`npm install ${config.packages.join(' ')}`));
|
|
403
|
+
process.exit(1);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else if (['antd', 'mantine', 'chakra'].includes(answers.designSystem)) {
|
|
407
|
+
// User declined installation - verify dependencies exist
|
|
408
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
409
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
410
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
411
|
+
const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
412
|
+
const config = DESIGN_SYSTEM_CONFIGS[answers.designSystem];
|
|
413
|
+
const missingDeps = config.packages.filter(pkg => !allDeps[pkg]);
|
|
414
|
+
if (missingDeps.length > 0) {
|
|
415
|
+
console.log(chalk.red('โ Required dependencies missing:'), missingDeps.join(', '));
|
|
416
|
+
console.log(chalk.yellow('Please install them manually:'));
|
|
417
|
+
console.log(chalk.cyan(`npm install ${missingDeps.join(' ')}`));
|
|
418
|
+
process.exit(1);
|
|
419
|
+
}
|
|
265
420
|
}
|
|
266
421
|
}
|
|
267
422
|
// Generate configuration
|
|
@@ -493,6 +648,10 @@ export async function setupCommand() {
|
|
|
493
648
|
}
|
|
494
649
|
// Clean up default Storybook template components to prevent conflicts
|
|
495
650
|
cleanupDefaultStorybookComponents();
|
|
651
|
+
// Set up Storybook preview file for design systems that require JSX
|
|
652
|
+
if (['chakra', 'antd', 'mantine'].includes(answers.designSystem)) {
|
|
653
|
+
setupStorybookPreview(answers.designSystem);
|
|
654
|
+
}
|
|
496
655
|
// Update package.json with convenience scripts
|
|
497
656
|
if (packageJson) {
|
|
498
657
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
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';
|