Skip to content

Commit d9cb888

Browse files
committed
add edit on github
1 parent a77a73f commit d9cb888

30 files changed

+3222
-3
lines changed

app/content/[[...slug]]/page.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { notFound } from 'next/navigation';
99
import { getMDXComponents } from '@/mdx-components';
1010
import type { Metadata } from 'next';
1111
import { createRelativeLink } from 'fumadocs-ui/mdx';
12+
import { GithubIcon } from 'lucide-react';
1213

1314
export default async function Page(props: PageProps<'/content/[[...slug]]'>) {
1415
const params = await props.params;
@@ -18,7 +19,20 @@ export default async function Page(props: PageProps<'/content/[[...slug]]'>) {
1819
const MDX = page.data.body;
1920

2021
return (
21-
<DocsPage toc={page.data.toc} full={page.data.full}>
22+
<DocsPage toc={page.data.toc} full={page.data.full}
23+
>
24+
25+
<div className="flex mb-4">
26+
<a
27+
href={`https://github.com/pulsebeamdev/docs/blob/main/content/${page.path}`}
28+
rel="noreferrer noopener"
29+
target="_blank"
30+
className="inline-flex items-center gap-2 rounded-md border bg-fd-secondary px-2 py-1 text-xs font-medium text-fd-secondary-foreground transition-colors hover:bg-fd-accent hover:text-fd-accent-foreground"
31+
>
32+
<GithubIcon className="size-3" />
33+
Edit on GitHub
34+
</a>
35+
</div>
2236
<DocsTitle>{page.data.title}</DocsTitle>
2337
<DocsDescription>{page.data.description}</DocsDescription>
2438
<DocsBody>

cli.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "node_modules/@fumadocs/cli/dist/schema/default.json",
3+
"aliases": {
4+
"uiDir": "./components/ui",
5+
"componentsDir": "./components",
6+
"blockDir": "./components",
7+
"cssDir": "./styles",
8+
"libDir": "./lib"
9+
},
10+
"baseDir": "",
11+
"uiLibrary": "radix-ui",
12+
"commands": {}
13+
}

components/layout/docs/client.tsx

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
'use client';
2+
3+
import {
4+
type ComponentProps,
5+
createContext,
6+
type ReactNode,
7+
use,
8+
useMemo,
9+
} from 'react';
10+
import { cn } from '../../../lib/cn';
11+
import { useSidebar } from '../sidebar/base';
12+
import { usePathname } from 'fumadocs-core/framework';
13+
import Link from 'fumadocs-core/link';
14+
import type { SidebarTab } from '../sidebar/tabs';
15+
import { isTabActive } from '../sidebar/tabs/dropdown';
16+
import { useIsScrollTop } from 'fumadocs-ui/utils/use-is-scroll-top';
17+
18+
export const LayoutContext = createContext<{
19+
isNavTransparent: boolean;
20+
} | null>(null);
21+
22+
export function LayoutContextProvider({
23+
navTransparentMode = 'none',
24+
children,
25+
}: {
26+
navTransparentMode?: 'always' | 'top' | 'none';
27+
children: ReactNode;
28+
}) {
29+
const isTop =
30+
useIsScrollTop({ enabled: navTransparentMode === 'top' }) ?? true;
31+
const isNavTransparent =
32+
navTransparentMode === 'top' ? isTop : navTransparentMode === 'always';
33+
34+
return (
35+
<LayoutContext
36+
value={useMemo(
37+
() => ({
38+
isNavTransparent,
39+
}),
40+
[isNavTransparent],
41+
)}
42+
>
43+
{children}
44+
</LayoutContext>
45+
);
46+
}
47+
48+
export function LayoutHeader(props: ComponentProps<'header'>) {
49+
const { isNavTransparent } = use(LayoutContext)!;
50+
51+
return (
52+
<header data-transparent={isNavTransparent} {...props}>
53+
{props.children}
54+
</header>
55+
);
56+
}
57+
58+
export function LayoutBody({
59+
className,
60+
style,
61+
children,
62+
...props
63+
}: ComponentProps<'div'>) {
64+
const { collapsed } = useSidebar();
65+
66+
return (
67+
<div
68+
id="nd-docs-layout"
69+
className={cn(
70+
'grid transition-[grid-template-columns] overflow-x-clip min-h-(--fd-docs-height) auto-cols-auto auto-rows-auto [--fd-docs-height:100dvh] [--fd-header-height:0px] [--fd-toc-popover-height:0px] [--fd-sidebar-width:0px] [--fd-toc-width:0px]',
71+
className,
72+
)}
73+
data-sidebar-collapsed={collapsed}
74+
style={
75+
{
76+
gridTemplate: `"sidebar header toc"
77+
"sidebar toc-popover toc"
78+
"sidebar main toc" 1fr / minmax(var(--fd-sidebar-col), 1fr) minmax(0, calc(var(--fd-layout-width,97rem) - var(--fd-sidebar-width) - var(--fd-toc-width))) minmax(min-content, 1fr)`,
79+
'--fd-docs-row-1': 'var(--fd-banner-height, 0px)',
80+
'--fd-docs-row-2':
81+
'calc(var(--fd-docs-row-1) + var(--fd-header-height))',
82+
'--fd-docs-row-3':
83+
'calc(var(--fd-docs-row-2) + var(--fd-toc-popover-height))',
84+
'--fd-sidebar-col': collapsed ? '0px' : 'var(--fd-sidebar-width)',
85+
...style,
86+
} as object
87+
}
88+
{...props}
89+
>
90+
{children}
91+
</div>
92+
);
93+
}
94+
95+
export function LayoutTabs({
96+
options,
97+
...props
98+
}: ComponentProps<'div'> & {
99+
options: SidebarTab[];
100+
}) {
101+
const pathname = usePathname();
102+
const selected = useMemo(() => {
103+
return options.findLast((option) => isTabActive(option, pathname));
104+
}, [options, pathname]);
105+
106+
return (
107+
<div
108+
{...props}
109+
className={cn(
110+
'flex flex-row items-end gap-6 overflow-auto [grid-area:main]',
111+
props.className,
112+
)}
113+
>
114+
{options.map((option, i) => (
115+
<Link
116+
key={i}
117+
href={option.url}
118+
className={cn(
119+
'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',
120+
option.unlisted && selected !== option && 'hidden',
121+
selected === option && 'border-fd-primary text-fd-primary',
122+
)}
123+
>
124+
{option.title}
125+
</Link>
126+
))}
127+
</div>
128+
);
129+
}

0 commit comments

Comments
 (0)