@fragments-sdk/cli 0.10.1 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/dist/ai-client-I6MDWNYA.js +21 -0
  2. package/dist/bin.js +292 -367
  3. package/dist/bin.js.map +1 -1
  4. package/dist/{chunk-PW7QTQA6.js → chunk-4OC7FTJB.js} +2 -2
  5. package/dist/{chunk-HRFUSSZI.js → chunk-AM4MRTMN.js} +2 -2
  6. package/dist/{chunk-5G3VZH43.js → chunk-GVDSFQ4E.js} +281 -351
  7. package/dist/chunk-GVDSFQ4E.js.map +1 -0
  8. package/dist/chunk-JJ2VRTBU.js +626 -0
  9. package/dist/chunk-JJ2VRTBU.js.map +1 -0
  10. package/dist/{chunk-D5PYOXEI.js → chunk-LVWFOLUZ.js} +148 -13
  11. package/dist/{chunk-D5PYOXEI.js.map → chunk-LVWFOLUZ.js.map} +1 -1
  12. package/dist/{chunk-WXSR2II7.js → chunk-OQKMEFOS.js} +58 -6
  13. package/dist/chunk-OQKMEFOS.js.map +1 -0
  14. package/dist/chunk-SXTKFDCR.js +104 -0
  15. package/dist/chunk-SXTKFDCR.js.map +1 -0
  16. package/dist/chunk-T5OMVL7E.js +443 -0
  17. package/dist/chunk-T5OMVL7E.js.map +1 -0
  18. package/dist/{chunk-ZM4ZQZWZ.js → chunk-TPWGL2XS.js} +39 -37
  19. package/dist/chunk-TPWGL2XS.js.map +1 -0
  20. package/dist/{chunk-OQO55NKV.js → chunk-WFS63PCW.js} +85 -11
  21. package/dist/chunk-WFS63PCW.js.map +1 -0
  22. package/dist/core/index.js +9 -1
  23. package/dist/{discovery-NEOY4MPN.js → discovery-ZJQSXF56.js} +3 -3
  24. package/dist/{generate-FBHSXR3D.js → generate-RJFS2JWA.js} +4 -4
  25. package/dist/index.js +7 -6
  26. package/dist/index.js.map +1 -1
  27. package/dist/init-ZSX3NRCZ.js +636 -0
  28. package/dist/init-ZSX3NRCZ.js.map +1 -0
  29. package/dist/mcp-bin.js +2 -2
  30. package/dist/{scan-CJF2DOQW.js → scan-3PMCJ4RB.js} +6 -6
  31. package/dist/scan-generate-SYU4PYZD.js +1115 -0
  32. package/dist/scan-generate-SYU4PYZD.js.map +1 -0
  33. package/dist/{service-TQYWY65E.js → service-VMGNJZ42.js} +3 -3
  34. package/dist/snapshot-XOISO2IS.js +139 -0
  35. package/dist/snapshot-XOISO2IS.js.map +1 -0
  36. package/dist/{static-viewer-NUBFPKWH.js → static-viewer-5GXH2MGE.js} +3 -3
  37. package/dist/static-viewer-5GXH2MGE.js.map +1 -0
  38. package/dist/{test-Z5LVO724.js → test-SI4NSHQX.js} +4 -4
  39. package/dist/{tokens-CE46OTMD.js → tokens-T6SIVUT5.js} +5 -5
  40. package/dist/{viewer-DNMNC5VS.js → viewer-7ZEAFBVN.js} +80 -58
  41. package/dist/viewer-7ZEAFBVN.js.map +1 -0
  42. package/package.json +6 -14
  43. package/src/ai-client.ts +156 -0
  44. package/src/bin.ts +74 -2
  45. package/src/build.ts +95 -33
  46. package/src/commands/__tests__/drift-sync.test.ts +252 -0
  47. package/src/commands/__tests__/scan-generate.test.ts +497 -45
  48. package/src/commands/enhance.ts +11 -35
  49. package/src/commands/init.ts +296 -193
  50. package/src/commands/scan-generate.ts +740 -139
  51. package/src/commands/scan.ts +37 -32
  52. package/src/commands/setup.ts +143 -52
  53. package/src/commands/snapshot.ts +197 -0
  54. package/src/commands/sync.ts +357 -0
  55. package/src/commands/validate.ts +43 -1
  56. package/src/core/component-extractor.test.ts +282 -0
  57. package/src/core/component-extractor.ts +1030 -0
  58. package/src/core/discovery.ts +93 -7
  59. package/src/service/enhance/props-extractor.ts +235 -13
  60. package/src/validators.ts +236 -0
  61. package/src/viewer/__tests__/viewer-integration.test.ts +85 -74
  62. package/src/viewer/server.ts +37 -22
  63. package/src/viewer/vite-plugin.ts +25 -9
  64. package/dist/chunk-5G3VZH43.js.map +0 -1
  65. package/dist/chunk-OQO55NKV.js.map +0 -1
  66. package/dist/chunk-WXSR2II7.js.map +0 -1
  67. package/dist/chunk-ZM4ZQZWZ.js.map +0 -1
  68. package/dist/init-NDQXUWDU.js +0 -796
  69. package/dist/init-NDQXUWDU.js.map +0 -1
  70. package/dist/scan-generate-SJAN5MVI.js +0 -691
  71. package/dist/scan-generate-SJAN5MVI.js.map +0 -1
  72. package/dist/viewer-DNMNC5VS.js.map +0 -1
  73. package/src/ai.ts +0 -266
  74. package/src/commands/init-framework.ts +0 -414
  75. package/src/mcp/bin.ts +0 -36
  76. package/src/migrate/bin.ts +0 -114
  77. package/src/theme/index.ts +0 -77
  78. package/src/viewer/__tests__/a11y-fixes.test.ts +0 -358
  79. package/src/viewer/__tests__/jsx-parser.test.ts +0 -502
  80. package/src/viewer/__tests__/render-utils.test.ts +0 -232
  81. package/src/viewer/__tests__/style-utils.test.ts +0 -404
  82. package/src/viewer/assets/fragments-logo.ts +0 -4
  83. package/src/viewer/assets/fragments_logo.png +0 -0
  84. package/src/viewer/bin.ts +0 -86
  85. package/src/viewer/cli/health.ts +0 -256
  86. package/src/viewer/cli/index.ts +0 -33
  87. package/src/viewer/cli/scan.ts +0 -124
  88. package/src/viewer/cli/utils.ts +0 -174
  89. package/src/viewer/components/AccessibilityPanel.tsx +0 -1457
  90. package/src/viewer/components/ActionCapture.tsx +0 -172
  91. package/src/viewer/components/ActionsPanel.tsx +0 -332
  92. package/src/viewer/components/AllVariantsPreview.tsx +0 -78
  93. package/src/viewer/components/App.tsx +0 -582
  94. package/src/viewer/components/BottomPanel.tsx +0 -288
  95. package/src/viewer/components/CodePanel.naming.test.tsx +0 -59
  96. package/src/viewer/components/CodePanel.tsx +0 -118
  97. package/src/viewer/components/CommandPalette.tsx +0 -392
  98. package/src/viewer/components/ComponentDocView.tsx +0 -164
  99. package/src/viewer/components/ComponentGraph.tsx +0 -380
  100. package/src/viewer/components/ComponentHeader.tsx +0 -88
  101. package/src/viewer/components/ContractPanel.tsx +0 -241
  102. package/src/viewer/components/EmptyVariantMessage.tsx +0 -54
  103. package/src/viewer/components/ErrorBoundary.tsx +0 -97
  104. package/src/viewer/components/FigmaEmbed.tsx +0 -238
  105. package/src/viewer/components/FragmentEditor.tsx +0 -525
  106. package/src/viewer/components/FragmentRenderer.tsx +0 -61
  107. package/src/viewer/components/HeaderSearch.tsx +0 -24
  108. package/src/viewer/components/HealthDashboard.tsx +0 -441
  109. package/src/viewer/components/HmrStatusIndicator.tsx +0 -61
  110. package/src/viewer/components/Icons.tsx +0 -479
  111. package/src/viewer/components/InteractionsPanel.tsx +0 -757
  112. package/src/viewer/components/IsolatedPreviewFrame.tsx +0 -346
  113. package/src/viewer/components/IsolatedRender.tsx +0 -113
  114. package/src/viewer/components/KeyboardShortcutsHelp.tsx +0 -53
  115. package/src/viewer/components/LandingPage.tsx +0 -421
  116. package/src/viewer/components/Layout.tsx +0 -27
  117. package/src/viewer/components/LeftSidebar.tsx +0 -472
  118. package/src/viewer/components/LoadErrorMessage.tsx +0 -102
  119. package/src/viewer/components/MultiViewportPreview.tsx +0 -522
  120. package/src/viewer/components/NoVariantsMessage.tsx +0 -59
  121. package/src/viewer/components/PanelShell.tsx +0 -161
  122. package/src/viewer/components/PerformancePanel.tsx +0 -304
  123. package/src/viewer/components/PreviewArea.tsx +0 -472
  124. package/src/viewer/components/PreviewAside.tsx +0 -168
  125. package/src/viewer/components/PreviewFrameHost.tsx +0 -303
  126. package/src/viewer/components/PreviewPane.tsx +0 -149
  127. package/src/viewer/components/PreviewToolbar.tsx +0 -80
  128. package/src/viewer/components/PropsEditor.tsx +0 -506
  129. package/src/viewer/components/PropsTable.tsx +0 -111
  130. package/src/viewer/components/RelationsSection.tsx +0 -88
  131. package/src/viewer/components/ResizablePanel.tsx +0 -271
  132. package/src/viewer/components/RightSidebar.tsx +0 -102
  133. package/src/viewer/components/RuntimeToolsRegistrar.tsx +0 -17
  134. package/src/viewer/components/ScreenshotButton.tsx +0 -90
  135. package/src/viewer/components/Sidebar.tsx +0 -169
  136. package/src/viewer/components/SkeletonLoader.tsx +0 -161
  137. package/src/viewer/components/ThemeProvider.tsx +0 -42
  138. package/src/viewer/components/Toast.tsx +0 -3
  139. package/src/viewer/components/TokenStylePanel.tsx +0 -699
  140. package/src/viewer/components/TopToolbar.tsx +0 -159
  141. package/src/viewer/components/UsageSection.tsx +0 -95
  142. package/src/viewer/components/VariantMatrix.tsx +0 -388
  143. package/src/viewer/components/VariantRenderer.tsx +0 -131
  144. package/src/viewer/components/VariantTabs.tsx +0 -40
  145. package/src/viewer/components/ViewerHeader.tsx +0 -69
  146. package/src/viewer/components/ViewerStateSync.tsx +0 -52
  147. package/src/viewer/components/ViewportSelector.tsx +0 -172
  148. package/src/viewer/components/WebMCPDevTools.tsx +0 -503
  149. package/src/viewer/components/WebMCPIntegration.tsx +0 -47
  150. package/src/viewer/components/WebMCPStatusIndicator.tsx +0 -60
  151. package/src/viewer/components/_future/CreatePage.tsx +0 -836
  152. package/src/viewer/components/viewer-utils.ts +0 -16
  153. package/src/viewer/composition-renderer.ts +0 -381
  154. package/src/viewer/constants/index.ts +0 -1
  155. package/src/viewer/constants/ui.ts +0 -166
  156. package/src/viewer/entry.tsx +0 -335
  157. package/src/viewer/hooks/index.ts +0 -2
  158. package/src/viewer/hooks/useA11yCache.ts +0 -383
  159. package/src/viewer/hooks/useA11yService.ts +0 -364
  160. package/src/viewer/hooks/useActions.ts +0 -138
  161. package/src/viewer/hooks/useAppState.ts +0 -147
  162. package/src/viewer/hooks/useCompiledFragments.ts +0 -42
  163. package/src/viewer/hooks/useFigmaIntegration.ts +0 -132
  164. package/src/viewer/hooks/useHmrStatus.ts +0 -109
  165. package/src/viewer/hooks/useKeyboardShortcuts.ts +0 -270
  166. package/src/viewer/hooks/usePreviewBridge.ts +0 -347
  167. package/src/viewer/hooks/useScrollSpy.ts +0 -78
  168. package/src/viewer/hooks/useUrlState.ts +0 -318
  169. package/src/viewer/hooks/useViewSettings.ts +0 -111
  170. package/src/viewer/index.html +0 -28
  171. package/src/viewer/intelligence/healthReport.ts +0 -505
  172. package/src/viewer/intelligence/styleDrift.ts +0 -340
  173. package/src/viewer/intelligence/usageScanner.ts +0 -309
  174. package/src/viewer/jsx-parser.ts +0 -486
  175. package/src/viewer/preview-frame-entry.tsx +0 -25
  176. package/src/viewer/preview-frame.html +0 -125
  177. package/src/viewer/public/favicon.ico +0 -0
  178. package/src/viewer/render-template.html +0 -68
  179. package/src/viewer/styles/globals.css +0 -278
  180. package/src/viewer/types/a11y.ts +0 -197
  181. package/src/viewer/utils/a11y-fixes.ts +0 -509
  182. package/src/viewer/utils/actionExport.ts +0 -372
  183. package/src/viewer/utils/colorSchemes.ts +0 -201
  184. package/src/viewer/utils/detectRelationships.ts +0 -256
  185. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +0 -10
  186. package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +0 -2
  187. package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +0 -274
  188. package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +0 -129
  189. package/src/viewer/vendor/shared/src/DocsPageAsideHost.tsx +0 -89
  190. package/src/viewer/vendor/shared/src/DocsPageShell.tsx +0 -124
  191. package/src/viewer/vendor/shared/src/DocsSearchCommand.tsx +0 -99
  192. package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +0 -66
  193. package/src/viewer/vendor/shared/src/PropsTable.module.scss +0 -68
  194. package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +0 -2
  195. package/src/viewer/vendor/shared/src/PropsTable.tsx +0 -76
  196. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +0 -114
  197. package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +0 -2
  198. package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +0 -137
  199. package/src/viewer/vendor/shared/src/docs-data/index.ts +0 -32
  200. package/src/viewer/vendor/shared/src/docs-data/mcp-configs.ts +0 -72
  201. package/src/viewer/vendor/shared/src/docs-data/palettes.ts +0 -75
  202. package/src/viewer/vendor/shared/src/docs-data/setup-examples.ts +0 -55
  203. package/src/viewer/vendor/shared/src/docs-layout.scss +0 -28
  204. package/src/viewer/vendor/shared/src/docs-layout.scss.d.ts +0 -2
  205. package/src/viewer/vendor/shared/src/index.ts +0 -34
  206. package/src/viewer/vendor/shared/src/types.ts +0 -53
  207. package/src/viewer/webmcp/__tests__/analytics.test.ts +0 -108
  208. package/src/viewer/webmcp/analytics.ts +0 -165
  209. package/src/viewer/webmcp/index.ts +0 -3
  210. package/src/viewer/webmcp/posthog-bridge.ts +0 -39
  211. package/src/viewer/webmcp/runtime-tools.ts +0 -152
  212. package/src/viewer/webmcp/scan-utils.ts +0 -135
  213. package/src/viewer/webmcp/use-tool-analytics.ts +0 -69
  214. package/src/viewer/webmcp/viewer-state.ts +0 -45
  215. /package/dist/{discovery-NEOY4MPN.js.map → ai-client-I6MDWNYA.js.map} +0 -0
  216. /package/dist/{chunk-PW7QTQA6.js.map → chunk-4OC7FTJB.js.map} +0 -0
  217. /package/dist/{chunk-HRFUSSZI.js.map → chunk-AM4MRTMN.js.map} +0 -0
  218. /package/dist/{scan-CJF2DOQW.js.map → discovery-ZJQSXF56.js.map} +0 -0
  219. /package/dist/{generate-FBHSXR3D.js.map → generate-RJFS2JWA.js.map} +0 -0
  220. /package/dist/{service-TQYWY65E.js.map → scan-3PMCJ4RB.js.map} +0 -0
  221. /package/dist/{static-viewer-NUBFPKWH.js.map → service-VMGNJZ42.js.map} +0 -0
  222. /package/dist/{test-Z5LVO724.js.map → test-SI4NSHQX.js.map} +0 -0
  223. /package/dist/{tokens-CE46OTMD.js.map → tokens-T6SIVUT5.js.map} +0 -0
@@ -1,89 +0,0 @@
1
- 'use client';
2
-
3
- import { createPortal } from 'react-dom';
4
- import * as React from 'react';
5
-
6
- interface DocsPageAsideContextValue {
7
- asideVisible: boolean;
8
- setAsideVisible: (visible: boolean) => void;
9
- asideWidth: string;
10
- setAsideWidth: (width: string) => void;
11
- asideContainer: HTMLDivElement | null;
12
- setAsideContainer: (container: HTMLDivElement | null) => void;
13
- }
14
-
15
- const DocsPageAsideContext = React.createContext<DocsPageAsideContextValue | null>(null);
16
-
17
- export function DocsPageAsideProvider({
18
- children,
19
- defaultWidth = '320px',
20
- }: {
21
- children: React.ReactNode;
22
- defaultWidth?: string;
23
- }) {
24
- const [asideVisible, setAsideVisible] = React.useState(false);
25
- const [asideWidth, setAsideWidth] = React.useState(defaultWidth);
26
- const [asideContainer, setAsideContainer] = React.useState<HTMLDivElement | null>(null);
27
-
28
- return (
29
- <DocsPageAsideContext.Provider
30
- value={{
31
- asideVisible,
32
- setAsideVisible,
33
- asideWidth,
34
- setAsideWidth,
35
- asideContainer,
36
- setAsideContainer,
37
- }}
38
- >
39
- {children}
40
- </DocsPageAsideContext.Provider>
41
- );
42
- }
43
-
44
- export function useDocsPageAside() {
45
- const context = React.useContext(DocsPageAsideContext);
46
- if (!context) {
47
- throw new Error('useDocsPageAside must be used within DocsPageAsideProvider');
48
- }
49
- return context;
50
- }
51
-
52
- export function DocsPageAsidePortal({ children, width = '320px' }: { children: React.ReactNode; width?: string }) {
53
- const { setAsideVisible, setAsideWidth, asideContainer } = useDocsPageAside();
54
-
55
- React.useLayoutEffect(() => {
56
- setAsideVisible(true);
57
- setAsideWidth(width);
58
-
59
- return () => {
60
- setAsideVisible(false);
61
- };
62
- }, [setAsideVisible, setAsideWidth, width]);
63
-
64
- if (!asideContainer) {
65
- return null;
66
- }
67
-
68
- return createPortal(children, asideContainer);
69
- }
70
-
71
- interface DocsPageAsideHostProps {
72
- className?: string;
73
- style?: React.CSSProperties;
74
- }
75
-
76
- export function DocsPageAsideHost({ className, style }: DocsPageAsideHostProps) {
77
- const { setAsideContainer } = useDocsPageAside();
78
-
79
- const asideContainerCallback = React.useCallback(
80
- (node: HTMLDivElement | null) => {
81
- setAsideContainer(node);
82
- },
83
- [setAsideContainer]
84
- );
85
-
86
- return (
87
- <div ref={asideContainerCallback} className={className} style={{ height: '100%', ...style }} />
88
- );
89
- }
@@ -1,124 +0,0 @@
1
- 'use client';
2
-
3
- import { AppShell } from '@fragments-sdk/ui';
4
- import type { ReactNode } from 'react';
5
- import { DocsPageAsideHost, DocsPageAsideProvider, useDocsPageAside } from './DocsPageAsideHost';
6
-
7
- type SidebarCollapsible = 'offcanvas' | 'icon' | 'none';
8
-
9
- interface DocsPageShellProps {
10
- header: ReactNode;
11
- sidebar: ReactNode;
12
- children: ReactNode;
13
- sidebarWidth?: string;
14
- sidebarCollapsible?: SidebarCollapsible;
15
- sidebarDefaultCollapsed?: boolean;
16
- sidebarAriaLabel?: string;
17
- mainId?: string;
18
- mainAriaLabel?: string;
19
- mainPadding?: 'none' | 'sm' | 'md' | 'lg';
20
- mainClassName?: string;
21
- aside?: ReactNode;
22
- asideWidth?: string;
23
- useAsidePortal?: boolean;
24
- }
25
-
26
- function DocsPageShellInner({
27
- header,
28
- sidebar,
29
- children,
30
- sidebarWidth = '260px',
31
- sidebarCollapsible = 'offcanvas',
32
- sidebarDefaultCollapsed,
33
- sidebarAriaLabel = 'Documentation sidebar',
34
- mainId = 'main-content',
35
- mainAriaLabel = 'Documentation content',
36
- mainPadding = 'lg',
37
- mainClassName,
38
- aside,
39
- asideWidth = '320px',
40
- useAsidePortal = false,
41
- }: DocsPageShellProps) {
42
- return (
43
- <AppShell>
44
- <AppShell.Header>{header}</AppShell.Header>
45
-
46
- <AppShell.Sidebar
47
- width={sidebarWidth}
48
- collapsible={sidebarCollapsible}
49
- defaultCollapsed={sidebarDefaultCollapsed}
50
- aria-label={sidebarAriaLabel}
51
- >
52
- {sidebar}
53
- </AppShell.Sidebar>
54
-
55
- <AppShell.Main
56
- id={mainId}
57
- aria-label={mainAriaLabel}
58
- padding={mainPadding}
59
- className={mainClassName}
60
- >
61
- {children}
62
- </AppShell.Main>
63
-
64
- {useAsidePortal ? <DocsPageAsideHost /> : null}
65
- {!useAsidePortal && aside ? <AppShell.Aside width={asideWidth}>{aside}</AppShell.Aside> : null}
66
- </AppShell>
67
- );
68
- }
69
-
70
- function DocsPageShellPortalInner({
71
- header,
72
- sidebar,
73
- children,
74
- sidebarWidth = '260px',
75
- sidebarCollapsible = 'offcanvas',
76
- sidebarDefaultCollapsed,
77
- sidebarAriaLabel = 'Documentation sidebar',
78
- mainId = 'main-content',
79
- mainAriaLabel = 'Documentation content',
80
- mainPadding = 'lg',
81
- mainClassName,
82
- }: DocsPageShellProps) {
83
- const { asideVisible, asideWidth } = useDocsPageAside();
84
-
85
- return (
86
- <AppShell>
87
- <AppShell.Header>{header}</AppShell.Header>
88
-
89
- <AppShell.Sidebar
90
- width={sidebarWidth}
91
- collapsible={sidebarCollapsible}
92
- defaultCollapsed={sidebarDefaultCollapsed}
93
- aria-label={sidebarAriaLabel}
94
- >
95
- {sidebar}
96
- </AppShell.Sidebar>
97
-
98
- <AppShell.Main
99
- id={mainId}
100
- aria-label={mainAriaLabel}
101
- padding={mainPadding}
102
- className={mainClassName}
103
- >
104
- {children}
105
- </AppShell.Main>
106
-
107
- <AppShell.Aside width={asideWidth} visible={asideVisible} aria-label="On-page controls">
108
- <DocsPageAsideHost />
109
- </AppShell.Aside>
110
- </AppShell>
111
- );
112
- }
113
-
114
- export function DocsPageShell(props: DocsPageShellProps) {
115
- if (props.useAsidePortal) {
116
- return (
117
- <DocsPageAsideProvider defaultWidth={props.asideWidth}>
118
- <DocsPageShellPortalInner {...props} />
119
- </DocsPageAsideProvider>
120
- );
121
- }
122
-
123
- return <DocsPageShellInner {...props} />;
124
- }
@@ -1,99 +0,0 @@
1
- 'use client';
2
-
3
- import { Command, Dialog, Button, Text, Stack } from '@fragments-sdk/ui';
4
- import { useEffect, useMemo, useState, useCallback } from 'react';
5
- import type { SearchItem } from './types';
6
-
7
- interface DocsSearchCommandProps {
8
- searchItems: SearchItem[];
9
- onSelect: (item: SearchItem) => void;
10
- placeholder?: string;
11
- maxResults?: number;
12
- }
13
-
14
- export function DocsSearchCommand({
15
- searchItems,
16
- onSelect,
17
- placeholder = 'Search docs...',
18
- maxResults = 9999,
19
- }: DocsSearchCommandProps) {
20
- const [open, setOpen] = useState(false);
21
-
22
- // Cmd+K / Ctrl+K to open
23
- useEffect(() => {
24
- const handleKeyDown = (event: KeyboardEvent) => {
25
- if ((event.metaKey || event.ctrlKey) && event.key === 'k') {
26
- event.preventDefault();
27
- setOpen((prev) => !prev);
28
- }
29
- };
30
-
31
- document.addEventListener('keydown', handleKeyDown);
32
- return () => document.removeEventListener('keydown', handleKeyDown);
33
- }, []);
34
-
35
- // Group items by section
36
- const grouped = useMemo(() => {
37
- const map = new Map<string, SearchItem[]>();
38
- for (const item of searchItems) {
39
- const section = item.section || 'Navigation';
40
- if (!map.has(section)) map.set(section, []);
41
- map.get(section)!.push(item);
42
- }
43
- return map;
44
- }, [searchItems]);
45
-
46
- const handleSelect = useCallback(
47
- (item: SearchItem) => {
48
- setOpen(false);
49
- onSelect(item);
50
- },
51
- [onSelect],
52
- );
53
-
54
- return (
55
- <>
56
- <Button
57
- variant="secondary"
58
- size="sm"
59
- onClick={() => setOpen(true)}
60
- aria-label="Search documentation"
61
- style={{ minWidth: 160, justifyContent: 'space-between' }}
62
- >
63
- <Text size="sm" color="secondary">Search...</Text>
64
- <Text size="xs" color="secondary" font="mono">⌘K</Text>
65
- </Button>
66
-
67
- <Dialog open={open} onOpenChange={setOpen}>
68
- <Dialog.Content size="sm" style={{ padding: 0, overflow: 'hidden' }}>
69
- <Command
70
- filter={(value, search) => {
71
- if (value.toLowerCase().includes(search.toLowerCase())) return 1;
72
- return 0;
73
- }}
74
- >
75
- <Command.Input placeholder={placeholder} />
76
- <Command.List>
77
- <Command.Empty>No results found.</Command.Empty>
78
- {[...grouped.entries()].map(([section, items]) => (
79
- <Command.Group key={section} heading={section}>
80
- {items.slice(0, maxResults).map((item) => (
81
- <Command.Item
82
- key={`${item.section}:${item.href}`}
83
- value={`${item.label} ${item.section}`}
84
- onItemSelect={() => handleSelect(item)}
85
- >
86
- <Stack direction="row" align="center" justify="between" style={{ width: '100%' }}>
87
- <Text size="sm">{item.label}</Text>
88
- </Stack>
89
- </Command.Item>
90
- ))}
91
- </Command.Group>
92
- ))}
93
- </Command.List>
94
- </Command>
95
- </Dialog.Content>
96
- </Dialog>
97
- </>
98
- );
99
- }
@@ -1,66 +0,0 @@
1
- 'use client';
2
-
3
- import { Sidebar } from '@fragments-sdk/ui';
4
- import type { ReactNode } from 'react';
5
- import type { DocsNavLinkRenderer, NavSection } from './types';
6
-
7
- interface DocsSidebarNavProps {
8
- sections: NavSection[];
9
- currentPath: string;
10
- renderLink?: DocsNavLinkRenderer;
11
- onNavigate?: () => void;
12
- isActive?: (href: string, currentPath: string) => boolean;
13
- footer?: ReactNode;
14
- ariaLabel?: string;
15
- }
16
-
17
- function defaultIsActive(href: string, currentPath: string): boolean {
18
- return currentPath === href;
19
- }
20
-
21
- const defaultLinkRenderer: DocsNavLinkRenderer = ({ href, label, onClick }) => (
22
- <a href={href} onClick={onClick}>
23
- {label}
24
- </a>
25
- );
26
-
27
- export function DocsSidebarNav({
28
- sections,
29
- currentPath,
30
- renderLink = defaultLinkRenderer,
31
- onNavigate,
32
- isActive = defaultIsActive,
33
- footer,
34
- ariaLabel = 'Navigation',
35
- }: DocsSidebarNavProps) {
36
- return (
37
- <>
38
- <Sidebar.Nav aria-label={ariaLabel}>
39
- {sections.map((section) => (
40
- <Sidebar.Section
41
- key={section.title}
42
- label={section.title}
43
- collapsible={section.collapsible}
44
- defaultOpen={section.defaultOpen}
45
- >
46
- {section.items.map((item) => (
47
- <Sidebar.Item
48
- key={item.href}
49
- active={isActive(item.href, currentPath)}
50
- asChild
51
- >
52
- {renderLink({
53
- href: item.href,
54
- label: item.label,
55
- onClick: onNavigate,
56
- })}
57
- </Sidebar.Item>
58
- ))}
59
- </Sidebar.Section>
60
- ))}
61
- </Sidebar.Nav>
62
-
63
- <Sidebar.Footer>{footer}</Sidebar.Footer>
64
- </>
65
- );
66
- }
@@ -1,68 +0,0 @@
1
- .container {
2
- margin: 1.5rem 0;
3
- overflow-x: auto;
4
- }
5
-
6
- .empty {
7
- color: var(--fui-text-tertiary);
8
- font-style: italic;
9
- }
10
-
11
- .table {
12
- width: 100%;
13
- border-collapse: collapse;
14
- font-size: 0.875rem;
15
-
16
- th, td {
17
- text-align: left;
18
- padding: 0.75rem;
19
- border-bottom: 1px solid var(--fui-border);
20
- }
21
-
22
- th {
23
- font-weight: var(--fui-font-weight-semibold);
24
- color: var(--fui-text-secondary);
25
- background-color: var(--fui-bg-secondary);
26
- }
27
-
28
- td {
29
- vertical-align: top;
30
- }
31
- }
32
-
33
- .propName {
34
- display: flex;
35
- align-items: center;
36
- gap: 0.5rem;
37
-
38
- code {
39
- font-weight: var(--fui-font-weight-semibold);
40
- }
41
- }
42
-
43
- .type {
44
- display: flex;
45
- flex-direction: column;
46
- gap: 0.25rem;
47
- }
48
-
49
- .values {
50
- display: flex;
51
- flex-wrap: wrap;
52
- gap: 0.25rem;
53
- }
54
-
55
- .value {
56
- font-size: 0.75rem;
57
- background-color: var(--fui-bg-tertiary);
58
- padding: 0.125rem 0.375rem;
59
- border-radius: var(--fui-radius-sm);
60
- }
61
-
62
- .default {
63
- color: var(--fui-color-accent);
64
- }
65
-
66
- .noDefault {
67
- color: var(--fui-text-tertiary);
68
- }
@@ -1,2 +0,0 @@
1
- declare const styles: Record<string, string>;
2
- export default styles;
@@ -1,76 +0,0 @@
1
- 'use client';
2
-
3
- import { Badge } from '@fragments-sdk/ui';
4
- import type { DocProp } from './types';
5
- import styles from './PropsTable.module.scss';
6
-
7
- /** Detect auto-generated descriptions like "variant prop" */
8
- function isGenericPropDescription(name: string, description: string): boolean {
9
- const lower = description.toLowerCase().trim();
10
- return lower === `${name.toLowerCase()} prop` || lower === `${name.toLowerCase()} property`;
11
- }
12
-
13
- interface PropsTableProps {
14
- props: Record<string, DocProp>;
15
- }
16
-
17
- export function PropsTable({ props }: PropsTableProps) {
18
- const propEntries = Object.entries(props);
19
-
20
- if (propEntries.length === 0) {
21
- return <p className={styles.empty}>No props documented</p>;
22
- }
23
-
24
- return (
25
- <div className={styles.container}>
26
- <table className={styles.table}>
27
- <thead>
28
- <tr>
29
- <th>Prop</th>
30
- <th>Type</th>
31
- <th>Default</th>
32
- <th>Description</th>
33
- </tr>
34
- </thead>
35
- <tbody>
36
- {propEntries.map(([name, prop]) => (
37
- <tr key={name}>
38
- <td>
39
- <span className={styles.propName}>
40
- <code>{name}</code>
41
- {prop.required && (
42
- <Badge size="sm" variant="error">
43
- Required
44
- </Badge>
45
- )}
46
- </span>
47
- </td>
48
- <td>
49
- <span className={styles.type}>
50
- <code>{prop.type}</code>
51
- {prop.values && (
52
- <span className={styles.values}>
53
- {prop.values.map((v) => (
54
- <code key={v} className={styles.value}>
55
- {v}
56
- </code>
57
- ))}
58
- </span>
59
- )}
60
- </span>
61
- </td>
62
- <td>
63
- {prop.default !== undefined ? (
64
- <code className={styles.default}>{String(prop.default)}</code>
65
- ) : (
66
- <span className={styles.noDefault}>Not set</span>
67
- )}
68
- </td>
69
- <td>{prop.description && !isGenericPropDescription(name, prop.description) ? prop.description : '—'}</td>
70
- </tr>
71
- ))}
72
- </tbody>
73
- </table>
74
- </div>
75
- );
76
- }
@@ -1,114 +0,0 @@
1
- // Shared variant preview card — used by docs and CLI viewer
2
- .card {
3
- border: 1px solid var(--fui-border);
4
- border-radius: var(--fui-radius-lg);
5
- overflow: hidden;
6
- background-color: var(--fui-bg-primary);
7
- }
8
-
9
- .highlighted {
10
- border-color: var(--fui-color-accent);
11
- box-shadow: 0 0 0 1px color-mix(in srgb, var(--fui-color-accent) 40%, transparent);
12
- }
13
-
14
- .header {
15
- display: flex;
16
- align-items: center;
17
- justify-content: space-between;
18
- gap: var(--fui-space-4);
19
- padding: var(--fui-space-2) var(--fui-space-4);
20
- background-color: var(--fui-bg-primary);
21
- border-bottom: 1px solid var(--fui-border);
22
- }
23
-
24
- .headerContent {
25
- flex: 1;
26
- min-width: 0;
27
- }
28
-
29
- .title {
30
- font-size: var(--fui-font-size-sm);
31
- font-weight: var(--fui-font-weight-semibold);
32
- color: var(--fui-text-primary);
33
- margin: 0;
34
- line-height: 1.4;
35
- }
36
-
37
- .description {
38
- font-size: var(--fui-font-size-xs);
39
- color: var(--fui-text-tertiary);
40
- margin: var(--fui-space-0-5) 0 0 0;
41
- line-height: 1.4;
42
- }
43
-
44
- // Preview area with subtle dotted grid pattern
45
- .previewPanel {
46
- position: relative;
47
- padding: var(--fui-space-4);
48
- display: flex;
49
- flex-direction: column;
50
- align-items: center;
51
- justify-content: center;
52
- background-color: var(--fui-bg-primary);
53
-
54
- // Subtle dotted grid pattern
55
- background-image: radial-gradient(circle, var(--fui-border) 1px, transparent 1px);
56
- background-size: 24px 24px;
57
- }
58
-
59
- // Code panel
60
- .codePanel {
61
- background-color: var(--fui-bg-tertiary);
62
- padding: 0 !important; // Override Tabs panel padding
63
-
64
- // Override CodeBlock styles for embedded use
65
- :global([class*="CodeBlock_container"]) {
66
- border: none;
67
- border-radius: 0;
68
- margin: 0;
69
- }
70
-
71
- :global([class*="CodeBlock_wrapper"]) {
72
- border-top-left-radius: 0;
73
- border-top-right-radius: 0;
74
- border: none;
75
- }
76
-
77
- :global([class*="CodeBlock_title"]) {
78
- display: none;
79
- }
80
- }
81
-
82
- .placeholder {
83
- color: var(--fui-text-tertiary);
84
- font-style: italic;
85
- font-size: var(--fui-font-size-sm);
86
- }
87
-
88
- .headerActions {
89
- display: flex;
90
- align-items: center;
91
- gap: var(--fui-space-2);
92
- flex-shrink: 0;
93
- }
94
-
95
- // Override Tabs styling for preview cards
96
- .card {
97
- :global([class*="Tabs_root"]) {
98
- display: flex;
99
- flex-direction: column;
100
- }
101
-
102
- // Tabs list sits inline with header
103
- :global([class*="Tabs_list"]) {
104
- padding: 0;
105
- border-bottom: none;
106
- background-color: transparent;
107
- flex-shrink: 0;
108
- }
109
-
110
- :global([class*="Tabs_listPills"]) {
111
- margin: 0;
112
- }
113
-
114
- }
@@ -1,2 +0,0 @@
1
- declare const styles: Record<string, string>;
2
- export default styles;