@tpitre/story-ui 3.5.0 → 3.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tpitre/story-ui",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "description": "AI-powered Storybook story generator with dynamic component discovery",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -39,6 +39,47 @@ declare global {
39
39
  * <Button>Click</Button>
40
40
  */
41
41
  const extractUsageCode = (fullStoryCode: string, variantName?: string): string => {
42
+ // Helper function to convert object-style props to JSX attribute syntax
43
+ // e.g., "color: 'blue', variant: 'filled'" -> 'color="blue" variant="filled"'
44
+ const convertToJsxAttributes = (propsStr: string): string => {
45
+ if (!propsStr.trim()) return '';
46
+
47
+ const attributes: string[] = [];
48
+ // Match key: value pairs, handling strings, booleans, numbers, and expressions
49
+ // Pattern: key: 'value' or key: "value" or key: true/false or key: 123 or key: expression
50
+ const propRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\btrue\b|\bfalse\b)|(\d+(?:\.\d+)?)|(\{[^}]+\})|([^,}\s]+))/g;
51
+
52
+ let match;
53
+ while ((match = propRegex.exec(propsStr)) !== null) {
54
+ const key = match[1];
55
+ const stringValueSingle = match[2]; // 'value'
56
+ const stringValueDouble = match[3]; // "value"
57
+ const boolValue = match[4]; // true/false
58
+ const numValue = match[5]; // 123 or 1.5
59
+ const objValue = match[6]; // {expression}
60
+ const otherValue = match[7]; // other expressions
61
+
62
+ if (stringValueSingle !== undefined) {
63
+ attributes.push(`${key}="${stringValueSingle}"`);
64
+ } else if (stringValueDouble !== undefined) {
65
+ attributes.push(`${key}="${stringValueDouble}"`);
66
+ } else if (boolValue !== undefined) {
67
+ if (boolValue === 'true') {
68
+ attributes.push(key); // Just the prop name for true (e.g., fullWidth)
69
+ }
70
+ // Skip false values - they're the default and don't need to be shown
71
+ } else if (numValue !== undefined) {
72
+ attributes.push(`${key}={${numValue}}`);
73
+ } else if (objValue !== undefined) {
74
+ attributes.push(`${key}=${objValue}`);
75
+ } else if (otherValue !== undefined) {
76
+ attributes.push(`${key}={${otherValue}}`);
77
+ }
78
+ }
79
+
80
+ return attributes.join(' ');
81
+ };
82
+
42
83
  // Helper function to generate JSX from args
43
84
  const generateJsxFromArgs = (argsStr: string, componentName: string): string | null => {
44
85
  try {
@@ -46,19 +87,22 @@ const extractUsageCode = (fullStoryCode: string, variantName?: string): string =
46
87
  const childrenMatch = argsStr.match(/children:\s*['"`]([^'"`]+)['"`]/);
47
88
  const children = childrenMatch ? childrenMatch[1] : '';
48
89
 
49
- // Extract other props (simplified)
90
+ // Extract other props (remove children first)
50
91
  const propsStr = argsStr
51
92
  .replace(/children:\s*['"`][^'"`]*['"`],?/, '') // Remove children
52
93
  .replace(/^\{|\}$/g, '') // Remove braces
53
94
  .trim();
54
95
 
96
+ // Convert to JSX attribute syntax
97
+ const jsxAttributes = convertToJsxAttributes(propsStr);
98
+
55
99
  if (children) {
56
- if (propsStr) {
57
- return `<${componentName} ${propsStr.replace(/,\s*$/, '')}>${children}</${componentName}>`;
100
+ if (jsxAttributes) {
101
+ return `<${componentName} ${jsxAttributes}>${children}</${componentName}>`;
58
102
  }
59
103
  return `<${componentName}>${children}</${componentName}>`;
60
- } else if (propsStr) {
61
- return `<${componentName} ${propsStr.replace(/,\s*$/, '')} />`;
104
+ } else if (jsxAttributes) {
105
+ return `<${componentName} ${jsxAttributes} />`;
62
106
  }
63
107
  return `<${componentName} />`;
64
108
  } catch {