Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 90cf1fe

Browse files
committed
UI: Support tabMode on <DocsLayout />
1 parent 1d56767 commit 90cf1fe

File tree

9 files changed

+91
-17
lines changed

9 files changed

+91
-17
lines changed

.changeset/all-cooks-smile.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'fumadocs-ui': patch
3+
---
4+
5+
Support `tabMode` on `<DocsLayout />`

.changeset/new-dryers-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'fumadocs-core': patch
3+
---
4+
5+
Support Negotiation API

packages/press/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './vite';

packages/press/src/vite.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PluginOption } from 'vite';
1+
import type { PluginOption } from 'vite';
22
import rsc from '@vitejs/plugin-rsc';
33
import tailwindcss from '@tailwindcss/vite';
44
import { unstable_reactRouterRSC as reactRouterRSC } from '@react-router/dev/vite';

packages/press/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export default defineConfig({
44
dts: true,
55
target: 'es2022',
66
format: 'esm',
7-
entry: [],
7+
entry: ['src/index.ts'],
88
});

packages/ui/src/layouts/docs/client.tsx

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
'use client';
22

33
import { Sidebar as SidebarIcon } from 'lucide-react';
4-
import { type ComponentProps } from 'react';
4+
import { type ComponentProps, useMemo } from 'react';
55
import { cn } from '@/utils/cn';
66
import { buttonVariants } from '@/components/ui/button';
77
import { useSidebar } from '@/contexts/sidebar';
88
import { useNav } from '@/contexts/layout';
99
import { SidebarCollapseTrigger } from '@/components/layout/sidebar';
1010
import { SearchToggle } from '@/components/layout/search-toggle';
11+
import type { Option } from '@/components/layout/root-toggle';
12+
import { usePathname } from 'fumadocs-core/framework';
13+
import { isTabActive } from '@/utils/is-active';
14+
import Link from 'fumadocs-core/link';
1115

1216
export function Navbar(props: ComponentProps<'header'>) {
1317
const { isTransparent } = useNav();
@@ -79,3 +83,56 @@ export function CollapsibleControl() {
7983
</div>
8084
);
8185
}
86+
87+
export function LayoutTabs({
88+
options,
89+
...props
90+
}: ComponentProps<'div'> & {
91+
options: Option[];
92+
}) {
93+
const pathname = usePathname();
94+
const selected = useMemo(() => {
95+
return options.findLast((option) => isTabActive(option, pathname));
96+
}, [options, pathname]);
97+
98+
return (
99+
<div
100+
{...props}
101+
className={cn(
102+
'flex flex-row items-end gap-6 overflow-auto',
103+
props.className,
104+
)}
105+
>
106+
{options.map((option) => (
107+
<LayoutTab
108+
key={option.url}
109+
selected={selected === option}
110+
option={option}
111+
/>
112+
))}
113+
</div>
114+
);
115+
}
116+
117+
function LayoutTab({
118+
option: { title, url, unlisted, props },
119+
selected = false,
120+
}: {
121+
option: Option;
122+
selected?: boolean;
123+
}) {
124+
return (
125+
<Link
126+
href={url}
127+
{...props}
128+
className={cn(
129+
'inline-flex border-b-2 border-transparent transition-colors items-center pb-1.5 font-medium gap-2 text-fd-muted-foreground text-sm text-nowrap hover:text-fd-accent-foreground',
130+
unlisted && !selected && 'hidden',
131+
selected && 'border-fd-primary text-fd-primary',
132+
props?.className,
133+
)}
134+
>
135+
{title}
136+
</Link>
137+
);
138+
}

packages/ui/src/layouts/docs/index.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ import {
3838
LanguageToggle,
3939
LanguageToggleText,
4040
} from '@/components/layout/language-toggle';
41-
import { CollapsibleControl, LayoutBody, Navbar } from '@/layouts/docs/client';
41+
import {
42+
CollapsibleControl,
43+
LayoutBody,
44+
LayoutTabs,
45+
Navbar,
46+
} from '@/layouts/docs/client';
4247
import { TreeContextProvider } from '@/contexts/tree';
4348
import { ThemeToggle } from '@/components/layout/theme-toggle';
4449
import { NavProvider } from '@/contexts/layout';
@@ -58,6 +63,8 @@ export interface DocsLayoutProps extends BaseLayoutProps {
5863

5964
sidebar?: SidebarOptions;
6065

66+
tabMode?: 'top' | 'auto';
67+
6168
/**
6269
* Props for the `div` container
6370
*/
@@ -95,8 +102,8 @@ export function DocsLayout({
95102
...sidebarProps
96103
} = {},
97104
searchToggle = {},
98-
disableThemeSwitch = false,
99-
themeSwitch = { enabled: !disableThemeSwitch },
105+
themeSwitch = {},
106+
tabMode = 'auto',
100107
i18n = false,
101108
children,
102109
...props
@@ -231,8 +238,9 @@ export function DocsLayout({
231238
(searchToggle.components?.lg ?? (
232239
<LargeSearchToggle hideIfDisabled />
233240
))}
234-
{tabs.length > 0 && <RootToggle options={tabs} />}
235-
241+
{tabs.length > 0 && tabMode === 'auto' && (
242+
<RootToggle options={tabs} />
243+
)}
236244
{banner}
237245
</SidebarHeader>
238246
{viewport}
@@ -321,6 +329,12 @@ export function DocsLayout({
321329
)}
322330
>
323331
{sidebarEnabled && sidebar()}
332+
{tabMode === 'top' && tabs.length > 0 && (
333+
<LayoutTabs
334+
options={tabs}
335+
className="sticky top-[calc(var(--fd-nav-height)+var(--fd-tocnav-height))] z-10 bg-fd-background border-b px-6 pt-3 xl:px-8 max-md:hidden"
336+
/>
337+
)}
324338
{children}
325339
</LayoutBody>
326340
</NavProvider>

packages/ui/src/layouts/notebook/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,7 @@ export function DocsLayout(props: DocsLayoutProps) {
106106
nav: { transparentMode, ...nav } = {},
107107
sidebar: { tabs: tabOptions, ...sidebarProps } = {},
108108
i18n = false,
109-
disableThemeSwitch = false,
110-
themeSwitch = { enabled: !disableThemeSwitch },
109+
themeSwitch = {},
111110
} = props;
112111

113112
const navMode = nav.mode ?? 'auto';

packages/ui/src/layouts/shared/index.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,6 @@ export interface BaseLayoutProps {
3232
}>;
3333
}>;
3434

35-
/**
36-
* Remove theme switcher component
37-
*
38-
* @deprecated Use `themeSwitch.enabled` instead.
39-
*/
40-
disableThemeSwitch?: boolean;
41-
4235
/**
4336
* I18n options
4437
*

0 commit comments

Comments
 (0)