Skip to content

Commit eb13e2c

Browse files
committed
feat: better docs
1 parent 11e918e commit eb13e2c

32 files changed

+1194
-372
lines changed

apps/docs/app/global.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
--color-sidebar-ring: var(--sidebar-ring);
4747

4848
--font-sans: var(--font-sans);
49-
--font-mono: var(--font-mono);
49+
--font-mono: var(--font-geist-mono);
5050
--font-serif: var(--font-serif);
5151
--font-manrope: var(--font-manrope);
5252

apps/docs/app/layout.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import './global.css';
22
import { RootProvider } from 'fumadocs-ui/provider';
33
import type { Metadata, Viewport } from 'next';
4-
import { Geist, Manrope } from 'next/font/google';
4+
import { Geist, Geist_Mono, Manrope } from 'next/font/google';
55
import Head from 'next/head';
66
import Script from 'next/script';
77
import { ThemeProvider } from 'next-themes';
@@ -15,6 +15,12 @@ const geist = Geist({
1515
variable: '--font-geist',
1616
});
1717

18+
const geistMono = Geist_Mono({
19+
subsets: ['latin'],
20+
weight: ['400', '500', '600', '700'],
21+
variable: '--font-geist-mono',
22+
});
23+
1824
const manrope = Manrope({
1925
subsets: ['latin'],
2026
weight: ['400', '500', '600', '700'],
@@ -90,7 +96,7 @@ export const viewport: Viewport = {
9096
export default function Layout({ children }: { children: ReactNode }) {
9197
return (
9298
<html
93-
className={`${geist.className} ${manrope.className}`}
99+
className={`${manrope.variable} ${geist.className} ${geistMono.variable} `}
94100
lang="en"
95101
suppressHydrationWarning
96102
>

apps/docs/components/custom-sidebar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default function CustomSidebar() {
6565
>
6666
<item.Icon
6767
className="size-5 flex-shrink-0 text-foreground"
68-
weight="duotone"
68+
weight="fill"
6969
/>
7070
<span className="flex-1 text-sm">{item.title}</span>
7171
{item.isNew && <NewBadge />}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import type * as React from 'react';
2+
import { Accordion as BaseAccordion } from '@/components/ui/accordion';
3+
import { cn } from '@/lib/utils';
4+
5+
export {
6+
AccordionContent,
7+
AccordionItem,
8+
AccordionTrigger,
9+
} from '@/components/ui/accordion';
10+
11+
function Accordion({
12+
className,
13+
...props
14+
}: React.ComponentProps<typeof BaseAccordion>) {
15+
return (
16+
<BaseAccordion className={cn('w-full space-y-2', className)} {...props} />
17+
);
18+
}
19+
20+
// Accordions wrapper component
21+
interface AccordionsProps extends React.ComponentProps<'div'> {
22+
type?: 'single' | 'multiple';
23+
collapsible?: boolean;
24+
}
25+
26+
function Accordions({
27+
className,
28+
type = 'single',
29+
collapsible = true,
30+
children,
31+
...props
32+
}: AccordionsProps) {
33+
return (
34+
<div
35+
className={cn(
36+
'rounded border border-border bg-card/50 backdrop-blur-sm',
37+
className
38+
)}
39+
{...props}
40+
>
41+
<Accordion collapsible={collapsible} type={type}>
42+
{children}
43+
</Accordion>
44+
</div>
45+
);
46+
}
47+
48+
export { Accordion, Accordions };
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import {
2+
CheckCircleIcon,
3+
InfoIcon,
4+
LightbulbIcon,
5+
WarningCircleIcon,
6+
XCircleIcon,
7+
} from '@phosphor-icons/react/ssr';
8+
import { cva, type VariantProps } from 'class-variance-authority';
9+
import type * as React from 'react';
10+
11+
import { cn } from '@/lib/utils';
12+
13+
const calloutVariants = cva(
14+
'group relative my-4 w-full rounded border backdrop-blur-sm transition-all duration-300',
15+
{
16+
variants: {
17+
type: {
18+
info: 'border-blue-200 bg-blue-50/80 hover:bg-blue-50/90 dark:border-blue-800/50 dark:bg-blue-950/20 dark:hover:bg-blue-950/30',
19+
success:
20+
'border-green-200 bg-green-50/80 hover:bg-green-50/90 dark:border-green-800/50 dark:bg-green-950/20 dark:hover:bg-green-950/30',
21+
warn: 'border-yellow-200 bg-yellow-50/80 hover:bg-yellow-50/90 dark:border-yellow-800/50 dark:bg-yellow-950/20 dark:hover:bg-yellow-950/30',
22+
error:
23+
'border-red-200 bg-red-50/80 hover:bg-red-50/90 dark:border-red-800/50 dark:bg-red-950/20 dark:hover:bg-red-950/30',
24+
tip: 'border-purple-200 bg-purple-50/80 hover:bg-purple-50/90 dark:border-purple-800/50 dark:bg-purple-950/20 dark:hover:bg-purple-950/30',
25+
note: 'border-border bg-card/50 hover:bg-card/70',
26+
},
27+
},
28+
defaultVariants: {
29+
type: 'info',
30+
},
31+
}
32+
);
33+
34+
const iconVariants = cva('size-5 shrink-0', {
35+
variants: {
36+
type: {
37+
info: 'text-blue-500 dark:text-blue-400',
38+
success: 'text-green-500 dark:text-green-400',
39+
warn: 'text-yellow-500 dark:text-yellow-400',
40+
error: 'text-red-500 dark:text-red-400',
41+
tip: 'text-purple-500 dark:text-purple-400',
42+
note: 'text-muted-foreground',
43+
},
44+
},
45+
defaultVariants: {
46+
type: 'info',
47+
},
48+
});
49+
50+
const iconMap = {
51+
info: InfoIcon,
52+
success: CheckCircleIcon,
53+
warn: WarningCircleIcon,
54+
error: XCircleIcon,
55+
tip: LightbulbIcon,
56+
note: InfoIcon,
57+
};
58+
59+
interface CalloutProps
60+
extends React.ComponentProps<'div'>,
61+
VariantProps<typeof calloutVariants> {
62+
title?: string;
63+
}
64+
65+
function Callout({
66+
className,
67+
type = 'info',
68+
title,
69+
children,
70+
...props
71+
}: CalloutProps) {
72+
const Icon = iconMap[type as keyof typeof iconMap];
73+
74+
return (
75+
<div
76+
className={cn(calloutVariants({ type }), className)}
77+
role="alert"
78+
{...props}
79+
>
80+
<div className="flex items-start gap-4 p-4">
81+
<Icon
82+
className={cn(iconVariants({ type }), 'mt-0.5')}
83+
weight="duotone"
84+
/>
85+
<div className="min-w-0 flex-1 space-y-2">
86+
{title && (
87+
<div className="font-semibold text-foreground tracking-tight">
88+
{title}
89+
</div>
90+
)}
91+
<div className="text-foreground text-sm leading-relaxed [&_p]:text-foreground [&_p]:leading-relaxed">
92+
{children}
93+
</div>
94+
</div>
95+
</div>
96+
97+
{/* Sci-fi corners */}
98+
<div className="pointer-events-none absolute inset-0">
99+
<div className="absolute top-0 left-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
100+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
101+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
102+
</div>
103+
<div className="-scale-x-[1] absolute top-0 right-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
104+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
105+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
106+
</div>
107+
<div className="-scale-y-[1] absolute bottom-0 left-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
108+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
109+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
110+
</div>
111+
<div className="-scale-[1] absolute right-0 bottom-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
112+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
113+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
114+
</div>
115+
</div>
116+
</div>
117+
);
118+
}
119+
120+
export { Callout };

apps/docs/components/docs/card.tsx

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import Link from 'next/link';
2+
import type * as React from 'react';
3+
4+
import { cn } from '@/lib/utils';
5+
6+
// Re-export the base card components
7+
export {
8+
CardContent,
9+
CardDescription,
10+
CardHeader,
11+
CardTitle,
12+
} from '@/components/ui/card';
13+
14+
interface CardProps extends React.ComponentProps<'div'> {
15+
href?: string;
16+
title?: string;
17+
description?: string;
18+
icon?: React.ReactNode;
19+
}
20+
21+
function Card({
22+
className,
23+
href,
24+
title,
25+
description,
26+
icon,
27+
children,
28+
...props
29+
}: CardProps) {
30+
const content = (
31+
<div
32+
className={cn(
33+
'group relative h-full rounded border border-border bg-card/50 backdrop-blur-sm transition-all duration-300 hover:bg-card/70',
34+
href && 'cursor-pointer',
35+
className
36+
)}
37+
{...props}
38+
>
39+
<div className="p-6">
40+
{icon && <div className="mb-4 text-muted-foreground">{icon}</div>}
41+
{title && (
42+
<h3 className="mb-3 font-semibold text-foreground text-lg leading-6">
43+
{title}
44+
</h3>
45+
)}
46+
{description && (
47+
<p className="text-muted-foreground text-sm leading-relaxed">
48+
{description}
49+
</p>
50+
)}
51+
{children}
52+
</div>
53+
54+
{/* Sci-fi corners */}
55+
<div className="pointer-events-none absolute inset-0">
56+
<div className="absolute top-0 left-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
57+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
58+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
59+
</div>
60+
<div className="-scale-x-[1] absolute top-0 right-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
61+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
62+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
63+
</div>
64+
<div className="-scale-y-[1] absolute bottom-0 left-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
65+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
66+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
67+
</div>
68+
<div className="-scale-[1] absolute right-0 bottom-0 h-2 w-2 group-hover:animate-[cornerGlitch_0.6s_ease-in-out]">
69+
<div className="absolute top-0 left-0.5 h-0.5 w-1.5 origin-left bg-foreground/20" />
70+
<div className="absolute top-0 left-0 h-2 w-0.5 origin-top bg-foreground/20" />
71+
</div>
72+
</div>
73+
</div>
74+
);
75+
76+
if (href) {
77+
const isExternal = href.startsWith('http');
78+
79+
if (isExternal) {
80+
return (
81+
<a
82+
className="block"
83+
href={href}
84+
rel="noopener noreferrer"
85+
target="_blank"
86+
>
87+
{content}
88+
</a>
89+
);
90+
}
91+
92+
return (
93+
<Link className="block" href={href}>
94+
{content}
95+
</Link>
96+
);
97+
}
98+
99+
return content;
100+
}
101+
102+
interface CardsProps extends React.ComponentProps<'div'> {
103+
cols?: 1 | 2 | 3 | 4;
104+
}
105+
106+
function Cards({ className, cols = 2, children, ...props }: CardsProps) {
107+
const gridCols = {
108+
1: 'grid-cols-1',
109+
2: 'grid-cols-1 md:grid-cols-2',
110+
3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
111+
4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
112+
};
113+
114+
return (
115+
<div className={cn('grid gap-4', gridCols[cols], className)} {...props}>
116+
{children}
117+
</div>
118+
);
119+
}
120+
121+
export { Card, Cards };

0 commit comments

Comments
 (0)