@fragments-sdk/cli 0.7.14 → 0.7.16
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/bin.js +7 -7
- package/dist/{chunk-CRTN6BIW.js → chunk-QLTLLQBI.js} +2 -2
- package/dist/{chunk-TQOGBAOZ.js → chunk-WLXFE6XW.js} +91 -2
- package/dist/chunk-WLXFE6XW.js.map +1 -0
- package/dist/core/index.d.ts +44 -3
- package/dist/core/index.js +11 -3
- package/dist/{defineFragment-C6PFzZyo.d.ts → defineFragment-BI9KoPrs.d.ts} +1 -1
- package/dist/{generate-ZPERYZLF.js → generate-ICIPKCKV.js} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/init-DIZ6UNBL.js +806 -0
- package/dist/init-DIZ6UNBL.js.map +1 -0
- package/dist/mcp-bin.js +2 -2
- package/dist/{scan-BSMLGBX4.js → scan-X3DI2X5G.js} +2 -2
- package/dist/{service-QACVPR37.js → service-JEWWTSKI.js} +2 -2
- package/dist/{static-viewer-2RQD5QLR.js → static-viewer-JIWCYKVK.js} +2 -2
- package/dist/{tokens-A3BZIQPB.js → tokens-K2AGUUOJ.js} +2 -2
- package/dist/{viewer-CNLZQUFO.js → viewer-QKIAPTPG.js} +126 -15
- package/dist/viewer-QKIAPTPG.js.map +1 -0
- package/package.json +3 -2
- package/src/commands/init-framework.ts +414 -0
- package/src/commands/init.ts +41 -1
- package/src/core/__tests__/preview-runtime.test.tsx +111 -0
- package/src/core/index.ts +13 -0
- package/src/core/preview-runtime.tsx +144 -0
- package/src/viewer/components/App.tsx +8 -3
- package/src/viewer/components/FragmentRenderer.tsx +61 -0
- package/src/viewer/components/HealthDashboard.tsx +1 -1
- package/src/viewer/components/IsolatedPreviewFrame.tsx +10 -8
- package/src/viewer/components/PreviewFrameHost.tsx +27 -60
- package/src/viewer/components/PropsTable.tsx +2 -2
- package/src/viewer/components/RuntimeToolsRegistrar.tsx +17 -0
- package/src/viewer/components/SkeletonLoader.tsx +114 -125
- package/src/viewer/components/VariantMatrix.tsx +3 -3
- package/src/viewer/components/ViewerStateSync.tsx +52 -0
- package/src/viewer/components/WebMCPDevTools.tsx +509 -0
- package/src/viewer/components/WebMCPIntegration.tsx +47 -0
- package/src/viewer/components/WebMCPStatusIndicator.tsx +60 -0
- package/src/viewer/entry.tsx +32 -5
- package/src/viewer/hooks/useA11yService.ts +1 -135
- package/src/viewer/hooks/useCompiledFragments.ts +42 -0
- package/src/viewer/index.html +1 -1
- package/src/viewer/public/favicon.ico +0 -0
- package/src/viewer/server.ts +59 -3
- package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +19 -0
- package/src/viewer/vendor/shared/src/DocsPageAsideHost.tsx +1 -1
- package/src/viewer/vendor/shared/src/DocsSearchCommand.tsx +69 -104
- package/src/viewer/vite-plugin.ts +76 -1
- package/src/viewer/webmcp/__tests__/analytics.test.ts +108 -0
- package/src/viewer/webmcp/analytics.ts +165 -0
- package/src/viewer/webmcp/index.ts +3 -0
- package/src/viewer/webmcp/posthog-bridge.ts +39 -0
- package/src/viewer/webmcp/runtime-tools.ts +152 -0
- package/src/viewer/webmcp/scan-utils.ts +135 -0
- package/src/viewer/webmcp/use-tool-analytics.ts +69 -0
- package/src/viewer/webmcp/viewer-state.ts +45 -0
- package/dist/chunk-TQOGBAOZ.js.map +0 -1
- package/dist/init-GID2DXB3.js +0 -498
- package/dist/init-GID2DXB3.js.map +0 -1
- package/dist/viewer-CNLZQUFO.js.map +0 -1
- package/src/viewer/components/StoryRenderer.tsx +0 -121
- /package/dist/{chunk-CRTN6BIW.js.map → chunk-QLTLLQBI.js.map} +0 -0
- /package/dist/{generate-ZPERYZLF.js.map → generate-ICIPKCKV.js.map} +0 -0
- /package/dist/{scan-BSMLGBX4.js.map → scan-X3DI2X5G.js.map} +0 -0
- /package/dist/{service-QACVPR37.js.map → service-JEWWTSKI.js.map} +0 -0
- /package/dist/{static-viewer-2RQD5QLR.js.map → static-viewer-JIWCYKVK.js.map} +0 -0
- /package/dist/{tokens-A3BZIQPB.js.map → tokens-K2AGUUOJ.js.map} +0 -0
|
@@ -11,149 +11,138 @@ import { Skeleton, Loading } from '@fragments-sdk/ui';
|
|
|
11
11
|
*/
|
|
12
12
|
export function AppSkeleton() {
|
|
13
13
|
return (
|
|
14
|
-
<div
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
<div
|
|
15
|
+
style={{
|
|
16
|
+
display: 'grid',
|
|
17
|
+
minHeight: '100vh',
|
|
18
|
+
minHeight: '100dvh',
|
|
19
|
+
gridTemplateRows: '56px 1fr',
|
|
20
|
+
gridTemplateColumns: '260px 1fr 240px',
|
|
21
|
+
gridTemplateAreas: '"header header header" "sidebar main aside"',
|
|
22
|
+
backgroundColor: 'var(--bg-primary)',
|
|
23
|
+
}}
|
|
24
|
+
>
|
|
25
|
+
<div
|
|
26
|
+
style={{
|
|
27
|
+
gridArea: 'header',
|
|
25
28
|
display: 'flex',
|
|
26
29
|
alignItems: 'center',
|
|
27
30
|
justifyContent: 'space-between',
|
|
28
|
-
|
|
31
|
+
gap: '16px',
|
|
32
|
+
padding: '0 16px',
|
|
29
33
|
borderBottom: '1px solid var(--border)',
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '32px', borderRadius: '6px' }} />
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
{/* Component list */}
|
|
41
|
-
<div style={{ flex: 1, padding: '0 8px', overflow: 'hidden' }}>
|
|
42
|
-
{/* Category 1 */}
|
|
43
|
-
<div style={{ marginBottom: '16px' }}>
|
|
44
|
-
<Skeleton variant="text" style={{ width: '64px', margin: '0 8px 8px' }} />
|
|
45
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
|
46
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '28px', borderRadius: '6px' }} />
|
|
47
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '28px', borderRadius: '6px' }} />
|
|
48
|
-
<Skeleton variant="rectangular" style={{ width: '75%', height: '28px', borderRadius: '6px' }} />
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
|
|
52
|
-
{/* Category 2 */}
|
|
53
|
-
<div style={{ marginBottom: '16px' }}>
|
|
54
|
-
<Skeleton variant="text" style={{ width: '80px', margin: '0 8px 8px' }} />
|
|
55
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
|
56
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '28px', borderRadius: '6px' }} />
|
|
57
|
-
<Skeleton variant="rectangular" style={{ width: '83%', height: '28px', borderRadius: '6px' }} />
|
|
58
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '28px', borderRadius: '6px' }} />
|
|
59
|
-
<Skeleton variant="rectangular" style={{ width: '66%', height: '28px', borderRadius: '6px' }} />
|
|
60
|
-
</div>
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
{/* Category 3 */}
|
|
64
|
-
<div>
|
|
65
|
-
<Skeleton variant="text" style={{ width: '96px', margin: '0 8px 8px' }} />
|
|
66
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
|
|
67
|
-
<Skeleton variant="rectangular" style={{ width: '80%', height: '28px', borderRadius: '6px' }} />
|
|
68
|
-
<Skeleton variant="rectangular" style={{ width: '100%', height: '28px', borderRadius: '6px' }} />
|
|
69
|
-
</div>
|
|
70
|
-
</div>
|
|
34
|
+
backgroundColor: 'var(--bg-primary)',
|
|
35
|
+
}}
|
|
36
|
+
>
|
|
37
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
|
38
|
+
<Skeleton.Circle size={20} />
|
|
39
|
+
<Skeleton variant="text" width={96} />
|
|
40
|
+
<Skeleton variant="text" width={64} />
|
|
71
41
|
</div>
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
<Skeleton
|
|
42
|
+
<Skeleton variant="rect" width={240} height={32} radius="md" />
|
|
43
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
44
|
+
<Skeleton variant="rect" width={64} height={28} radius="md" />
|
|
45
|
+
<Skeleton.Circle size={20} />
|
|
46
|
+
<Skeleton.Circle size={20} />
|
|
47
|
+
<Skeleton.Circle size={20} />
|
|
76
48
|
</div>
|
|
77
49
|
</div>
|
|
78
50
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
51
|
+
<aside
|
|
52
|
+
style={{
|
|
53
|
+
gridArea: 'sidebar',
|
|
54
|
+
borderRight: '1px solid var(--border)',
|
|
55
|
+
backgroundColor: 'var(--bg-primary)',
|
|
83
56
|
display: 'flex',
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
|
91
|
-
<Skeleton variant="text" style={{ width: '96px', height: '20px' }} />
|
|
92
|
-
<Skeleton variant="text" style={{ width: '64px', height: '16px' }} />
|
|
93
|
-
</div>
|
|
94
|
-
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
|
95
|
-
<Skeleton variant="rectangular" style={{ width: '64px', height: '28px', borderRadius: '4px' }} />
|
|
96
|
-
<Skeleton variant="rectangular" style={{ width: '96px', height: '28px', borderRadius: '4px' }} />
|
|
97
|
-
<Skeleton variant="rectangular" style={{ width: '80px', height: '28px', borderRadius: '4px' }} />
|
|
98
|
-
<Skeleton variant="circular" style={{ width: '24px', height: '24px' }} />
|
|
99
|
-
<Skeleton variant="circular" style={{ width: '24px', height: '24px' }} />
|
|
100
|
-
</div>
|
|
57
|
+
flexDirection: 'column',
|
|
58
|
+
minHeight: 0,
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<div style={{ padding: '12px 16px' }}>
|
|
62
|
+
<Skeleton variant="rect" height={32} radius="md" />
|
|
101
63
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
<Skeleton variant="rectangular" style={{ width: '80px', height: '28px', borderRadius: '6px' }} />
|
|
112
|
-
<Skeleton variant="rectangular" style={{ width: '56px', height: '28px', borderRadius: '6px' }} />
|
|
113
|
-
<Skeleton variant="rectangular" style={{ width: '72px', height: '28px', borderRadius: '6px' }} />
|
|
114
|
-
<Skeleton variant="rectangular" style={{ width: '48px', height: '28px', borderRadius: '6px' }} />
|
|
115
|
-
</div>
|
|
64
|
+
<div style={{ padding: '0 12px', display: 'flex', flexDirection: 'column', gap: '12px', overflow: 'hidden' }}>
|
|
65
|
+
<Skeleton variant="text" width={68} />
|
|
66
|
+
<Skeleton variant="rect" height={30} radius="md" />
|
|
67
|
+
<Skeleton variant="rect" height={30} radius="md" />
|
|
68
|
+
<Skeleton variant="rect" height={30} radius="md" />
|
|
69
|
+
<Skeleton variant="text" width={84} />
|
|
70
|
+
<Skeleton variant="rect" height={30} radius="md" />
|
|
71
|
+
<Skeleton variant="rect" height={30} radius="md" />
|
|
72
|
+
<Skeleton variant="rect" width="78%" height={30} radius="md" />
|
|
116
73
|
</div>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '32px' }}>
|
|
120
|
-
<Skeleton variant="rectangular" style={{ width: '256px', height: '128px', borderRadius: '8px' }} />
|
|
74
|
+
<div style={{ marginTop: 'auto', padding: '12px 16px', borderTop: '1px solid var(--border-subtle)' }}>
|
|
75
|
+
<Skeleton variant="text" width={92} />
|
|
121
76
|
</div>
|
|
77
|
+
</aside>
|
|
122
78
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<div style={{
|
|
143
|
-
<Skeleton variant="text"
|
|
144
|
-
<Skeleton variant="
|
|
79
|
+
<main
|
|
80
|
+
style={{
|
|
81
|
+
gridArea: 'main',
|
|
82
|
+
display: 'flex',
|
|
83
|
+
flexDirection: 'column',
|
|
84
|
+
minWidth: 0,
|
|
85
|
+
minHeight: 0,
|
|
86
|
+
backgroundColor: 'var(--bg-primary)',
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<div style={{ flex: 1, padding: '20px', overflow: 'hidden' }}>
|
|
90
|
+
<div
|
|
91
|
+
style={{
|
|
92
|
+
border: '1px solid var(--border)',
|
|
93
|
+
borderRadius: '10px',
|
|
94
|
+
overflow: 'hidden',
|
|
95
|
+
marginBottom: '16px',
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<div style={{ padding: '12px 14px', borderBottom: '1px solid var(--border-subtle)', backgroundColor: 'var(--bg-secondary)', display: 'flex', gap: '10px' }}>
|
|
99
|
+
<Skeleton variant="text" width={84} />
|
|
100
|
+
<Skeleton variant="text" width={120} />
|
|
101
|
+
</div>
|
|
102
|
+
<div style={{ padding: '24px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
103
|
+
<Skeleton variant="rect" width={280} height={120} radius="lg" />
|
|
145
104
|
</div>
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
105
|
+
</div>
|
|
106
|
+
|
|
107
|
+
<div
|
|
108
|
+
style={{
|
|
109
|
+
border: '1px solid var(--border)',
|
|
110
|
+
borderRadius: '10px',
|
|
111
|
+
overflow: 'hidden',
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
<div style={{ height: '40px', display: 'flex', alignItems: 'center', gap: '6px', padding: '0 14px', borderBottom: '1px solid var(--border-subtle)', backgroundColor: 'var(--bg-secondary)' }}>
|
|
115
|
+
<Skeleton variant="rect" width={52} height={22} radius="md" />
|
|
116
|
+
<Skeleton variant="rect" width={88} height={22} radius="md" />
|
|
117
|
+
<Skeleton variant="rect" width={58} height={22} radius="md" />
|
|
149
118
|
</div>
|
|
150
|
-
<div style={{
|
|
151
|
-
<Skeleton
|
|
152
|
-
<Skeleton variant="rectangular" style={{ width: '80px', height: '32px', borderRadius: '4px' }} />
|
|
119
|
+
<div style={{ padding: '16px' }}>
|
|
120
|
+
<Skeleton.Text lines={4} lastLineWidth={72} />
|
|
153
121
|
</div>
|
|
154
122
|
</div>
|
|
155
123
|
</div>
|
|
156
|
-
</
|
|
124
|
+
</main>
|
|
125
|
+
|
|
126
|
+
<aside
|
|
127
|
+
style={{
|
|
128
|
+
gridArea: 'aside',
|
|
129
|
+
borderLeft: '1px solid var(--border)',
|
|
130
|
+
backgroundColor: 'var(--bg-primary)',
|
|
131
|
+
padding: '16px 14px',
|
|
132
|
+
}}
|
|
133
|
+
>
|
|
134
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
|
|
135
|
+
<Skeleton variant="text" width={92} />
|
|
136
|
+
<Skeleton variant="text" width={64} />
|
|
137
|
+
<Skeleton variant="text" width={48} />
|
|
138
|
+
<Skeleton variant="text" width={76} />
|
|
139
|
+
<Skeleton variant="rect" height={1} />
|
|
140
|
+
<Skeleton variant="text" width={86} />
|
|
141
|
+
<Skeleton variant="rect" width="100%" height={26} radius="md" />
|
|
142
|
+
<Skeleton variant="rect" width="84%" height={26} radius="md" />
|
|
143
|
+
<Skeleton variant="rect" width="70%" height={26} radius="md" />
|
|
144
|
+
</div>
|
|
145
|
+
</aside>
|
|
157
146
|
</div>
|
|
158
147
|
);
|
|
159
148
|
}
|
|
@@ -14,7 +14,7 @@ import { useState, useMemo, useRef, useCallback } from "react";
|
|
|
14
14
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
15
15
|
import type { FragmentVariant } from "../../core/index.js";
|
|
16
16
|
import { ErrorBoundary } from "./ErrorBoundary.js";
|
|
17
|
-
import {
|
|
17
|
+
import { FragmentRenderer, LoaderIndicator } from "./FragmentRenderer.js";
|
|
18
18
|
import { IsolatedPreviewFrame } from "./IsolatedPreviewFrame.js";
|
|
19
19
|
import { ChevronDownIcon } from "./Icons.js";
|
|
20
20
|
|
|
@@ -389,7 +389,7 @@ function VariantCard({
|
|
|
389
389
|
</div>
|
|
390
390
|
}
|
|
391
391
|
>
|
|
392
|
-
<
|
|
392
|
+
<FragmentRenderer variant={variant}>
|
|
393
393
|
{(content, isLoading, error) => {
|
|
394
394
|
if (isLoading) {
|
|
395
395
|
return (
|
|
@@ -407,7 +407,7 @@ function VariantCard({
|
|
|
407
407
|
}
|
|
408
408
|
return content;
|
|
409
409
|
}}
|
|
410
|
-
</
|
|
410
|
+
</FragmentRenderer>
|
|
411
411
|
</ErrorBoundary>
|
|
412
412
|
</div>
|
|
413
413
|
)}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { setViewerState } from '../webmcp/viewer-state.js';
|
|
3
|
+
import { useUrlState } from '../hooks/useUrlState.js';
|
|
4
|
+
import { useAppState } from '../hooks/useAppState.js';
|
|
5
|
+
import { useViewSettings } from '../hooks/useViewSettings.js';
|
|
6
|
+
import { useTheme } from './ThemeProvider.js';
|
|
7
|
+
import { BRAND, type FragmentDefinition } from '../../core/index.js';
|
|
8
|
+
|
|
9
|
+
interface ViewerStateSyncProps {
|
|
10
|
+
fragments: Array<{ path: string; fragment: FragmentDefinition }>;
|
|
11
|
+
activeVariantIndex: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function ViewerStateSync({ fragments, activeVariantIndex }: ViewerStateSyncProps) {
|
|
15
|
+
const { state: urlState } = useUrlState();
|
|
16
|
+
const { state: uiState } = useAppState();
|
|
17
|
+
const viewSettings = useViewSettings();
|
|
18
|
+
const { resolvedTheme } = useTheme();
|
|
19
|
+
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const activeFragment = urlState.component
|
|
22
|
+
? fragments.find(f => f.fragment.meta.name.toLowerCase() === urlState.component!.toLowerCase())
|
|
23
|
+
: null;
|
|
24
|
+
|
|
25
|
+
const variants = activeFragment?.fragment.variants ?? [];
|
|
26
|
+
|
|
27
|
+
setViewerState({
|
|
28
|
+
currentComponent: activeFragment?.fragment.meta.name ?? null,
|
|
29
|
+
currentVariant: variants[activeVariantIndex]?.name ?? null,
|
|
30
|
+
variantIndex: activeVariantIndex,
|
|
31
|
+
totalVariants: variants.length,
|
|
32
|
+
viewport: viewSettings.viewport,
|
|
33
|
+
zoom: viewSettings.zoom,
|
|
34
|
+
theme: resolvedTheme,
|
|
35
|
+
panels: {
|
|
36
|
+
activePanel: uiState.activePanel,
|
|
37
|
+
panelOpen: uiState.panelOpen,
|
|
38
|
+
},
|
|
39
|
+
viewMode: {
|
|
40
|
+
matrixView: uiState.showMatrixView,
|
|
41
|
+
multiViewport: uiState.showMultiViewport,
|
|
42
|
+
comparison: uiState.showComparison,
|
|
43
|
+
},
|
|
44
|
+
designSystem: {
|
|
45
|
+
name: BRAND.name,
|
|
46
|
+
componentCount: fragments.length,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}, [urlState, uiState, viewSettings, resolvedTheme, fragments, activeVariantIndex]);
|
|
50
|
+
|
|
51
|
+
return null;
|
|
52
|
+
}
|