@windrun-huaiin/third-ui 26.0.0 → 28.0.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 (210) hide show
  1. package/dist/ai/ai-prompt-textarea.d.ts +72 -0
  2. package/dist/ai/ai-prompt-textarea.js +114 -0
  3. package/dist/ai/ai-prompt-textarea.mjs +112 -0
  4. package/dist/ai/index.d.ts +1 -0
  5. package/dist/ai/index.js +2 -0
  6. package/dist/ai/index.mjs +1 -0
  7. package/dist/clerk/clerk-provider-client.js +0 -1
  8. package/dist/clerk/clerk-provider-client.mjs +0 -1
  9. package/dist/clerk/fingerprint/fingerprint-client.js +0 -4
  10. package/dist/clerk/fingerprint/fingerprint-client.mjs +0 -4
  11. package/dist/clerk/fingerprint/use-fingerprint.js +0 -6
  12. package/dist/clerk/fingerprint/use-fingerprint.mjs +0 -6
  13. package/dist/clerk/signin-with-fingerprint-client.js +0 -9
  14. package/dist/clerk/signin-with-fingerprint-client.mjs +0 -9
  15. package/dist/clerk/signup-button-with-fingerprint-client.js +0 -16
  16. package/dist/clerk/signup-button-with-fingerprint-client.mjs +0 -16
  17. package/dist/clerk/signup-with-fingerprint-client.js +0 -9
  18. package/dist/clerk/signup-with-fingerprint-client.mjs +0 -9
  19. package/dist/fuma/base/custom-header.js +10 -8
  20. package/dist/fuma/base/custom-header.mjs +10 -8
  21. package/dist/fuma/base/custom-home-layout.d.ts +0 -4
  22. package/dist/fuma/base/docs-root-provider.d.ts +19 -0
  23. package/dist/fuma/base/docs-root-provider.js +17 -0
  24. package/dist/fuma/base/docs-root-provider.mjs +15 -0
  25. package/dist/fuma/base/index.d.ts +5 -0
  26. package/dist/fuma/base/index.js +16 -7
  27. package/dist/fuma/base/index.mjs +5 -1
  28. package/dist/fuma/base/nav-config.d.ts +10 -0
  29. package/dist/fuma/base/nav-config.js +32 -0
  30. package/dist/fuma/base/nav-config.mjs +28 -0
  31. package/dist/fuma/base/site-docs-layout.d.ts +11 -0
  32. package/dist/fuma/base/site-docs-layout.js +15 -0
  33. package/dist/fuma/base/site-docs-layout.mjs +13 -0
  34. package/dist/fuma/base/site-home-layout.d.ts +24 -0
  35. package/dist/fuma/base/site-home-layout.js +16 -0
  36. package/dist/fuma/base/site-home-layout.mjs +14 -0
  37. package/dist/fuma/base/site-layout-shared.d.ts +89 -0
  38. package/dist/fuma/base/site-layout-shared.js +48 -0
  39. package/dist/fuma/base/site-layout-shared.mjs +42 -0
  40. package/dist/fuma/base/site-layout.d.ts +4 -116
  41. package/dist/fuma/base/site-layout.js +2 -2
  42. package/dist/fuma/base/site-layout.mjs +2 -2
  43. package/dist/fuma/fuma-page-genarator.d.ts +1 -1
  44. package/dist/fuma/fuma-page-genarator.js +65 -10
  45. package/dist/fuma/fuma-page-genarator.mjs +61 -6
  46. package/dist/fuma/llm-copy-handler.js +0 -9
  47. package/dist/fuma/llm-copy-handler.mjs +0 -9
  48. package/dist/fuma/mdx/index.d.ts +0 -1
  49. package/dist/fuma/mdx/index.js +0 -2
  50. package/dist/fuma/mdx/index.mjs +0 -1
  51. package/dist/fuma/mdx/suno-embed.js +3 -1
  52. package/dist/fuma/mdx/suno-embed.mjs +3 -1
  53. package/dist/fuma/mdx/toc-base.js +0 -1
  54. package/dist/fuma/mdx/toc-base.mjs +0 -1
  55. package/dist/fuma/server/features/widgets.js +5 -1
  56. package/dist/fuma/server/features/widgets.mjs +5 -1
  57. package/dist/fuma/server/llm-copy-handler.d.ts +2 -0
  58. package/dist/fuma/server/llm-copy-handler.js +7 -0
  59. package/dist/fuma/server/llm-copy-handler.mjs +1 -0
  60. package/dist/fuma/server/page-generator.d.ts +2 -0
  61. package/dist/fuma/server/page-generator.js +7 -0
  62. package/dist/fuma/server/page-generator.mjs +1 -0
  63. package/dist/lib/seo-metadata.js +3 -3
  64. package/dist/lib/seo-metadata.mjs +1 -1
  65. package/dist/lib/seo-util.js +4 -4
  66. package/dist/lib/seo-util.mjs +1 -1
  67. package/dist/lib/site-docs-helper.d.ts +51 -0
  68. package/dist/lib/site-docs-helper.js +68 -0
  69. package/dist/lib/site-docs-helper.mjs +66 -0
  70. package/dist/main/alert-dialog/index.js +14 -0
  71. package/dist/main/alert-dialog/index.mjs +5 -0
  72. package/dist/main/buttons/gradient-button.d.ts +20 -0
  73. package/dist/main/buttons/gradient-button.js +88 -0
  74. package/dist/main/buttons/gradient-button.mjs +86 -0
  75. package/dist/main/buttons/index.d.ts +3 -0
  76. package/dist/main/buttons/index.js +12 -0
  77. package/dist/main/buttons/index.mjs +4 -0
  78. package/dist/main/buttons/x-button.d.ts +39 -0
  79. package/dist/main/buttons/x-button.js +92 -0
  80. package/dist/main/buttons/x-button.mjs +90 -0
  81. package/dist/main/buttons/x-toggle-button.d.ts +32 -0
  82. package/dist/main/buttons/x-toggle-button.js +95 -0
  83. package/dist/main/buttons/x-toggle-button.mjs +74 -0
  84. package/dist/main/credit/credit-nav-button.js +25 -1
  85. package/dist/main/credit/credit-nav-button.mjs +25 -1
  86. package/dist/main/credit/credit-overview-client.js +3 -2
  87. package/dist/main/credit/credit-overview-client.mjs +3 -2
  88. package/dist/main/credit/index.d.ts +4 -0
  89. package/dist/main/credit/index.js +10 -0
  90. package/dist/main/credit/index.mjs +3 -0
  91. package/dist/main/credit/server.d.ts +2 -0
  92. package/dist/main/credit/server.js +7 -0
  93. package/dist/main/credit/server.mjs +1 -0
  94. package/dist/main/cta.js +4 -2
  95. package/dist/main/cta.mjs +4 -2
  96. package/dist/main/footer.js +3 -3
  97. package/dist/main/footer.mjs +1 -1
  98. package/dist/main/hero/index.d.ts +2 -0
  99. package/dist/main/hero/index.js +10 -0
  100. package/dist/main/hero/index.mjs +3 -0
  101. package/dist/main/home/server.d.ts +7 -0
  102. package/dist/main/home/server.js +19 -0
  103. package/dist/main/home/server.mjs +7 -0
  104. package/dist/main/index.d.ts +0 -15
  105. package/dist/main/index.js +0 -43
  106. package/dist/main/index.mjs +0 -21
  107. package/dist/main/loading/index.d.ts +1 -0
  108. package/dist/main/loading/index.js +9 -0
  109. package/dist/main/loading/index.mjs +2 -0
  110. package/dist/main/loading-frame/index.d.ts +1 -0
  111. package/dist/main/loading-frame/index.js +9 -0
  112. package/dist/main/loading-frame/index.mjs +2 -0
  113. package/dist/main/money-price/index.d.ts +4 -0
  114. package/dist/main/money-price/index.js +15 -0
  115. package/dist/main/money-price/index.mjs +4 -0
  116. package/dist/main/money-price/money-price-button.d.ts +1 -1
  117. package/dist/main/money-price/money-price-button.js +12 -9
  118. package/dist/main/money-price/money-price-button.mjs +12 -9
  119. package/dist/main/money-price/money-price-interactive.d.ts +1 -1
  120. package/dist/main/money-price/money-price-interactive.js +22 -25
  121. package/dist/main/money-price/money-price-interactive.mjs +22 -25
  122. package/dist/main/money-price/money-price-types.d.ts +2 -0
  123. package/dist/main/money-price/server.d.ts +5 -0
  124. package/dist/main/money-price/server.js +18 -0
  125. package/dist/main/money-price/server.mjs +4 -0
  126. package/package.json +94 -4
  127. package/src/ai/index.ts +1 -0
  128. package/src/clerk/clerk-provider-client.tsx +1 -3
  129. package/src/clerk/fingerprint/fingerprint-client.ts +0 -4
  130. package/src/clerk/fingerprint/use-fingerprint.ts +0 -6
  131. package/src/clerk/signin-with-fingerprint-client.tsx +0 -10
  132. package/src/clerk/signup-button-with-fingerprint-client.tsx +0 -17
  133. package/src/clerk/signup-with-fingerprint-client.tsx +0 -10
  134. package/src/fuma/base/custom-header.tsx +12 -8
  135. package/src/fuma/base/custom-home-layout.tsx +3 -6
  136. package/src/fuma/base/docs-root-provider.tsx +58 -0
  137. package/src/fuma/base/index.ts +5 -0
  138. package/src/fuma/base/nav-config.ts +81 -0
  139. package/src/fuma/base/site-docs-layout.tsx +35 -0
  140. package/src/fuma/base/site-home-layout.tsx +78 -0
  141. package/src/fuma/base/site-layout-shared.tsx +190 -0
  142. package/src/fuma/base/site-layout.tsx +4 -289
  143. package/src/fuma/fuma-banner-suit.tsx +1 -1
  144. package/src/fuma/fuma-page-genarator.tsx +61 -8
  145. package/src/fuma/llm-copy-handler.ts +0 -11
  146. package/src/fuma/mdx/index.ts +0 -1
  147. package/src/fuma/mdx/suno-embed.tsx +1 -1
  148. package/src/fuma/mdx/toc-base.tsx +0 -1
  149. package/src/fuma/mdx/toc-footer-wrapper.tsx +2 -2
  150. package/src/fuma/server/features/widgets.tsx +1 -1
  151. package/src/fuma/server/llm-copy-handler.ts +2 -0
  152. package/src/fuma/server/page-generator.ts +2 -0
  153. package/src/lib/seo-metadata.ts +1 -1
  154. package/src/lib/seo-util.ts +2 -2
  155. package/src/lib/server.ts +1 -1
  156. package/src/{fuma/mdx → main/buttons}/gradient-button.tsx +10 -21
  157. package/src/main/buttons/index.ts +5 -0
  158. package/src/main/{x-button.tsx → buttons/x-button.tsx} +28 -42
  159. package/src/main/credit/credit-nav-button.tsx +36 -3
  160. package/src/main/credit/credit-overview-client.tsx +1 -1
  161. package/src/main/credit/index.ts +11 -0
  162. package/src/main/credit/server.ts +7 -0
  163. package/src/main/cta.tsx +1 -1
  164. package/src/main/footer.tsx +1 -2
  165. package/src/main/hero/index.ts +4 -0
  166. package/src/main/home/server.ts +7 -0
  167. package/src/main/index.ts +1 -20
  168. package/src/main/language-detector.tsx +0 -1
  169. package/src/main/loading/index.ts +3 -0
  170. package/src/main/loading-frame/index.ts +3 -0
  171. package/src/main/money-price/index.ts +18 -0
  172. package/src/main/money-price/money-price-button.tsx +17 -9
  173. package/src/main/money-price/money-price-interactive.tsx +30 -25
  174. package/src/main/money-price/money-price-types.ts +2 -0
  175. package/src/main/money-price/server.ts +22 -0
  176. package/dist/fuma/mdx/features.d.ts +0 -8
  177. package/dist/fuma/mdx/features.js +0 -92
  178. package/dist/fuma/mdx/features.mjs +0 -85
  179. package/dist/fuma/mdx/image-grid.d.ts +0 -6
  180. package/dist/fuma/mdx/image-grid.js +0 -17
  181. package/dist/fuma/mdx/image-grid.mjs +0 -15
  182. package/dist/fuma/mdx/image-zoom.d.ts +0 -22
  183. package/dist/fuma/mdx/image-zoom.js +0 -39
  184. package/dist/fuma/mdx/image-zoom.mjs +0 -37
  185. package/dist/fuma/mdx/markdown-component-map.d.ts +0 -3
  186. package/dist/fuma/mdx/markdown-component-map.js +0 -79
  187. package/dist/fuma/mdx/markdown-component-map.mjs +0 -77
  188. package/dist/fuma/mdx/math.d.ts +0 -17
  189. package/dist/fuma/mdx/math.js +0 -60
  190. package/dist/fuma/mdx/math.mjs +0 -57
  191. package/dist/fuma/mdx/mermaid.d.ts +0 -13
  192. package/dist/fuma/mdx/mermaid.js +0 -360
  193. package/dist/fuma/mdx/mermaid.mjs +0 -358
  194. package/dist/fuma/mdx/site-mdx-components.d.ts +0 -13
  195. package/dist/fuma/mdx/site-mdx-components.js +0 -19
  196. package/dist/fuma/mdx/site-mdx-components.mjs +0 -17
  197. package/dist/fuma/mdx/site-mdx-presets.d.ts +0 -13
  198. package/dist/fuma/mdx/site-mdx-presets.js +0 -49
  199. package/dist/fuma/mdx/site-mdx-presets.mjs +0 -45
  200. package/dist/fuma/server/optional-features.d.ts +0 -6
  201. package/dist/fuma/server/optional-features.js +0 -17
  202. package/dist/fuma/server/optional-features.mjs +0 -6
  203. package/dist/fuma/server/site-mdx-components.d.ts +0 -13
  204. package/dist/fuma/server/site-mdx-components.js +0 -18
  205. package/dist/fuma/server/site-mdx-components.mjs +0 -16
  206. package/dist/fuma/server/site-mdx-presets.d.ts +0 -195
  207. package/dist/fuma/server/site-mdx-presets.js +0 -55
  208. package/dist/fuma/server/site-mdx-presets.mjs +0 -52
  209. /package/src/{main → ai}/ai-prompt-textarea.tsx +0 -0
  210. /package/src/main/{x-toggle-button.tsx → buttons/x-toggle-button.tsx} +0 -0
@@ -0,0 +1,190 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import type { HomeLayoutProps } from 'fumadocs-ui/layouts/home';
3
+ import type { LinkItemType } from 'fumadocs-ui/layouts/shared';
4
+
5
+ export type ExtendedLinkItem = LinkItemType & {
6
+ mobilePinned?: boolean;
7
+ prefetch?: boolean;
8
+ };
9
+
10
+ type SiteMenuConfig = HTMLAttributes<HTMLElement> & {
11
+ banner?: ReactNode;
12
+ };
13
+
14
+ interface SiteNavSharedFields {
15
+ secondary?: boolean;
16
+ mobilePinned?: boolean;
17
+ }
18
+
19
+ export interface SiteNavLinkItemConfig extends SiteNavSharedFields {
20
+ type?: 'main' | 'icon' | 'button';
21
+ text: ReactNode;
22
+ url: string;
23
+ external?: boolean;
24
+ prefetch?: boolean;
25
+ icon?: ReactNode;
26
+ description?: ReactNode;
27
+ menu?: SiteMenuConfig;
28
+ on?: 'nav' | 'menu' | 'all';
29
+ label?: string;
30
+ }
31
+
32
+ export interface SiteNavMenuItemConfig extends SiteNavSharedFields {
33
+ type: 'menu';
34
+ text: ReactNode;
35
+ url?: string;
36
+ external?: boolean;
37
+ prefetch?: boolean;
38
+ icon?: ReactNode;
39
+ description?: ReactNode;
40
+ items: SiteNavItemConfig[];
41
+ menu?: SiteMenuConfig;
42
+ on?: 'nav' | 'menu' | 'all';
43
+ }
44
+
45
+ export interface SiteNavCustomItemConfig extends SiteNavSharedFields {
46
+ type: 'custom';
47
+ children: ReactNode;
48
+ }
49
+
50
+ export type SiteNavItemConfig =
51
+ | SiteNavLinkItemConfig
52
+ | SiteNavMenuItemConfig
53
+ | SiteNavCustomItemConfig;
54
+
55
+ export interface SiteBaseLayoutConfig {
56
+ nav?: HomeLayoutProps['nav'];
57
+ i18n?: HomeLayoutProps['i18n'];
58
+ githubUrl?: string;
59
+ links?: SiteNavItemConfig[];
60
+ searchToggle?: HomeLayoutProps['searchToggle'];
61
+ themeSwitch?: HomeLayoutProps['themeSwitch'];
62
+ }
63
+
64
+ export interface SiteMenuLeafConfig {
65
+ text: ReactNode;
66
+ path: string;
67
+ description?: ReactNode;
68
+ icon?: ReactNode;
69
+ className?: string;
70
+ external?: boolean;
71
+ prefetch?: boolean;
72
+ }
73
+
74
+ export interface SiteMenuGroupConfig {
75
+ text: ReactNode;
76
+ path?: string;
77
+ prefetch?: boolean;
78
+ landing?: SiteMenuLeafConfig;
79
+ items: SiteMenuLeafConfig[];
80
+ }
81
+
82
+ export interface CreateSiteNavItemContext {
83
+ resolveUrl: (path: string) => string;
84
+ }
85
+
86
+ export interface CreateSiteNavGroupOptions {
87
+ featuredClassName?: string;
88
+ featuredBanner?: ReactNode;
89
+ }
90
+
91
+ export interface CreateSiteBaseLayoutOptions {
92
+ homeUrl: string;
93
+ title: ReactNode;
94
+ i18n?: HomeLayoutProps['i18n'];
95
+ githubUrl?: string;
96
+ transparentMode?: HomeLayoutProps['nav'] extends infer T
97
+ ? T extends { transparentMode?: infer U }
98
+ ? U
99
+ : never
100
+ : never;
101
+ }
102
+
103
+ export function normalizeNavItems(items?: SiteNavItemConfig[]): ExtendedLinkItem[] | undefined {
104
+ if (!items) return undefined;
105
+
106
+ return items.map((item) => {
107
+ if (item.type === 'menu') {
108
+ return {
109
+ ...item,
110
+ items: normalizeNavItems(item.items) ?? [],
111
+ } as ExtendedLinkItem;
112
+ }
113
+
114
+ return item as ExtendedLinkItem;
115
+ });
116
+ }
117
+
118
+ export function createSiteNavLink(
119
+ item: SiteMenuLeafConfig,
120
+ context: CreateSiteNavItemContext,
121
+ ): SiteNavLinkItemConfig {
122
+ return {
123
+ type: 'main',
124
+ text: item.text,
125
+ ...(item.description ? { description: item.description } : {}),
126
+ url: context.resolveUrl(item.path),
127
+ ...(item.external ? { external: item.external } : {}),
128
+ ...(item.prefetch !== undefined ? { prefetch: item.prefetch } : {}),
129
+ ...(item.icon || item.className
130
+ ? {
131
+ menu: {
132
+ ...(item.icon ? { banner: item.icon } : {}),
133
+ ...(item.className ? { className: item.className } : {}),
134
+ },
135
+ }
136
+ : {}),
137
+ };
138
+ }
139
+
140
+ export function createSiteNavGroup(
141
+ item: SiteMenuGroupConfig,
142
+ context: CreateSiteNavItemContext,
143
+ options?: CreateSiteNavGroupOptions,
144
+ ): SiteNavMenuItemConfig {
145
+ return {
146
+ type: 'menu',
147
+ text: item.text,
148
+ ...(item.path ? { url: context.resolveUrl(item.path) } : {}),
149
+ ...(item.prefetch !== undefined ? { prefetch: item.prefetch } : {}),
150
+ items: [
151
+ ...(item.landing
152
+ ? [
153
+ {
154
+ ...createSiteNavLink(item.landing, context),
155
+ menu: {
156
+ ...(options?.featuredBanner ? { banner: options.featuredBanner } : {}),
157
+ className: options?.featuredClassName ?? 'md:row-span-2',
158
+ },
159
+ } satisfies SiteNavLinkItemConfig,
160
+ ]
161
+ : []),
162
+ ...item.items.map((child) => createSiteNavLink(child, context)),
163
+ ],
164
+ };
165
+ }
166
+
167
+ export function createSiteBaseLayoutConfig(
168
+ options: CreateSiteBaseLayoutOptions,
169
+ ): SiteBaseLayoutConfig {
170
+ return {
171
+ nav: {
172
+ url: options.homeUrl,
173
+ title: options.title,
174
+ transparentMode: options.transparentMode ?? 'none',
175
+ },
176
+ ...(options.i18n ? { i18n: options.i18n } : {}),
177
+ ...(options.githubUrl ? { githubUrl: options.githubUrl } : {}),
178
+ };
179
+ }
180
+
181
+ export function toHomeLayoutOptions(config: SiteBaseLayoutConfig): HomeLayoutProps {
182
+ return {
183
+ ...(config.nav ? { nav: config.nav } : {}),
184
+ ...(config.i18n ? { i18n: config.i18n } : {}),
185
+ ...(config.githubUrl ? { githubUrl: config.githubUrl } : {}),
186
+ ...(config.links ? { links: normalizeNavItems(config.links) } : {}),
187
+ ...(config.searchToggle ? { searchToggle: config.searchToggle } : {}),
188
+ ...(config.themeSwitch ? { themeSwitch: config.themeSwitch } : {}),
189
+ };
190
+ }
@@ -1,289 +1,4 @@
1
- import { type ComponentProps, type HTMLAttributes, type ReactNode } from 'react';
2
- import { RootProvider } from 'fumadocs-ui/provider/next';
3
- import { DocsLayout, type DocsLayoutProps } from 'fumadocs-ui/layouts/docs';
4
- import { type HomeLayoutProps } from 'fumadocs-ui/layouts/home';
5
- import { CustomHomeLayout, type CustomHomeLayoutProps, type ExtendedLinkItem, type HeaderActionOrders } from './custom-home-layout';
6
-
7
- type RootProviderI18n = NonNullable<ComponentProps<typeof RootProvider>['i18n']>;
8
-
9
- export interface DocsRootProviderProps {
10
- i18n: RootProviderI18n;
11
- children: ReactNode;
12
- }
13
-
14
- type SiteMenuConfig = HTMLAttributes<HTMLElement> & {
15
- banner?: ReactNode;
16
- };
17
-
18
- interface SiteNavSharedFields {
19
- secondary?: boolean;
20
- mobilePinned?: boolean;
21
- }
22
-
23
- export interface SiteNavLinkItemConfig extends SiteNavSharedFields {
24
- type?: 'main' | 'icon' | 'button';
25
- text: ReactNode;
26
- url: string;
27
- external?: boolean;
28
- icon?: ReactNode;
29
- description?: ReactNode;
30
- menu?: SiteMenuConfig;
31
- on?: 'nav' | 'menu' | 'all';
32
- label?: string;
33
- }
34
-
35
- export interface SiteNavMenuItemConfig extends SiteNavSharedFields {
36
- type: 'menu';
37
- text: ReactNode;
38
- url?: string;
39
- external?: boolean;
40
- icon?: ReactNode;
41
- description?: ReactNode;
42
- items: SiteNavItemConfig[];
43
- menu?: SiteMenuConfig;
44
- on?: 'nav' | 'menu' | 'all';
45
- }
46
-
47
- export interface SiteNavCustomItemConfig extends SiteNavSharedFields {
48
- type: 'custom';
49
- children: ReactNode;
50
- }
51
-
52
- export type SiteNavItemConfig =
53
- | SiteNavLinkItemConfig
54
- | SiteNavMenuItemConfig
55
- | SiteNavCustomItemConfig;
56
-
57
- export interface SiteBaseLayoutConfig {
58
- nav?: HomeLayoutProps['nav'];
59
- i18n?: HomeLayoutProps['i18n'];
60
- githubUrl?: string;
61
- links?: SiteNavItemConfig[];
62
- searchToggle?: HomeLayoutProps['searchToggle'];
63
- themeSwitch?: HomeLayoutProps['themeSwitch'];
64
- }
65
-
66
- export interface SiteHomeLayoutConfig extends SiteBaseLayoutConfig {
67
- showBanner?: boolean;
68
- bannerHeight?: number;
69
- headerHeight?: number;
70
- headerPaddingTop?: number;
71
- navbarClassName?: string;
72
- floatingNav?: boolean;
73
- banner?: ReactNode;
74
- footer?: ReactNode;
75
- goToTop?: ReactNode;
76
- showFooter?: boolean;
77
- showGoToTop?: boolean;
78
- actionOrders?: HeaderActionOrders;
79
- localePrefixAsNeeded?: boolean;
80
- defaultLocale?: string;
81
- }
82
-
83
- export interface SiteDocsLayoutConfig extends SiteBaseLayoutConfig {
84
- tree: DocsLayoutProps['tree'];
85
- sidebar?: DocsLayoutProps['sidebar'];
86
- }
87
-
88
- export interface SiteMenuLeafConfig {
89
- text: ReactNode;
90
- path: string;
91
- description?: ReactNode;
92
- icon?: ReactNode;
93
- className?: string;
94
- external?: boolean;
95
- }
96
-
97
- export interface SiteMenuGroupConfig {
98
- text: ReactNode;
99
- path?: string;
100
- landing?: SiteMenuLeafConfig;
101
- items: SiteMenuLeafConfig[];
102
- }
103
-
104
- export interface CreateSiteNavItemContext {
105
- resolveUrl: (path: string) => string;
106
- }
107
-
108
- export interface CreateSiteNavGroupOptions {
109
- featuredClassName?: string;
110
- featuredBanner?: ReactNode;
111
- }
112
-
113
- export interface CreateSiteBaseLayoutOptions {
114
- homeUrl: string;
115
- title: ReactNode;
116
- i18n?: HomeLayoutProps['i18n'];
117
- githubUrl?: string;
118
- transparentMode?: HomeLayoutProps['nav'] extends infer T
119
- ? T extends { transparentMode?: infer U }
120
- ? U
121
- : never
122
- : never;
123
- }
124
-
125
- function normalizeNavItems(items?: SiteNavItemConfig[]): ExtendedLinkItem[] | undefined {
126
- if (!items) return undefined;
127
-
128
- return items.map((item) => {
129
- if (item.type === 'menu') {
130
- return {
131
- ...item,
132
- items: normalizeNavItems(item.items) ?? [],
133
- } as ExtendedLinkItem;
134
- }
135
-
136
- return item as ExtendedLinkItem;
137
- });
138
- }
139
-
140
- export function createSiteNavLink(
141
- item: SiteMenuLeafConfig,
142
- context: CreateSiteNavItemContext,
143
- ): SiteNavLinkItemConfig {
144
- return {
145
- type: 'main',
146
- text: item.text,
147
- ...(item.description ? { description: item.description } : {}),
148
- url: context.resolveUrl(item.path),
149
- ...(item.external ? { external: item.external } : {}),
150
- ...(item.icon || item.className
151
- ? {
152
- menu: {
153
- ...(item.icon ? { banner: item.icon } : {}),
154
- ...(item.className ? { className: item.className } : {}),
155
- },
156
- }
157
- : {}),
158
- };
159
- }
160
-
161
- export function createSiteNavGroup(
162
- item: SiteMenuGroupConfig,
163
- context: CreateSiteNavItemContext,
164
- options?: CreateSiteNavGroupOptions,
165
- ): SiteNavMenuItemConfig {
166
- return {
167
- type: 'menu',
168
- text: item.text,
169
- ...(item.path ? { url: context.resolveUrl(item.path) } : {}),
170
- items: [
171
- ...(item.landing
172
- ? [
173
- {
174
- ...createSiteNavLink(item.landing, context),
175
- menu: {
176
- ...(options?.featuredBanner ? { banner: options.featuredBanner } : {}),
177
- className: options?.featuredClassName ?? 'md:row-span-2',
178
- },
179
- } satisfies SiteNavLinkItemConfig,
180
- ]
181
- : []),
182
- ...item.items.map((child) => createSiteNavLink(child, context)),
183
- ],
184
- };
185
- }
186
-
187
- export function createSiteBaseLayoutConfig(
188
- options: CreateSiteBaseLayoutOptions,
189
- ): SiteBaseLayoutConfig {
190
- return {
191
- nav: {
192
- url: options.homeUrl,
193
- title: options.title,
194
- transparentMode: options.transparentMode ?? 'none',
195
- },
196
- ...(options.i18n ? { i18n: options.i18n } : {}),
197
- ...(options.githubUrl ? { githubUrl: options.githubUrl } : {}),
198
- };
199
- }
200
-
201
- function toHomeLayoutOptions(config: SiteBaseLayoutConfig): HomeLayoutProps {
202
- return {
203
- ...(config.nav ? { nav: config.nav } : {}),
204
- ...(config.i18n ? { i18n: config.i18n } : {}),
205
- ...(config.githubUrl ? { githubUrl: config.githubUrl } : {}),
206
- ...(config.links ? { links: normalizeNavItems(config.links) } : {}),
207
- ...(config.searchToggle ? { searchToggle: config.searchToggle } : {}),
208
- ...(config.themeSwitch ? { themeSwitch: config.themeSwitch } : {}),
209
- };
210
- }
211
-
212
- function toDocsLayoutOptions(config: SiteDocsLayoutConfig): DocsLayoutProps {
213
- return {
214
- ...(config.nav ? { nav: config.nav } : {}),
215
- ...(config.i18n ? { i18n: config.i18n } : {}),
216
- ...(config.githubUrl ? { githubUrl: config.githubUrl } : {}),
217
- ...(config.links ? { links: normalizeNavItems(config.links) } : {}),
218
- ...(config.searchToggle ? { searchToggle: config.searchToggle } : {}),
219
- ...(config.themeSwitch ? { themeSwitch: config.themeSwitch } : {}),
220
- ...(config.sidebar ? { sidebar: config.sidebar } : {}),
221
- tree: config.tree,
222
- };
223
- }
224
-
225
- export function DocsRootProvider({ i18n, children }: DocsRootProviderProps) {
226
- return <RootProvider i18n={i18n}>{children}</RootProvider>;
227
- }
228
-
229
- export function SiteHomeLayout({
230
- locale,
231
- config,
232
- children,
233
- }: {
234
- locale: string;
235
- config: SiteHomeLayoutConfig;
236
- children: ReactNode;
237
- }) {
238
- const {
239
- actionOrders,
240
- banner,
241
- bannerHeight,
242
- defaultLocale,
243
- floatingNav,
244
- footer,
245
- goToTop,
246
- headerHeight,
247
- headerPaddingTop,
248
- localePrefixAsNeeded,
249
- navbarClassName,
250
- showBanner,
251
- showFooter,
252
- showGoToTop,
253
- ...baseConfig
254
- } = config;
255
-
256
- const options = toHomeLayoutOptions(baseConfig);
257
-
258
- const layoutProps: CustomHomeLayoutProps = {
259
- locale,
260
- options,
261
- ...(actionOrders ? { actionOrders } : {}),
262
- ...(banner ? { banner } : {}),
263
- ...(bannerHeight != null ? { bannerHeight } : {}),
264
- ...(defaultLocale ? { defaultLocale } : {}),
265
- ...(floatingNav != null ? { floatingNav } : {}),
266
- ...(footer ? { footer } : {}),
267
- ...(goToTop ? { goToTop } : {}),
268
- ...(headerHeight != null ? { headerHeight } : {}),
269
- ...(headerPaddingTop != null ? { headerPaddingTop } : {}),
270
- ...(localePrefixAsNeeded != null ? { localePrefixAsNeeded } : {}),
271
- ...(navbarClassName ? { navbarClassName } : {}),
272
- ...(showBanner != null ? { showBanner } : {}),
273
- ...(showFooter != null ? { showFooter } : {}),
274
- ...(showGoToTop != null ? { showGoToTop } : {}),
275
- };
276
-
277
- return <CustomHomeLayout {...layoutProps}>{children}</CustomHomeLayout>;
278
- }
279
-
280
- export function SiteDocsLayout({
281
- config,
282
- children,
283
- }: {
284
- config: SiteDocsLayoutConfig;
285
- children: ReactNode;
286
- }) {
287
- const options = toDocsLayoutOptions(config);
288
- return <DocsLayout {...options}>{children}</DocsLayout>;
289
- }
1
+ export * from './docs-root-provider';
2
+ export * from './site-docs-layout';
3
+ export * from './site-home-layout';
4
+ export * from './site-layout-shared';
@@ -1,5 +1,5 @@
1
1
  import { getTranslations } from 'next-intl/server';
2
- import { Banner } from '@third-ui/fuma/mdx/banner';
2
+ import { Banner } from './mdx/banner';
3
3
 
4
4
  export async function FumaBannerSuit({
5
5
  locale,
@@ -1,9 +1,9 @@
1
1
  import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/page';
2
2
  import { ReactNode, ReactElement, cloneElement, type CSSProperties } from 'react';
3
- import { TocFooterWrapper } from '@third-ui/fuma/mdx/toc-footer-wrapper';
4
- import type { LLMCopyButtonProps, LLMCopyButton } from '@third-ui/fuma/mdx/toc-base';
5
- import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
6
- import { PortableClerkTOC, PortableClerkTOCTitle } from '@third-ui/fuma/mdx/toc-clerk-portable';
3
+ import { TocFooterWrapper } from './mdx/toc-footer-wrapper';
4
+ import type { LLMCopyButtonProps, LLMCopyButton } from './mdx/toc-base';
5
+ import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib/utils';
6
+ import { PortableClerkTOC, PortableClerkTOCTitle } from './mdx/toc-clerk-portable';
7
7
  import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
8
8
 
9
9
  export type FumaPageTocRenderMode =
@@ -99,6 +99,14 @@ export function createFumaPage({
99
99
  localePrefixAsNeeded = true,
100
100
  defaultLocale = 'en',
101
101
  }: FumaPageParams) {
102
+ const isLocalMdDebugEnabled = process.env.LOCAL_MD_DEBUG?.toLowerCase() === 'true';
103
+ const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now());
104
+ const durationMs = (startedAt: number) => Number((now() - startedAt).toFixed(1));
105
+ const logFumaPageDebug = (message: string, details?: Record<string, unknown>) => {
106
+ if (!isLocalMdDebugEnabled) return;
107
+ console.log(`[fuma-page] ${message}`, details ?? {});
108
+ };
109
+
102
110
  const getSource = async () => {
103
111
  if (typeof mdxContentSource === 'function') {
104
112
  return await mdxContentSource();
@@ -108,11 +116,28 @@ export function createFumaPage({
108
116
  };
109
117
 
110
118
  const Page = async function Page({ params }: { params: Promise<{ locale: string; slug?: string[] }> }) {
119
+ const pageStartedAt = now();
111
120
  const { slug, locale } = await params;
121
+ const sourceStartedAt = now();
112
122
  const source = await getSource();
123
+ logFumaPageDebug('page:source-ready', {
124
+ sourceKey,
125
+ locale,
126
+ slug,
127
+ durationMs: durationMs(sourceStartedAt),
128
+ });
129
+
130
+ const getPageStartedAt = now();
113
131
  const page = source.getPage(slug, locale);
132
+ logFumaPageDebug('page:get-page', {
133
+ sourceKey,
134
+ locale,
135
+ slug,
136
+ found: Boolean(page),
137
+ durationMs: durationMs(getPageStartedAt),
138
+ totalElapsedMs: durationMs(pageStartedAt),
139
+ });
114
140
  if (!page) {
115
- console.log('[FumaPage] missing page', { slug, locale, available: source.pageTree?.[locale]?.children?.map((c: any) => c.url) });
116
141
  return (
117
142
  <DocsPage
118
143
  full
@@ -143,7 +168,19 @@ export function createFumaPage({
143
168
 
144
169
  const content =
145
170
  typeof page.data.load === 'function'
146
- ? await page.data.load(getMDXComponents())
171
+ ? await (async () => {
172
+ const loadStartedAt = now();
173
+ const result = await page.data.load(getMDXComponents());
174
+ logFumaPageDebug('page:load', {
175
+ sourceKey,
176
+ locale,
177
+ slug,
178
+ pagePath: page.path,
179
+ durationMs: durationMs(loadStartedAt),
180
+ totalElapsedMs: durationMs(pageStartedAt),
181
+ });
182
+ return result;
183
+ })()
147
184
  : {
148
185
  body: await page.data.body({ components: getMDXComponents() }),
149
186
  toc: page.data.toc ?? [],
@@ -174,14 +211,30 @@ export function createFumaPage({
174
211
  );
175
212
  };
176
213
 
177
- function generateStaticParams() {
178
- return getSource().then((source) => source.generateParams('slug', 'locale'));
214
+ async function generateStaticParams() {
215
+ const startedAt = now();
216
+ const source = await getSource();
217
+ const params = source.generateParams('slug', 'locale');
218
+ logFumaPageDebug('generateStaticParams', {
219
+ sourceKey,
220
+ count: Array.isArray(params) ? params.length : undefined,
221
+ durationMs: durationMs(startedAt),
222
+ });
223
+ return params;
179
224
  }
180
225
 
181
226
  async function generateMetadata(props: { params: Promise<{ slug?: string[]; locale?: string }> }) {
227
+ const startedAt = now();
182
228
  const { slug, locale } = await props.params;
183
229
  const source = await getSource();
184
230
  const page = source.getPage(slug, locale);
231
+ logFumaPageDebug('generateMetadata:get-page', {
232
+ sourceKey,
233
+ locale,
234
+ slug,
235
+ found: Boolean(page),
236
+ durationMs: durationMs(startedAt),
237
+ });
185
238
  if (!page) {
186
239
  return {
187
240
  title: '404 - Page Not Found',
@@ -21,17 +21,10 @@ export type LLMCopyHandlerOptions = {
21
21
  */
22
22
  export async function LLMCopyHandler(options: LLMCopyHandlerOptions): Promise<{ text?: string; error?: string; status: number }> {
23
23
  const { sourceDir, dataSource, requestedPath, locale } = options;
24
-
25
- // log received parameters
26
- console.log(`[LLMCopy] Received, locale=${locale}, path=${requestedPath}`);
27
-
28
24
  const slug = requestedPath?.split('/') || [];
29
25
 
30
26
  try {
31
- console.log('[LLMCopy] Attempting to call getPage()');
32
27
  const page = dataSource.getPage(slug, locale);
33
- // console.log(page);
34
- console.log('[LLMCopy] Call to getPage() completed.');
35
28
 
36
29
  if (!page) {
37
30
  console.error(`[LLMCopy] Page or page data not found for locale=${locale}, path=${requestedPath}`);
@@ -46,19 +39,15 @@ export async function LLMCopyHandler(options: LLMCopyHandlerOptions): Promise<{
46
39
  const description = page.data?.description ?? page.description;
47
40
  const relativeMdxFilePath = page.path;
48
41
  const absoluteFilePath = nodePath.join(process.cwd(), sourceDir, relativeMdxFilePath);
49
- console.log(`[LLMCopy] Attempting to read MDX content from: ${absoluteFilePath}`);
50
42
 
51
43
  let mdxContent: string;
52
44
  try {
53
45
  mdxContent = fs.readFileSync(absoluteFilePath, 'utf-8');
54
- console.log(`[LLMCopy] Successfully read MDX content from: ${absoluteFilePath}`);
55
46
  } catch (readError: any) {
56
47
  console.error(`[LLMCopy] Failed to read file at: ${absoluteFilePath}. Error: ${readError.message}`);
57
48
  console.error('[LLMCopy] Read Error object details:', JSON.stringify(readError, Object.getOwnPropertyNames(readError), 2));
58
49
  // directory traversal debug logs
59
50
  try {
60
- console.log(`[LLMCopy] Current CWD: ${process.cwd()}`);
61
- console.log(`[LLMCopy] CWD contents: ${fs.readdirSync(process.cwd()).join(', ')}`);
62
51
  const srcPath = nodePath.join(process.cwd(), 'src');
63
52
  if (fs.existsSync(srcPath)) {
64
53
  console.log(`[LLMCopy] src dir contents: ${fs.readdirSync(srcPath).join(', ')}`);
@@ -2,7 +2,6 @@
2
2
 
3
3
  export * from './trophy-card';
4
4
  export * from './zia-card';
5
- export * from './gradient-button';
6
5
  export * from './toc-base';
7
6
  export * from './fuma-github-info';
8
7
  export * from './zia-file';
@@ -4,7 +4,7 @@ import { useEffect, useRef, useState } from 'react';
4
4
  import { cn } from '@windrun-huaiin/lib/utils';
5
5
  import { themeBgColor, themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
6
6
  import { SnakeLoadingFrame } from '../../main/snake-loading-frame';
7
- import { GradientButton } from './gradient-button';
7
+ import { GradientButton } from '../../main/buttons';
8
8
 
9
9
  interface SunoEmbedProps {
10
10
  src: string;
@@ -32,7 +32,6 @@ export function LLMCopyButton({ llmApiUrl, sourceKey }: LLMCopyButtonProps = {})
32
32
  if (sourceKey) {
33
33
  apiUrl += `&sourceKey=${encodeURIComponent(sourceKey)}`;
34
34
  }
35
- console.log('Fetching LLM content from:', apiUrl);
36
35
 
37
36
  let content: string;
38
37
  try {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { EditOnGitHub, LastUpdatedDate } from '@third-ui/fuma/mdx/toc-base';
3
+ import { EditOnGitHub, LastUpdatedDate } from './toc-base';
4
4
  import React from 'react';
5
5
 
6
6
  interface TocFooterProps {
@@ -19,4 +19,4 @@ export function TocFooterWrapper({ lastModified, editPath, githubBaseUrl, copyBu
19
19
  {showEdit && <EditOnGitHub url={`${githubBaseUrl}${editPath}`} />}
20
20
  </div>
21
21
  );
22
- }
22
+ }
@@ -2,7 +2,7 @@ import type { MDXComponents } from 'mdx/types';
2
2
  import { lazy } from 'react';
3
3
  import { TrophyCard } from '../../mdx/trophy-card';
4
4
  import { ZiaCard } from '../../mdx/zia-card';
5
- import { GradientButton } from '../../mdx/gradient-button';
5
+ import { GradientButton } from '../../../main/buttons';
6
6
  import { ZiaFile, ZiaFolder } from '../../mdx/zia-file';
7
7
  import { SunoEmbed } from '../../mdx/suno-embed';
8
8
 
@@ -0,0 +1,2 @@
1
+ export { LLMCopyHandler } from '../llm-copy-handler';
2
+ export type { LLMCopyHandlerOptions } from '../llm-copy-handler';