vibe-design-system 2.8.70 → 2.8.72

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": "vibe-design-system",
3
- "version": "2.8.70",
3
+ "version": "2.8.72",
4
4
  "description": "Auto-generate design systems for vibe coding projects",
5
5
  "homepage": "https://vibedesign.tech",
6
6
  "repository": {
@@ -4099,9 +4099,11 @@ function writeComponentInventoryStory(components, foundations) {
4099
4099
  }
4100
4100
 
4101
4101
  const { actualExport, isDefault } = exportInfo;
4102
- importInfoMap[comp.name] = { identifier, importAlias, isDefault, actualExport, skip: false };
4102
+ const isShadcn = (comp.group || '').toLowerCase() === 'shadcn';
4103
+ importInfoMap[comp.name] = { identifier, importAlias, isDefault, actualExport, skip: false, isShadcn };
4103
4104
 
4104
- if (!seenAliases.has(importAlias)) {
4105
+ // Only import shadcn UI primitives — project components are shown via story iframes
4106
+ if (isShadcn && !seenAliases.has(importAlias)) {
4105
4107
  seenAliases.add(importAlias);
4106
4108
  orderedImports.push({ identifier, importAlias, isDefault, actualExport });
4107
4109
  }
@@ -4186,10 +4188,13 @@ function writeComponentInventoryStory(components, foundations) {
4186
4188
  return `import { ${namedPart} } from "${imp.importAlias}";`;
4187
4189
  });
4188
4190
 
4189
- // ── PREVIEWS map entries (only for non-skipped components) ─────────────────
4191
+ // ── PREVIEWS map: only shadcn UI primitives (safe to render with no props) ──
4190
4192
  const TEXT_CHILD_NAMES = new Set(['button','badge','toggle','label','link','chip','tag','pill']);
4191
4193
  const previewEntries = components
4192
- .filter(comp => importInfoMap[comp.name] && !importInfoMap[comp.name].skip)
4194
+ .filter(comp => {
4195
+ const info = importInfoMap[comp.name];
4196
+ return info && !info.skip && info.isShadcn;
4197
+ })
4193
4198
  .map(comp => {
4194
4199
  const { identifier } = importInfoMap[comp.name];
4195
4200
  const hasText = TEXT_CHILD_NAMES.has(identifier.toLowerCase());
@@ -4199,6 +4204,32 @@ function writeComponentInventoryStory(components, foundations) {
4199
4204
  return ` ${JSON.stringify(comp.name)}: ${call}`;
4200
4205
  });
4201
4206
 
4207
+ // ── STORY_IDS map: project components get embedded as story iframes ─────────
4208
+ // Uses Storybook's sanitize logic: lowercase + replace non-alphanumeric with '-'
4209
+ // PascalCase names stay as one word ("AppHeader" → "appheader"), matching real IDs
4210
+ function toStoryId(category, pascalName) {
4211
+ return [category, pascalName].join('/')
4212
+ .toLowerCase().replace(/[^a-z0-9/]+/g, '-').replace(/-*\/+/g, '-')
4213
+ .replace(/-+/g, '-').replace(/^-|-$/g, '') + '--default';
4214
+ }
4215
+ const storyIdEntries = components
4216
+ .filter(comp => {
4217
+ const info = importInfoMap[comp.name];
4218
+ return info && !info.isShadcn; // project (non-shadcn) components only
4219
+ })
4220
+ .map(comp => {
4221
+ // Find the category for this component from categorized
4222
+ const cat = Object.keys(categorized).find(c => categorized[c].some(x => x.name === comp.name));
4223
+ if (!cat) return null;
4224
+ // Use PascalCase identifier to match Storybook story title field (no hyphenation of PascalCase)
4225
+ const pascalId = toPascalLocal(comp.name);
4226
+ // Only include if a story file actually exists for this component
4227
+ const storyFile = path.join(STORIES_DIR, `${pascalId}.stories.tsx`);
4228
+ if (!fs.existsSync(storyFile)) return null; // no story → shape HTML fallback
4229
+ return ` ${JSON.stringify(comp.name)}: ${JSON.stringify(toStoryId(cat, pascalId))}`;
4230
+ })
4231
+ .filter(Boolean);
4232
+
4202
4233
  // ── Generate story file ────────────────────────────────────────────────────
4203
4234
  const content = [
4204
4235
  `import React from "react";`,
@@ -4224,10 +4255,14 @@ function writeComponentInventoryStory(components, foundations) {
4224
4255
  ] : [
4225
4256
  `const _PW = ({ children }: { children: React.ReactNode }) => React.createElement(React.Fragment, null, children) as React.ReactElement;`,
4226
4257
  ]),
4227
- // PREVIEWS: each component renders via its real import; ErrorBoundary catches failures
4258
+ // PREVIEWS: shadcn UI primitives rendered directly (safe with no props)
4228
4259
  `const PREVIEWS: Record<string, () => React.ReactElement> = {`,
4229
4260
  ...previewEntries.map(e => e + ','),
4230
4261
  `};`,
4262
+ // STORY_IDS: project components shown via their own story iframe
4263
+ `const STORY_IDS: Record<string, string> = {`,
4264
+ ...storyIdEntries.map(e => e + ','),
4265
+ `};`,
4231
4266
  ``,
4232
4267
  // Inventory data (metadata only — visual rendering is done at runtime via PREVIEWS)
4233
4268
  `const inventoryData: { category: string; components: { name: string; group: string; tokenCount: number; propCount: number; colorSwatches: { token: string; hex: string }[]; previewHtml: string; previewScale: number; active: boolean }[] }[] = ${JSON.stringify(inventoryData)};`,
@@ -4235,30 +4270,44 @@ function writeComponentInventoryStory(components, foundations) {
4235
4270
  `const activeComponents = ${activeComponents};`,
4236
4271
  `const uniqueTokens = ${uniqueTokens};`,
4237
4272
  ``,
4238
- // CardPreview: renders the actual component at the right scale, falls back to shape HTML
4273
+ // CardPreview: shadcn direct render; project story iframe; else shape HTML
4239
4274
  `const _InvPreview = ({ comp }: { comp: any }) => {`,
4240
- ` const s: number = comp.previewScale || 0.4;`,
4241
- ` const centered = s >= 0.9;`,
4242
4275
  ` const fn = PREVIEWS[comp.name];`,
4276
+ ` const storyId = STORY_IDS[comp.name];`,
4243
4277
  ` const shapeHtml = (`,
4244
4278
  ` <div style={{ width: "100%", height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}`,
4245
4279
  ` dangerouslySetInnerHTML={{ __html: comp.previewHtml }} />`,
4246
4280
  ` );`,
4247
- ` const wPct = (+(100 / s).toFixed(1)) + "%";`,
4248
- ` const innerStyle: React.CSSProperties = centered`,
4249
- ` ? { position: "absolute", top: "50%", left: "50%",`,
4250
- ` transform: "translate(-50%, -50%) scale(" + s + ")",`,
4251
- ` transformOrigin: "center center", pointerEvents: "none" }`,
4252
- ` : { position: "absolute", top: 0, left: 0, width: wPct,`,
4253
- ` transform: "scale(" + s + ")",`,
4254
- ` transformOrigin: "top left", pointerEvents: "none" };`,
4255
- ` return (`,
4256
- ` <div style={{ height: 96, overflow: "hidden", position: "relative", background: "#fff" }}>`,
4257
- ` <_EB fallback={shapeHtml}>`,
4258
- ` {fn ? <_PW><div style={innerStyle}>{fn()}</div></_PW> : shapeHtml}`,
4259
- ` </_EB>`,
4260
- ` </div>`,
4261
- ` );`,
4281
+ ` // Shadcn primitives: render directly with scale`,
4282
+ ` if (fn) {`,
4283
+ ` const s: number = comp.previewScale || 0.65;`,
4284
+ ` const centered = s >= 0.9;`,
4285
+ ` const wPct = (+(100 / s).toFixed(1)) + "%";`,
4286
+ ` const innerStyle: React.CSSProperties = centered`,
4287
+ ` ? { position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%) scale(" + s + ")", transformOrigin: "center center", pointerEvents: "none" }`,
4288
+ ` : { position: "absolute", top: 0, left: 0, width: wPct, transform: "scale(" + s + ")", transformOrigin: "top left", pointerEvents: "none" };`,
4289
+ ` return (`,
4290
+ ` <div style={{ height: 140, overflow: "hidden", position: "relative", background: "#fff" }}>`,
4291
+ ` <_EB fallback={shapeHtml}>`,
4292
+ ` <_PW><div style={innerStyle}>{fn()}</div></_PW>`,
4293
+ ` </_EB>`,
4294
+ ` </div>`,
4295
+ ` );`,
4296
+ ` }`,
4297
+ ` // Project components: embed their own story as iframe`,
4298
+ ` if (storyId) {`,
4299
+ ` return (`,
4300
+ ` <div style={{ height: 140, overflow: "hidden", position: "relative", background: "#fff" }}>`,
4301
+ ` <iframe`,
4302
+ ` src={"/iframe.html?id=" + storyId + "&viewMode=story"}`,
4303
+ ` style={{ width: "300%", height: "424px", transform: "scale(0.333)", transformOrigin: "top left", border: "none", pointerEvents: "none", display: "block" }}`,
4304
+ ` loading="lazy"`,
4305
+ ` />`,
4306
+ ` </div>`,
4307
+ ` );`,
4308
+ ` }`,
4309
+ ` // Fallback: shape HTML`,
4310
+ ` return <div style={{ height: 140, display: "flex", alignItems: "center", justifyContent: "center" }} dangerouslySetInnerHTML={{ __html: comp.previewHtml }} />;`,
4262
4311
  `};`,
4263
4312
  `const InventoryCard = ({ comp }: { comp: any }) => (`,
4264
4313
  ` <div style={{ border: "1px solid " + (comp.active ? "#e5e7eb" : "#f0f0f0"), borderRadius: 10, overflow: "hidden", background: comp.active ? "#fff" : "#fafafa", display: "flex", flexDirection: "column" as any, boxShadow: comp.active ? "0 1px 3px rgba(0,0,0,0.05)" : "none", opacity: comp.active ? 1 : 0.55 }}>`,