@fragments-sdk/cli 0.9.0 → 0.10.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.
Files changed (166) hide show
  1. package/dist/bin.d.ts +1 -0
  2. package/dist/bin.js +502 -84
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-CJEGT3WD.js → chunk-566BNPQZ.js} +21 -6
  5. package/dist/chunk-566BNPQZ.js.map +1 -0
  6. package/dist/{chunk-WI6SLMSO.js → chunk-CAMXG5HJ.js} +5 -5
  7. package/dist/chunk-D2CDBRNU.js +2 -0
  8. package/dist/{chunk-YMPGYEWK.js → chunk-D5PYOXEI.js} +2 -2
  9. package/dist/{chunk-NGIMCIK2.js → chunk-OQO55NKV.js} +405 -34
  10. package/dist/chunk-OQO55NKV.js.map +1 -0
  11. package/dist/{chunk-TOIE7VXF.js → chunk-PW7QTQA6.js} +2 -2
  12. package/dist/{chunk-AWYCDRPG.js → chunk-WXSR2II7.js} +2 -2
  13. package/dist/chunk-WXSR2II7.js.map +1 -0
  14. package/dist/{chunk-2JIKCJX3.js → chunk-ZDA3PLQ6.js} +17 -14
  15. package/dist/chunk-ZDA3PLQ6.js.map +1 -0
  16. package/dist/core/index.d.ts +1 -2092
  17. package/dist/core/index.js +26 -21
  18. package/dist/{discovery-Z4RDDFVR.js → discovery-NEOY4MPN.js} +3 -3
  19. package/dist/generate-BGKTKO6E.js +459 -0
  20. package/dist/generate-BGKTKO6E.js.map +1 -0
  21. package/dist/index.d.ts +3 -5
  22. package/dist/index.js +7 -8
  23. package/dist/index.js.map +1 -1
  24. package/dist/{init-KSAAS7X3.js → init-Q53R5Q2T.js} +66 -76
  25. package/dist/init-Q53R5Q2T.js.map +1 -0
  26. package/dist/mcp-bin.js +5 -7
  27. package/dist/mcp-bin.js.map +1 -1
  28. package/dist/scan-OQU7M4GH.js +14 -0
  29. package/dist/scan-generate-T5QNUG7N.js +691 -0
  30. package/dist/scan-generate-T5QNUG7N.js.map +1 -0
  31. package/dist/{service-A5GIGGGK.js → service-TQYWY65E.js} +4 -5
  32. package/dist/{static-viewer-NSODM5VX.js → static-viewer-NUBFPKWH.js} +4 -5
  33. package/dist/static-viewer-NUBFPKWH.js.map +1 -0
  34. package/dist/{test-RPWZAYSJ.js → test-2CSOSS3B.js} +4 -5
  35. package/dist/{test-RPWZAYSJ.js.map → test-2CSOSS3B.js.map} +1 -1
  36. package/dist/{tokens-NIXSZRX7.js → tokens-DXEGYTOJ.js} +6 -7
  37. package/dist/{tokens-NIXSZRX7.js.map → tokens-DXEGYTOJ.js.map} +1 -1
  38. package/dist/{viewer-SBTJDMP7.js → viewer-DBEPYM3G.js} +245 -23
  39. package/dist/viewer-DBEPYM3G.js.map +1 -0
  40. package/package.json +2 -1
  41. package/src/bin.ts +33 -1
  42. package/src/build.ts +13 -3
  43. package/src/commands/__tests__/scan-generate.test.ts +308 -0
  44. package/src/commands/build.ts +16 -2
  45. package/src/commands/generate.ts +383 -68
  46. package/src/commands/init.ts +81 -56
  47. package/src/commands/perf.ts +1 -1
  48. package/src/commands/scan-generate.ts +1013 -0
  49. package/src/commands/setup.ts +499 -0
  50. package/src/core/auto-props.ts +1 -1
  51. package/src/core/bundle-measurer.ts +2 -2
  52. package/src/core/config.ts +16 -4
  53. package/src/core/discovery.ts +2 -2
  54. package/src/core/generators/context.ts +1 -1
  55. package/src/core/generators/registry.ts +3 -3
  56. package/src/core/generators/typescript-extractor.ts +11 -1
  57. package/src/core/graph-extractor.ts +1 -1
  58. package/src/core/index.ts +3 -190
  59. package/src/core/loader.ts +2 -2
  60. package/src/core/parser.ts +1 -1
  61. package/src/core/previewLoader.ts +1 -1
  62. package/src/index.ts +2 -2
  63. package/src/migrate/converter.ts +9 -1
  64. package/src/migrate/parser.ts +2 -0
  65. package/src/migrate/types.ts +2 -0
  66. package/src/service/snippet-validation.test.ts +1 -1
  67. package/src/service/snippet-validation.ts +2 -2
  68. package/src/setup.ts +69 -24
  69. package/src/viewer/__tests__/viewer-integration.test.ts +4 -10
  70. package/src/viewer/components/AccessibilityPanel.tsx +305 -312
  71. package/src/viewer/components/ActionsPanel.tsx +31 -29
  72. package/src/viewer/components/AllVariantsPreview.tsx +78 -0
  73. package/src/viewer/components/App.tsx +187 -740
  74. package/src/viewer/components/BottomPanel.tsx +228 -132
  75. package/src/viewer/components/CodePanel.tsx +1 -1
  76. package/src/viewer/components/CommandPalette.tsx +7 -10
  77. package/src/viewer/components/ComponentDocView.tsx +164 -0
  78. package/src/viewer/components/ComponentGraph.tsx +111 -142
  79. package/src/viewer/components/ContractPanel.tsx +6 -6
  80. package/src/viewer/components/EmptyVariantMessage.tsx +54 -0
  81. package/src/viewer/components/FigmaEmbed.tsx +20 -18
  82. package/src/viewer/components/FragmentEditor.tsx +92 -115
  83. package/src/viewer/components/HeaderSearch.tsx +24 -0
  84. package/src/viewer/components/HealthDashboard.tsx +16 -2
  85. package/src/viewer/components/Icons.tsx +9 -0
  86. package/src/viewer/components/InteractionsPanel.tsx +101 -117
  87. package/src/viewer/components/IsolatedPreviewFrame.tsx +1 -0
  88. package/src/viewer/components/LandingPage.tsx +3 -3
  89. package/src/viewer/components/LeftSidebar.tsx +141 -63
  90. package/src/viewer/components/LoadErrorMessage.tsx +102 -0
  91. package/src/viewer/components/MultiViewportPreview.tsx +61 -142
  92. package/src/viewer/components/NoVariantsMessage.tsx +59 -0
  93. package/src/viewer/components/PanelShell.tsx +161 -0
  94. package/src/viewer/components/PerformancePanel.tsx +31 -28
  95. package/src/viewer/components/PreviewArea.tsx +1 -1
  96. package/src/viewer/components/PreviewAside.tsx +168 -0
  97. package/src/viewer/components/PreviewFrameHost.tsx +3 -3
  98. package/src/viewer/components/PropsEditor.tsx +70 -156
  99. package/src/viewer/components/ResizablePanel.tsx +103 -263
  100. package/src/viewer/components/RightSidebar.tsx +3 -9
  101. package/src/viewer/components/SkeletonLoader.tsx +13 -13
  102. package/src/viewer/components/TokenStylePanel.tsx +182 -209
  103. package/src/viewer/components/TopToolbar.tsx +159 -0
  104. package/src/viewer/components/VariantMatrix.tsx +42 -86
  105. package/src/viewer/components/VariantTabs.tsx +3 -3
  106. package/src/viewer/components/ViewerHeader.tsx +69 -0
  107. package/src/viewer/components/WebMCPDevTools.tsx +17 -23
  108. package/src/viewer/components/viewer-utils.ts +16 -0
  109. package/src/viewer/entry.tsx +5 -0
  110. package/src/viewer/hooks/useAppState.ts +27 -4
  111. package/src/viewer/hooks/usePreviewBridge.ts +2 -2
  112. package/src/viewer/preview-frame.html +6 -12
  113. package/src/viewer/server.ts +169 -2
  114. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +10 -0
  115. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +2 -0
  116. package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +274 -0
  117. package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +6 -18
  118. package/src/viewer/vendor/shared/src/DocsPageShell.tsx +5 -0
  119. package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +5 -16
  120. package/src/viewer/vendor/shared/src/PropsTable.module.scss +68 -0
  121. package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +2 -0
  122. package/src/viewer/vendor/shared/src/PropsTable.tsx +76 -0
  123. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +114 -0
  124. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +2 -0
  125. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +134 -0
  126. package/src/viewer/vendor/shared/src/index.ts +8 -0
  127. package/src/viewer/vendor/shared/src/types.ts +12 -0
  128. package/src/viewer/vite-plugin.ts +109 -4
  129. package/dist/chunk-2JIKCJX3.js.map +0 -1
  130. package/dist/chunk-AWYCDRPG.js.map +0 -1
  131. package/dist/chunk-CJEGT3WD.js.map +0 -1
  132. package/dist/chunk-EKLMXTWU.js +0 -80
  133. package/dist/chunk-EKLMXTWU.js.map +0 -1
  134. package/dist/chunk-GOVI6COW.js +0 -195
  135. package/dist/chunk-GOVI6COW.js.map +0 -1
  136. package/dist/chunk-NGIMCIK2.js.map +0 -1
  137. package/dist/defineFragment-D0UTve-I.d.ts +0 -665
  138. package/dist/generate-35OIMW4Y.js +0 -252
  139. package/dist/generate-35OIMW4Y.js.map +0 -1
  140. package/dist/init-KSAAS7X3.js.map +0 -1
  141. package/dist/scan-65RH3QMM.js +0 -15
  142. package/dist/viewer-SBTJDMP7.js.map +0 -1
  143. package/src/core/__tests__/preview-runtime.test.tsx +0 -111
  144. package/src/core/composition.test.ts +0 -262
  145. package/src/core/composition.ts +0 -318
  146. package/src/core/constants.ts +0 -114
  147. package/src/core/context.ts +0 -2
  148. package/src/core/defineFragment.ts +0 -141
  149. package/src/core/figma.ts +0 -263
  150. package/src/core/fragment-types.ts +0 -214
  151. package/src/core/performance-presets.ts +0 -142
  152. package/src/core/preview-runtime.tsx +0 -144
  153. package/src/core/schema.ts +0 -221
  154. package/src/core/storyAdapter.test.ts +0 -571
  155. package/src/core/storyAdapter.ts +0 -761
  156. package/src/core/storybook-csf.ts +0 -11
  157. package/src/core/token-parser.ts +0 -321
  158. package/src/core/token-types.ts +0 -287
  159. package/src/core/types.ts +0 -762
  160. /package/dist/{chunk-WI6SLMSO.js.map → chunk-CAMXG5HJ.js.map} +0 -0
  161. /package/dist/{discovery-Z4RDDFVR.js.map → chunk-D2CDBRNU.js.map} +0 -0
  162. /package/dist/{chunk-YMPGYEWK.js.map → chunk-D5PYOXEI.js.map} +0 -0
  163. /package/dist/{chunk-TOIE7VXF.js.map → chunk-PW7QTQA6.js.map} +0 -0
  164. /package/dist/{scan-65RH3QMM.js.map → discovery-NEOY4MPN.js.map} +0 -0
  165. /package/dist/{service-A5GIGGGK.js.map → scan-OQU7M4GH.js.map} +0 -0
  166. /package/dist/{static-viewer-NSODM5VX.js.map → service-TQYWY65E.js.map} +0 -0
@@ -8,7 +8,7 @@
8
8
  import { useState, useMemo } from "react";
9
9
  import type { ActionLog } from "../hooks/useActions.js";
10
10
  import { formatActionArg } from "../hooks/useActions.js";
11
- import { Button, Stack, Text, Badge, Input, Menu, Separator } from "@fragments-sdk/ui";
11
+ import { Button, Stack, Text, Badge, Input, Menu, Separator, Box } from "@fragments-sdk/ui";
12
12
  import {
13
13
  TrashIcon,
14
14
  ChevronDownIcon,
@@ -93,14 +93,14 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
93
93
  // No logs state
94
94
  if (logs.length === 0) {
95
95
  return (
96
- <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
97
- <div style={{ padding: '16px', borderBottom: '1px solid var(--border)' }}>
96
+ <Stack style={{ height: '100%' }}>
97
+ <Box padding="md" borderBottom>
98
98
  <Stack direction="row" align="center" gap="sm">
99
99
  <PlayIcon style={{ width: 16, height: 16 }} />
100
100
  <Text weight="medium">Actions</Text>
101
101
  </Stack>
102
- </div>
103
- <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '32px', textAlign: 'center' }}>
102
+ </Box>
103
+ <Stack align="center" justify="center" style={{ flex: 1, padding: '32px', textAlign: 'center' }}>
104
104
  <div style={{ maxWidth: '28rem' }}>
105
105
  <div style={{ width: '48px', height: '48px', borderRadius: '9999px', background: 'var(--bg-secondary)', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 16px' }}>
106
106
  <PlayIcon style={{ width: 24, height: 24, color: 'var(--text-tertiary)' }} />
@@ -110,18 +110,18 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
110
110
  </Text>
111
111
  <Text size="sm" color="tertiary">
112
112
  Interact with the component to see callback invocations here.
113
- Actions like <code style={{ padding: '2px 4px', background: 'var(--bg-secondary)', borderRadius: '4px', fontSize: '12px' }}>onClick</code>, <code style={{ padding: '2px 4px', background: 'var(--bg-secondary)', borderRadius: '4px', fontSize: '12px' }}>onChange</code>, etc. will be logged automatically.
113
+ Actions like <Box as="code" padding="xs" background="secondary" rounded="sm" style={{ fontSize: '12px', display: 'inline' }}>onClick</Box>, <Box as="code" padding="xs" background="secondary" rounded="sm" style={{ fontSize: '12px', display: 'inline' }}>onChange</Box>, etc. will be logged automatically.
114
114
  </Text>
115
115
  </div>
116
- </div>
117
- </div>
116
+ </Stack>
117
+ </Stack>
118
118
  );
119
119
  }
120
120
 
121
121
  return (
122
- <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
122
+ <Stack style={{ height: '100%' }}>
123
123
  {/* Header */}
124
- <div style={{ padding: '12px', borderBottom: '1px solid var(--border)' }}>
124
+ <Box padding="sm" borderBottom>
125
125
  <Stack direction="row" align="center" justify="between" gap="sm">
126
126
  <Stack direction="row" align="center" gap="sm" style={{ flex: 1 }}>
127
127
  <Stack direction="row" align="center" gap="sm">
@@ -147,12 +147,14 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
147
147
  </Button>
148
148
  </Menu.Trigger>
149
149
  <Menu.Content>
150
- <div style={{ padding: '6px 12px', fontSize: '12px', fontWeight: 500, color: 'var(--text-tertiary)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>
151
- Export as
152
- </div>
150
+ <Box paddingX="sm" paddingY="xs">
151
+ <Text size="xs" weight="medium" color="tertiary" style={{ textTransform: 'uppercase', letterSpacing: '0.05em' }}>
152
+ Export as
153
+ </Text>
154
+ </Box>
153
155
 
154
156
  {/* JSON */}
155
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px 12px' }}>
157
+ <Stack direction="row" align="center" justify="between" style={{ padding: '6px 12px' }}>
156
158
  <Text size="sm" color="secondary">JSON</Text>
157
159
  <Stack direction="row" gap="xs">
158
160
  <Menu.Item onSelect={() => handleExport('json', 'copy')}>
@@ -162,10 +164,10 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
162
164
  <DownloadIcon style={{ width: 14, height: 14 }} />
163
165
  </Menu.Item>
164
166
  </Stack>
165
- </div>
167
+ </Stack>
166
168
 
167
169
  {/* Jest */}
168
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px 12px' }}>
170
+ <Stack direction="row" align="center" justify="between" style={{ padding: '6px 12px' }}>
169
171
  <Text size="sm" color="secondary">Jest Assertions</Text>
170
172
  <Stack direction="row" gap="xs">
171
173
  <Menu.Item onSelect={() => handleExport('jest', 'copy')}>
@@ -175,10 +177,10 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
175
177
  <DownloadIcon style={{ width: 14, height: 14 }} />
176
178
  </Menu.Item>
177
179
  </Stack>
178
- </div>
180
+ </Stack>
179
181
 
180
182
  {/* Playwright */}
181
- <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '6px 12px' }}>
183
+ <Stack direction="row" align="center" justify="between" style={{ padding: '6px 12px' }}>
182
184
  <Text size="sm" color="secondary">Playwright Test</Text>
183
185
  <Stack direction="row" gap="xs">
184
186
  <Menu.Item onSelect={() => handleExport('playwright', 'copy')}>
@@ -188,14 +190,14 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
188
190
  <DownloadIcon style={{ width: 14, height: 14 }} />
189
191
  </Menu.Item>
190
192
  </Stack>
191
- </div>
193
+ </Stack>
192
194
 
193
195
  <Separator />
194
- <div style={{ padding: '6px 12px' }}>
196
+ <Box paddingX="sm" paddingY="xs">
195
197
  <Text size="xs" color="tertiary">
196
198
  {logs.length} action{logs.length !== 1 ? 's' : ''} recorded
197
199
  </Text>
198
- </div>
200
+ </Box>
199
201
  </Menu.Content>
200
202
  </Menu>
201
203
 
@@ -209,14 +211,14 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
209
211
  </Button>
210
212
  </Stack>
211
213
  </Stack>
212
- </div>
214
+ </Box>
213
215
 
214
216
  {/* Log list */}
215
- <div style={{ flex: 1, overflowY: 'auto' }}>
217
+ <Box overflow="auto" style={{ flex: 1 }}>
216
218
  {filteredLogs.length === 0 ? (
217
- <div style={{ padding: '16px', textAlign: 'center' }}>
219
+ <Box padding="md" style={{ textAlign: 'center' }}>
218
220
  <Text size="sm" color="tertiary">No actions match "{filter}"</Text>
219
- </div>
221
+ </Box>
220
222
  ) : (
221
223
  <div>
222
224
  {filteredLogs.map((log, index) => (
@@ -231,8 +233,8 @@ export function ActionsPanel({ logs, onClear, componentName = 'Component', varia
231
233
  ))}
232
234
  </div>
233
235
  )}
234
- </div>
235
- </div>
236
+ </Box>
237
+ </Stack>
236
238
  );
237
239
  }
238
240
 
@@ -311,7 +313,7 @@ function ActionLogItem({ log, isExpanded, onToggle, formatTime }: ActionLogItemP
311
313
  {/* Expanded args */}
312
314
  {isExpanded && hasArgs && (
313
315
  <div style={{ padding: '0 12px 12px 36px' }}>
314
- <div style={{ background: 'var(--bg-secondary)', borderRadius: '8px', padding: '8px', overflowX: 'auto' }}>
316
+ <Box padding="sm" background="secondary" rounded="lg" overflow="auto">
315
317
  {log.args.map((arg, index) => (
316
318
  <div key={index} style={{ marginBottom: index < log.args.length - 1 ? '4px' : 0 }}>
317
319
  <Text size="xs" color="tertiary" as="span">
@@ -322,7 +324,7 @@ function ActionLogItem({ log, isExpanded, onToggle, formatTime }: ActionLogItemP
322
324
  </pre>
323
325
  </div>
324
326
  ))}
325
- </div>
327
+ </Box>
326
328
  </div>
327
329
  )}
328
330
  </div>
@@ -0,0 +1,78 @@
1
+ import type { ReactNode } from "react";
2
+ import type { FragmentVariant } from "../../core/index.js";
3
+ import type { useViewSettings } from "../hooks/useViewSettings.js";
4
+ import type { useTheme } from "./ThemeProvider.js";
5
+ import { Stack } from "@fragments-sdk/ui";
6
+ import { VariantPreviewCard } from "@fragments-sdk/shared";
7
+ import { PreviewArea } from "./PreviewArea.js";
8
+ import { resolveDisplayedCode } from "./CodePanel.js";
9
+ import { getVariantSectionId } from "./viewer-utils.js";
10
+
11
+ interface AllVariantsPreviewProps {
12
+ componentName: string;
13
+ fragmentPath: string;
14
+ variants: FragmentVariant[];
15
+ focusedVariantIndex: number;
16
+ zoom: ReturnType<typeof useViewSettings>["zoom"];
17
+ viewport: ReturnType<typeof useViewSettings>["viewport"];
18
+ customSize: ReturnType<typeof useViewSettings>["customSize"];
19
+ previewTheme: ReturnType<typeof useTheme>["resolvedTheme"];
20
+ showComparison: boolean;
21
+ allFigmaUrls: string[];
22
+ fallbackFigmaUrl?: string;
23
+ onRetry: () => void;
24
+ renderVariantContent: (variant: FragmentVariant) => ReactNode;
25
+ previewKeyBase: string;
26
+ }
27
+
28
+ export function AllVariantsPreview({
29
+ componentName,
30
+ fragmentPath,
31
+ variants,
32
+ focusedVariantIndex,
33
+ zoom,
34
+ viewport,
35
+ customSize,
36
+ previewTheme,
37
+ showComparison,
38
+ allFigmaUrls,
39
+ fallbackFigmaUrl,
40
+ onRetry,
41
+ renderVariantContent,
42
+ previewKeyBase,
43
+ }: AllVariantsPreviewProps) {
44
+ return (
45
+ <Stack gap="lg" style={{ padding: "20px" }}>
46
+ {variants.map((variant, index) => (
47
+ <VariantPreviewCard
48
+ key={variant.name}
49
+ name={variant.name}
50
+ description={variant.description}
51
+ code={resolveDisplayedCode(componentName, variant)}
52
+ id={getVariantSectionId(componentName, variant.name)}
53
+ highlight={index === focusedVariantIndex}
54
+ >
55
+ <PreviewArea
56
+ componentName={componentName}
57
+ fragmentPath={fragmentPath}
58
+ variant={variant}
59
+ variants={variants}
60
+ zoom={zoom}
61
+ viewport={viewport}
62
+ customSize={customSize}
63
+ previewTheme={previewTheme}
64
+ showMatrixView={false}
65
+ showMultiViewport={false}
66
+ showComparison={showComparison}
67
+ figmaUrl={variant.figma || fallbackFigmaUrl}
68
+ allFigmaUrls={allFigmaUrls}
69
+ onSelectVariant={() => {}}
70
+ onRetry={onRetry}
71
+ renderContent={() => renderVariantContent(variant)}
72
+ previewKey={`${previewKeyBase}-${index}`}
73
+ />
74
+ </VariantPreviewCard>
75
+ ))}
76
+ </Stack>
77
+ );
78
+ }