@fragments-sdk/cli 0.2.2

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.
Files changed (259) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +106 -0
  3. package/dist/bin.d.ts +1 -0
  4. package/dist/bin.js +4783 -0
  5. package/dist/bin.js.map +1 -0
  6. package/dist/chunk-4FDQSGKX.js +786 -0
  7. package/dist/chunk-4FDQSGKX.js.map +1 -0
  8. package/dist/chunk-7H2MMGYG.js +369 -0
  9. package/dist/chunk-7H2MMGYG.js.map +1 -0
  10. package/dist/chunk-BSCG3IP7.js +619 -0
  11. package/dist/chunk-BSCG3IP7.js.map +1 -0
  12. package/dist/chunk-LY2CFFPY.js +898 -0
  13. package/dist/chunk-LY2CFFPY.js.map +1 -0
  14. package/dist/chunk-MUZ6CM66.js +6636 -0
  15. package/dist/chunk-MUZ6CM66.js.map +1 -0
  16. package/dist/chunk-OAENNG3G.js +1489 -0
  17. package/dist/chunk-OAENNG3G.js.map +1 -0
  18. package/dist/chunk-XHNKNI6J.js +235 -0
  19. package/dist/chunk-XHNKNI6J.js.map +1 -0
  20. package/dist/core-DWKLGY4N.js +68 -0
  21. package/dist/core-DWKLGY4N.js.map +1 -0
  22. package/dist/generate-4LQNJ7SX.js +249 -0
  23. package/dist/generate-4LQNJ7SX.js.map +1 -0
  24. package/dist/index.d.ts +775 -0
  25. package/dist/index.js +41 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/init-EMVI47QG.js +416 -0
  28. package/dist/init-EMVI47QG.js.map +1 -0
  29. package/dist/mcp-bin.d.ts +1 -0
  30. package/dist/mcp-bin.js +1117 -0
  31. package/dist/mcp-bin.js.map +1 -0
  32. package/dist/scan-4YPRF7FV.js +12 -0
  33. package/dist/scan-4YPRF7FV.js.map +1 -0
  34. package/dist/service-QSZMZJBJ.js +208 -0
  35. package/dist/service-QSZMZJBJ.js.map +1 -0
  36. package/dist/static-viewer-MIPGZ4Z7.js +12 -0
  37. package/dist/static-viewer-MIPGZ4Z7.js.map +1 -0
  38. package/dist/test-SQ5ZHXWU.js +1067 -0
  39. package/dist/test-SQ5ZHXWU.js.map +1 -0
  40. package/dist/tokens-HSGMYK64.js +173 -0
  41. package/dist/tokens-HSGMYK64.js.map +1 -0
  42. package/dist/viewer-YRF4SQE4.js +11101 -0
  43. package/dist/viewer-YRF4SQE4.js.map +1 -0
  44. package/package.json +107 -0
  45. package/src/ai.ts +266 -0
  46. package/src/analyze.ts +265 -0
  47. package/src/bin.ts +916 -0
  48. package/src/build.ts +248 -0
  49. package/src/commands/a11y.ts +302 -0
  50. package/src/commands/add.ts +313 -0
  51. package/src/commands/audit.ts +195 -0
  52. package/src/commands/baseline.ts +221 -0
  53. package/src/commands/build.ts +144 -0
  54. package/src/commands/compare.ts +337 -0
  55. package/src/commands/context.ts +107 -0
  56. package/src/commands/dev.ts +107 -0
  57. package/src/commands/enhance.ts +858 -0
  58. package/src/commands/generate.ts +391 -0
  59. package/src/commands/init.ts +531 -0
  60. package/src/commands/link/figma.ts +645 -0
  61. package/src/commands/link/index.ts +10 -0
  62. package/src/commands/link/storybook.ts +267 -0
  63. package/src/commands/list.ts +49 -0
  64. package/src/commands/metrics.ts +114 -0
  65. package/src/commands/reset.ts +242 -0
  66. package/src/commands/scan.ts +537 -0
  67. package/src/commands/storygen.ts +207 -0
  68. package/src/commands/tokens.ts +251 -0
  69. package/src/commands/validate.ts +93 -0
  70. package/src/commands/verify.ts +215 -0
  71. package/src/core/composition.test.ts +262 -0
  72. package/src/core/composition.ts +255 -0
  73. package/src/core/config.ts +84 -0
  74. package/src/core/constants.ts +111 -0
  75. package/src/core/context.ts +380 -0
  76. package/src/core/defineSegment.ts +137 -0
  77. package/src/core/discovery.ts +337 -0
  78. package/src/core/figma.ts +263 -0
  79. package/src/core/fragment-types.ts +214 -0
  80. package/src/core/generators/context.ts +389 -0
  81. package/src/core/generators/index.ts +23 -0
  82. package/src/core/generators/registry.ts +364 -0
  83. package/src/core/generators/typescript-extractor.ts +374 -0
  84. package/src/core/importAnalyzer.ts +217 -0
  85. package/src/core/index.ts +149 -0
  86. package/src/core/loader.ts +155 -0
  87. package/src/core/node.ts +63 -0
  88. package/src/core/parser.ts +551 -0
  89. package/src/core/previewLoader.ts +172 -0
  90. package/src/core/schema/fragment.schema.json +189 -0
  91. package/src/core/schema/registry.schema.json +137 -0
  92. package/src/core/schema.ts +182 -0
  93. package/src/core/storyAdapter.test.ts +571 -0
  94. package/src/core/storyAdapter.ts +761 -0
  95. package/src/core/token-types.ts +287 -0
  96. package/src/core/types.ts +754 -0
  97. package/src/diff.ts +323 -0
  98. package/src/index.ts +43 -0
  99. package/src/mcp/__tests__/projectFields.test.ts +130 -0
  100. package/src/mcp/bin.ts +36 -0
  101. package/src/mcp/index.ts +8 -0
  102. package/src/mcp/server.ts +1310 -0
  103. package/src/mcp/utils.ts +54 -0
  104. package/src/mcp-bin.ts +36 -0
  105. package/src/migrate/__tests__/argTypes/argTypes.test.ts +189 -0
  106. package/src/migrate/__tests__/args/args.test.ts +452 -0
  107. package/src/migrate/__tests__/meta/meta.test.ts +198 -0
  108. package/src/migrate/__tests__/stories/stories.test.ts +278 -0
  109. package/src/migrate/__tests__/utils/utils.test.ts +371 -0
  110. package/src/migrate/__tests__/values/values.test.ts +303 -0
  111. package/src/migrate/bin.ts +108 -0
  112. package/src/migrate/converter.ts +658 -0
  113. package/src/migrate/detect.ts +196 -0
  114. package/src/migrate/index.ts +45 -0
  115. package/src/migrate/migrate.ts +163 -0
  116. package/src/migrate/parser.ts +1136 -0
  117. package/src/migrate/report.ts +624 -0
  118. package/src/migrate/types.ts +169 -0
  119. package/src/screenshot.ts +249 -0
  120. package/src/service/__tests__/ast-utils.test.ts +426 -0
  121. package/src/service/__tests__/enhance-scanner.test.ts +200 -0
  122. package/src/service/__tests__/figma/figma.test.ts +652 -0
  123. package/src/service/__tests__/metrics-store.test.ts +409 -0
  124. package/src/service/__tests__/patch-generator.test.ts +186 -0
  125. package/src/service/__tests__/props-extractor.test.ts +365 -0
  126. package/src/service/__tests__/token-registry.test.ts +267 -0
  127. package/src/service/analytics.ts +659 -0
  128. package/src/service/ast-utils.ts +444 -0
  129. package/src/service/browser-pool.ts +339 -0
  130. package/src/service/capture.ts +267 -0
  131. package/src/service/diff.ts +279 -0
  132. package/src/service/enhance/aggregator.ts +489 -0
  133. package/src/service/enhance/cache.ts +275 -0
  134. package/src/service/enhance/codebase-scanner.ts +357 -0
  135. package/src/service/enhance/context-generator.ts +529 -0
  136. package/src/service/enhance/doc-extractor.ts +523 -0
  137. package/src/service/enhance/index.ts +131 -0
  138. package/src/service/enhance/props-extractor.ts +665 -0
  139. package/src/service/enhance/scanner.ts +445 -0
  140. package/src/service/enhance/storybook-parser.ts +552 -0
  141. package/src/service/enhance/types.ts +346 -0
  142. package/src/service/enhance/variant-renderer.ts +479 -0
  143. package/src/service/figma.ts +1008 -0
  144. package/src/service/index.ts +249 -0
  145. package/src/service/metrics-store.ts +333 -0
  146. package/src/service/patch-generator.ts +349 -0
  147. package/src/service/report.ts +854 -0
  148. package/src/service/storage.ts +401 -0
  149. package/src/service/token-fixes.ts +281 -0
  150. package/src/service/token-parser.ts +504 -0
  151. package/src/service/token-registry.ts +721 -0
  152. package/src/service/utils.ts +172 -0
  153. package/src/setup.ts +241 -0
  154. package/src/shared/command-wrapper.ts +81 -0
  155. package/src/shared/dev-server-client.ts +199 -0
  156. package/src/shared/index.ts +8 -0
  157. package/src/shared/segment-loader.ts +59 -0
  158. package/src/shared/types.ts +147 -0
  159. package/src/static-viewer.ts +715 -0
  160. package/src/test/discovery.ts +172 -0
  161. package/src/test/index.ts +281 -0
  162. package/src/test/reporters/console.ts +194 -0
  163. package/src/test/reporters/json.ts +190 -0
  164. package/src/test/reporters/junit.ts +186 -0
  165. package/src/test/runner.ts +598 -0
  166. package/src/test/types.ts +245 -0
  167. package/src/test/watch.ts +200 -0
  168. package/src/validators.ts +152 -0
  169. package/src/viewer/__tests__/jsx-parser.test.ts +502 -0
  170. package/src/viewer/__tests__/render-utils.test.ts +232 -0
  171. package/src/viewer/__tests__/style-utils.test.ts +404 -0
  172. package/src/viewer/bin.ts +86 -0
  173. package/src/viewer/cli/health.ts +256 -0
  174. package/src/viewer/cli/index.ts +33 -0
  175. package/src/viewer/cli/scan.ts +124 -0
  176. package/src/viewer/cli/utils.ts +174 -0
  177. package/src/viewer/components/AccessibilityPanel.tsx +1404 -0
  178. package/src/viewer/components/ActionCapture.tsx +172 -0
  179. package/src/viewer/components/ActionsPanel.tsx +371 -0
  180. package/src/viewer/components/App.tsx +638 -0
  181. package/src/viewer/components/BottomPanel.tsx +224 -0
  182. package/src/viewer/components/CodePanel.tsx +589 -0
  183. package/src/viewer/components/CommandPalette.tsx +336 -0
  184. package/src/viewer/components/ComponentGraph.tsx +394 -0
  185. package/src/viewer/components/ComponentHeader.tsx +85 -0
  186. package/src/viewer/components/ContractPanel.tsx +234 -0
  187. package/src/viewer/components/ErrorBoundary.tsx +85 -0
  188. package/src/viewer/components/FigmaEmbed.tsx +231 -0
  189. package/src/viewer/components/FragmentEditor.tsx +485 -0
  190. package/src/viewer/components/HealthDashboard.tsx +452 -0
  191. package/src/viewer/components/HmrStatusIndicator.tsx +71 -0
  192. package/src/viewer/components/Icons.tsx +417 -0
  193. package/src/viewer/components/InteractionsPanel.tsx +720 -0
  194. package/src/viewer/components/IsolatedPreviewFrame.tsx +321 -0
  195. package/src/viewer/components/IsolatedRender.tsx +111 -0
  196. package/src/viewer/components/KeyboardShortcutsHelp.tsx +89 -0
  197. package/src/viewer/components/LandingPage.tsx +441 -0
  198. package/src/viewer/components/Layout.tsx +22 -0
  199. package/src/viewer/components/LeftSidebar.tsx +391 -0
  200. package/src/viewer/components/MultiViewportPreview.tsx +429 -0
  201. package/src/viewer/components/PreviewArea.tsx +404 -0
  202. package/src/viewer/components/PreviewFrameHost.tsx +310 -0
  203. package/src/viewer/components/PreviewPane.tsx +150 -0
  204. package/src/viewer/components/PreviewToolbar.tsx +176 -0
  205. package/src/viewer/components/PropsEditor.tsx +512 -0
  206. package/src/viewer/components/PropsTable.tsx +98 -0
  207. package/src/viewer/components/RelationsSection.tsx +57 -0
  208. package/src/viewer/components/ResizablePanel.tsx +328 -0
  209. package/src/viewer/components/RightSidebar.tsx +118 -0
  210. package/src/viewer/components/ScreenshotButton.tsx +90 -0
  211. package/src/viewer/components/Sidebar.tsx +169 -0
  212. package/src/viewer/components/SkeletonLoader.tsx +156 -0
  213. package/src/viewer/components/StoryRenderer.tsx +128 -0
  214. package/src/viewer/components/ThemeProvider.tsx +96 -0
  215. package/src/viewer/components/Toast.tsx +67 -0
  216. package/src/viewer/components/TokenStylePanel.tsx +708 -0
  217. package/src/viewer/components/UsageSection.tsx +95 -0
  218. package/src/viewer/components/VariantMatrix.tsx +350 -0
  219. package/src/viewer/components/VariantRenderer.tsx +131 -0
  220. package/src/viewer/components/VariantTabs.tsx +84 -0
  221. package/src/viewer/components/ViewportSelector.tsx +165 -0
  222. package/src/viewer/components/_future/CreatePage.tsx +836 -0
  223. package/src/viewer/composition-renderer.ts +381 -0
  224. package/src/viewer/constants/index.ts +1 -0
  225. package/src/viewer/constants/ui.ts +185 -0
  226. package/src/viewer/entry.tsx +299 -0
  227. package/src/viewer/hooks/index.ts +2 -0
  228. package/src/viewer/hooks/useA11yCache.ts +383 -0
  229. package/src/viewer/hooks/useA11yService.ts +498 -0
  230. package/src/viewer/hooks/useActions.ts +138 -0
  231. package/src/viewer/hooks/useAppState.ts +124 -0
  232. package/src/viewer/hooks/useFigmaIntegration.ts +132 -0
  233. package/src/viewer/hooks/useHmrStatus.ts +109 -0
  234. package/src/viewer/hooks/useKeyboardShortcuts.ts +222 -0
  235. package/src/viewer/hooks/usePreviewBridge.ts +347 -0
  236. package/src/viewer/hooks/useScrollSpy.ts +78 -0
  237. package/src/viewer/hooks/useUrlState.ts +330 -0
  238. package/src/viewer/hooks/useViewSettings.ts +125 -0
  239. package/src/viewer/index.html +28 -0
  240. package/src/viewer/index.ts +14 -0
  241. package/src/viewer/intelligence/healthReport.ts +505 -0
  242. package/src/viewer/intelligence/styleDrift.ts +340 -0
  243. package/src/viewer/intelligence/usageScanner.ts +309 -0
  244. package/src/viewer/jsx-parser.ts +485 -0
  245. package/src/viewer/postcss.config.js +6 -0
  246. package/src/viewer/preview-frame-entry.tsx +25 -0
  247. package/src/viewer/preview-frame.html +109 -0
  248. package/src/viewer/render-template.html +68 -0
  249. package/src/viewer/render-utils.ts +170 -0
  250. package/src/viewer/server.ts +276 -0
  251. package/src/viewer/style-utils.ts +414 -0
  252. package/src/viewer/styles/globals.css +355 -0
  253. package/src/viewer/tailwind.config.js +37 -0
  254. package/src/viewer/types/a11y.ts +197 -0
  255. package/src/viewer/utils/a11y-fixes.ts +471 -0
  256. package/src/viewer/utils/actionExport.ts +372 -0
  257. package/src/viewer/utils/colorSchemes.ts +201 -0
  258. package/src/viewer/utils/detectRelationships.ts +256 -0
  259. package/src/viewer/vite-plugin.ts +2143 -0
@@ -0,0 +1,619 @@
1
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ BRAND
4
+ } from "./chunk-XHNKNI6J.js";
5
+
6
+ // src/static-viewer.ts
7
+ import { readFile } from "fs/promises";
8
+ function generateStaticViewer(data) {
9
+ const segments = Object.values(data.segments);
10
+ const categories = /* @__PURE__ */ new Map();
11
+ for (const segment of segments) {
12
+ const category = segment.meta.category ?? "Uncategorized";
13
+ if (!categories.has(category)) {
14
+ categories.set(category, []);
15
+ }
16
+ categories.get(category).push(segment);
17
+ }
18
+ const sortedCategories = Array.from(categories.entries()).sort(
19
+ (a, b) => a[0].localeCompare(b[0])
20
+ );
21
+ return `<!DOCTYPE html>
22
+ <html lang="en">
23
+ <head>
24
+ <meta charset="UTF-8">
25
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
26
+ <title>${BRAND.name} - Design System Viewer</title>
27
+ <link rel="preconnect" href="https://fonts.googleapis.com">
28
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
29
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
30
+ <style>
31
+ :root {
32
+ --bg-primary: #0a0a0f;
33
+ --bg-secondary: #12121a;
34
+ --bg-tertiary: #1a1a24;
35
+ --bg-hover: #22222e;
36
+ --border-color: #2a2a3a;
37
+ --text-primary: #f5f5f7;
38
+ --text-secondary: #a0a0b0;
39
+ --text-muted: #606070;
40
+ --accent: #6366f1;
41
+ --accent-hover: #818cf8;
42
+ --success: #22c55e;
43
+ --warning: #f59e0b;
44
+ --error: #ef4444;
45
+ --code-bg: #1e1e2e;
46
+ }
47
+
48
+ * {
49
+ margin: 0;
50
+ padding: 0;
51
+ box-sizing: border-box;
52
+ }
53
+
54
+ body {
55
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
56
+ background: var(--bg-primary);
57
+ color: var(--text-primary);
58
+ line-height: 1.6;
59
+ }
60
+
61
+ .layout {
62
+ display: grid;
63
+ grid-template-columns: 280px 1fr;
64
+ min-height: 100vh;
65
+ }
66
+
67
+ /* Sidebar */
68
+ .sidebar {
69
+ background: var(--bg-secondary);
70
+ border-right: 1px solid var(--border-color);
71
+ padding: 24px 0;
72
+ position: sticky;
73
+ top: 0;
74
+ height: 100vh;
75
+ overflow-y: auto;
76
+ }
77
+
78
+ .sidebar-header {
79
+ padding: 0 20px 20px;
80
+ border-bottom: 1px solid var(--border-color);
81
+ margin-bottom: 16px;
82
+ }
83
+
84
+ .sidebar-header h1 {
85
+ font-size: 20px;
86
+ font-weight: 700;
87
+ background: linear-gradient(135deg, var(--accent), #a855f7);
88
+ -webkit-background-clip: text;
89
+ -webkit-text-fill-color: transparent;
90
+ }
91
+
92
+ .sidebar-header .subtitle {
93
+ font-size: 12px;
94
+ color: var(--text-muted);
95
+ margin-top: 4px;
96
+ }
97
+
98
+ .sidebar-stats {
99
+ display: flex;
100
+ gap: 16px;
101
+ padding: 12px 20px;
102
+ background: var(--bg-tertiary);
103
+ margin: 0 12px 16px;
104
+ border-radius: 8px;
105
+ }
106
+
107
+ .stat {
108
+ text-align: center;
109
+ }
110
+
111
+ .stat-value {
112
+ font-size: 20px;
113
+ font-weight: 700;
114
+ color: var(--accent);
115
+ }
116
+
117
+ .stat-label {
118
+ font-size: 11px;
119
+ color: var(--text-muted);
120
+ text-transform: uppercase;
121
+ letter-spacing: 0.5px;
122
+ }
123
+
124
+ .category {
125
+ margin-bottom: 8px;
126
+ }
127
+
128
+ .category-header {
129
+ padding: 8px 20px;
130
+ font-size: 11px;
131
+ font-weight: 600;
132
+ text-transform: uppercase;
133
+ letter-spacing: 0.5px;
134
+ color: var(--text-muted);
135
+ }
136
+
137
+ .nav-item {
138
+ display: block;
139
+ padding: 8px 20px 8px 32px;
140
+ color: var(--text-secondary);
141
+ text-decoration: none;
142
+ font-size: 14px;
143
+ transition: all 0.15s;
144
+ }
145
+
146
+ .nav-item:hover {
147
+ background: var(--bg-hover);
148
+ color: var(--text-primary);
149
+ }
150
+
151
+ .nav-item.active {
152
+ background: var(--accent);
153
+ color: white;
154
+ }
155
+
156
+ /* Main Content */
157
+ .main {
158
+ padding: 40px 60px;
159
+ max-width: 1000px;
160
+ }
161
+
162
+ .component-section {
163
+ margin-bottom: 60px;
164
+ scroll-margin-top: 40px;
165
+ }
166
+
167
+ .component-header {
168
+ margin-bottom: 24px;
169
+ padding-bottom: 16px;
170
+ border-bottom: 1px solid var(--border-color);
171
+ }
172
+
173
+ .component-name {
174
+ font-size: 32px;
175
+ font-weight: 700;
176
+ margin-bottom: 8px;
177
+ }
178
+
179
+ .component-description {
180
+ font-size: 16px;
181
+ color: var(--text-secondary);
182
+ line-height: 1.7;
183
+ }
184
+
185
+ .component-meta {
186
+ display: flex;
187
+ gap: 16px;
188
+ margin-top: 16px;
189
+ }
190
+
191
+ .meta-badge {
192
+ display: inline-flex;
193
+ align-items: center;
194
+ gap: 6px;
195
+ padding: 4px 12px;
196
+ background: var(--bg-tertiary);
197
+ border-radius: 20px;
198
+ font-size: 12px;
199
+ color: var(--text-secondary);
200
+ }
201
+
202
+ .meta-badge.status-stable { color: var(--success); }
203
+ .meta-badge.status-beta { color: var(--warning); }
204
+ .meta-badge.status-deprecated { color: var(--error); }
205
+
206
+ /* Sections */
207
+ .section {
208
+ margin-bottom: 32px;
209
+ }
210
+
211
+ .section-title {
212
+ font-size: 18px;
213
+ font-weight: 600;
214
+ margin-bottom: 16px;
215
+ color: var(--text-primary);
216
+ }
217
+
218
+ /* Usage Guidelines */
219
+ .usage-list {
220
+ list-style: none;
221
+ }
222
+
223
+ .usage-item {
224
+ display: flex;
225
+ gap: 12px;
226
+ padding: 12px 16px;
227
+ background: var(--bg-secondary);
228
+ border-radius: 8px;
229
+ margin-bottom: 8px;
230
+ font-size: 14px;
231
+ }
232
+
233
+ .usage-item.when::before {
234
+ content: '\u2713';
235
+ color: var(--success);
236
+ font-weight: bold;
237
+ }
238
+
239
+ .usage-item.when-not::before {
240
+ content: '\u2717';
241
+ color: var(--error);
242
+ font-weight: bold;
243
+ }
244
+
245
+ /* Props Table */
246
+ .props-table {
247
+ width: 100%;
248
+ border-collapse: collapse;
249
+ font-size: 14px;
250
+ }
251
+
252
+ .props-table th {
253
+ text-align: left;
254
+ padding: 12px 16px;
255
+ background: var(--bg-tertiary);
256
+ font-weight: 600;
257
+ color: var(--text-secondary);
258
+ font-size: 12px;
259
+ text-transform: uppercase;
260
+ letter-spacing: 0.5px;
261
+ }
262
+
263
+ .props-table td {
264
+ padding: 12px 16px;
265
+ border-bottom: 1px solid var(--border-color);
266
+ vertical-align: top;
267
+ }
268
+
269
+ .props-table tr:hover td {
270
+ background: var(--bg-secondary);
271
+ }
272
+
273
+ .prop-name {
274
+ font-family: 'JetBrains Mono', monospace;
275
+ color: var(--accent);
276
+ }
277
+
278
+ .prop-type {
279
+ font-family: 'JetBrains Mono', monospace;
280
+ font-size: 13px;
281
+ color: var(--text-muted);
282
+ }
283
+
284
+ .prop-required {
285
+ color: var(--error);
286
+ font-size: 11px;
287
+ font-weight: 600;
288
+ }
289
+
290
+ .prop-default {
291
+ font-family: 'JetBrains Mono', monospace;
292
+ font-size: 13px;
293
+ color: var(--text-muted);
294
+ background: var(--code-bg);
295
+ padding: 2px 6px;
296
+ border-radius: 4px;
297
+ }
298
+
299
+ /* Variants */
300
+ .variants-grid {
301
+ display: grid;
302
+ gap: 16px;
303
+ }
304
+
305
+ .variant-card {
306
+ background: var(--bg-secondary);
307
+ border: 1px solid var(--border-color);
308
+ border-radius: 12px;
309
+ padding: 20px;
310
+ }
311
+
312
+ .variant-name {
313
+ font-weight: 600;
314
+ margin-bottom: 8px;
315
+ }
316
+
317
+ .variant-description {
318
+ font-size: 14px;
319
+ color: var(--text-secondary);
320
+ margin-bottom: 12px;
321
+ }
322
+
323
+ .variant-code {
324
+ font-family: 'JetBrains Mono', monospace;
325
+ font-size: 13px;
326
+ background: var(--code-bg);
327
+ padding: 12px 16px;
328
+ border-radius: 8px;
329
+ overflow-x: auto;
330
+ color: var(--text-secondary);
331
+ }
332
+
333
+ /* Relations */
334
+ .relations-list {
335
+ display: flex;
336
+ flex-wrap: wrap;
337
+ gap: 8px;
338
+ }
339
+
340
+ .relation-tag {
341
+ padding: 6px 14px;
342
+ background: var(--bg-tertiary);
343
+ border: 1px solid var(--border-color);
344
+ border-radius: 20px;
345
+ font-size: 13px;
346
+ color: var(--text-secondary);
347
+ text-decoration: none;
348
+ transition: all 0.15s;
349
+ }
350
+
351
+ .relation-tag:hover {
352
+ border-color: var(--accent);
353
+ color: var(--accent);
354
+ }
355
+
356
+ /* Search */
357
+ .search-container {
358
+ padding: 0 12px 16px;
359
+ }
360
+
361
+ .search-input {
362
+ width: 100%;
363
+ padding: 10px 14px;
364
+ background: var(--bg-tertiary);
365
+ border: 1px solid var(--border-color);
366
+ border-radius: 8px;
367
+ color: var(--text-primary);
368
+ font-size: 14px;
369
+ outline: none;
370
+ transition: border-color 0.15s;
371
+ }
372
+
373
+ .search-input:focus {
374
+ border-color: var(--accent);
375
+ }
376
+
377
+ .search-input::placeholder {
378
+ color: var(--text-muted);
379
+ }
380
+
381
+ /* Empty State */
382
+ .empty-state {
383
+ text-align: center;
384
+ padding: 80px 40px;
385
+ color: var(--text-muted);
386
+ }
387
+
388
+ .empty-state h2 {
389
+ font-size: 24px;
390
+ margin-bottom: 12px;
391
+ color: var(--text-secondary);
392
+ }
393
+
394
+ @media (max-width: 900px) {
395
+ .layout {
396
+ grid-template-columns: 1fr;
397
+ }
398
+
399
+ .sidebar {
400
+ position: relative;
401
+ height: auto;
402
+ border-right: none;
403
+ border-bottom: 1px solid var(--border-color);
404
+ }
405
+
406
+ .main {
407
+ padding: 24px;
408
+ }
409
+ }
410
+ </style>
411
+ </head>
412
+ <body>
413
+ <div class="layout">
414
+ <aside class="sidebar">
415
+ <div class="sidebar-header">
416
+ <h1>${BRAND.name}</h1>
417
+ <div class="subtitle">Design System Documentation</div>
418
+ </div>
419
+
420
+ <div class="sidebar-stats">
421
+ <div class="stat">
422
+ <div class="stat-value">${segments.length}</div>
423
+ <div class="stat-label">Components</div>
424
+ </div>
425
+ <div class="stat">
426
+ <div class="stat-value">${segments.reduce(
427
+ (sum, s) => sum + s.variants.length,
428
+ 0
429
+ )}</div>
430
+ <div class="stat-label">Variants</div>
431
+ </div>
432
+ </div>
433
+
434
+ <div class="search-container">
435
+ <input type="text" class="search-input" placeholder="Search components..." id="search">
436
+ </div>
437
+
438
+ <nav id="nav">
439
+ ${sortedCategories.map(
440
+ ([category, items]) => `
441
+ <div class="category">
442
+ <div class="category-header">${category}</div>
443
+ ${items.sort((a, b) => a.meta.name.localeCompare(b.meta.name)).map(
444
+ (item) => `
445
+ <a href="#${item.meta.name}" class="nav-item">${item.meta.name}</a>
446
+ `
447
+ ).join("")}
448
+ </div>
449
+ `
450
+ ).join("")}
451
+ </nav>
452
+ </aside>
453
+
454
+ <main class="main" id="main">
455
+ ${segments.length === 0 ? `
456
+ <div class="empty-state">
457
+ <h2>No Components Found</h2>
458
+ <p>Run <code>segments build</code> to compile your segment files.</p>
459
+ </div>
460
+ ` : segments.sort((a, b) => a.meta.name.localeCompare(b.meta.name)).map(
461
+ (segment) => `
462
+ <section class="component-section" id="${segment.meta.name}">
463
+ <div class="component-header">
464
+ <h2 class="component-name">${segment.meta.name}</h2>
465
+ <p class="component-description">${segment.meta.description}</p>
466
+ <div class="component-meta">
467
+ ${segment.meta.status ? `<span class="meta-badge status-${segment.meta.status}">${segment.meta.status}</span>` : ""}
468
+ ${segment.meta.category ? `<span class="meta-badge">${segment.meta.category}</span>` : ""}
469
+ ${segment.meta.tags?.map((tag) => `<span class="meta-badge">${tag}</span>`).join("") ?? ""}
470
+ </div>
471
+ </div>
472
+
473
+ ${segment.usage ? `
474
+ <div class="section">
475
+ <h3 class="section-title">Usage Guidelines</h3>
476
+ ${segment.usage.when?.length ? `
477
+ <ul class="usage-list">
478
+ ${segment.usage.when.map((item) => `<li class="usage-item when">${item}</li>`).join("")}
479
+ </ul>
480
+ ` : ""}
481
+ ${segment.usage.whenNot?.length ? `
482
+ <ul class="usage-list" style="margin-top: 12px;">
483
+ ${segment.usage.whenNot.map(
484
+ (item) => `<li class="usage-item when-not">${item}</li>`
485
+ ).join("")}
486
+ </ul>
487
+ ` : ""}
488
+ </div>
489
+ ` : ""}
490
+
491
+ ${segment.props && Object.keys(segment.props).length ? `
492
+ <div class="section">
493
+ <h3 class="section-title">Props</h3>
494
+ <table class="props-table">
495
+ <thead>
496
+ <tr>
497
+ <th>Name</th>
498
+ <th>Type</th>
499
+ <th>Default</th>
500
+ <th>Description</th>
501
+ </tr>
502
+ </thead>
503
+ <tbody>
504
+ ${Object.entries(segment.props).map(
505
+ ([name, prop]) => `
506
+ <tr>
507
+ <td>
508
+ <span class="prop-name">${name}</span>
509
+ ${prop.required ? '<span class="prop-required">*</span>' : ""}
510
+ </td>
511
+ <td><span class="prop-type">${prop.type}</span></td>
512
+ <td>${prop.default !== void 0 ? `<span class="prop-default">${prop.default}</span>` : "\u2014"}</td>
513
+ <td>${prop.description ?? ""}</td>
514
+ </tr>
515
+ `
516
+ ).join("")}
517
+ </tbody>
518
+ </table>
519
+ </div>
520
+ ` : ""}
521
+
522
+ ${segment.variants?.length ? `
523
+ <div class="section">
524
+ <h3 class="section-title">Variants</h3>
525
+ <div class="variants-grid">
526
+ ${segment.variants.map(
527
+ (variant) => `
528
+ <div class="variant-card">
529
+ <div class="variant-name">${variant.name}</div>
530
+ ${variant.description ? `<div class="variant-description">${variant.description}</div>` : ""}
531
+ ${variant.code ? `<pre class="variant-code">${escapeHtml(
532
+ variant.code
533
+ )}</pre>` : ""}
534
+ </div>
535
+ `
536
+ ).join("")}
537
+ </div>
538
+ </div>
539
+ ` : ""}
540
+
541
+ ${segment.relations?.length ? `
542
+ <div class="section">
543
+ <h3 class="section-title">Related Components</h3>
544
+ <div class="relations-list">
545
+ ${segment.relations.map(
546
+ (rel) => `<a href="#${rel.component}" class="relation-tag" title="${rel.note}">${rel.relationship === "parent" ? "\u2191" : rel.relationship === "child" ? "\u2193" : "\u2194"} ${rel.component}</a>`
547
+ ).join("")}
548
+ </div>
549
+ </div>
550
+ ` : ""}
551
+ </section>
552
+ `
553
+ ).join("")}
554
+ </main>
555
+ </div>
556
+
557
+ <script>
558
+ // Search functionality
559
+ const searchInput = document.getElementById('search');
560
+ const nav = document.getElementById('nav');
561
+ const main = document.getElementById('main');
562
+
563
+ searchInput.addEventListener('input', (e) => {
564
+ const query = e.target.value.toLowerCase();
565
+
566
+ // Filter nav items
567
+ nav.querySelectorAll('.nav-item').forEach(item => {
568
+ const name = item.textContent.toLowerCase();
569
+ item.style.display = name.includes(query) ? '' : 'none';
570
+ });
571
+
572
+ // Show/hide categories with no visible items
573
+ nav.querySelectorAll('.category').forEach(cat => {
574
+ const hasVisible = Array.from(cat.querySelectorAll('.nav-item')).some(
575
+ item => item.style.display !== 'none'
576
+ );
577
+ cat.style.display = hasVisible ? '' : 'none';
578
+ });
579
+
580
+ // Filter main sections
581
+ main.querySelectorAll('.component-section').forEach(section => {
582
+ const name = section.id.toLowerCase();
583
+ section.style.display = name.includes(query) ? '' : 'none';
584
+ });
585
+ });
586
+
587
+ // Highlight active nav item on scroll
588
+ const sections = document.querySelectorAll('.component-section');
589
+ const navItems = document.querySelectorAll('.nav-item');
590
+
591
+ const observer = new IntersectionObserver((entries) => {
592
+ entries.forEach(entry => {
593
+ if (entry.isIntersecting) {
594
+ navItems.forEach(item => {
595
+ item.classList.toggle('active', item.getAttribute('href') === '#' + entry.target.id);
596
+ });
597
+ }
598
+ });
599
+ }, { threshold: 0.3 });
600
+
601
+ sections.forEach(section => observer.observe(section));
602
+ </script>
603
+ </body>
604
+ </html>`;
605
+ }
606
+ function escapeHtml(str) {
607
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
608
+ }
609
+ async function generateViewerFromJson(jsonPath) {
610
+ const content = await readFile(jsonPath, "utf-8");
611
+ const data = JSON.parse(content);
612
+ return generateStaticViewer(data);
613
+ }
614
+
615
+ export {
616
+ generateStaticViewer,
617
+ generateViewerFromJson
618
+ };
619
+ //# sourceMappingURL=chunk-BSCG3IP7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/static-viewer.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport type { CompiledSegmentsFile } from \"./core/index.js\";\nimport { BRAND } from \"./core/index.js\";\n\n/**\n * Generate a static HTML viewer for the segments.json file.\n * This viewer shows component documentation without needing to render actual components.\n */\nexport function generateStaticViewer(data: CompiledSegmentsFile): string {\n const segments = Object.values(data.segments);\n\n // Group by category\n const categories = new Map<string, typeof segments>();\n for (const segment of segments) {\n const category = segment.meta.category ?? \"Uncategorized\";\n if (!categories.has(category)) {\n categories.set(category, []);\n }\n categories.get(category)!.push(segment);\n }\n\n // Sort categories and components\n const sortedCategories = Array.from(categories.entries()).sort((a, b) =>\n a[0].localeCompare(b[0])\n );\n\n return `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${BRAND.name} - Design System Viewer</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap\" rel=\"stylesheet\">\n <style>\n :root {\n --bg-primary: #0a0a0f;\n --bg-secondary: #12121a;\n --bg-tertiary: #1a1a24;\n --bg-hover: #22222e;\n --border-color: #2a2a3a;\n --text-primary: #f5f5f7;\n --text-secondary: #a0a0b0;\n --text-muted: #606070;\n --accent: #6366f1;\n --accent-hover: #818cf8;\n --success: #22c55e;\n --warning: #f59e0b;\n --error: #ef4444;\n --code-bg: #1e1e2e;\n }\n \n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n }\n \n body {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n background: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.6;\n }\n \n .layout {\n display: grid;\n grid-template-columns: 280px 1fr;\n min-height: 100vh;\n }\n \n /* Sidebar */\n .sidebar {\n background: var(--bg-secondary);\n border-right: 1px solid var(--border-color);\n padding: 24px 0;\n position: sticky;\n top: 0;\n height: 100vh;\n overflow-y: auto;\n }\n \n .sidebar-header {\n padding: 0 20px 20px;\n border-bottom: 1px solid var(--border-color);\n margin-bottom: 16px;\n }\n \n .sidebar-header h1 {\n font-size: 20px;\n font-weight: 700;\n background: linear-gradient(135deg, var(--accent), #a855f7);\n -webkit-background-clip: text;\n -webkit-text-fill-color: transparent;\n }\n \n .sidebar-header .subtitle {\n font-size: 12px;\n color: var(--text-muted);\n margin-top: 4px;\n }\n \n .sidebar-stats {\n display: flex;\n gap: 16px;\n padding: 12px 20px;\n background: var(--bg-tertiary);\n margin: 0 12px 16px;\n border-radius: 8px;\n }\n \n .stat {\n text-align: center;\n }\n \n .stat-value {\n font-size: 20px;\n font-weight: 700;\n color: var(--accent);\n }\n \n .stat-label {\n font-size: 11px;\n color: var(--text-muted);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .category {\n margin-bottom: 8px;\n }\n \n .category-header {\n padding: 8px 20px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--text-muted);\n }\n \n .nav-item {\n display: block;\n padding: 8px 20px 8px 32px;\n color: var(--text-secondary);\n text-decoration: none;\n font-size: 14px;\n transition: all 0.15s;\n }\n \n .nav-item:hover {\n background: var(--bg-hover);\n color: var(--text-primary);\n }\n \n .nav-item.active {\n background: var(--accent);\n color: white;\n }\n \n /* Main Content */\n .main {\n padding: 40px 60px;\n max-width: 1000px;\n }\n \n .component-section {\n margin-bottom: 60px;\n scroll-margin-top: 40px;\n }\n \n .component-header {\n margin-bottom: 24px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border-color);\n }\n \n .component-name {\n font-size: 32px;\n font-weight: 700;\n margin-bottom: 8px;\n }\n \n .component-description {\n font-size: 16px;\n color: var(--text-secondary);\n line-height: 1.7;\n }\n \n .component-meta {\n display: flex;\n gap: 16px;\n margin-top: 16px;\n }\n \n .meta-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n background: var(--bg-tertiary);\n border-radius: 20px;\n font-size: 12px;\n color: var(--text-secondary);\n }\n \n .meta-badge.status-stable { color: var(--success); }\n .meta-badge.status-beta { color: var(--warning); }\n .meta-badge.status-deprecated { color: var(--error); }\n \n /* Sections */\n .section {\n margin-bottom: 32px;\n }\n \n .section-title {\n font-size: 18px;\n font-weight: 600;\n margin-bottom: 16px;\n color: var(--text-primary);\n }\n \n /* Usage Guidelines */\n .usage-list {\n list-style: none;\n }\n \n .usage-item {\n display: flex;\n gap: 12px;\n padding: 12px 16px;\n background: var(--bg-secondary);\n border-radius: 8px;\n margin-bottom: 8px;\n font-size: 14px;\n }\n \n .usage-item.when::before {\n content: '✓';\n color: var(--success);\n font-weight: bold;\n }\n \n .usage-item.when-not::before {\n content: '✗';\n color: var(--error);\n font-weight: bold;\n }\n \n /* Props Table */\n .props-table {\n width: 100%;\n border-collapse: collapse;\n font-size: 14px;\n }\n \n .props-table th {\n text-align: left;\n padding: 12px 16px;\n background: var(--bg-tertiary);\n font-weight: 600;\n color: var(--text-secondary);\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n }\n \n .props-table td {\n padding: 12px 16px;\n border-bottom: 1px solid var(--border-color);\n vertical-align: top;\n }\n \n .props-table tr:hover td {\n background: var(--bg-secondary);\n }\n \n .prop-name {\n font-family: 'JetBrains Mono', monospace;\n color: var(--accent);\n }\n \n .prop-type {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n color: var(--text-muted);\n }\n \n .prop-required {\n color: var(--error);\n font-size: 11px;\n font-weight: 600;\n }\n \n .prop-default {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n color: var(--text-muted);\n background: var(--code-bg);\n padding: 2px 6px;\n border-radius: 4px;\n }\n \n /* Variants */\n .variants-grid {\n display: grid;\n gap: 16px;\n }\n \n .variant-card {\n background: var(--bg-secondary);\n border: 1px solid var(--border-color);\n border-radius: 12px;\n padding: 20px;\n }\n \n .variant-name {\n font-weight: 600;\n margin-bottom: 8px;\n }\n \n .variant-description {\n font-size: 14px;\n color: var(--text-secondary);\n margin-bottom: 12px;\n }\n \n .variant-code {\n font-family: 'JetBrains Mono', monospace;\n font-size: 13px;\n background: var(--code-bg);\n padding: 12px 16px;\n border-radius: 8px;\n overflow-x: auto;\n color: var(--text-secondary);\n }\n \n /* Relations */\n .relations-list {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n }\n \n .relation-tag {\n padding: 6px 14px;\n background: var(--bg-tertiary);\n border: 1px solid var(--border-color);\n border-radius: 20px;\n font-size: 13px;\n color: var(--text-secondary);\n text-decoration: none;\n transition: all 0.15s;\n }\n \n .relation-tag:hover {\n border-color: var(--accent);\n color: var(--accent);\n }\n \n /* Search */\n .search-container {\n padding: 0 12px 16px;\n }\n \n .search-input {\n width: 100%;\n padding: 10px 14px;\n background: var(--bg-tertiary);\n border: 1px solid var(--border-color);\n border-radius: 8px;\n color: var(--text-primary);\n font-size: 14px;\n outline: none;\n transition: border-color 0.15s;\n }\n \n .search-input:focus {\n border-color: var(--accent);\n }\n \n .search-input::placeholder {\n color: var(--text-muted);\n }\n \n /* Empty State */\n .empty-state {\n text-align: center;\n padding: 80px 40px;\n color: var(--text-muted);\n }\n \n .empty-state h2 {\n font-size: 24px;\n margin-bottom: 12px;\n color: var(--text-secondary);\n }\n \n @media (max-width: 900px) {\n .layout {\n grid-template-columns: 1fr;\n }\n \n .sidebar {\n position: relative;\n height: auto;\n border-right: none;\n border-bottom: 1px solid var(--border-color);\n }\n \n .main {\n padding: 24px;\n }\n }\n </style>\n</head>\n<body>\n <div class=\"layout\">\n <aside class=\"sidebar\">\n <div class=\"sidebar-header\">\n <h1>${BRAND.name}</h1>\n <div class=\"subtitle\">Design System Documentation</div>\n </div>\n \n <div class=\"sidebar-stats\">\n <div class=\"stat\">\n <div class=\"stat-value\">${segments.length}</div>\n <div class=\"stat-label\">Components</div>\n </div>\n <div class=\"stat\">\n <div class=\"stat-value\">${segments.reduce(\n (sum, s) => sum + s.variants.length,\n 0\n )}</div>\n <div class=\"stat-label\">Variants</div>\n </div>\n </div>\n \n <div class=\"search-container\">\n <input type=\"text\" class=\"search-input\" placeholder=\"Search components...\" id=\"search\">\n </div>\n \n <nav id=\"nav\">\n ${sortedCategories\n .map(\n ([category, items]) => `\n <div class=\"category\">\n <div class=\"category-header\">${category}</div>\n ${items\n .sort((a, b) => a.meta.name.localeCompare(b.meta.name))\n .map(\n (item) => `\n <a href=\"#${item.meta.name}\" class=\"nav-item\">${item.meta.name}</a>\n `\n )\n .join(\"\")}\n </div>\n `\n )\n .join(\"\")}\n </nav>\n </aside>\n \n <main class=\"main\" id=\"main\">\n ${\n segments.length === 0\n ? `\n <div class=\"empty-state\">\n <h2>No Components Found</h2>\n <p>Run <code>segments build</code> to compile your segment files.</p>\n </div>\n `\n : segments\n .sort((a, b) => a.meta.name.localeCompare(b.meta.name))\n .map(\n (segment) => `\n <section class=\"component-section\" id=\"${segment.meta.name}\">\n <div class=\"component-header\">\n <h2 class=\"component-name\">${segment.meta.name}</h2>\n <p class=\"component-description\">${segment.meta.description}</p>\n <div class=\"component-meta\">\n ${\n segment.meta.status\n ? `<span class=\"meta-badge status-${segment.meta.status}\">${segment.meta.status}</span>`\n : \"\"\n }\n ${\n segment.meta.category\n ? `<span class=\"meta-badge\">${segment.meta.category}</span>`\n : \"\"\n }\n ${\n segment.meta.tags\n ?.map((tag) => `<span class=\"meta-badge\">${tag}</span>`)\n .join(\"\") ?? \"\"\n }\n </div>\n </div>\n \n ${\n segment.usage\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Usage Guidelines</h3>\n ${\n segment.usage.when?.length\n ? `\n <ul class=\"usage-list\">\n ${segment.usage.when\n .map((item) => `<li class=\"usage-item when\">${item}</li>`)\n .join(\"\")}\n </ul>\n `\n : \"\"\n }\n ${\n segment.usage.whenNot?.length\n ? `\n <ul class=\"usage-list\" style=\"margin-top: 12px;\">\n ${segment.usage.whenNot\n .map(\n (item) => `<li class=\"usage-item when-not\">${item}</li>`\n )\n .join(\"\")}\n </ul>\n `\n : \"\"\n }\n </div>\n `\n : \"\"\n }\n \n ${\n segment.props && Object.keys(segment.props).length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Props</h3>\n <table class=\"props-table\">\n <thead>\n <tr>\n <th>Name</th>\n <th>Type</th>\n <th>Default</th>\n <th>Description</th>\n </tr>\n </thead>\n <tbody>\n ${Object.entries(segment.props)\n .map(\n ([name, prop]) => `\n <tr>\n <td>\n <span class=\"prop-name\">${name}</span>\n ${\n prop.required\n ? '<span class=\"prop-required\">*</span>'\n : \"\"\n }\n </td>\n <td><span class=\"prop-type\">${prop.type}</span></td>\n <td>${\n prop.default !== undefined\n ? `<span class=\"prop-default\">${prop.default}</span>`\n : \"—\"\n }</td>\n <td>${prop.description ?? \"\"}</td>\n </tr>\n `\n )\n .join(\"\")}\n </tbody>\n </table>\n </div>\n `\n : \"\"\n }\n \n ${\n segment.variants?.length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Variants</h3>\n <div class=\"variants-grid\">\n ${segment.variants\n .map(\n (variant) => `\n <div class=\"variant-card\">\n <div class=\"variant-name\">${variant.name}</div>\n ${\n variant.description\n ? `<div class=\"variant-description\">${variant.description}</div>`\n : \"\"\n }\n ${\n variant.code\n ? `<pre class=\"variant-code\">${escapeHtml(\n variant.code\n )}</pre>`\n : \"\"\n }\n </div>\n `\n )\n .join(\"\")}\n </div>\n </div>\n `\n : \"\"\n }\n \n ${\n segment.relations?.length\n ? `\n <div class=\"section\">\n <h3 class=\"section-title\">Related Components</h3>\n <div class=\"relations-list\">\n ${segment.relations\n .map(\n (rel) =>\n `<a href=\"#${\n rel.component\n }\" class=\"relation-tag\" title=\"${rel.note}\">${\n rel.relationship === \"parent\"\n ? \"↑\"\n : rel.relationship === \"child\"\n ? \"↓\"\n : \"↔\"\n } ${rel.component}</a>`\n )\n .join(\"\")}\n </div>\n </div>\n `\n : \"\"\n }\n </section>\n `\n )\n .join(\"\")\n }\n </main>\n </div>\n \n <script>\n // Search functionality\n const searchInput = document.getElementById('search');\n const nav = document.getElementById('nav');\n const main = document.getElementById('main');\n \n searchInput.addEventListener('input', (e) => {\n const query = e.target.value.toLowerCase();\n \n // Filter nav items\n nav.querySelectorAll('.nav-item').forEach(item => {\n const name = item.textContent.toLowerCase();\n item.style.display = name.includes(query) ? '' : 'none';\n });\n \n // Show/hide categories with no visible items\n nav.querySelectorAll('.category').forEach(cat => {\n const hasVisible = Array.from(cat.querySelectorAll('.nav-item')).some(\n item => item.style.display !== 'none'\n );\n cat.style.display = hasVisible ? '' : 'none';\n });\n \n // Filter main sections\n main.querySelectorAll('.component-section').forEach(section => {\n const name = section.id.toLowerCase();\n section.style.display = name.includes(query) ? '' : 'none';\n });\n });\n \n // Highlight active nav item on scroll\n const sections = document.querySelectorAll('.component-section');\n const navItems = document.querySelectorAll('.nav-item');\n \n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navItems.forEach(item => {\n item.classList.toggle('active', item.getAttribute('href') === '#' + entry.target.id);\n });\n }\n });\n }, { threshold: 0.3 });\n \n sections.forEach(section => observer.observe(section));\n </script>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n\n/**\n * Load segments.json and generate static viewer\n */\nexport async function generateViewerFromJson(\n jsonPath: string\n): Promise<string> {\n const content = await readFile(jsonPath, \"utf-8\");\n const data = JSON.parse(content) as CompiledSegmentsFile;\n return generateStaticViewer(data);\n}\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB;AASlB,SAAS,qBAAqB,MAAoC;AACvE,QAAM,WAAW,OAAO,OAAO,KAAK,QAAQ;AAG5C,QAAM,aAAa,oBAAI,IAA6B;AACpD,aAAW,WAAW,UAAU;AAC9B,UAAM,WAAW,QAAQ,KAAK,YAAY;AAC1C,QAAI,CAAC,WAAW,IAAI,QAAQ,GAAG;AAC7B,iBAAW,IAAI,UAAU,CAAC,CAAC;AAAA,IAC7B;AACA,eAAW,IAAI,QAAQ,EAAG,KAAK,OAAO;AAAA,EACxC;AAGA,QAAM,mBAAmB,MAAM,KAAK,WAAW,QAAQ,CAAC,EAAE;AAAA,IAAK,CAAC,GAAG,MACjE,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC;AAAA,EACzB;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,WAKE,MAAM,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":[]}