@windrun-huaiin/third-ui 23.0.0 → 23.1.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.
- package/README.md +152 -189
- package/dist/fuma/fuma-page-genarator.d.ts +3 -1
- package/dist/fuma/fuma-page-genarator.js +33 -6
- package/dist/fuma/fuma-page-genarator.mjs +34 -7
- package/dist/fuma/mdx/index.js +1 -0
- package/dist/fuma/mdx/index.mjs +1 -1
- package/dist/fuma/mdx/toc-clerk-portable.d.ts +1 -0
- package/dist/fuma/mdx/toc-clerk-portable.js +12 -9
- package/dist/fuma/mdx/toc-clerk-portable.mjs +11 -9
- package/dist/fuma/server/features/code.d.ts +1 -2
- package/dist/fuma/server/features/code.js +2 -3
- package/dist/fuma/server/features/code.mjs +2 -3
- package/dist/fuma/server/site-mdx-base.js +5 -1
- package/dist/fuma/server/site-mdx-base.mjs +5 -1
- package/dist/fuma/server/site-mdx-fallbacks.d.ts +7 -0
- package/dist/fuma/server/site-mdx-fallbacks.js +30 -0
- package/dist/fuma/server/site-mdx-fallbacks.mjs +29 -1
- package/package.json +4 -14
- package/src/fuma/fuma-page-genarator.tsx +80 -12
- package/src/fuma/mdx/toc-clerk-portable.tsx +65 -27
- package/src/fuma/server/features/code.tsx +5 -9
- package/src/fuma/server/site-mdx-base.tsx +6 -2
- package/src/fuma/server/site-mdx-fallbacks.tsx +50 -0
- package/src/fuma/server/optional-features.tsx +0 -6
- package/src/fuma/server/site-mdx-components.tsx +0 -46
- package/src/fuma/server/site-mdx-presets.ts +0 -131
package/README.md
CHANGED
|
@@ -1,222 +1,185 @@
|
|
|
1
1
|
# @windrun-huaiin/third-ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This README currently documents only the Fuma/MDX component design in `third-ui`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Other modules in this package, such as Clerk, main application UI, AI UI, fingerprint, SEO helpers, and shared layout utilities, are intentionally not covered here.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
## MDX Component Layer
|
|
8
|
+
|
|
9
|
+
The Fuma/MDX part of `third-ui` provides the rendering component map used by application MDX pages.
|
|
10
|
+
|
|
11
|
+
It is not responsible for reading files or compiling MDX. That belongs to `@windrun-huaiin/fumadocs-local-md`.
|
|
12
|
+
|
|
13
|
+
The split is:
|
|
14
|
+
|
|
15
|
+
- `local-md`: content source, frontmatter/meta parsing, Markdown/MDX compilation, render execution safety.
|
|
16
|
+
- `third-ui`: React components used when MDX is rendered.
|
|
17
|
+
- application: chooses which compiler features and renderer features are imported.
|
|
18
|
+
|
|
19
|
+
## Design Goals
|
|
20
|
+
|
|
21
|
+
- Keep the base MDX component map useful but small.
|
|
22
|
+
- Make heavyweight rendering features explicit imports.
|
|
23
|
+
- Avoid old aggregate component entries that import every renderer feature at module load time.
|
|
24
|
+
- Let application code be the capability declaration.
|
|
25
|
+
- Preserve a safe fallback path when disabled or unknown MDX components appear in content.
|
|
26
|
+
- Keep renderer-only capabilities separate from compiler-only capabilities.
|
|
27
|
+
|
|
28
|
+
## Current Entry Model
|
|
29
|
+
|
|
30
|
+
New applications should use the base site MDX entry:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
@windrun-huaiin/third-ui/fuma/server/site-mdx/base
|
|
9
34
|
```
|
|
10
35
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
│ └── app/
|
|
19
|
-
│ └── globals.css
|
|
20
|
-
├── node_modules/
|
|
21
|
-
│ ├── @windrun-huaiin/
|
|
22
|
-
│ │ ├── third-ui/
|
|
23
|
-
│ │ │ └── src/ # This is third-ui src
|
|
24
|
-
│ │ └── base-ui/
|
|
25
|
-
│ │ └── src/ # This is base-ui src
|
|
26
|
-
└── package.json
|
|
36
|
+
Optional renderer features live behind physical subpath entries:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
@windrun-huaiin/third-ui/fuma/server/site-mdx/features/code
|
|
40
|
+
@windrun-huaiin/third-ui/fuma/server/site-mdx/features/math
|
|
41
|
+
@windrun-huaiin/third-ui/fuma/server/site-mdx/features/mermaid
|
|
42
|
+
@windrun-huaiin/third-ui/fuma/server/site-mdx/features/type-table
|
|
27
43
|
```
|
|
28
44
|
|
|
29
|
-
|
|
45
|
+
The old aggregate entries have been removed. There is no supported `site-mdx-components` entry and no `optional-features` aggregate entry.
|
|
30
46
|
|
|
31
|
-
|
|
32
|
-
@import 'tailwindcss';
|
|
47
|
+
## Base Components
|
|
33
48
|
|
|
34
|
-
|
|
35
|
-
@source "../node_modules/@windrun-huaiin/base-ui/src/**/*.{js,ts,jsx,tsx}";
|
|
36
|
-
@source "./src/**/*.{js,ts,jsx,tsx}";
|
|
49
|
+
The base entry is the minimum component set for normal documentation content.
|
|
37
50
|
|
|
38
|
-
|
|
39
|
-
@import '@windrun-huaiin/third-ui/styles/third-ui.css';
|
|
40
|
-
```
|
|
51
|
+
It includes:
|
|
41
52
|
|
|
53
|
+
- Fuma UI basics: `Card`, `Cards`, `Callout`, `File`, `Folder`, `Files`, `Accordion`, `Accordions`, `Tab`, `Tabs`.
|
|
54
|
+
- Markdown element renderers: headings, links, blockquote, lists, table, inline code, pre, image, and related primitive tags.
|
|
55
|
+
- Site-level lightweight components: `SiteX`, `TrophyCard`, `ZiaCard`, `GradientButton`, `ZiaFile`, `ZiaFolder`, `SunoEmbed`.
|
|
56
|
+
- Image rendering integration with image fallback and CDN-related options.
|
|
57
|
+
- Feature-specific fallback components for disabled math, Mermaid, type table, and code-tab style components.
|
|
42
58
|
|
|
43
|
-
|
|
59
|
+
It intentionally does not include heavyweight renderer implementations such as Mermaid, KaTeX rendering, Fuma codeblock rendering, or type-table rendering.
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
## Renderer Feature Matrix
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
63
|
+
| Capability | Renderer Entry | Compiler Entry Required | Notes |
|
|
64
|
+
| --- | --- | --- | --- |
|
|
65
|
+
| `base` | `site-mdx/base` | `local-md/presets/fuma-docs/base` | Required for normal MDX rendering |
|
|
66
|
+
| `code` | `site-mdx/features/code` | `local-md/presets/fuma-docs/features/code` | Enables Fuma codeblock UI and built-in language icon mapping |
|
|
67
|
+
| `math` | `site-mdx/features/math` | `local-md/presets/fuma-docs/features/math` | Enables `MathBlock` and `InlineMath` rendering |
|
|
68
|
+
| `mermaid` | `site-mdx/features/mermaid` | Not required | Renderer-only component capability |
|
|
69
|
+
| `type-table` | `site-mdx/features/type-table` | Not required | Renderer-only component capability |
|
|
70
|
+
| `npm` | Not required | `local-md/presets/fuma-docs/features/npm` | Compiler-only content transform |
|
|
51
71
|
|
|
52
|
-
|
|
53
|
-
import { CTA, Features } from '@windrun-huaiin/third-ui/main';
|
|
72
|
+
This table is the main rule for application integration.
|
|
54
73
|
|
|
55
|
-
|
|
56
|
-
import { FumaPageGenerator, FumaBannerSuit } from '@windrun-huaiin/third-ui/fuma/server';
|
|
74
|
+
`code` and `math` need both compiler and renderer support. `npm` is compiler-only. `mermaid` and `type-table` are renderer-only.
|
|
57
75
|
|
|
58
|
-
|
|
59
|
-
import { TocFooterWrapper, PortableClerkTOC } from '@windrun-huaiin/third-ui/fuma/mdx';
|
|
60
|
-
```
|
|
76
|
+
## Bundle Cropping Rule
|
|
61
77
|
|
|
62
|
-
|
|
63
|
-
```tsx
|
|
64
|
-
// Clerk user component (need to pass in translations and configuration)
|
|
65
|
-
<ClerkUser
|
|
66
|
-
locale="zh"
|
|
67
|
-
clerkAuthInModal={true}
|
|
68
|
-
t={{ signIn: "Sign in" }}
|
|
69
|
-
t2={{ terms: "Terms of Service", privacy: "Privacy Policy" }}
|
|
70
|
-
/>
|
|
71
|
-
|
|
72
|
-
// Clerk organization component
|
|
73
|
-
<ClerkOrganization locale="zh" className="custom-class" />
|
|
74
|
-
|
|
75
|
-
// Main application components
|
|
76
|
-
<CTA />
|
|
77
|
-
<Features />
|
|
78
|
-
```
|
|
78
|
+
Renderer pruning is based on import boundaries.
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
1. **Modularization**: Grouped by functional domain, support import on demand
|
|
83
|
-
2. **Parameterization**: Remove hard-coded dependencies, pass configuration through props
|
|
84
|
-
3. **Type safety**: Full TypeScript support
|
|
85
|
-
4. **Path alias**: Use `@/` alias internally, keep code clean
|
|
86
|
-
|
|
87
|
-
## Dependencies
|
|
88
|
-
|
|
89
|
-
- `@windrun-huaiin/base-ui`: Base UI components
|
|
90
|
-
- `@windrun-huaiin/lib`: General utility library
|
|
91
|
-
- `@clerk/nextjs`: Clerk authentication
|
|
92
|
-
- `fumadocs-core`, `fumadocs-ui`: Fumadocs documentation
|
|
93
|
-
|
|
94
|
-
## Notes
|
|
95
|
-
|
|
96
|
-
- Components have removed direct `appConfig` dependencies, and configuration is passed through props
|
|
97
|
-
- Clerk components need to provide correct translations in the application layer
|
|
98
|
-
- Some components may require specific CSS animation classes (e.g. `animate-cta-gradient-wave`)
|
|
99
|
-
|
|
100
|
-
## Component List
|
|
101
|
-
|
|
102
|
-
### Clerk module
|
|
103
|
-
- `ClerkProviderClient` - Clerk authentication provider
|
|
104
|
-
- `ClerkUser` - User button component
|
|
105
|
-
- `ClerkOrganization` - Organization switcher component
|
|
106
|
-
|
|
107
|
-
### Main module
|
|
108
|
-
- `CTA` - Call-to-Action component
|
|
109
|
-
- `Features` - Feature showcase component
|
|
110
|
-
- `Footer` - Footer component
|
|
111
|
-
- `Gallery` - Image gallery component
|
|
112
|
-
- `GoToTop` - Go to top button
|
|
113
|
-
- `SEOContent` - SEO content component
|
|
114
|
-
- `Tips` - Tip component
|
|
115
|
-
|
|
116
|
-
### Fuma module
|
|
117
|
-
- `getMDXComponents` - MDX component configuration function
|
|
118
|
-
- `createMDXComponents` - MDX component factory function
|
|
119
|
-
- `TocFooter` - Table of contents footer component
|
|
120
|
-
- `FumaBannerSuit` - Fumadocs banner component
|
|
121
|
-
|
|
122
|
-
### Fuma MDX submodule
|
|
123
|
-
- `Mermaid` - Flowchart component
|
|
124
|
-
- `ImageZoom` - Image zoom component
|
|
125
|
-
- `TrophyCard` - Trophy card component
|
|
126
|
-
- `ImageGrid` - Image grid component
|
|
127
|
-
- `ZiaCard` - Zia card component
|
|
128
|
-
- `GradientButton` - Gradient button component
|
|
129
|
-
|
|
130
|
-
## Usage
|
|
131
|
-
|
|
132
|
-
### Clerk components
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
import { ClerkProviderClient, ClerkUser } from '@windrun-huaiin/third-ui/clerk';
|
|
136
|
-
|
|
137
|
-
// Use in layout.tsx
|
|
138
|
-
<ClerkProviderClient
|
|
139
|
-
signInUrl="/sign-in"
|
|
140
|
-
signUpUrl="/sign-up"
|
|
141
|
-
waitlistUrl="/waitlist"
|
|
142
|
-
>
|
|
143
|
-
{children}
|
|
144
|
-
</ClerkProviderClient>
|
|
145
|
-
|
|
146
|
-
// Use in navigation bar
|
|
147
|
-
<ClerkUser clerkAuthInModal={true} />
|
|
148
|
-
```
|
|
80
|
+
If an application does not import `site-mdx/features/mermaid`, Mermaid renderer code should not be pulled into the base renderer entry. The same rule applies to code, math, and type-table renderer features.
|
|
149
81
|
|
|
150
|
-
|
|
82
|
+
Do not reintroduce a file that imports all renderer features and then chooses one at runtime. That pattern defeats bundle cropping because static imports run before configuration checks.
|
|
151
83
|
|
|
152
|
-
|
|
153
|
-
import { CTA, Features, Footer } from '@windrun-huaiin/third-ui/main';
|
|
84
|
+
Correct model:
|
|
154
85
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
<Footer />
|
|
159
|
-
```
|
|
86
|
+
- base entry imports only base renderers and lightweight fallback components.
|
|
87
|
+
- each optional feature entry imports only its own renderer implementation.
|
|
88
|
+
- application code imports the feature entries it wants.
|
|
160
89
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
// Use TocFooter
|
|
180
|
-
<TocFooter
|
|
181
|
-
lastModified={page.data.date}
|
|
182
|
-
showCopy={true}
|
|
183
|
-
editPath="src/docs/your-file.mdx"
|
|
184
|
-
githubBaseUrl="https://github.com/your-org/your-repo/edit/main/"
|
|
185
|
-
/>
|
|
186
|
-
```
|
|
90
|
+
## Fallback Design
|
|
91
|
+
|
|
92
|
+
There are two fallback layers.
|
|
93
|
+
|
|
94
|
+
The first layer lives in `third-ui`.
|
|
95
|
+
|
|
96
|
+
It provides feature-aware fallbacks for known but disabled MDX capabilities:
|
|
97
|
+
|
|
98
|
+
- `MathBlock`
|
|
99
|
+
- `InlineMath`
|
|
100
|
+
- `Mermaid`
|
|
101
|
+
- `TypeTable`
|
|
102
|
+
- `CodeBlockTab`
|
|
103
|
+
- `CodeBlockTabs`
|
|
104
|
+
- `CodeBlockTabsList`
|
|
105
|
+
- `CodeBlockTabsTrigger`
|
|
106
|
+
|
|
107
|
+
These fallbacks render visible warning blocks instead of silently dropping content.
|
|
187
108
|
|
|
188
|
-
|
|
109
|
+
The second layer lives in `local-md`.
|
|
189
110
|
|
|
190
|
-
|
|
111
|
+
It is the final safety net for arbitrary unknown PascalCase components, such as:
|
|
191
112
|
|
|
192
113
|
```mdx
|
|
193
|
-
|
|
194
|
-
<Mermaid
|
|
195
|
-
chart="graph TD; A-->B"
|
|
196
|
-
title="My Diagram"
|
|
197
|
-
/>
|
|
198
|
-
|
|
199
|
-
<!-- Image grid, CDN URL automatically applied -->
|
|
200
|
-
<ImageGrid
|
|
201
|
-
type="url"
|
|
202
|
-
images={["image1.webp", "image2.webp"]}
|
|
203
|
-
altPrefix="example"
|
|
204
|
-
/>
|
|
205
|
-
|
|
206
|
-
<!-- Image zoom, placeholder image automatically applied -->
|
|
207
|
-
<ImageZoom src="/some-image.jpg" alt="Example" />
|
|
114
|
+
<CalloutXXX />
|
|
208
115
|
```
|
|
209
116
|
|
|
210
|
-
|
|
117
|
+
`local-md` detects missing component references from the compiled MDX output and injects generic fallback components before rendering. This prevents unknown MDX components from crashing the page.
|
|
118
|
+
|
|
119
|
+
The priority order is:
|
|
120
|
+
|
|
121
|
+
- application-provided MDX components
|
|
122
|
+
- enabled `third-ui` renderer feature components
|
|
123
|
+
- `third-ui` known disabled-feature fallbacks
|
|
124
|
+
- `local-md` generic unknown-component fallback
|
|
125
|
+
|
|
126
|
+
## Heavy Renderer Boundary
|
|
127
|
+
|
|
128
|
+
Heavy renderers are isolated under dedicated feature paths or heavy modules.
|
|
129
|
+
|
|
130
|
+
Examples:
|
|
131
|
+
|
|
132
|
+
- Mermaid rendering is behind the Mermaid feature entry.
|
|
133
|
+
- Math rendering uses the math feature entry and lazy heavy math renderer.
|
|
134
|
+
- Type table rendering is behind the type-table feature entry.
|
|
135
|
+
- Fuma codeblock rendering is behind the code feature entry.
|
|
136
|
+
|
|
137
|
+
The code renderer owns its programming-language icon map internally. Applications should not pass a global icon map into `createCodeMdxComponents()`.
|
|
138
|
+
|
|
139
|
+
This keeps `site-mdx/base` from becoming a hidden dependency sink.
|
|
140
|
+
|
|
141
|
+
## Application Rules
|
|
142
|
+
|
|
143
|
+
Applications should treat their MDX integration files as the capability declaration.
|
|
144
|
+
|
|
145
|
+
For `apps/ddaas`, the important files are:
|
|
146
|
+
|
|
147
|
+
- `src/lib/content-source.ts`: compiler/source capabilities.
|
|
148
|
+
- `src/components/mdx-components.tsx`: renderer/component capabilities.
|
|
149
|
+
|
|
150
|
+
When enabling a capability:
|
|
151
|
+
|
|
152
|
+
- import the compiler feature only if the capability needs compiler support.
|
|
153
|
+
- import the renderer feature only if the capability needs renderer support.
|
|
154
|
+
- add the imported feature to the matching `features` list.
|
|
155
|
+
- do not import unused feature entries “just in case”.
|
|
156
|
+
|
|
157
|
+
If an application creates its own MDX component and that component imports a heavy package directly, the package can still enter the bundle. That is expected and belongs to the application layer.
|
|
158
|
+
|
|
159
|
+
## Styling
|
|
160
|
+
|
|
161
|
+
MDX components assume the application includes the package styles and Tailwind source scanning for `third-ui`.
|
|
162
|
+
|
|
163
|
+
The exact global CSS setup is application-specific, but MDX pages need the same base styles used by the rest of the Fuma UI integration.
|
|
164
|
+
|
|
165
|
+
## Export Map
|
|
166
|
+
|
|
167
|
+
MDX-related exports currently relevant to this design:
|
|
211
168
|
|
|
169
|
+
| Export | Purpose |
|
|
170
|
+
| --- | --- |
|
|
171
|
+
| `./fuma/server/site-mdx/base` | Recommended base MDX component factory |
|
|
172
|
+
| `./fuma/server/site-mdx/features/code` | Optional code renderer components |
|
|
173
|
+
| `./fuma/server/site-mdx/features/math` | Optional math renderer components |
|
|
174
|
+
| `./fuma/server/site-mdx/features/mermaid` | Optional Mermaid renderer components |
|
|
175
|
+
| `./fuma/server/site-mdx/features/type-table` | Optional type-table renderer components |
|
|
176
|
+
| `./fuma/mdx` | Shared MDX building blocks used by pages and widgets |
|
|
177
|
+
| `./fuma/heavy` | Heavy renderer exports; avoid importing from app base paths unless intentionally needed |
|
|
178
|
+
| `./fuma/share` | Shared markdown component utilities |
|
|
212
179
|
|
|
213
|
-
##
|
|
180
|
+
## Non-Goals
|
|
214
181
|
|
|
215
|
-
-
|
|
216
|
-
-
|
|
217
|
-
-
|
|
218
|
-
-
|
|
219
|
-
- [Newspaper Template](https://newspaper-template.org/en)
|
|
220
|
-
- [breathing exercise](https://breathingexercise.net/en)
|
|
221
|
-
- [ai directory list](https://aidirectorylist.com/en)
|
|
222
|
-
- [reve image directory](https://reveimage.directory/en)
|
|
182
|
+
- This README does not document Clerk, main UI, AI UI, fingerprint, or SEO helpers.
|
|
183
|
+
- The base MDX entry should not become an all-features preset.
|
|
184
|
+
- Runtime feature flags should not be used as the primary pruning mechanism.
|
|
185
|
+
- Unknown MDX components should not crash the page.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactNode, ReactElement } from 'react';
|
|
2
2
|
import type { LLMCopyButtonProps, LLMCopyButton } from '@third-ui/fuma/mdx/toc-base';
|
|
3
|
+
export type FumaPageTocRenderMode = 'portable-clerk' | 'fumadocs-clerk' | 'fumadocs-normal';
|
|
3
4
|
interface FumaPageParams {
|
|
4
5
|
sourceKey: string;
|
|
5
6
|
mdxContentSource: any | (() => Promise<any>);
|
|
@@ -14,11 +15,12 @@ interface FumaPageParams {
|
|
|
14
15
|
supportedLocales?: string[];
|
|
15
16
|
showBreadcrumb?: boolean;
|
|
16
17
|
showTableOfContent?: boolean;
|
|
18
|
+
tocRenderMode?: FumaPageTocRenderMode;
|
|
17
19
|
showTableOfContentPopover?: boolean;
|
|
18
20
|
localePrefixAsNeeded?: boolean;
|
|
19
21
|
defaultLocale?: string;
|
|
20
22
|
}
|
|
21
|
-
export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales, showBreadcrumb, showTableOfContent, showTableOfContentPopover, localePrefixAsNeeded, defaultLocale, }: FumaPageParams): {
|
|
23
|
+
export declare function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales, showBreadcrumb, showTableOfContent, tocRenderMode, showTableOfContentPopover, localePrefixAsNeeded, defaultLocale, }: FumaPageParams): {
|
|
22
24
|
Page: ({ params }: {
|
|
23
25
|
params: Promise<{
|
|
24
26
|
locale: string;
|
|
@@ -7,8 +7,9 @@ var React = require('react');
|
|
|
7
7
|
var tocFooterWrapper = require('./mdx/toc-footer-wrapper.js');
|
|
8
8
|
var lib = require('@windrun-huaiin/lib');
|
|
9
9
|
var tocClerkPortable = require('./mdx/toc-clerk-portable.js');
|
|
10
|
+
var lib$1 = require('@windrun-huaiin/base-ui/lib');
|
|
10
11
|
|
|
11
|
-
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
12
|
+
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, tocRenderMode = 'portable-clerk', showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
12
13
|
const getSource = () => tslib.__awaiter(this, void 0, void 0, function* () {
|
|
13
14
|
if (typeof mdxContentSource === 'function') {
|
|
14
15
|
return yield mdxContentSource();
|
|
@@ -35,12 +36,14 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
35
36
|
body: yield page$1.data.body({ components: getMDXComponents() }),
|
|
36
37
|
toc: (_e = page$1.data.toc) !== null && _e !== void 0 ? _e : [],
|
|
37
38
|
};
|
|
38
|
-
return (jsxRuntime.jsxs(page.DocsPage, { breadcrumb: { enabled: showBreadcrumb }, tableOfContent: {
|
|
39
|
+
return (jsxRuntime.jsxs(page.DocsPage, { breadcrumb: { enabled: showBreadcrumb }, tableOfContent: resolveTableOfContentOptions({
|
|
39
40
|
enabled: showTableOfContent,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
tocRenderMode,
|
|
42
|
+
toc: content.toc,
|
|
43
|
+
footer: tocFooterElement,
|
|
44
|
+
}), tableOfContentPopover: {
|
|
45
|
+
enabled: showTableOfContentPopover && tocRenderMode !== 'portable-clerk',
|
|
46
|
+
style: tocRenderMode === 'fumadocs-clerk' ? 'clerk' : 'normal',
|
|
44
47
|
}, toc: content.toc, className: "max-sm:pb-16", children: [jsxRuntime.jsx(page.DocsTitle, { children: page$1.data.title }), jsxRuntime.jsx(page.DocsDescription, { className: "mb-2", children: page$1.data.description }), jsxRuntime.jsx(page.DocsBody, { className: "text-fd-foreground/80", children: content.body })] }));
|
|
45
48
|
});
|
|
46
49
|
};
|
|
@@ -87,5 +90,29 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
87
90
|
generateMetadata,
|
|
88
91
|
};
|
|
89
92
|
}
|
|
93
|
+
function resolveTableOfContentOptions({ enabled, tocRenderMode, toc, footer, }) {
|
|
94
|
+
if (tocRenderMode === 'portable-clerk') {
|
|
95
|
+
return {
|
|
96
|
+
enabled,
|
|
97
|
+
single: false,
|
|
98
|
+
component: (jsxRuntime.jsx(tocClerkPortable.PortableClerkTOC, { toc: toc, footer: footer })),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const themedTocProps = {
|
|
102
|
+
container: {
|
|
103
|
+
className: '[--color-fd-primary:var(--third-ui-toc-primary)] [--color-fd-primary-foreground:var(--third-ui-toc-primary-foreground)] [&_#toc-title]:hidden',
|
|
104
|
+
style: {
|
|
105
|
+
'--third-ui-toc-primary': lib$1.themeSvgIconColor,
|
|
106
|
+
'--third-ui-toc-primary-foreground': '#ffffff',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
header: jsxRuntime.jsx(tocClerkPortable.PortableClerkTOCTitle, {}),
|
|
110
|
+
footer,
|
|
111
|
+
};
|
|
112
|
+
if (tocRenderMode === 'fumadocs-clerk') {
|
|
113
|
+
return Object.assign({ enabled, single: false, style: 'clerk' }, themedTocProps);
|
|
114
|
+
}
|
|
115
|
+
return Object.assign({ enabled, single: false, style: 'normal' }, themedTocProps);
|
|
116
|
+
}
|
|
90
117
|
|
|
91
118
|
exports.createFumaPage = createFumaPage;
|
|
@@ -4,9 +4,10 @@ import { DocsPage, DocsTitle, DocsDescription, DocsBody } from 'fumadocs-ui/page
|
|
|
4
4
|
import { cloneElement } from 'react';
|
|
5
5
|
import { TocFooterWrapper } from './mdx/toc-footer-wrapper.mjs';
|
|
6
6
|
import { getAsNeededLocalizedUrl } from '@windrun-huaiin/lib';
|
|
7
|
-
import { PortableClerkTOC } from './mdx/toc-clerk-portable.mjs';
|
|
7
|
+
import { PortableClerkTOC, PortableClerkTOCTitle } from './mdx/toc-clerk-portable.mjs';
|
|
8
|
+
import { themeSvgIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
8
9
|
|
|
9
|
-
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
10
|
+
function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSourceDir, githubBaseUrl, copyButtonComponent, siteIcon, FallbackPage, supportedLocales = ['en'], showBreadcrumb = true, showTableOfContent = true, tocRenderMode = 'portable-clerk', showTableOfContentPopover = false, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
10
11
|
const getSource = () => __awaiter(this, void 0, void 0, function* () {
|
|
11
12
|
if (typeof mdxContentSource === 'function') {
|
|
12
13
|
return yield mdxContentSource();
|
|
@@ -33,12 +34,14 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
33
34
|
body: yield page.data.body({ components: getMDXComponents() }),
|
|
34
35
|
toc: (_e = page.data.toc) !== null && _e !== void 0 ? _e : [],
|
|
35
36
|
};
|
|
36
|
-
return (jsxs(DocsPage, { breadcrumb: { enabled: showBreadcrumb }, tableOfContent: {
|
|
37
|
+
return (jsxs(DocsPage, { breadcrumb: { enabled: showBreadcrumb }, tableOfContent: resolveTableOfContentOptions({
|
|
37
38
|
enabled: showTableOfContent,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
tocRenderMode,
|
|
40
|
+
toc: content.toc,
|
|
41
|
+
footer: tocFooterElement,
|
|
42
|
+
}), tableOfContentPopover: {
|
|
43
|
+
enabled: showTableOfContentPopover && tocRenderMode !== 'portable-clerk',
|
|
44
|
+
style: tocRenderMode === 'fumadocs-clerk' ? 'clerk' : 'normal',
|
|
42
45
|
}, toc: content.toc, className: "max-sm:pb-16", children: [jsx(DocsTitle, { children: page.data.title }), jsx(DocsDescription, { className: "mb-2", children: page.data.description }), jsx(DocsBody, { className: "text-fd-foreground/80", children: content.body })] }));
|
|
43
46
|
});
|
|
44
47
|
};
|
|
@@ -85,5 +88,29 @@ function createFumaPage({ sourceKey, mdxContentSource, getMDXComponents, mdxSour
|
|
|
85
88
|
generateMetadata,
|
|
86
89
|
};
|
|
87
90
|
}
|
|
91
|
+
function resolveTableOfContentOptions({ enabled, tocRenderMode, toc, footer, }) {
|
|
92
|
+
if (tocRenderMode === 'portable-clerk') {
|
|
93
|
+
return {
|
|
94
|
+
enabled,
|
|
95
|
+
single: false,
|
|
96
|
+
component: (jsx(PortableClerkTOC, { toc: toc, footer: footer })),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const themedTocProps = {
|
|
100
|
+
container: {
|
|
101
|
+
className: '[--color-fd-primary:var(--third-ui-toc-primary)] [--color-fd-primary-foreground:var(--third-ui-toc-primary-foreground)] [&_#toc-title]:hidden',
|
|
102
|
+
style: {
|
|
103
|
+
'--third-ui-toc-primary': themeSvgIconColor,
|
|
104
|
+
'--third-ui-toc-primary-foreground': '#ffffff',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
header: jsx(PortableClerkTOCTitle, {}),
|
|
108
|
+
footer,
|
|
109
|
+
};
|
|
110
|
+
if (tocRenderMode === 'fumadocs-clerk') {
|
|
111
|
+
return Object.assign({ enabled, single: false, style: 'clerk' }, themedTocProps);
|
|
112
|
+
}
|
|
113
|
+
return Object.assign({ enabled, single: false, style: 'normal' }, themedTocProps);
|
|
114
|
+
}
|
|
88
115
|
|
|
89
116
|
export { createFumaPage };
|
package/dist/fuma/mdx/index.js
CHANGED
|
@@ -28,5 +28,6 @@ exports.PortableClerkTOC = tocClerkPortable.PortableClerkTOC;
|
|
|
28
28
|
exports.PortableClerkTOCItems = tocClerkPortable.PortableClerkTOCItems;
|
|
29
29
|
exports.PortableClerkTOCPopover = tocClerkPortable.PortableClerkTOCPopover;
|
|
30
30
|
exports.PortableClerkTOCScrollArea = tocClerkPortable.PortableClerkTOCScrollArea;
|
|
31
|
+
exports.PortableClerkTOCTitle = tocClerkPortable.PortableClerkTOCTitle;
|
|
31
32
|
exports.Banner = banner.Banner;
|
|
32
33
|
exports.SunoEmbed = sunoEmbed.SunoEmbed;
|
package/dist/fuma/mdx/index.mjs
CHANGED
|
@@ -6,6 +6,6 @@ export { EditOnGitHub, LLMCopyButton, LastUpdatedDate } from './toc-base.mjs';
|
|
|
6
6
|
export { FumaGithubInfo } from './fuma-github-info.mjs';
|
|
7
7
|
export { ZiaFile, ZiaFolder } from './zia-file.mjs';
|
|
8
8
|
export { TocFooterWrapper } from './toc-footer-wrapper.mjs';
|
|
9
|
-
export { PortableClerkTOC, PortableClerkTOCItems, PortableClerkTOCPopover, PortableClerkTOCScrollArea } from './toc-clerk-portable.mjs';
|
|
9
|
+
export { PortableClerkTOC, PortableClerkTOCItems, PortableClerkTOCPopover, PortableClerkTOCScrollArea, PortableClerkTOCTitle } from './toc-clerk-portable.mjs';
|
|
10
10
|
export { Banner } from './banner.mjs';
|
|
11
11
|
export { SunoEmbed } from './suno-embed.mjs';
|
|
@@ -15,6 +15,7 @@ type PortableClerkTOCProps = {
|
|
|
15
15
|
};
|
|
16
16
|
export declare function PortableClerkTOC({ toc, header, footer, title, emptyLabel, className, }: PortableClerkTOCProps): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export declare function PortableClerkTOCPopover({ toc, header, footer, emptyLabel, }: Omit<PortableClerkTOCProps, 'title' | 'className'>): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare function PortableClerkTOCTitle({ className, ...props }: ComponentProps<'h3'>): import("react/jsx-runtime").JSX.Element;
|
|
18
19
|
export declare function PortableClerkTOCScrollArea({ ref, className, ...props }: ComponentProps<'div'>): import("react/jsx-runtime").JSX.Element;
|
|
19
20
|
export declare function PortableClerkTOCItems({ toc, emptyLabel, ref, className, ...props }: ComponentProps<'div'> & {
|
|
20
21
|
toc: TOCItemType[];
|
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
var tslib = require('tslib');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var Primitive = require('fumadocs-core/toc');
|
|
7
|
-
var
|
|
7
|
+
var i18n = require('fumadocs-ui/contexts/i18n');
|
|
8
|
+
var collapsible = require('fumadocs-ui/components/ui/collapsible');
|
|
8
9
|
var React = require('react');
|
|
9
10
|
var lib = require('@windrun-huaiin/base-ui/lib');
|
|
11
|
+
var icons = require('@windrun-huaiin/base-ui/icons');
|
|
10
12
|
|
|
11
13
|
function _interopNamespaceDefault(e) {
|
|
12
14
|
var n = Object.create(null);
|
|
@@ -49,15 +51,15 @@ const CLERK_STEP_BADGE_RADIUS = 7;
|
|
|
49
51
|
const CLERK_DEPTH_GROUP_LINE_OFFSETS = [6, 18, 30, 42];
|
|
50
52
|
// Max number of characters rendered for a TOC label before trimming with ellipsis.
|
|
51
53
|
const CLERK_MAX_LABEL_LENGTH = 44;
|
|
52
|
-
function PortableClerkTOC({ toc
|
|
53
|
-
return (jsxRuntime.
|
|
54
|
-
children: jsxRuntime.jsx(PortableClerkTOCItems, { toc: toc$1, emptyLabel: emptyLabel }),
|
|
55
|
-
} }));
|
|
54
|
+
function PortableClerkTOC({ toc, header, footer, title, emptyLabel = 'No headings', className, }) {
|
|
55
|
+
return (jsxRuntime.jsxs("div", { id: "nd-toc", className: cn('sticky top-(--fd-docs-row-1) h-[calc(var(--fd-docs-height)-var(--fd-docs-row-1))] flex flex-col [grid-area:toc] w-(--fd-toc-width) pt-12 pe-4 pb-2 max-xl:hidden', className), children: [header, title !== null && title !== void 0 ? title : jsxRuntime.jsx(PortableClerkTOCTitle, {}), jsxRuntime.jsx(PortableClerkTOCScrollArea, { children: jsxRuntime.jsx(PortableClerkTOCItems, { toc: toc, emptyLabel: emptyLabel }) }), footer] }));
|
|
56
56
|
}
|
|
57
|
-
function PortableClerkTOCPopover({ toc
|
|
58
|
-
return (jsxRuntime.jsx(
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
function PortableClerkTOCPopover({ toc, header, footer, emptyLabel = 'No headings', }) {
|
|
58
|
+
return (jsxRuntime.jsx(collapsible.Collapsible, { "data-toc-popover": "", className: "sticky top-(--fd-docs-row-2) z-10 [grid-area:toc-popover] h-(--fd-toc-popover-height) xl:hidden max-xl:layout:[--fd-toc-popover-height:--spacing(10)]", children: jsxRuntime.jsxs("header", { className: "border-b bg-fd-background/80 backdrop-blur-sm transition-colors", children: [jsxRuntime.jsxs(collapsible.CollapsibleTrigger, { "data-toc-popover-trigger": "", className: "flex w-full h-10 items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:size-4 md:px-6", children: [jsxRuntime.jsx(icons.NotepadTextIcon, { className: "shrink-0" }), jsxRuntime.jsx("span", { className: "flex-1 truncate", children: jsxRuntime.jsx(i18n.I18nLabel, { label: "toc" }) }), jsxRuntime.jsx(icons.ChevronDownIcon, { className: "shrink-0 transition-transform mx-0.5" })] }), jsxRuntime.jsx(collapsible.CollapsibleContent, { "data-toc-popover-content": "", children: jsxRuntime.jsxs("div", { className: "flex max-h-[50vh] flex-col px-4 md:px-6", children: [header, jsxRuntime.jsx(PortableClerkTOCScrollArea, { children: jsxRuntime.jsx(PortableClerkTOCItems, { toc: toc, emptyLabel: emptyLabel }) }), footer] }) })] }) }));
|
|
59
|
+
}
|
|
60
|
+
function PortableClerkTOCTitle(_a) {
|
|
61
|
+
var { className } = _a, props = tslib.__rest(_a, ["className"]);
|
|
62
|
+
return (jsxRuntime.jsxs("h3", Object.assign({ id: "toc-title", className: cn('inline-flex items-center gap-1.5 text-sm text-fd-muted-foreground', className) }, props, { children: [jsxRuntime.jsx(icons.NotepadTextIcon, { className: cn('size-4', lib.themeIconColor) }), jsxRuntime.jsx(i18n.I18nLabel, { label: "toc" })] })));
|
|
61
63
|
}
|
|
62
64
|
function PortableClerkTOCScrollArea(_a) {
|
|
63
65
|
var { ref, className } = _a, props = tslib.__rest(_a, ["ref", "className"]);
|
|
@@ -390,3 +392,4 @@ exports.PortableClerkTOC = PortableClerkTOC;
|
|
|
390
392
|
exports.PortableClerkTOCItems = PortableClerkTOCItems;
|
|
391
393
|
exports.PortableClerkTOCPopover = PortableClerkTOCPopover;
|
|
392
394
|
exports.PortableClerkTOCScrollArea = PortableClerkTOCScrollArea;
|
|
395
|
+
exports.PortableClerkTOCTitle = PortableClerkTOCTitle;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { __rest } from 'tslib';
|
|
3
|
-
import {
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import * as Primitive from 'fumadocs-core/toc';
|
|
5
|
-
import {
|
|
5
|
+
import { I18nLabel } from 'fumadocs-ui/contexts/i18n';
|
|
6
|
+
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from 'fumadocs-ui/components/ui/collapsible';
|
|
6
7
|
import { useRef, useState, useMemo, useLayoutEffect, useEffect } from 'react';
|
|
7
8
|
import { themeSvgIconColor, themeIconColor } from '@windrun-huaiin/base-ui/lib';
|
|
9
|
+
import { NotepadTextIcon, ChevronDownIcon } from '@windrun-huaiin/base-ui/icons';
|
|
8
10
|
|
|
9
11
|
// Base stroke width for both the inactive rail and the active highlight path.
|
|
10
12
|
const CLERK_PATH_STROKE_WIDTH = 1;
|
|
@@ -29,14 +31,14 @@ const CLERK_DEPTH_GROUP_LINE_OFFSETS = [6, 18, 30, 42];
|
|
|
29
31
|
// Max number of characters rendered for a TOC label before trimming with ellipsis.
|
|
30
32
|
const CLERK_MAX_LABEL_LENGTH = 44;
|
|
31
33
|
function PortableClerkTOC({ toc, header, footer, title, emptyLabel = 'No headings', className, }) {
|
|
32
|
-
return (
|
|
33
|
-
children: jsx(PortableClerkTOCItems, { toc: toc, emptyLabel: emptyLabel }),
|
|
34
|
-
} }));
|
|
34
|
+
return (jsxs("div", { id: "nd-toc", className: cn('sticky top-(--fd-docs-row-1) h-[calc(var(--fd-docs-height)-var(--fd-docs-row-1))] flex flex-col [grid-area:toc] w-(--fd-toc-width) pt-12 pe-4 pb-2 max-xl:hidden', className), children: [header, title !== null && title !== void 0 ? title : jsx(PortableClerkTOCTitle, {}), jsx(PortableClerkTOCScrollArea, { children: jsx(PortableClerkTOCItems, { toc: toc, emptyLabel: emptyLabel }) }), footer] }));
|
|
35
35
|
}
|
|
36
36
|
function PortableClerkTOCPopover({ toc, header, footer, emptyLabel = 'No headings', }) {
|
|
37
|
-
return (jsx(
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
return (jsx(Collapsible, { "data-toc-popover": "", className: "sticky top-(--fd-docs-row-2) z-10 [grid-area:toc-popover] h-(--fd-toc-popover-height) xl:hidden max-xl:layout:[--fd-toc-popover-height:--spacing(10)]", children: jsxs("header", { className: "border-b bg-fd-background/80 backdrop-blur-sm transition-colors", children: [jsxs(CollapsibleTrigger, { "data-toc-popover-trigger": "", className: "flex w-full h-10 items-center text-sm text-fd-muted-foreground gap-2.5 px-4 py-2.5 text-start focus-visible:outline-none [&_svg]:size-4 md:px-6", children: [jsx(NotepadTextIcon, { className: "shrink-0" }), jsx("span", { className: "flex-1 truncate", children: jsx(I18nLabel, { label: "toc" }) }), jsx(ChevronDownIcon, { className: "shrink-0 transition-transform mx-0.5" })] }), jsx(CollapsibleContent, { "data-toc-popover-content": "", children: jsxs("div", { className: "flex max-h-[50vh] flex-col px-4 md:px-6", children: [header, jsx(PortableClerkTOCScrollArea, { children: jsx(PortableClerkTOCItems, { toc: toc, emptyLabel: emptyLabel }) }), footer] }) })] }) }));
|
|
38
|
+
}
|
|
39
|
+
function PortableClerkTOCTitle(_a) {
|
|
40
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
41
|
+
return (jsxs("h3", Object.assign({ id: "toc-title", className: cn('inline-flex items-center gap-1.5 text-sm text-fd-muted-foreground', className) }, props, { children: [jsx(NotepadTextIcon, { className: cn('size-4', themeIconColor) }), jsx(I18nLabel, { label: "toc" })] })));
|
|
40
42
|
}
|
|
41
43
|
function PortableClerkTOCScrollArea(_a) {
|
|
42
44
|
var { ref, className } = _a, props = __rest(_a, ["ref", "className"]);
|
|
@@ -365,4 +367,4 @@ function mergeRefs(...refs) {
|
|
|
365
367
|
};
|
|
366
368
|
}
|
|
367
369
|
|
|
368
|
-
export { PortableClerkTOC, PortableClerkTOCItems, PortableClerkTOCPopover, PortableClerkTOCScrollArea };
|
|
370
|
+
export { PortableClerkTOC, PortableClerkTOCItems, PortableClerkTOCPopover, PortableClerkTOCScrollArea, PortableClerkTOCTitle };
|