@windrun-huaiin/third-ui 21.0.0 → 22.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.
- package/dist/ai/ai-markdown.js +1 -1
- package/dist/ai/ai-markdown.mjs +1 -1
- package/dist/clerk/clerk-page-context-generator.js +3 -2
- package/dist/clerk/clerk-page-context-generator.mjs +3 -2
- package/dist/clerk/clerk-page-generator.js +4 -3
- package/dist/clerk/clerk-page-generator.mjs +4 -3
- package/dist/fuma/base/custom-header.d.ts +1 -1
- package/dist/fuma/base/custom-header.js +38 -36
- package/dist/fuma/base/custom-header.mjs +25 -23
- package/dist/fuma/base/custom-home-layout.d.ts +1 -1
- package/dist/fuma/base/custom-home-layout.js +1 -1
- package/dist/fuma/base/custom-home-layout.mjs +1 -1
- package/dist/fuma/base/header-theme-switch.d.ts +5 -0
- package/dist/fuma/base/header-theme-switch.js +42 -0
- package/dist/fuma/base/header-theme-switch.mjs +40 -0
- package/dist/fuma/base/index.d.ts +1 -0
- package/dist/fuma/base/index.js +7 -0
- package/dist/fuma/base/index.mjs +1 -0
- package/dist/fuma/base/site-layout.d.ts +116 -0
- package/dist/fuma/base/site-layout.js +72 -0
- package/dist/fuma/base/site-layout.mjs +65 -0
- package/dist/fuma/fuma-banner-suit.js +9 -6
- package/dist/fuma/fuma-banner-suit.mjs +10 -7
- package/dist/fuma/fuma-page-genarator.js +1 -1
- package/dist/fuma/fuma-page-genarator.mjs +1 -1
- package/dist/fuma/heavy/image-grid.d.ts +6 -0
- package/dist/fuma/heavy/image-grid.js +17 -0
- package/dist/fuma/heavy/image-grid.mjs +15 -0
- package/dist/fuma/heavy/image-zoom.d.ts +22 -0
- package/dist/fuma/heavy/image-zoom.js +39 -0
- package/dist/fuma/heavy/image-zoom.mjs +37 -0
- package/dist/fuma/heavy/index.d.ts +4 -0
- package/dist/fuma/heavy/index.js +15 -0
- package/dist/fuma/heavy/index.mjs +5 -0
- package/dist/fuma/heavy/math.d.ts +17 -0
- package/dist/fuma/heavy/math.js +60 -0
- package/dist/fuma/heavy/math.mjs +57 -0
- package/dist/fuma/heavy/mermaid.d.ts +13 -0
- package/dist/fuma/heavy/mermaid.js +360 -0
- package/dist/fuma/heavy/mermaid.mjs +358 -0
- package/dist/fuma/mdx/features.d.ts +8 -0
- package/dist/fuma/mdx/features.js +92 -0
- package/dist/fuma/mdx/features.mjs +85 -0
- package/dist/fuma/mdx/index.d.ts +0 -5
- package/dist/fuma/mdx/index.js +0 -11
- package/dist/fuma/mdx/index.mjs +0 -5
- package/dist/fuma/mdx/markdown-component-map.js +7 -1
- package/dist/fuma/mdx/markdown-component-map.mjs +7 -1
- package/dist/fuma/mdx/site-mdx-components.d.ts +13 -0
- package/dist/fuma/mdx/site-mdx-components.js +19 -0
- package/dist/fuma/mdx/site-mdx-components.mjs +17 -0
- package/dist/fuma/mdx/site-mdx-presets.d.ts +13 -0
- package/dist/fuma/mdx/site-mdx-presets.js +49 -0
- package/dist/fuma/mdx/site-mdx-presets.mjs +45 -0
- package/dist/fuma/mdx/toc-clerk-portable.js +9 -5
- package/dist/fuma/mdx/toc-clerk-portable.mjs +8 -4
- package/dist/fuma/mdx/zia-file.js +1 -0
- package/dist/fuma/mdx/zia-file.mjs +1 -0
- package/dist/fuma/server/optional-features.d.ts +8 -0
- package/dist/fuma/server/optional-features.js +111 -0
- package/dist/fuma/server/optional-features.mjs +104 -0
- package/dist/fuma/server/site-mdx-components.d.ts +13 -0
- package/dist/fuma/server/site-mdx-components.js +19 -0
- package/dist/fuma/server/site-mdx-components.mjs +17 -0
- package/dist/fuma/server/site-mdx-presets.d.ts +194 -0
- package/dist/fuma/server/site-mdx-presets.js +46 -0
- package/dist/fuma/server/site-mdx-presets.mjs +42 -0
- package/dist/fuma/share/index.d.ts +1 -0
- package/dist/fuma/share/index.js +7 -0
- package/dist/fuma/share/index.mjs +1 -0
- package/dist/fuma/share/markdown-component-map.d.ts +3 -0
- package/dist/fuma/share/markdown-component-map.js +79 -0
- package/dist/fuma/share/markdown-component-map.mjs +77 -0
- package/dist/lib/fuma-schema-check-util.js +19 -5
- package/dist/lib/fuma-schema-check-util.mjs +19 -5
- package/dist/lib/seo-metadata.d.ts +10 -0
- package/dist/main/x-button.js +2 -2
- package/dist/main/x-button.mjs +2 -2
- package/package.json +31 -8
- package/src/ai/ai-markdown.tsx +1 -1
- package/src/clerk/clerk-page-context-generator.tsx +6 -3
- package/src/clerk/clerk-page-generator.tsx +7 -4
- package/src/fuma/base/custom-header.tsx +32 -35
- package/src/fuma/base/custom-home-layout.tsx +2 -2
- package/src/fuma/base/header-theme-switch.tsx +88 -0
- package/src/fuma/base/index.ts +1 -0
- package/src/fuma/base/site-layout.tsx +289 -0
- package/src/fuma/fuma-banner-suit.tsx +30 -28
- package/src/fuma/fuma-page-genarator.tsx +1 -1
- package/src/fuma/{mdx → heavy}/image-grid.tsx +1 -1
- package/src/fuma/heavy/index.ts +7 -0
- package/src/fuma/mdx/index.ts +0 -5
- package/src/fuma/mdx/toc-clerk-portable.tsx +27 -24
- package/src/fuma/mdx/zia-file.tsx +3 -1
- package/src/fuma/server/optional-features.tsx +168 -0
- package/src/fuma/server/site-mdx-components.tsx +48 -0
- package/src/fuma/server/site-mdx-presets.ts +80 -0
- package/src/fuma/share/index.ts +1 -0
- package/src/fuma/{mdx → share}/markdown-component-map.tsx +1 -1
- package/src/lib/fuma-schema-check-util.ts +22 -6
- package/src/lib/seo-metadata.ts +47 -0
- package/src/main/x-button.tsx +2 -2
- package/src/styles/fuma.css +3 -7
- package/src/styles/third-ui.css +0 -4
- /package/src/fuma/{mdx → heavy}/image-zoom.tsx +0 -0
- /package/src/fuma/{mdx → heavy}/math.tsx +0 -0
- /package/src/fuma/{mdx → heavy}/mermaid.tsx +0 -0
|
@@ -5,28 +5,24 @@ import {
|
|
|
5
5
|
type CSSProperties,
|
|
6
6
|
Fragment,
|
|
7
7
|
type ReactNode,
|
|
8
|
+
type FC,
|
|
8
9
|
useMemo,
|
|
9
10
|
useState,
|
|
10
11
|
} from 'react';
|
|
11
12
|
import { cva } from 'class-variance-authority';
|
|
12
13
|
import { ChevronDownIcon, LanguagesIcon } from '@windrun-huaiin/base-ui/icons';
|
|
14
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
13
15
|
import Link from 'fumadocs-core/link';
|
|
14
16
|
import { HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
|
15
17
|
import {
|
|
16
|
-
|
|
18
|
+
LinkItem,
|
|
17
19
|
type LinkItemType,
|
|
18
|
-
|
|
20
|
+
resolveLinkItems,
|
|
19
21
|
} from 'fumadocs-ui/layouts/shared';
|
|
20
|
-
import { cn } from 'fumadocs-ui/utils/cn';
|
|
21
22
|
import {
|
|
22
|
-
LargeSearchToggle,
|
|
23
|
-
SearchToggle,
|
|
24
|
-
} from 'fumadocs-ui/components/layout/search-toggle';
|
|
25
|
-
import { ThemeToggle } from 'fumadocs-ui/components/layout/theme-toggle';
|
|
26
|
-
import {
|
|
27
|
-
LanguageToggleText,
|
|
28
23
|
type LanguageSelectProps,
|
|
29
|
-
|
|
24
|
+
LanguageSelectText,
|
|
25
|
+
} from 'fumadocs-ui/layouts/shared/slots/language-select';
|
|
30
26
|
import {
|
|
31
27
|
NavigationMenu,
|
|
32
28
|
NavigationMenuContent,
|
|
@@ -38,12 +34,12 @@ import {
|
|
|
38
34
|
} from 'fumadocs-ui/components/ui/navigation-menu';
|
|
39
35
|
import { Popover, PopoverContent, PopoverTrigger } from 'fumadocs-ui/components/ui/popover';
|
|
40
36
|
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
41
|
-
import { useNav } from 'fumadocs-ui/contexts/layout';
|
|
42
37
|
import { useI18n } from 'fumadocs-ui/contexts/i18n';
|
|
38
|
+
import { HeaderThemeSwitch } from './header-theme-switch';
|
|
43
39
|
|
|
44
40
|
export type NavbarCSSVars = CSSProperties & {
|
|
45
41
|
'--fd-banner-height'?: string;
|
|
46
|
-
'--fd-
|
|
42
|
+
'--fd-header-height'?: string;
|
|
47
43
|
'--fd-nav-max-width'?: string;
|
|
48
44
|
};
|
|
49
45
|
|
|
@@ -143,7 +139,7 @@ export function CustomHomeHeader({
|
|
|
143
139
|
mobileMenuActionsOrder = DEFAULT_MOBILE_MENU_ACTIONS,
|
|
144
140
|
}: CustomHomeHeaderProps) {
|
|
145
141
|
const finalLinks = useMemo(
|
|
146
|
-
() =>
|
|
142
|
+
() => resolveLinkItems({ links, githubUrl }),
|
|
147
143
|
[links, githubUrl],
|
|
148
144
|
);
|
|
149
145
|
|
|
@@ -172,16 +168,11 @@ export function CustomHomeHeader({
|
|
|
172
168
|
const desktopActionNodes: Record<DesktopAction, ReactNode> = {
|
|
173
169
|
search:
|
|
174
170
|
searchToggle.enabled !== false
|
|
175
|
-
? searchToggle.components?.lg ??
|
|
176
|
-
<LargeSearchToggle
|
|
177
|
-
className="w-full rounded-full ps-2.5 max-w-[240px]"
|
|
178
|
-
hideIfDisabled
|
|
179
|
-
/>
|
|
180
|
-
)
|
|
171
|
+
? searchToggle.components?.lg ?? null
|
|
181
172
|
: null,
|
|
182
173
|
theme:
|
|
183
174
|
themeSwitch.enabled !== false
|
|
184
|
-
? themeSwitch.component ?? <
|
|
175
|
+
? themeSwitch.component ?? <HeaderThemeSwitch mode={themeSwitch?.mode} />
|
|
185
176
|
: null,
|
|
186
177
|
i18n: i18n ? (
|
|
187
178
|
<CompactLanguageToggle>
|
|
@@ -238,13 +229,13 @@ export function CustomHomeHeader({
|
|
|
238
229
|
i18n: i18n ? (
|
|
239
230
|
<CompactLanguageToggle>
|
|
240
231
|
<LanguagesIcon className="size-5" />
|
|
241
|
-
<
|
|
232
|
+
<LanguageSelectText />
|
|
242
233
|
<ChevronDownIcon className="size-3 text-fd-muted-foreground" />
|
|
243
234
|
</CompactLanguageToggle>
|
|
244
235
|
) : null,
|
|
245
236
|
theme:
|
|
246
237
|
themeSwitch.enabled !== false
|
|
247
|
-
? themeSwitch.component ?? <
|
|
238
|
+
? themeSwitch.component ?? <HeaderThemeSwitch mode={themeSwitch?.mode} />
|
|
248
239
|
: null,
|
|
249
240
|
};
|
|
250
241
|
const shouldRenderMobileUtilities = mobileMenuActionsOrder.some(
|
|
@@ -305,9 +296,7 @@ export function CustomHomeHeader({
|
|
|
305
296
|
) : null;
|
|
306
297
|
const mobileSearchNode =
|
|
307
298
|
searchToggle.enabled !== false
|
|
308
|
-
? searchToggle.components?.sm ??
|
|
309
|
-
<SearchToggle className="p-2" hideIfDisabled />
|
|
310
|
-
)
|
|
299
|
+
? searchToggle.components?.sm ?? null
|
|
311
300
|
: null;
|
|
312
301
|
const mobileBarNodes: Record<MobileBarAction, ReactNode> = {
|
|
313
302
|
pinned: mobilePinnedNode,
|
|
@@ -329,7 +318,7 @@ export function CustomHomeHeader({
|
|
|
329
318
|
href={nav.url ?? '/'}
|
|
330
319
|
className="inline-flex items-center gap-2.5 font-semibold"
|
|
331
320
|
>
|
|
332
|
-
{nav.title}
|
|
321
|
+
{renderNavTitle(nav.title)}
|
|
333
322
|
</Link>
|
|
334
323
|
{nav.children}
|
|
335
324
|
<ul className="flex flex-row items-center gap-2 px-6 max-sm:hidden">
|
|
@@ -379,11 +368,11 @@ function CustomNavbar({
|
|
|
379
368
|
...props
|
|
380
369
|
}: CustomNavbarProps) {
|
|
381
370
|
const [value, setValue] = useState('');
|
|
382
|
-
const
|
|
371
|
+
const isTransparent = false;
|
|
383
372
|
|
|
384
373
|
const cssVars: NavbarCSSVars = {
|
|
385
374
|
'--fd-banner-height': `${bannerHeight}rem`,
|
|
386
|
-
'--fd-
|
|
375
|
+
'--fd-header-height': `${headerHeight}rem`,
|
|
387
376
|
...(maxContentWidth
|
|
388
377
|
? {
|
|
389
378
|
'--fd-nav-max-width':
|
|
@@ -401,9 +390,8 @@ function CustomNavbar({
|
|
|
401
390
|
: maxContentWidth
|
|
402
391
|
: '88rem';
|
|
403
392
|
const minNavWidth = '15rem';
|
|
404
|
-
const floatingWidth = `clamp(${minNavWidth}, 100vw, ${resolvedMaxWidth})`;
|
|
405
393
|
const widthStyle = floating
|
|
406
|
-
? { width:
|
|
394
|
+
? { width: `clamp(${minNavWidth}, 100vw, ${resolvedMaxWidth})` }
|
|
407
395
|
: { width: '100%', maxWidth: resolvedMaxWidth, minWidth: minNavWidth };
|
|
408
396
|
const headerStyle = {
|
|
409
397
|
...cssVars,
|
|
@@ -431,7 +419,7 @@ function CustomNavbar({
|
|
|
431
419
|
>
|
|
432
420
|
<NavigationMenuList
|
|
433
421
|
className="flex w-full items-center gap-4 px-1"
|
|
434
|
-
style={{ height: 'var(--fd-
|
|
422
|
+
style={{ height: 'var(--fd-header-height)' }}
|
|
435
423
|
asChild
|
|
436
424
|
>
|
|
437
425
|
<nav>{props.children}</nav>
|
|
@@ -535,7 +523,7 @@ function NavbarLinkItem({
|
|
|
535
523
|
return (
|
|
536
524
|
<NavigationMenuItem>
|
|
537
525
|
<NavigationMenuLink asChild>
|
|
538
|
-
<
|
|
526
|
+
<LinkItem
|
|
539
527
|
item={item}
|
|
540
528
|
aria-label={item.type === 'icon' ? item.label : undefined}
|
|
541
529
|
{...props}
|
|
@@ -545,7 +533,7 @@ function NavbarLinkItem({
|
|
|
545
533
|
)}
|
|
546
534
|
>
|
|
547
535
|
{item.type === 'icon' ? item.icon : item.text}
|
|
548
|
-
</
|
|
536
|
+
</LinkItem>
|
|
549
537
|
</NavigationMenuLink>
|
|
550
538
|
</NavigationMenuItem>
|
|
551
539
|
);
|
|
@@ -593,7 +581,7 @@ function MenuLinkItem({
|
|
|
593
581
|
|
|
594
582
|
return (
|
|
595
583
|
<NavigationMenuLink asChild>
|
|
596
|
-
<
|
|
584
|
+
<LinkItem
|
|
597
585
|
item={item}
|
|
598
586
|
className={cn(
|
|
599
587
|
{
|
|
@@ -613,7 +601,7 @@ function MenuLinkItem({
|
|
|
613
601
|
>
|
|
614
602
|
{item.icon}
|
|
615
603
|
{item.type === 'icon' ? undefined : item.text}
|
|
616
|
-
</
|
|
604
|
+
</LinkItem>
|
|
617
605
|
</NavigationMenuLink>
|
|
618
606
|
);
|
|
619
607
|
}
|
|
@@ -719,3 +707,12 @@ function isSecondary(item: LinkItemType): boolean {
|
|
|
719
707
|
function isMobilePinned(item: LinkItemType): boolean {
|
|
720
708
|
return Boolean((item as { mobilePinned?: boolean }).mobilePinned);
|
|
721
709
|
}
|
|
710
|
+
|
|
711
|
+
function renderNavTitle(title: unknown): ReactNode {
|
|
712
|
+
if (typeof title === 'function') {
|
|
713
|
+
const TitleComponent = title as FC<ComponentProps<'a'>>;
|
|
714
|
+
return <TitleComponent />;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return (title as ReactNode | null | undefined) ?? null;
|
|
718
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import { HomeLayout, type HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
|
3
|
-
import { type LinkItemType } from 'fumadocs-ui/layouts/
|
|
3
|
+
import { type LinkItemType } from 'fumadocs-ui/layouts/shared';
|
|
4
4
|
import { FumaBannerSuit } from '@third-ui/fuma/fuma-banner-suit';
|
|
5
5
|
import { Footer } from '@third-ui/main/footer';
|
|
6
6
|
import { GoToTop } from '@third-ui/main/go-to-top';
|
|
@@ -129,7 +129,7 @@ export function CustomHomeLayout({
|
|
|
129
129
|
|
|
130
130
|
const layoutStyle: NavbarCSSVars = {
|
|
131
131
|
'--fd-banner-height': `${resolvedBannerHeight}rem`,
|
|
132
|
-
'--fd-
|
|
132
|
+
'--fd-header-height': `${headerHeight}rem`,
|
|
133
133
|
paddingTop: floatingNav
|
|
134
134
|
? `calc(var(--fd-banner-height) + ${resolvedPaddingTop}rem)`
|
|
135
135
|
: `${resolvedPaddingTop}rem`,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { AirplayIcon, MoonIcon, SunIcon } from '@windrun-huaiin/base-ui/icons';
|
|
5
|
+
import { useTheme } from 'next-themes';
|
|
6
|
+
import { type ComponentProps, useEffect, useState } from 'react';
|
|
7
|
+
import { cn } from '@windrun-huaiin/lib/utils';
|
|
8
|
+
|
|
9
|
+
const itemVariants = cva('inline-flex size-6.5 items-center justify-center rounded-full p-1.5', {
|
|
10
|
+
variants: {
|
|
11
|
+
active: {
|
|
12
|
+
true: 'bg-fd-accent',
|
|
13
|
+
false: '',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const full = [['light', SunIcon] as const, ['dark', MoonIcon] as const, ['system', AirplayIcon] as const];
|
|
19
|
+
|
|
20
|
+
export interface HeaderThemeSwitchProps extends ComponentProps<'div'> {
|
|
21
|
+
mode?: 'light-dark' | 'light-dark-system';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function HeaderThemeSwitch({
|
|
25
|
+
className,
|
|
26
|
+
mode = 'light-dark',
|
|
27
|
+
...props
|
|
28
|
+
}: HeaderThemeSwitchProps) {
|
|
29
|
+
const { setTheme, theme, resolvedTheme } = useTheme();
|
|
30
|
+
const [mounted, setMounted] = useState(false);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
setMounted(true);
|
|
34
|
+
}, []);
|
|
35
|
+
|
|
36
|
+
const container = cn(
|
|
37
|
+
'inline-flex items-center rounded-full border p-1 overflow-hidden *:rounded-full',
|
|
38
|
+
className,
|
|
39
|
+
);
|
|
40
|
+
const iconClassName = 'size-3.5 text-neutral-600 dark:text-neutral-300';
|
|
41
|
+
|
|
42
|
+
if (mode === 'light-dark') {
|
|
43
|
+
const value = mounted ? resolvedTheme : null;
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<button
|
|
47
|
+
type="button"
|
|
48
|
+
className={container}
|
|
49
|
+
aria-label="Toggle Theme"
|
|
50
|
+
onClick={() => setTheme(value === 'light' ? 'dark' : 'light')}
|
|
51
|
+
data-theme-toggle=""
|
|
52
|
+
>
|
|
53
|
+
{full.map(([key, Icon]) => {
|
|
54
|
+
if (key === 'system') return null;
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Icon
|
|
58
|
+
key={key}
|
|
59
|
+
fill="currentColor"
|
|
60
|
+
className={cn(
|
|
61
|
+
itemVariants({ active: value === key }),
|
|
62
|
+
iconClassName,
|
|
63
|
+
)}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const value = mounted ? theme : null;
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div className={container} data-theme-toggle="" {...props}>
|
|
75
|
+
{full.map(([key, Icon]) => (
|
|
76
|
+
<button
|
|
77
|
+
key={key}
|
|
78
|
+
type="button"
|
|
79
|
+
aria-label={key}
|
|
80
|
+
className={cn(itemVariants({ active: value === key }))}
|
|
81
|
+
onClick={() => setTheme(key)}
|
|
82
|
+
>
|
|
83
|
+
<Icon className={iconClassName} fill="currentColor" />
|
|
84
|
+
</button>
|
|
85
|
+
))}
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
package/src/fuma/base/index.ts
CHANGED
|
@@ -0,0 +1,289 @@
|
|
|
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
|
+
}
|
|
@@ -10,36 +10,38 @@ export async function FumaBannerSuit({
|
|
|
10
10
|
showBanner: boolean;
|
|
11
11
|
floating?: boolean;
|
|
12
12
|
}) {
|
|
13
|
-
const
|
|
14
|
-
const heightValue = showBanner ? 3 : 0.5;
|
|
13
|
+
const heightValue = 3;
|
|
15
14
|
const height = `${heightValue}rem`;
|
|
15
|
+
|
|
16
|
+
if (!showBanner) {
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
aria-hidden="true"
|
|
20
|
+
className="m-0 rounded-none bg-neutral-100 dark:bg-neutral-900"
|
|
21
|
+
style={{
|
|
22
|
+
position: floating ? 'fixed' : 'relative',
|
|
23
|
+
top: floating ? 0 : undefined,
|
|
24
|
+
left: floating ? 0 : undefined,
|
|
25
|
+
width: floating ? '100vw' : '100%',
|
|
26
|
+
zIndex: floating ? 1001 : undefined,
|
|
27
|
+
height,
|
|
28
|
+
minHeight: height,
|
|
29
|
+
maxHeight: height,
|
|
30
|
+
}}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const t = await getTranslations({ locale, namespace: 'home' });
|
|
16
36
|
const bannerText = t('banner');
|
|
17
37
|
return (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<p className="text-sm sm:text-xl md:text-xl">{bannerText}</p>
|
|
27
|
-
</Banner>
|
|
28
|
-
) : (
|
|
29
|
-
<div
|
|
30
|
-
className="m-0 rounded-none bg-neutral-100 dark:bg-neutral-900"
|
|
31
|
-
style={{
|
|
32
|
-
position: floating ? 'fixed' : 'relative',
|
|
33
|
-
top: floating ? 0 : undefined,
|
|
34
|
-
left: floating ? 0 : undefined,
|
|
35
|
-
width: floating ? '100vw' : '100%',
|
|
36
|
-
zIndex: floating ? 1001 : undefined,
|
|
37
|
-
height: height,
|
|
38
|
-
minHeight: height,
|
|
39
|
-
maxHeight: height,
|
|
40
|
-
}}
|
|
41
|
-
/>
|
|
42
|
-
)}
|
|
43
|
-
</>
|
|
38
|
+
<Banner
|
|
39
|
+
variant="rainbow"
|
|
40
|
+
changeLayout={true}
|
|
41
|
+
height={heightValue}
|
|
42
|
+
floating={floating}
|
|
43
|
+
>
|
|
44
|
+
<p className="text-sm sm:text-xl md:text-xl">{bannerText}</p>
|
|
45
|
+
</Banner>
|
|
44
46
|
);
|
|
45
47
|
}
|
|
@@ -137,7 +137,7 @@ export function createFumaPage({
|
|
|
137
137
|
enabled: false,
|
|
138
138
|
}}
|
|
139
139
|
toc={content.toc}
|
|
140
|
-
|
|
140
|
+
className="max-sm:pb-16"
|
|
141
141
|
>
|
|
142
142
|
<DocsTitle>{page.data.title}</DocsTitle>
|
|
143
143
|
<DocsDescription className="mb-2">{page.data.description}</DocsDescription>
|
package/src/fuma/mdx/index.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
export * from './mermaid';
|
|
4
|
-
export * from './image-zoom';
|
|
5
3
|
export * from './trophy-card';
|
|
6
|
-
export * from './image-grid';
|
|
7
4
|
export * from './zia-card';
|
|
8
5
|
export * from './gradient-button';
|
|
9
6
|
export * from './toc-base';
|
|
@@ -13,5 +10,3 @@ export * from './toc-footer-wrapper';
|
|
|
13
10
|
export * from './toc-clerk-portable';
|
|
14
11
|
export * from './banner';
|
|
15
12
|
export * from './suno-embed';
|
|
16
|
-
export * from './markdown-component-map';
|
|
17
|
-
export * from './math';
|