@windrun-huaiin/third-ui 31.1.0 → 31.2.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/fuma/base/custom-header.d.ts +2 -4
- package/dist/fuma/base/custom-header.js +9 -7
- package/dist/fuma/base/custom-header.mjs +9 -7
- package/dist/fuma/base/custom-home-layout.d.ts +1 -6
- package/dist/fuma/base/custom-home-layout.js +3 -6
- package/dist/fuma/base/custom-home-layout.mjs +3 -6
- package/dist/fuma/base/docs-root-provider.d.ts +3 -1
- package/dist/fuma/base/docs-root-provider.js +5 -2
- package/dist/fuma/base/docs-root-provider.mjs +5 -2
- package/dist/fuma/base/header-theme-switch.d.ts +2 -3
- package/dist/fuma/base/header-theme-switch.js +2 -10
- package/dist/fuma/base/header-theme-switch.mjs +2 -10
- package/dist/fuma/base/site-docs-layout.d.ts +1 -1
- package/dist/fuma/base/site-docs-layout.js +3 -22
- package/dist/fuma/base/site-docs-layout.mjs +3 -22
- package/dist/fuma/base/site-docs-theme-switch.d.ts +2 -0
- package/dist/fuma/base/site-docs-theme-switch.js +16 -0
- package/dist/fuma/base/site-docs-theme-switch.mjs +14 -0
- package/dist/fuma/base/site-home-layout.js +2 -2
- package/dist/fuma/base/site-home-layout.mjs +2 -2
- package/dist/fuma/base/site-layout-shared.d.ts +1 -2
- package/dist/fuma/base/site-theme-context.d.ts +8 -0
- package/dist/fuma/base/site-theme-context.js +19 -0
- package/dist/fuma/base/site-theme-context.mjs +16 -0
- package/dist/fuma/base/site-theme-provider.js +0 -7
- package/dist/fuma/base/site-theme-provider.mjs +0 -7
- package/package.json +3 -3
- package/src/fuma/base/custom-header.tsx +10 -12
- package/src/fuma/base/custom-home-layout.tsx +0 -12
- package/src/fuma/base/docs-root-provider.tsx +9 -1
- package/src/fuma/base/header-theme-switch.tsx +2 -32
- package/src/fuma/base/site-docs-layout.tsx +7 -22
- package/src/fuma/base/site-docs-theme-switch.tsx +15 -0
- package/src/fuma/base/site-home-layout.tsx +0 -1
- package/src/fuma/base/site-layout-shared.tsx +0 -2
- package/src/fuma/base/site-theme-context.tsx +30 -0
- package/src/fuma/base/site-theme-provider.tsx +0 -8
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
2
|
import { HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
|
3
|
-
import type { SiteThemeSwitchConfig } from './site-layout-shared';
|
|
4
3
|
export type NavbarCSSVars = CSSProperties & {
|
|
5
4
|
'--fd-banner-height'?: string;
|
|
6
5
|
'--fd-header-height'?: string;
|
|
7
6
|
'--fd-nav-max-width'?: string;
|
|
8
7
|
};
|
|
9
|
-
export interface CustomHomeHeaderProps extends
|
|
8
|
+
export interface CustomHomeHeaderProps extends HomeLayoutProps {
|
|
10
9
|
/**
|
|
11
10
|
* Banner height in rem units
|
|
12
11
|
*
|
|
@@ -47,9 +46,8 @@ export interface CustomHomeHeaderProps extends Omit<HomeLayoutProps, 'themeSwitc
|
|
|
47
46
|
* Control order of utilities inside the mobile dropdown.
|
|
48
47
|
*/
|
|
49
48
|
mobileMenuActionsOrder?: MobileMenuAction[];
|
|
50
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
51
49
|
}
|
|
52
50
|
export type DesktopAction = 'search' | 'theme' | 'i18n' | 'secondary' | 'github';
|
|
53
51
|
export type MobileBarAction = 'pinned' | 'search' | 'menu';
|
|
54
52
|
export type MobileMenuAction = 'secondary' | 'github' | 'separator' | 'i18n' | 'theme';
|
|
55
|
-
export declare function CustomHomeHeader({ nav, i18n, links, githubUrl,
|
|
53
|
+
export declare function CustomHomeHeader({ nav, i18n, links, githubUrl, searchToggle, bannerHeight, headerHeight, maxContentWidth, navbarClassName, floating, desktopActionsOrder, mobileBarActionsOrder, mobileMenuActionsOrder, }: CustomHomeHeaderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,6 +15,7 @@ var popover = require('fumadocs-ui/components/ui/popover');
|
|
|
15
15
|
var button = require('fumadocs-ui/components/ui/button');
|
|
16
16
|
var i18n = require('fumadocs-ui/contexts/i18n');
|
|
17
17
|
var headerThemeSwitch = require('./header-theme-switch.js');
|
|
18
|
+
var siteThemeContext = require('./site-theme-context.js');
|
|
18
19
|
|
|
19
20
|
const PrefetchLinkItem = shared.LinkItem;
|
|
20
21
|
const DEFAULT_DESKTOP_ACTIONS = [
|
|
@@ -34,8 +35,9 @@ const DEFAULT_MOBILE_MENU_ACTIONS = [
|
|
|
34
35
|
'i18n',
|
|
35
36
|
'theme',
|
|
36
37
|
];
|
|
37
|
-
function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl,
|
|
38
|
+
function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, searchToggle = {}, bannerHeight = 0, headerHeight = 2.5, maxContentWidth = 1400, navbarClassName, floating = false, desktopActionsOrder = DEFAULT_DESKTOP_ACTIONS, mobileBarActionsOrder = DEFAULT_MOBILE_BAR_ACTIONS, mobileMenuActionsOrder = DEFAULT_MOBILE_MENU_ACTIONS, }) {
|
|
38
39
|
var _a, _b, _c, _d, _e;
|
|
40
|
+
const themeMode = siteThemeContext.useSiteThemeMode();
|
|
39
41
|
const finalLinks = React.useMemo(() => shared.resolveLinkItems({ links, githubUrl }), [links, githubUrl]);
|
|
40
42
|
const navItems = finalLinks.filter((item) => { var _a; return ['nav', 'all'].includes((_a = item.on) !== null && _a !== void 0 ? _a : 'all'); });
|
|
41
43
|
const menuItems = finalLinks.filter((item) => { var _a; return ['menu', 'all'].includes((_a = item.on) !== null && _a !== void 0 ? _a : 'all'); });
|
|
@@ -55,8 +57,8 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
55
57
|
search: searchToggle.enabled !== false
|
|
56
58
|
? (_b = (_a = searchToggle.components) === null || _a === void 0 ? void 0 : _a.lg) !== null && _b !== void 0 ? _b : null
|
|
57
59
|
: null,
|
|
58
|
-
theme: shouldShowThemeSwitch(
|
|
59
|
-
? (jsxRuntime.jsx(headerThemeSwitch.HeaderThemeSwitch, { mode: normalizeThemeSwitchMode(
|
|
60
|
+
theme: shouldShowThemeSwitch(themeMode)
|
|
61
|
+
? (jsxRuntime.jsx(headerThemeSwitch.HeaderThemeSwitch, { mode: normalizeThemeSwitchMode() }))
|
|
60
62
|
: null,
|
|
61
63
|
i18n: i18n ? (jsxRuntime.jsx(CompactLanguageToggle, { children: jsxRuntime.jsx(icons.LanguagesIcon, { className: "size-5" }) })) : null,
|
|
62
64
|
secondary: desktopSecondaryDisplayItems.length ? (jsxRuntime.jsx("ul", { className: "flex flex-row gap-2 items-center empty:hidden", children: desktopSecondaryDisplayItems.map((item, i) => (jsxRuntime.jsx(NavbarLinkItem, { item: item, className: utils.cn(item.type === 'icon' && [
|
|
@@ -78,8 +80,8 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
78
80
|
github: githubMobileMenuItem ? (jsxRuntime.jsx(MenuLinkItem, { item: githubMobileMenuItem, className: "-me-1.5" })) : null,
|
|
79
81
|
separator: jsxRuntime.jsx("div", { role: "separator", className: "flex-1" }),
|
|
80
82
|
i18n: i18n ? (jsxRuntime.jsxs(CompactLanguageToggle, { children: [jsxRuntime.jsx(icons.LanguagesIcon, { className: "size-5" }), jsxRuntime.jsx(languageSelect.LanguageSelectText, {}), jsxRuntime.jsx(icons.ChevronDownIcon, { className: "size-3 text-fd-muted-foreground" })] })) : null,
|
|
81
|
-
theme: shouldShowThemeSwitch(
|
|
82
|
-
? (jsxRuntime.jsx(headerThemeSwitch.HeaderThemeSwitch, { mode: normalizeThemeSwitchMode(
|
|
83
|
+
theme: shouldShowThemeSwitch(themeMode)
|
|
84
|
+
? (jsxRuntime.jsx(headerThemeSwitch.HeaderThemeSwitch, { mode: normalizeThemeSwitchMode() }))
|
|
83
85
|
: null,
|
|
84
86
|
};
|
|
85
87
|
const shouldRenderMobileUtilities = mobileMenuActionsOrder.some((action) => action !== 'separator' && Boolean(mobileMenuActionNodes[action]));
|
|
@@ -121,10 +123,10 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
121
123
|
}) })] }));
|
|
122
124
|
}
|
|
123
125
|
function shouldShowThemeSwitch(mode) {
|
|
124
|
-
return mode === 'light-dark
|
|
126
|
+
return mode === 'light-dark-system' || mode == null;
|
|
125
127
|
}
|
|
126
128
|
function normalizeThemeSwitchMode(mode) {
|
|
127
|
-
return
|
|
129
|
+
return 'light-dark-system';
|
|
128
130
|
}
|
|
129
131
|
function CustomNavbar(_a) {
|
|
130
132
|
var { bannerHeight = 0, headerHeight = 2.5, maxContentWidth = 1400, className, style, floating = false } = _a, props = tslib.__rest(_a, ["bannerHeight", "headerHeight", "maxContentWidth", "className", "style", "floating"]);
|
|
@@ -13,6 +13,7 @@ import { Popover, PopoverTrigger, PopoverContent } from 'fumadocs-ui/components/
|
|
|
13
13
|
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
14
14
|
import { useI18n } from 'fumadocs-ui/contexts/i18n';
|
|
15
15
|
import { HeaderThemeSwitch } from './header-theme-switch.mjs';
|
|
16
|
+
import { useSiteThemeMode } from './site-theme-context.mjs';
|
|
16
17
|
|
|
17
18
|
const PrefetchLinkItem = LinkItem;
|
|
18
19
|
const DEFAULT_DESKTOP_ACTIONS = [
|
|
@@ -32,8 +33,9 @@ const DEFAULT_MOBILE_MENU_ACTIONS = [
|
|
|
32
33
|
'i18n',
|
|
33
34
|
'theme',
|
|
34
35
|
];
|
|
35
|
-
function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl,
|
|
36
|
+
function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, searchToggle = {}, bannerHeight = 0, headerHeight = 2.5, maxContentWidth = 1400, navbarClassName, floating = false, desktopActionsOrder = DEFAULT_DESKTOP_ACTIONS, mobileBarActionsOrder = DEFAULT_MOBILE_BAR_ACTIONS, mobileMenuActionsOrder = DEFAULT_MOBILE_MENU_ACTIONS, }) {
|
|
36
37
|
var _a, _b, _c, _d, _e;
|
|
38
|
+
const themeMode = useSiteThemeMode();
|
|
37
39
|
const finalLinks = useMemo(() => resolveLinkItems({ links, githubUrl }), [links, githubUrl]);
|
|
38
40
|
const navItems = finalLinks.filter((item) => { var _a; return ['nav', 'all'].includes((_a = item.on) !== null && _a !== void 0 ? _a : 'all'); });
|
|
39
41
|
const menuItems = finalLinks.filter((item) => { var _a; return ['menu', 'all'].includes((_a = item.on) !== null && _a !== void 0 ? _a : 'all'); });
|
|
@@ -53,8 +55,8 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
53
55
|
search: searchToggle.enabled !== false
|
|
54
56
|
? (_b = (_a = searchToggle.components) === null || _a === void 0 ? void 0 : _a.lg) !== null && _b !== void 0 ? _b : null
|
|
55
57
|
: null,
|
|
56
|
-
theme: shouldShowThemeSwitch(
|
|
57
|
-
? (jsx(HeaderThemeSwitch, { mode: normalizeThemeSwitchMode(
|
|
58
|
+
theme: shouldShowThemeSwitch(themeMode)
|
|
59
|
+
? (jsx(HeaderThemeSwitch, { mode: normalizeThemeSwitchMode() }))
|
|
58
60
|
: null,
|
|
59
61
|
i18n: i18n ? (jsx(CompactLanguageToggle, { children: jsx(LanguagesIcon, { className: "size-5" }) })) : null,
|
|
60
62
|
secondary: desktopSecondaryDisplayItems.length ? (jsx("ul", { className: "flex flex-row gap-2 items-center empty:hidden", children: desktopSecondaryDisplayItems.map((item, i) => (jsx(NavbarLinkItem, { item: item, className: cn(item.type === 'icon' && [
|
|
@@ -76,8 +78,8 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
76
78
|
github: githubMobileMenuItem ? (jsx(MenuLinkItem, { item: githubMobileMenuItem, className: "-me-1.5" })) : null,
|
|
77
79
|
separator: jsx("div", { role: "separator", className: "flex-1" }),
|
|
78
80
|
i18n: i18n ? (jsxs(CompactLanguageToggle, { children: [jsx(LanguagesIcon, { className: "size-5" }), jsx(LanguageSelectText, {}), jsx(ChevronDownIcon, { className: "size-3 text-fd-muted-foreground" })] })) : null,
|
|
79
|
-
theme: shouldShowThemeSwitch(
|
|
80
|
-
? (jsx(HeaderThemeSwitch, { mode: normalizeThemeSwitchMode(
|
|
81
|
+
theme: shouldShowThemeSwitch(themeMode)
|
|
82
|
+
? (jsx(HeaderThemeSwitch, { mode: normalizeThemeSwitchMode() }))
|
|
81
83
|
: null,
|
|
82
84
|
};
|
|
83
85
|
const shouldRenderMobileUtilities = mobileMenuActionsOrder.some((action) => action !== 'separator' && Boolean(mobileMenuActionNodes[action]));
|
|
@@ -119,10 +121,10 @@ function CustomHomeHeader({ nav = {}, i18n = false, links, githubUrl, themeSwitc
|
|
|
119
121
|
}) })] }));
|
|
120
122
|
}
|
|
121
123
|
function shouldShowThemeSwitch(mode) {
|
|
122
|
-
return mode === 'light-dark
|
|
124
|
+
return mode === 'light-dark-system' || mode == null;
|
|
123
125
|
}
|
|
124
126
|
function normalizeThemeSwitchMode(mode) {
|
|
125
|
-
return
|
|
127
|
+
return 'light-dark-system';
|
|
126
128
|
}
|
|
127
129
|
function CustomNavbar(_a) {
|
|
128
130
|
var { bannerHeight = 0, headerHeight = 2.5, maxContentWidth = 1400, className, style, floating = false } = _a, props = __rest(_a, ["bannerHeight", "headerHeight", "maxContentWidth", "className", "style", "floating"]);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import { type HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
|
3
3
|
import { type DesktopAction, type MobileBarAction, type MobileMenuAction } from './custom-header';
|
|
4
|
-
import type { SiteThemeSwitchConfig } from './site-layout-shared';
|
|
5
4
|
export interface CustomHomeLayoutProps {
|
|
6
5
|
locale: string;
|
|
7
6
|
options: HomeLayoutProps;
|
|
@@ -77,10 +76,6 @@ export interface CustomHomeLayoutProps {
|
|
|
77
76
|
* The default locale for the application (default: 'en')
|
|
78
77
|
*/
|
|
79
78
|
defaultLocale?: string;
|
|
80
|
-
/**
|
|
81
|
-
* Theme mode for this layout group.
|
|
82
|
-
*/
|
|
83
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
84
79
|
children?: ReactNode;
|
|
85
80
|
}
|
|
86
81
|
export interface HeaderActionOrders {
|
|
@@ -88,7 +83,7 @@ export interface HeaderActionOrders {
|
|
|
88
83
|
mobileBar?: MobileBarAction[];
|
|
89
84
|
mobileMenu?: MobileMenuAction[];
|
|
90
85
|
}
|
|
91
|
-
export declare function CustomHomeLayout({ locale, options, children, showBanner, bannerHeight, headerHeight, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter, showGoToTop, style, floatingNav, actionOrders, localePrefixAsNeeded, defaultLocale,
|
|
86
|
+
export declare function CustomHomeLayout({ locale, options, children, showBanner, bannerHeight, headerHeight, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter, showGoToTop, style, floatingNav, actionOrders, localePrefixAsNeeded, defaultLocale, }: CustomHomeLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
92
87
|
export declare function HomeTitle({ children, className, }: {
|
|
93
88
|
children: ReactNode;
|
|
94
89
|
className?: string;
|
|
@@ -6,11 +6,9 @@ var home = require('fumadocs-ui/layouts/home');
|
|
|
6
6
|
var fumaBannerSuit = require('../fuma-banner-suit.js');
|
|
7
7
|
var footer = require('../../main/footer.js');
|
|
8
8
|
var goToTop = require('../../main/go-to-top.js');
|
|
9
|
-
var siteThemeProvider = require('./site-theme-provider.js');
|
|
10
9
|
var customHeader = require('./custom-header.js');
|
|
11
10
|
|
|
12
|
-
function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer: footer$1, goToTop: goToTop$1, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localePrefixAsNeeded = true, defaultLocale = 'en',
|
|
13
|
-
var _a;
|
|
11
|
+
function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer: footer$1, goToTop: goToTop$1, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
14
12
|
const resolvedBannerHeight = bannerHeight !== null && bannerHeight !== void 0 ? bannerHeight : (showBanner ? 3 : 0.5);
|
|
15
13
|
const resolvedPaddingTop = headerPaddingTop !== null && headerPaddingTop !== void 0 ? headerPaddingTop : (showBanner ? 0 : 0.5);
|
|
16
14
|
const layoutStyle = Object.assign({ '--fd-banner-height': `${resolvedBannerHeight}rem`, '--fd-header-height': `${headerHeight}rem`, paddingTop: floatingNav
|
|
@@ -18,9 +16,8 @@ function CustomHomeLayout({ locale, options, children, showBanner = false, banne
|
|
|
18
16
|
: `${resolvedPaddingTop}rem` }, style);
|
|
19
17
|
const { nav } = options, homeLayoutProps = tslib.__rest(options, ["nav"]);
|
|
20
18
|
const navOptions = nav !== null && nav !== void 0 ? nav : {};
|
|
21
|
-
const header = (jsxRuntime.jsx(customHeader.CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions,
|
|
22
|
-
|
|
23
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsxRuntime.jsx(fumaBannerSuit.FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxRuntime.jsx(siteThemeProvider.SiteThemeProvider, { mode: themeMode, children: jsxRuntime.jsxs(home.HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer$1 !== null && footer$1 !== void 0 ? footer$1 : jsxRuntime.jsx(footer.Footer, { locale: locale, localePrefixAsNeeded: localePrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop$1 !== null && goToTop$1 !== void 0 ? goToTop$1 : jsxRuntime.jsx(goToTop.GoToTop, {}) : null] })) })] }));
|
|
19
|
+
const header = (jsxRuntime.jsx(customHeader.CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions, bannerHeight: resolvedBannerHeight, headerHeight: headerHeight, navbarClassName: navbarClassName, floating: floatingNav, desktopActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.desktop, mobileBarActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileBar, mobileMenuActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileMenu })));
|
|
20
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsxRuntime.jsx(fumaBannerSuit.FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxRuntime.jsxs(home.HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer$1 !== null && footer$1 !== void 0 ? footer$1 : jsxRuntime.jsx(footer.Footer, { locale: locale, localePrefixAsNeeded: localePrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop$1 !== null && goToTop$1 !== void 0 ? goToTop$1 : jsxRuntime.jsx(goToTop.GoToTop, {}) : null] }))] }));
|
|
24
21
|
}
|
|
25
22
|
function HomeTitle({ children, className, }) {
|
|
26
23
|
return (jsxRuntime.jsx("span", { className: `font-medium in-[.uwu]:hidden in-[header]:text-[clamp(12px,3vw,15px)]! ${className !== null && className !== void 0 ? className : ''}`, children: children }));
|
|
@@ -4,11 +4,9 @@ import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
|
|
4
4
|
import { FumaBannerSuit } from '../fuma-banner-suit.mjs';
|
|
5
5
|
import { Footer } from '../../main/footer.mjs';
|
|
6
6
|
import { GoToTop } from '../../main/go-to-top.mjs';
|
|
7
|
-
import { SiteThemeProvider } from './site-theme-provider.mjs';
|
|
8
7
|
import { CustomHomeHeader } from './custom-header.mjs';
|
|
9
8
|
|
|
10
|
-
function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localePrefixAsNeeded = true, defaultLocale = 'en',
|
|
11
|
-
var _a;
|
|
9
|
+
function CustomHomeLayout({ locale, options, children, showBanner = false, bannerHeight, headerHeight = 2.5, headerPaddingTop, navbarClassName, banner, footer, goToTop, showFooter = true, showGoToTop = true, style, floatingNav = false, actionOrders, localePrefixAsNeeded = true, defaultLocale = 'en', }) {
|
|
12
10
|
const resolvedBannerHeight = bannerHeight !== null && bannerHeight !== void 0 ? bannerHeight : (showBanner ? 3 : 0.5);
|
|
13
11
|
const resolvedPaddingTop = headerPaddingTop !== null && headerPaddingTop !== void 0 ? headerPaddingTop : (showBanner ? 0 : 0.5);
|
|
14
12
|
const layoutStyle = Object.assign({ '--fd-banner-height': `${resolvedBannerHeight}rem`, '--fd-header-height': `${headerHeight}rem`, paddingTop: floatingNav
|
|
@@ -16,9 +14,8 @@ function CustomHomeLayout({ locale, options, children, showBanner = false, banne
|
|
|
16
14
|
: `${resolvedPaddingTop}rem` }, style);
|
|
17
15
|
const { nav } = options, homeLayoutProps = __rest(options, ["nav"]);
|
|
18
16
|
const navOptions = nav !== null && nav !== void 0 ? nav : {};
|
|
19
|
-
const header = (jsx(CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions,
|
|
20
|
-
|
|
21
|
-
return (jsxs(Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsx(FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsx(SiteThemeProvider, { mode: themeMode, children: jsxs(HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer !== null && footer !== void 0 ? footer : jsx(Footer, { locale: locale, localePrefixAsNeeded: localePrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop !== null && goToTop !== void 0 ? goToTop : jsx(GoToTop, {}) : null] })) })] }));
|
|
17
|
+
const header = (jsx(CustomHomeHeader, Object.assign({}, homeLayoutProps, { nav: navOptions, bannerHeight: resolvedBannerHeight, headerHeight: headerHeight, navbarClassName: navbarClassName, floating: floatingNav, desktopActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.desktop, mobileBarActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileBar, mobileMenuActionsOrder: actionOrders === null || actionOrders === void 0 ? void 0 : actionOrders.mobileMenu })));
|
|
18
|
+
return (jsxs(Fragment, { children: [banner !== null && banner !== void 0 ? banner : (jsx(FumaBannerSuit, { locale: locale, showBanner: showBanner, floating: floatingNav })), jsxs(HomeLayout, Object.assign({}, homeLayoutProps, { nav: Object.assign(Object.assign({}, navOptions), { component: header }), className: 'bg-neutral-100 dark:bg-neutral-900', style: layoutStyle, children: [children, showFooter ? footer !== null && footer !== void 0 ? footer : jsx(Footer, { locale: locale, localePrefixAsNeeded: localePrefixAsNeeded, defaultLocale: defaultLocale }) : null, showGoToTop ? goToTop !== null && goToTop !== void 0 ? goToTop : jsx(GoToTop, {}) : null] }))] }));
|
|
22
19
|
}
|
|
23
20
|
function HomeTitle({ children, className, }) {
|
|
24
21
|
return (jsx("span", { className: `font-medium in-[.uwu]:hidden in-[header]:text-[clamp(12px,3vw,15px)]! ${className !== null && className !== void 0 ? className : ''}`, children: children }));
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { ComponentProps, ReactNode } from 'react';
|
|
2
2
|
import { NextProvider } from 'fumadocs-core/framework/next';
|
|
3
3
|
import { type I18nProviderProps } from 'fumadocs-ui/contexts/i18n';
|
|
4
|
+
import type { SiteThemeProviderProps } from './site-theme-provider';
|
|
4
5
|
type NextProviderComponents = {
|
|
5
6
|
Link?: ComponentProps<typeof NextProvider>['Link'];
|
|
6
7
|
Image?: ComponentProps<typeof NextProvider>['Image'];
|
|
7
8
|
};
|
|
8
9
|
export interface DocsRootProviderProps {
|
|
9
10
|
i18n: Omit<I18nProviderProps, 'children'>;
|
|
11
|
+
theme?: Omit<SiteThemeProviderProps, 'children'>;
|
|
10
12
|
components?: NextProviderComponents;
|
|
11
13
|
children: ReactNode;
|
|
12
14
|
}
|
|
13
|
-
export declare function DocsRootProvider({ i18n, components, children, }: DocsRootProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function DocsRootProvider({ i18n, theme, components, children, }: DocsRootProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
14
16
|
export {};
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var next = require('fumadocs-core/framework/next');
|
|
5
5
|
var i18n = require('fumadocs-ui/contexts/i18n');
|
|
6
|
+
var siteThemeContext = require('./site-theme-context.js');
|
|
6
7
|
|
|
7
|
-
function DocsRootProvider({ i18n: i18n$1, components, children, }) {
|
|
8
|
-
|
|
8
|
+
function DocsRootProvider({ i18n: i18n$1, theme = {}, components, children, }) {
|
|
9
|
+
var _a;
|
|
10
|
+
const themeMode = (_a = theme.mode) !== null && _a !== void 0 ? _a : 'light-dark-system';
|
|
11
|
+
return (jsxRuntime.jsx(next.NextProvider, { Link: components === null || components === void 0 ? void 0 : components.Link, Image: components === null || components === void 0 ? void 0 : components.Image, children: jsxRuntime.jsx(i18n.I18nProvider, Object.assign({}, i18n$1, { children: jsxRuntime.jsx(siteThemeContext.SiteThemeRootProvider, Object.assign({}, theme, { mode: themeMode, children: children })) })) }));
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
exports.DocsRootProvider = DocsRootProvider;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { NextProvider } from 'fumadocs-core/framework/next';
|
|
3
3
|
import { I18nProvider } from 'fumadocs-ui/contexts/i18n';
|
|
4
|
+
import { SiteThemeRootProvider } from './site-theme-context.mjs';
|
|
4
5
|
|
|
5
|
-
function DocsRootProvider({ i18n, components, children, }) {
|
|
6
|
-
|
|
6
|
+
function DocsRootProvider({ i18n, theme = {}, components, children, }) {
|
|
7
|
+
var _a;
|
|
8
|
+
const themeMode = (_a = theme.mode) !== null && _a !== void 0 ? _a : 'light-dark-system';
|
|
9
|
+
return (jsx(NextProvider, { Link: components === null || components === void 0 ? void 0 : components.Link, Image: components === null || components === void 0 ? void 0 : components.Image, children: jsx(I18nProvider, Object.assign({}, i18n, { children: jsx(SiteThemeRootProvider, Object.assign({}, theme, { mode: themeMode, children: children })) })) }));
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export { DocsRootProvider };
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type ComponentProps } from 'react';
|
|
2
|
-
import type { SiteThemeSwitchMode } from './site-layout-shared';
|
|
3
2
|
export interface HeaderThemeSwitchProps extends ComponentProps<'div'> {
|
|
4
|
-
mode?:
|
|
3
|
+
mode?: 'light-dark-system';
|
|
5
4
|
}
|
|
6
|
-
export declare function HeaderThemeSwitch({ className,
|
|
5
|
+
export declare function HeaderThemeSwitch({ className, ...props }: HeaderThemeSwitchProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -19,22 +19,14 @@ const itemVariants = classVarianceAuthority.cva('inline-flex size-6.5 items-cent
|
|
|
19
19
|
});
|
|
20
20
|
const full = [['light', icons.SunIcon], ['dark', icons.MoonIcon], ['system', icons.AirplayIcon]];
|
|
21
21
|
function HeaderThemeSwitch(_a) {
|
|
22
|
-
var { className
|
|
23
|
-
const { setTheme, theme
|
|
22
|
+
var { className } = _a, props = tslib.__rest(_a, ["className"]);
|
|
23
|
+
const { setTheme, theme } = nextThemes.useTheme();
|
|
24
24
|
const [mounted, setMounted] = React.useState(false);
|
|
25
25
|
React.useEffect(() => {
|
|
26
26
|
setMounted(true);
|
|
27
27
|
}, []);
|
|
28
28
|
const container = utils.cn('inline-flex items-center rounded-full border p-1 overflow-hidden *:rounded-full', className);
|
|
29
29
|
const iconClassName = 'size-3.5 text-neutral-600 dark:text-neutral-300';
|
|
30
|
-
if (mode === 'light-dark') {
|
|
31
|
-
const value = mounted ? resolvedTheme : null;
|
|
32
|
-
return (jsxRuntime.jsx("button", { type: "button", className: container, "aria-label": "Toggle Theme", onClick: () => setTheme(value === 'light' ? 'dark' : 'light'), "data-theme-toggle": "", children: full.map(([key, Icon]) => {
|
|
33
|
-
if (key === 'system')
|
|
34
|
-
return null;
|
|
35
|
-
return (jsxRuntime.jsx(Icon, { fill: "currentColor", className: utils.cn(itemVariants({ active: value === key }), iconClassName) }, key));
|
|
36
|
-
}) }));
|
|
37
|
-
}
|
|
38
30
|
const value = mounted ? theme : null;
|
|
39
31
|
return (jsxRuntime.jsx("div", Object.assign({ className: container, "data-theme-toggle": "" }, props, { children: full.map(([key, Icon]) => (jsxRuntime.jsx("button", { type: "button", "aria-label": key, className: utils.cn(itemVariants({ active: value === key })), onClick: () => setTheme(key), children: jsxRuntime.jsx(Icon, { className: iconClassName, fill: "currentColor" }) }, key))) })));
|
|
40
32
|
}
|
|
@@ -17,22 +17,14 @@ const itemVariants = cva('inline-flex size-6.5 items-center justify-center round
|
|
|
17
17
|
});
|
|
18
18
|
const full = [['light', SunIcon], ['dark', MoonIcon], ['system', AirplayIcon]];
|
|
19
19
|
function HeaderThemeSwitch(_a) {
|
|
20
|
-
var { className
|
|
21
|
-
const { setTheme, theme
|
|
20
|
+
var { className } = _a, props = __rest(_a, ["className"]);
|
|
21
|
+
const { setTheme, theme } = useTheme();
|
|
22
22
|
const [mounted, setMounted] = useState(false);
|
|
23
23
|
useEffect(() => {
|
|
24
24
|
setMounted(true);
|
|
25
25
|
}, []);
|
|
26
26
|
const container = cn('inline-flex items-center rounded-full border p-1 overflow-hidden *:rounded-full', className);
|
|
27
27
|
const iconClassName = 'size-3.5 text-neutral-600 dark:text-neutral-300';
|
|
28
|
-
if (mode === 'light-dark') {
|
|
29
|
-
const value = mounted ? resolvedTheme : null;
|
|
30
|
-
return (jsx("button", { type: "button", className: container, "aria-label": "Toggle Theme", onClick: () => setTheme(value === 'light' ? 'dark' : 'light'), "data-theme-toggle": "", children: full.map(([key, Icon]) => {
|
|
31
|
-
if (key === 'system')
|
|
32
|
-
return null;
|
|
33
|
-
return (jsx(Icon, { fill: "currentColor", className: cn(itemVariants({ active: value === key }), iconClassName) }, key));
|
|
34
|
-
}) }));
|
|
35
|
-
}
|
|
36
28
|
const value = mounted ? theme : null;
|
|
37
29
|
return (jsx("div", Object.assign({ className: container, "data-theme-toggle": "" }, props, { children: full.map(([key, Icon]) => (jsx("button", { type: "button", "aria-label": key, className: cn(itemVariants({ active: value === key })), onClick: () => setTheme(key), children: jsx(Icon, { className: iconClassName, fill: "currentColor" }) }, key))) })));
|
|
38
30
|
}
|
|
@@ -4,7 +4,7 @@ import { type SiteBaseLayoutConfig } from './site-layout-shared';
|
|
|
4
4
|
export interface SiteDocsLayoutConfig extends SiteBaseLayoutConfig {
|
|
5
5
|
tree: DocsLayoutProps['tree'];
|
|
6
6
|
sidebar?: DocsLayoutProps['sidebar'];
|
|
7
|
-
|
|
7
|
+
slots?: DocsLayoutProps['slots'];
|
|
8
8
|
}
|
|
9
9
|
export declare function SiteDocsLayout({ config, children, }: {
|
|
10
10
|
config: SiteDocsLayoutConfig;
|
|
@@ -3,33 +3,14 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var docs = require('fumadocs-ui/layouts/docs');
|
|
5
5
|
var siteLayoutShared = require('./site-layout-shared.js');
|
|
6
|
-
var
|
|
6
|
+
var siteDocsThemeSwitch = require('./site-docs-theme-switch.js');
|
|
7
7
|
|
|
8
8
|
function toDocsLayoutOptions(config) {
|
|
9
|
-
|
|
10
|
-
const themeMode = (_b = (_a = config.themeSwitch) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : 'light-dark-system';
|
|
11
|
-
const shouldShowThemeSwitch = config.themeProvider !== false &&
|
|
12
|
-
(themeMode === 'light-dark' || themeMode === 'light-dark-system');
|
|
13
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (config.nav ? { nav: config.nav } : {})), (config.i18n ? { i18n: config.i18n } : {})), (config.githubUrl ? { githubUrl: config.githubUrl } : {})), (config.links ? { links: siteLayoutShared.normalizeNavItems(config.links) } : {})), (config.searchToggle ? { searchToggle: config.searchToggle } : {})), (shouldShowThemeSwitch
|
|
14
|
-
? {
|
|
15
|
-
themeSwitch: {
|
|
16
|
-
mode: themeMode,
|
|
17
|
-
},
|
|
18
|
-
}
|
|
19
|
-
: {
|
|
20
|
-
themeSwitch: {
|
|
21
|
-
enabled: false,
|
|
22
|
-
},
|
|
23
|
-
})), (config.sidebar ? { sidebar: config.sidebar } : {})), { tree: config.tree });
|
|
9
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (config.nav ? { nav: config.nav } : {})), (config.i18n ? { i18n: config.i18n } : {})), (config.githubUrl ? { githubUrl: config.githubUrl } : {})), (config.links ? { links: siteLayoutShared.normalizeNavItems(config.links) } : {})), (config.searchToggle ? { searchToggle: config.searchToggle } : {})), { slots: Object.assign(Object.assign({}, config.slots), { themeSwitch: siteDocsThemeSwitch.SiteDocsThemeSwitch }) }), (config.sidebar ? { sidebar: config.sidebar } : {})), { tree: config.tree });
|
|
24
10
|
}
|
|
25
11
|
function SiteDocsLayout({ config, children, }) {
|
|
26
|
-
var _a, _b;
|
|
27
12
|
const options = toDocsLayoutOptions(config);
|
|
28
|
-
|
|
29
|
-
const body = jsxRuntime.jsx(docs.DocsLayout, Object.assign({}, options, { children: children }));
|
|
30
|
-
if (config.themeProvider === false)
|
|
31
|
-
return body;
|
|
32
|
-
return jsxRuntime.jsx(siteThemeProvider.SiteThemeProvider, { mode: themeMode, children: body });
|
|
13
|
+
return jsxRuntime.jsx(docs.DocsLayout, Object.assign({}, options, { children: children }));
|
|
33
14
|
}
|
|
34
15
|
|
|
35
16
|
exports.SiteDocsLayout = SiteDocsLayout;
|
|
@@ -1,33 +1,14 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
|
|
3
3
|
import { normalizeNavItems } from './site-layout-shared.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import { SiteDocsThemeSwitch } from './site-docs-theme-switch.mjs';
|
|
5
5
|
|
|
6
6
|
function toDocsLayoutOptions(config) {
|
|
7
|
-
|
|
8
|
-
const themeMode = (_b = (_a = config.themeSwitch) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : 'light-dark-system';
|
|
9
|
-
const shouldShowThemeSwitch = config.themeProvider !== false &&
|
|
10
|
-
(themeMode === 'light-dark' || themeMode === 'light-dark-system');
|
|
11
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (config.nav ? { nav: config.nav } : {})), (config.i18n ? { i18n: config.i18n } : {})), (config.githubUrl ? { githubUrl: config.githubUrl } : {})), (config.links ? { links: normalizeNavItems(config.links) } : {})), (config.searchToggle ? { searchToggle: config.searchToggle } : {})), (shouldShowThemeSwitch
|
|
12
|
-
? {
|
|
13
|
-
themeSwitch: {
|
|
14
|
-
mode: themeMode,
|
|
15
|
-
},
|
|
16
|
-
}
|
|
17
|
-
: {
|
|
18
|
-
themeSwitch: {
|
|
19
|
-
enabled: false,
|
|
20
|
-
},
|
|
21
|
-
})), (config.sidebar ? { sidebar: config.sidebar } : {})), { tree: config.tree });
|
|
7
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (config.nav ? { nav: config.nav } : {})), (config.i18n ? { i18n: config.i18n } : {})), (config.githubUrl ? { githubUrl: config.githubUrl } : {})), (config.links ? { links: normalizeNavItems(config.links) } : {})), (config.searchToggle ? { searchToggle: config.searchToggle } : {})), { slots: Object.assign(Object.assign({}, config.slots), { themeSwitch: SiteDocsThemeSwitch }) }), (config.sidebar ? { sidebar: config.sidebar } : {})), { tree: config.tree });
|
|
22
8
|
}
|
|
23
9
|
function SiteDocsLayout({ config, children, }) {
|
|
24
|
-
var _a, _b;
|
|
25
10
|
const options = toDocsLayoutOptions(config);
|
|
26
|
-
|
|
27
|
-
const body = jsx(DocsLayout, Object.assign({}, options, { children: children }));
|
|
28
|
-
if (config.themeProvider === false)
|
|
29
|
-
return body;
|
|
30
|
-
return jsx(SiteThemeProvider, { mode: themeMode, children: body });
|
|
11
|
+
return jsx(DocsLayout, Object.assign({}, options, { children: children }));
|
|
31
12
|
}
|
|
32
13
|
|
|
33
14
|
export { SiteDocsLayout };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var headerThemeSwitch = require('./header-theme-switch.js');
|
|
6
|
+
var siteThemeContext = require('./site-theme-context.js');
|
|
7
|
+
|
|
8
|
+
function SiteDocsThemeSwitch(props) {
|
|
9
|
+
const themeMode = siteThemeContext.useSiteThemeMode();
|
|
10
|
+
if (themeMode !== 'light-dark-system') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
return jsxRuntime.jsx(headerThemeSwitch.HeaderThemeSwitch, Object.assign({}, props, { mode: "light-dark-system" }));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.SiteDocsThemeSwitch = SiteDocsThemeSwitch;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { HeaderThemeSwitch } from './header-theme-switch.mjs';
|
|
4
|
+
import { useSiteThemeMode } from './site-theme-context.mjs';
|
|
5
|
+
|
|
6
|
+
function SiteDocsThemeSwitch(props) {
|
|
7
|
+
const themeMode = useSiteThemeMode();
|
|
8
|
+
if (themeMode !== 'light-dark-system') {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return jsx(HeaderThemeSwitch, Object.assign({}, props, { mode: "light-dark-system" }));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { SiteDocsThemeSwitch };
|
|
@@ -8,8 +8,8 @@ var siteLayoutShared = require('./site-layout-shared.js');
|
|
|
8
8
|
function SiteHomeLayout({ locale, config, children, }) {
|
|
9
9
|
const { actionOrders, banner, bannerHeight, defaultLocale, floatingNav, footer, goToTop, headerHeight, headerPaddingTop, localePrefixAsNeeded, navbarClassName, showBanner, showFooter, showGoToTop } = config, baseConfig = tslib.__rest(config, ["actionOrders", "banner", "bannerHeight", "defaultLocale", "floatingNav", "footer", "goToTop", "headerHeight", "headerPaddingTop", "localePrefixAsNeeded", "navbarClassName", "showBanner", "showFooter", "showGoToTop"]);
|
|
10
10
|
const options = siteLayoutShared.toHomeLayoutOptions(baseConfig);
|
|
11
|
-
const layoutProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(
|
|
12
|
-
options }, (actionOrders ? { actionOrders } : {})), (banner ? { banner } : {})), (bannerHeight != null ? { bannerHeight } : {})), (defaultLocale ? { defaultLocale } : {})), (floatingNav != null ? { floatingNav } : {})), (footer ? { footer } : {})), (goToTop ? { goToTop } : {})), (headerHeight != null ? { headerHeight } : {})), (headerPaddingTop != null ? { headerPaddingTop } : {})), (localePrefixAsNeeded != null ? { localePrefixAsNeeded } : {})), (navbarClassName ? { navbarClassName } : {})), (showBanner != null ? { showBanner } : {})), (showFooter != null ? { showFooter } : {})), (showGoToTop != null ? { showGoToTop } : {}))
|
|
11
|
+
const layoutProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ locale,
|
|
12
|
+
options }, (actionOrders ? { actionOrders } : {})), (banner ? { banner } : {})), (bannerHeight != null ? { bannerHeight } : {})), (defaultLocale ? { defaultLocale } : {})), (floatingNav != null ? { floatingNav } : {})), (footer ? { footer } : {})), (goToTop ? { goToTop } : {})), (headerHeight != null ? { headerHeight } : {})), (headerPaddingTop != null ? { headerPaddingTop } : {})), (localePrefixAsNeeded != null ? { localePrefixAsNeeded } : {})), (navbarClassName ? { navbarClassName } : {})), (showBanner != null ? { showBanner } : {})), (showFooter != null ? { showFooter } : {})), (showGoToTop != null ? { showGoToTop } : {}));
|
|
13
13
|
return jsxRuntime.jsx(customHomeLayout.CustomHomeLayout, Object.assign({}, layoutProps, { children: children }));
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -6,8 +6,8 @@ import { toHomeLayoutOptions } from './site-layout-shared.mjs';
|
|
|
6
6
|
function SiteHomeLayout({ locale, config, children, }) {
|
|
7
7
|
const { actionOrders, banner, bannerHeight, defaultLocale, floatingNav, footer, goToTop, headerHeight, headerPaddingTop, localePrefixAsNeeded, navbarClassName, showBanner, showFooter, showGoToTop } = config, baseConfig = __rest(config, ["actionOrders", "banner", "bannerHeight", "defaultLocale", "floatingNav", "footer", "goToTop", "headerHeight", "headerPaddingTop", "localePrefixAsNeeded", "navbarClassName", "showBanner", "showFooter", "showGoToTop"]);
|
|
8
8
|
const options = toHomeLayoutOptions(baseConfig);
|
|
9
|
-
const layoutProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(
|
|
10
|
-
options }, (actionOrders ? { actionOrders } : {})), (banner ? { banner } : {})), (bannerHeight != null ? { bannerHeight } : {})), (defaultLocale ? { defaultLocale } : {})), (floatingNav != null ? { floatingNav } : {})), (footer ? { footer } : {})), (goToTop ? { goToTop } : {})), (headerHeight != null ? { headerHeight } : {})), (headerPaddingTop != null ? { headerPaddingTop } : {})), (localePrefixAsNeeded != null ? { localePrefixAsNeeded } : {})), (navbarClassName ? { navbarClassName } : {})), (showBanner != null ? { showBanner } : {})), (showFooter != null ? { showFooter } : {})), (showGoToTop != null ? { showGoToTop } : {}))
|
|
9
|
+
const layoutProps = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ locale,
|
|
10
|
+
options }, (actionOrders ? { actionOrders } : {})), (banner ? { banner } : {})), (bannerHeight != null ? { bannerHeight } : {})), (defaultLocale ? { defaultLocale } : {})), (floatingNav != null ? { floatingNav } : {})), (footer ? { footer } : {})), (goToTop ? { goToTop } : {})), (headerHeight != null ? { headerHeight } : {})), (headerPaddingTop != null ? { headerPaddingTop } : {})), (localePrefixAsNeeded != null ? { localePrefixAsNeeded } : {})), (navbarClassName ? { navbarClassName } : {})), (showBanner != null ? { showBanner } : {})), (showFooter != null ? { showFooter } : {})), (showGoToTop != null ? { showGoToTop } : {}));
|
|
11
11
|
return jsx(CustomHomeLayout, Object.assign({}, layoutProps, { children: children }));
|
|
12
12
|
}
|
|
13
13
|
|
|
@@ -47,9 +47,8 @@ export interface SiteBaseLayoutConfig {
|
|
|
47
47
|
githubUrl?: string;
|
|
48
48
|
links?: SiteNavItemConfig[];
|
|
49
49
|
searchToggle?: HomeLayoutProps['searchToggle'];
|
|
50
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
51
50
|
}
|
|
52
|
-
export type SiteThemeSwitchMode = 'light-dark-system' | 'light-
|
|
51
|
+
export type SiteThemeSwitchMode = 'light-dark-system' | 'light-only' | 'dark-only';
|
|
53
52
|
export interface SiteThemeSwitchConfig {
|
|
54
53
|
mode?: SiteThemeSwitchMode;
|
|
55
54
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { SiteThemeSwitchMode } from './site-layout-shared';
|
|
3
|
+
import { type SiteThemeProviderProps } from './site-theme-provider';
|
|
4
|
+
export declare function useSiteThemeMode(): SiteThemeSwitchMode;
|
|
5
|
+
export interface SiteThemeRootProviderProps extends Omit<SiteThemeProviderProps, 'children'> {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
export declare function SiteThemeRootProvider({ mode, children, ...props }: SiteThemeRootProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var tslib = require('tslib');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
var React = require('react');
|
|
7
|
+
var siteThemeProvider = require('./site-theme-provider.js');
|
|
8
|
+
|
|
9
|
+
const SiteThemeModeContext = React.createContext('light-dark-system');
|
|
10
|
+
function useSiteThemeMode() {
|
|
11
|
+
return React.useContext(SiteThemeModeContext);
|
|
12
|
+
}
|
|
13
|
+
function SiteThemeRootProvider(_a) {
|
|
14
|
+
var { mode = 'light-dark-system', children } = _a, props = tslib.__rest(_a, ["mode", "children"]);
|
|
15
|
+
return (jsxRuntime.jsx(SiteThemeModeContext.Provider, { value: mode, children: jsxRuntime.jsx(siteThemeProvider.SiteThemeProvider, Object.assign({}, props, { mode: mode, children: children })) }));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
exports.SiteThemeRootProvider = SiteThemeRootProvider;
|
|
19
|
+
exports.useSiteThemeMode = useSiteThemeMode;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { __rest } from 'tslib';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { createContext, useContext } from 'react';
|
|
5
|
+
import { SiteThemeProvider } from './site-theme-provider.mjs';
|
|
6
|
+
|
|
7
|
+
const SiteThemeModeContext = createContext('light-dark-system');
|
|
8
|
+
function useSiteThemeMode() {
|
|
9
|
+
return useContext(SiteThemeModeContext);
|
|
10
|
+
}
|
|
11
|
+
function SiteThemeRootProvider(_a) {
|
|
12
|
+
var { mode = 'light-dark-system', children } = _a, props = __rest(_a, ["mode", "children"]);
|
|
13
|
+
return (jsx(SiteThemeModeContext.Provider, { value: mode, children: jsx(SiteThemeProvider, Object.assign({}, props, { mode: mode, children: children })) }));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { SiteThemeRootProvider, useSiteThemeMode };
|
|
@@ -24,13 +24,6 @@ function resolveThemeProviderProps(mode) {
|
|
|
24
24
|
defaultTheme: 'dark',
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
if (mode === 'light-dark') {
|
|
28
|
-
return {
|
|
29
|
-
enableSystem: false,
|
|
30
|
-
defaultTheme: 'light',
|
|
31
|
-
forcedTheme: undefined,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
27
|
return {
|
|
35
28
|
enableSystem: true,
|
|
36
29
|
defaultTheme: 'system',
|
|
@@ -22,13 +22,6 @@ function resolveThemeProviderProps(mode) {
|
|
|
22
22
|
defaultTheme: 'dark',
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
if (mode === 'light-dark') {
|
|
26
|
-
return {
|
|
27
|
-
enableSystem: false,
|
|
28
|
-
defaultTheme: 'light',
|
|
29
|
-
forcedTheme: undefined,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
25
|
return {
|
|
33
26
|
enableSystem: true,
|
|
34
27
|
defaultTheme: 'system',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windrun-huaiin/third-ui",
|
|
3
|
-
"version": "31.
|
|
3
|
+
"version": "31.2.0",
|
|
4
4
|
"description": "Third-party integrated UI components for windrun-huaiin projects",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./clerk": {
|
|
@@ -243,9 +243,9 @@
|
|
|
243
243
|
"tslib": "^2.8.1",
|
|
244
244
|
"unified": "^11.0.5",
|
|
245
245
|
"zod": "^4.3.6",
|
|
246
|
+
"@windrun-huaiin/lib": "^31.0.1",
|
|
246
247
|
"@windrun-huaiin/base-ui": "^31.0.0",
|
|
247
|
-
"@windrun-huaiin/contracts": "^31.0.0"
|
|
248
|
-
"@windrun-huaiin/lib": "^31.0.0"
|
|
248
|
+
"@windrun-huaiin/contracts": "^31.0.0"
|
|
249
249
|
},
|
|
250
250
|
"peerDependencies": {
|
|
251
251
|
"clsx": "^2.1.1",
|
|
@@ -35,9 +35,9 @@ import { Popover, PopoverContent, PopoverTrigger } from 'fumadocs-ui/components/
|
|
|
35
35
|
import { buttonVariants } from 'fumadocs-ui/components/ui/button';
|
|
36
36
|
import { useI18n } from 'fumadocs-ui/contexts/i18n';
|
|
37
37
|
import { HeaderThemeSwitch } from './header-theme-switch';
|
|
38
|
+
import { useSiteThemeMode } from './site-theme-context';
|
|
38
39
|
import type {
|
|
39
40
|
ExtendedLinkItem,
|
|
40
|
-
SiteThemeSwitchConfig,
|
|
41
41
|
SiteThemeSwitchMode,
|
|
42
42
|
} from './site-layout-shared';
|
|
43
43
|
|
|
@@ -51,8 +51,7 @@ const PrefetchLinkItem = LinkItem as (
|
|
|
51
51
|
props: ComponentProps<typeof LinkItem> & { prefetch?: boolean },
|
|
52
52
|
) => ReactNode;
|
|
53
53
|
|
|
54
|
-
export interface CustomHomeHeaderProps
|
|
55
|
-
extends Omit<HomeLayoutProps, 'themeSwitch'> {
|
|
54
|
+
export interface CustomHomeHeaderProps extends HomeLayoutProps {
|
|
56
55
|
/**
|
|
57
56
|
* Banner height in rem units
|
|
58
57
|
*
|
|
@@ -97,7 +96,6 @@ export interface CustomHomeHeaderProps
|
|
|
97
96
|
* Control order of utilities inside the mobile dropdown.
|
|
98
97
|
*/
|
|
99
98
|
mobileMenuActionsOrder?: MobileMenuAction[];
|
|
100
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
101
99
|
}
|
|
102
100
|
|
|
103
101
|
export type DesktopAction =
|
|
@@ -137,7 +135,6 @@ export function CustomHomeHeader({
|
|
|
137
135
|
i18n = false,
|
|
138
136
|
links,
|
|
139
137
|
githubUrl,
|
|
140
|
-
themeSwitch = {},
|
|
141
138
|
searchToggle = {},
|
|
142
139
|
bannerHeight = 0,
|
|
143
140
|
headerHeight = 2.5,
|
|
@@ -148,6 +145,7 @@ export function CustomHomeHeader({
|
|
|
148
145
|
mobileBarActionsOrder = DEFAULT_MOBILE_BAR_ACTIONS,
|
|
149
146
|
mobileMenuActionsOrder = DEFAULT_MOBILE_MENU_ACTIONS,
|
|
150
147
|
}: CustomHomeHeaderProps) {
|
|
148
|
+
const themeMode = useSiteThemeMode();
|
|
151
149
|
const finalLinks = useMemo(
|
|
152
150
|
() => resolveLinkItems({ links, githubUrl }),
|
|
153
151
|
[links, githubUrl],
|
|
@@ -181,10 +179,10 @@ export function CustomHomeHeader({
|
|
|
181
179
|
? searchToggle.components?.lg ?? null
|
|
182
180
|
: null,
|
|
183
181
|
theme:
|
|
184
|
-
shouldShowThemeSwitch(
|
|
182
|
+
shouldShowThemeSwitch(themeMode)
|
|
185
183
|
? (
|
|
186
184
|
<HeaderThemeSwitch
|
|
187
|
-
mode={normalizeThemeSwitchMode(
|
|
185
|
+
mode={normalizeThemeSwitchMode(themeMode)}
|
|
188
186
|
/>
|
|
189
187
|
)
|
|
190
188
|
: null,
|
|
@@ -248,10 +246,10 @@ export function CustomHomeHeader({
|
|
|
248
246
|
</CompactLanguageToggle>
|
|
249
247
|
) : null,
|
|
250
248
|
theme:
|
|
251
|
-
shouldShowThemeSwitch(
|
|
249
|
+
shouldShowThemeSwitch(themeMode)
|
|
252
250
|
? (
|
|
253
251
|
<HeaderThemeSwitch
|
|
254
|
-
mode={normalizeThemeSwitchMode(
|
|
252
|
+
mode={normalizeThemeSwitchMode(themeMode)}
|
|
255
253
|
/>
|
|
256
254
|
)
|
|
257
255
|
: null,
|
|
@@ -371,13 +369,13 @@ export function CustomHomeHeader({
|
|
|
371
369
|
}
|
|
372
370
|
|
|
373
371
|
function shouldShowThemeSwitch(mode?: SiteThemeSwitchMode): boolean {
|
|
374
|
-
return mode === 'light-dark
|
|
372
|
+
return mode === 'light-dark-system' || mode == null;
|
|
375
373
|
}
|
|
376
374
|
|
|
377
375
|
function normalizeThemeSwitchMode(
|
|
378
376
|
mode?: SiteThemeSwitchMode,
|
|
379
|
-
): 'light-dark
|
|
380
|
-
return
|
|
377
|
+
): 'light-dark-system' {
|
|
378
|
+
return 'light-dark-system';
|
|
381
379
|
}
|
|
382
380
|
|
|
383
381
|
interface CustomNavbarProps extends ComponentProps<'div'> {
|
|
@@ -3,16 +3,13 @@ import { HomeLayout, type HomeLayoutProps } from 'fumadocs-ui/layouts/home';
|
|
|
3
3
|
import { FumaBannerSuit } from '../fuma-banner-suit';
|
|
4
4
|
import { Footer } from '../../main/footer';
|
|
5
5
|
import { GoToTop } from '../../main/go-to-top';
|
|
6
|
-
import { SiteThemeProvider } from './site-theme-provider';
|
|
7
6
|
import {
|
|
8
7
|
NavbarCSSVars,
|
|
9
8
|
CustomHomeHeader,
|
|
10
9
|
type DesktopAction,
|
|
11
10
|
type MobileBarAction,
|
|
12
11
|
type MobileMenuAction,
|
|
13
|
-
type CustomHomeHeaderProps,
|
|
14
12
|
} from './custom-header';
|
|
15
|
-
import type { SiteThemeSwitchConfig } from './site-layout-shared';
|
|
16
13
|
|
|
17
14
|
// - Set bannerHeight/headerHeight to the rem values expected by the project. Use bannerHeight = 0 when there is no banner.
|
|
18
15
|
// - layoutStyle passes the variables to HomeLayout's main element, offsetting content without has-banner/no-banner classes.
|
|
@@ -94,10 +91,6 @@ export interface CustomHomeLayoutProps {
|
|
|
94
91
|
* The default locale for the application (default: 'en')
|
|
95
92
|
*/
|
|
96
93
|
defaultLocale?: string;
|
|
97
|
-
/**
|
|
98
|
-
* Theme mode for this layout group.
|
|
99
|
-
*/
|
|
100
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
101
94
|
children?: ReactNode;
|
|
102
95
|
}
|
|
103
96
|
|
|
@@ -126,7 +119,6 @@ export function CustomHomeLayout({
|
|
|
126
119
|
actionOrders,
|
|
127
120
|
localePrefixAsNeeded = true,
|
|
128
121
|
defaultLocale = 'en',
|
|
129
|
-
themeSwitch,
|
|
130
122
|
}: CustomHomeLayoutProps) {
|
|
131
123
|
const resolvedBannerHeight = bannerHeight ?? (showBanner ? 3 : 0.5);
|
|
132
124
|
const resolvedPaddingTop =
|
|
@@ -147,7 +139,6 @@ export function CustomHomeLayout({
|
|
|
147
139
|
<CustomHomeHeader
|
|
148
140
|
{...homeLayoutProps}
|
|
149
141
|
nav={navOptions}
|
|
150
|
-
themeSwitch={themeSwitch}
|
|
151
142
|
bannerHeight={resolvedBannerHeight}
|
|
152
143
|
headerHeight={headerHeight}
|
|
153
144
|
navbarClassName={navbarClassName}
|
|
@@ -157,7 +148,6 @@ export function CustomHomeLayout({
|
|
|
157
148
|
mobileMenuActionsOrder={actionOrders?.mobileMenu}
|
|
158
149
|
/>
|
|
159
150
|
);
|
|
160
|
-
const themeMode = themeSwitch?.mode ?? 'light-dark-system';
|
|
161
151
|
|
|
162
152
|
return (
|
|
163
153
|
<>
|
|
@@ -168,7 +158,6 @@ export function CustomHomeLayout({
|
|
|
168
158
|
floating={floatingNav}
|
|
169
159
|
/>
|
|
170
160
|
)}
|
|
171
|
-
<SiteThemeProvider mode={themeMode}>
|
|
172
161
|
<HomeLayout
|
|
173
162
|
{...homeLayoutProps}
|
|
174
163
|
nav={{
|
|
@@ -182,7 +171,6 @@ export function CustomHomeLayout({
|
|
|
182
171
|
{showFooter ? footer ?? <Footer locale={locale} localePrefixAsNeeded={localePrefixAsNeeded} defaultLocale={defaultLocale} /> : null}
|
|
183
172
|
{showGoToTop ? goToTop ?? <GoToTop /> : null}
|
|
184
173
|
</HomeLayout>
|
|
185
|
-
</SiteThemeProvider>
|
|
186
174
|
</>
|
|
187
175
|
);
|
|
188
176
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps, ReactNode } from 'react';
|
|
2
2
|
import { NextProvider } from 'fumadocs-core/framework/next';
|
|
3
3
|
import { I18nProvider, type I18nProviderProps } from 'fumadocs-ui/contexts/i18n';
|
|
4
|
+
import { SiteThemeRootProvider } from './site-theme-context';
|
|
5
|
+
import type { SiteThemeProviderProps } from './site-theme-provider';
|
|
4
6
|
|
|
5
7
|
type NextProviderComponents = {
|
|
6
8
|
Link?: ComponentProps<typeof NextProvider>['Link'];
|
|
@@ -9,22 +11,28 @@ type NextProviderComponents = {
|
|
|
9
11
|
|
|
10
12
|
export interface DocsRootProviderProps {
|
|
11
13
|
i18n: Omit<I18nProviderProps, 'children'>;
|
|
14
|
+
theme?: Omit<SiteThemeProviderProps, 'children'>;
|
|
12
15
|
components?: NextProviderComponents;
|
|
13
16
|
children: ReactNode;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
export function DocsRootProvider({
|
|
17
20
|
i18n,
|
|
21
|
+
theme = {},
|
|
18
22
|
components,
|
|
19
23
|
children,
|
|
20
24
|
}: DocsRootProviderProps) {
|
|
25
|
+
const themeMode = theme.mode ?? 'light-dark-system';
|
|
26
|
+
|
|
21
27
|
return (
|
|
22
28
|
<NextProvider
|
|
23
29
|
Link={components?.Link}
|
|
24
30
|
Image={components?.Image}
|
|
25
31
|
>
|
|
26
32
|
<I18nProvider {...i18n}>
|
|
27
|
-
{
|
|
33
|
+
<SiteThemeRootProvider {...theme} mode={themeMode}>
|
|
34
|
+
{children}
|
|
35
|
+
</SiteThemeRootProvider>
|
|
28
36
|
</I18nProvider>
|
|
29
37
|
</NextProvider>
|
|
30
38
|
);
|
|
@@ -19,15 +19,14 @@ const itemVariants = cva('inline-flex size-6.5 items-center justify-center round
|
|
|
19
19
|
const full = [['light', SunIcon] as const, ['dark', MoonIcon] as const, ['system', AirplayIcon] as const];
|
|
20
20
|
|
|
21
21
|
export interface HeaderThemeSwitchProps extends ComponentProps<'div'> {
|
|
22
|
-
mode?:
|
|
22
|
+
mode?: 'light-dark-system';
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function HeaderThemeSwitch({
|
|
26
26
|
className,
|
|
27
|
-
mode = 'light-dark',
|
|
28
27
|
...props
|
|
29
28
|
}: HeaderThemeSwitchProps) {
|
|
30
|
-
const { setTheme, theme
|
|
29
|
+
const { setTheme, theme } = useTheme();
|
|
31
30
|
const [mounted, setMounted] = useState(false);
|
|
32
31
|
|
|
33
32
|
useEffect(() => {
|
|
@@ -40,35 +39,6 @@ export function HeaderThemeSwitch({
|
|
|
40
39
|
);
|
|
41
40
|
const iconClassName = 'size-3.5 text-neutral-600 dark:text-neutral-300';
|
|
42
41
|
|
|
43
|
-
if (mode === 'light-dark') {
|
|
44
|
-
const value = mounted ? resolvedTheme : null;
|
|
45
|
-
|
|
46
|
-
return (
|
|
47
|
-
<button
|
|
48
|
-
type="button"
|
|
49
|
-
className={container}
|
|
50
|
-
aria-label="Toggle Theme"
|
|
51
|
-
onClick={() => setTheme(value === 'light' ? 'dark' : 'light')}
|
|
52
|
-
data-theme-toggle=""
|
|
53
|
-
>
|
|
54
|
-
{full.map(([key, Icon]) => {
|
|
55
|
-
if (key === 'system') return null;
|
|
56
|
-
|
|
57
|
-
return (
|
|
58
|
-
<Icon
|
|
59
|
-
key={key}
|
|
60
|
-
fill="currentColor"
|
|
61
|
-
className={cn(
|
|
62
|
-
itemVariants({ active: value === key }),
|
|
63
|
-
iconClassName,
|
|
64
|
-
)}
|
|
65
|
-
/>
|
|
66
|
-
);
|
|
67
|
-
})}
|
|
68
|
-
</button>
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
42
|
const value = mounted ? theme : null;
|
|
73
43
|
|
|
74
44
|
return (
|
|
@@ -4,36 +4,25 @@ import {
|
|
|
4
4
|
normalizeNavItems,
|
|
5
5
|
type SiteBaseLayoutConfig,
|
|
6
6
|
} from './site-layout-shared';
|
|
7
|
-
import {
|
|
7
|
+
import { SiteDocsThemeSwitch } from './site-docs-theme-switch';
|
|
8
8
|
|
|
9
9
|
export interface SiteDocsLayoutConfig extends SiteBaseLayoutConfig {
|
|
10
10
|
tree: DocsLayoutProps['tree'];
|
|
11
11
|
sidebar?: DocsLayoutProps['sidebar'];
|
|
12
|
-
|
|
12
|
+
slots?: DocsLayoutProps['slots'];
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
function toDocsLayoutOptions(config: SiteDocsLayoutConfig): DocsLayoutProps {
|
|
16
|
-
const themeMode = config.themeSwitch?.mode ?? 'light-dark-system';
|
|
17
|
-
const shouldShowThemeSwitch =
|
|
18
|
-
config.themeProvider !== false &&
|
|
19
|
-
(themeMode === 'light-dark' || themeMode === 'light-dark-system');
|
|
20
16
|
return {
|
|
21
17
|
...(config.nav ? { nav: config.nav } : {}),
|
|
22
18
|
...(config.i18n ? { i18n: config.i18n } : {}),
|
|
23
19
|
...(config.githubUrl ? { githubUrl: config.githubUrl } : {}),
|
|
24
20
|
...(config.links ? { links: normalizeNavItems(config.links) } : {}),
|
|
25
21
|
...(config.searchToggle ? { searchToggle: config.searchToggle } : {}),
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
: {
|
|
33
|
-
themeSwitch: {
|
|
34
|
-
enabled: false,
|
|
35
|
-
},
|
|
36
|
-
}),
|
|
22
|
+
slots: {
|
|
23
|
+
...config.slots,
|
|
24
|
+
themeSwitch: SiteDocsThemeSwitch,
|
|
25
|
+
},
|
|
37
26
|
...(config.sidebar ? { sidebar: config.sidebar } : {}),
|
|
38
27
|
tree: config.tree,
|
|
39
28
|
};
|
|
@@ -47,10 +36,6 @@ export function SiteDocsLayout({
|
|
|
47
36
|
children: ReactNode;
|
|
48
37
|
}) {
|
|
49
38
|
const options = toDocsLayoutOptions(config);
|
|
50
|
-
const themeMode = config.themeSwitch?.mode ?? 'light-dark-system';
|
|
51
|
-
const body = <DocsLayout {...options}>{children}</DocsLayout>;
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return <SiteThemeProvider mode={themeMode}>{body}</SiteThemeProvider>;
|
|
40
|
+
return <DocsLayout {...options}>{children}</DocsLayout>;
|
|
56
41
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { ComponentProps } from 'react';
|
|
4
|
+
import { HeaderThemeSwitch } from './header-theme-switch';
|
|
5
|
+
import { useSiteThemeMode } from './site-theme-context';
|
|
6
|
+
|
|
7
|
+
export function SiteDocsThemeSwitch(props: ComponentProps<'div'>) {
|
|
8
|
+
const themeMode = useSiteThemeMode();
|
|
9
|
+
|
|
10
|
+
if (themeMode !== 'light-dark-system') {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return <HeaderThemeSwitch {...props} mode="light-dark-system" />;
|
|
15
|
+
}
|
|
@@ -72,7 +72,6 @@ export function SiteHomeLayout({
|
|
|
72
72
|
...(showBanner != null ? { showBanner } : {}),
|
|
73
73
|
...(showFooter != null ? { showFooter } : {}),
|
|
74
74
|
...(showGoToTop != null ? { showGoToTop } : {}),
|
|
75
|
-
...(config.themeSwitch ? { themeSwitch: config.themeSwitch } : {}),
|
|
76
75
|
};
|
|
77
76
|
|
|
78
77
|
return <CustomHomeLayout {...layoutProps}>{children}</CustomHomeLayout>;
|
|
@@ -58,12 +58,10 @@ export interface SiteBaseLayoutConfig {
|
|
|
58
58
|
githubUrl?: string;
|
|
59
59
|
links?: SiteNavItemConfig[];
|
|
60
60
|
searchToggle?: HomeLayoutProps['searchToggle'];
|
|
61
|
-
themeSwitch?: SiteThemeSwitchConfig;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export type SiteThemeSwitchMode =
|
|
65
64
|
| 'light-dark-system'
|
|
66
|
-
| 'light-dark'
|
|
67
65
|
| 'light-only'
|
|
68
66
|
| 'dark-only';
|
|
69
67
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, type ReactNode, useContext } from 'react';
|
|
4
|
+
import type { SiteThemeSwitchMode } from './site-layout-shared';
|
|
5
|
+
import { SiteThemeProvider, type SiteThemeProviderProps } from './site-theme-provider';
|
|
6
|
+
|
|
7
|
+
const SiteThemeModeContext = createContext<SiteThemeSwitchMode>('light-dark-system');
|
|
8
|
+
|
|
9
|
+
export function useSiteThemeMode(): SiteThemeSwitchMode {
|
|
10
|
+
return useContext(SiteThemeModeContext);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SiteThemeRootProviderProps
|
|
14
|
+
extends Omit<SiteThemeProviderProps, 'children'> {
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function SiteThemeRootProvider({
|
|
19
|
+
mode = 'light-dark-system',
|
|
20
|
+
children,
|
|
21
|
+
...props
|
|
22
|
+
}: SiteThemeRootProviderProps) {
|
|
23
|
+
return (
|
|
24
|
+
<SiteThemeModeContext.Provider value={mode}>
|
|
25
|
+
<SiteThemeProvider {...props} mode={mode}>
|
|
26
|
+
{children}
|
|
27
|
+
</SiteThemeProvider>
|
|
28
|
+
</SiteThemeModeContext.Provider>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
@@ -43,14 +43,6 @@ function resolveThemeProviderProps(mode: SiteThemeSwitchMode): ThemeProviderProp
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
if (mode === 'light-dark') {
|
|
47
|
-
return {
|
|
48
|
-
enableSystem: false,
|
|
49
|
-
defaultTheme: 'light',
|
|
50
|
-
forcedTheme: undefined,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
46
|
return {
|
|
55
47
|
enableSystem: true,
|
|
56
48
|
defaultTheme: 'system',
|