Skip to content

Commit a00c4bf

Browse files
committed
fix(shell-docs): replicate canonical page layout architecture (fixed-height body, internal scroll on content wrapper, sidebar pinning, TOC inside wrapper, route shells)
1 parent 708e5aa commit a00c4bf

9 files changed

Lines changed: 398 additions & 302 deletions

File tree

showcase/shell-docs/src/app/[[...slug]]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function DocsOverview() {
4040
const navTree = buildNavTree(CONTENT_DIR);
4141

4242
return (
43-
<div className="flex" style={{ height: "calc(100vh - 53px)" }}>
43+
<div className="flex h-full w-full">
4444
<SidebarNav className="w-[240px] shrink-0 border-r border-[var(--border)] bg-[var(--bg)] overflow-y-auto p-4">
4545
<SidebarFrameworkSelector />
4646
<div className="mb-4" />

showcase/shell-docs/src/app/[framework]/[[...slug]]/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ function FrameworkLandingPage({ framework }: { framework: string }) {
343343
const tree = mergeFrameworkNav(rootNav, overrideNav, integration.name);
344344

345345
return (
346-
<div className="flex" style={{ height: "calc(100vh - 53px)" }}>
346+
<div className="flex h-full w-full">
347347
<aside className="w-[240px] shrink-0 border-r border-[var(--border)] bg-[var(--bg)] overflow-y-auto p-4">
348348
<SidebarFrameworkSelector />
349349
{tree.map((node, i) => (
@@ -446,7 +446,7 @@ function NotAvailableForFrameworkPage({
446446
}) {
447447
const title = humanizeSlug(slugPath);
448448
return (
449-
<div className="flex" style={{ height: "calc(100vh - 53px)" }}>
449+
<div className="flex h-full w-full">
450450
<aside className="w-[240px] shrink-0 border-r border-[var(--border)] bg-[var(--bg)] overflow-y-auto p-4">
451451
<SidebarFrameworkSelector />
452452
<Link

showcase/shell-docs/src/app/ag-ui/[[...slug]]/page.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,15 @@ export default async function AgUiDocPage({
376376
);
377377
}
378378

379-
// Overview page: no sidebar, card-based landing
379+
// Overview page: no sidebar, card-based landing. Wrap in a scroll
380+
// container because <main> in the root layout is fixed-height with
381+
// hidden overflow (canonical layout architecture).
380382
if (isOverview) {
381-
return <OverviewContent />;
383+
return (
384+
<div className="flex-1 min-w-0 overflow-y-auto">
385+
<OverviewContent />
386+
</div>
387+
);
382388
}
383389

384390
// Doc page: sidebar + MDX content. slugPath is user-supplied (URL
@@ -434,7 +440,7 @@ export default async function AgUiDocPage({
434440
}
435441

436442
return (
437-
<div className="flex" style={{ height: "calc(100vh - 53px)" }}>
443+
<div className="flex h-full w-full">
438444
{/* Sidebar */}
439445
<SidebarNav className="w-[220px] shrink-0 border-r border-[var(--border)] bg-[var(--bg)] overflow-y-auto p-4">
440446
<Link

showcase/shell-docs/src/app/layout.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type { Metadata } from "next";
2-
import { Plus_Jakarta_Sans, Spline_Sans_Mono } from "next/font/google";
2+
import { Plus_Jakarta_Sans } from "next/font/google";
33
import Script from "next/script";
44
import { Suspense } from "react";
55
import { AnalyticsClient } from "@/components/analytics-client";
6+
import { Banners } from "@/components/banners";
67
import { BrandNav } from "@/components/brand-nav";
78
import { FrameworkProvider } from "@/components/framework-provider";
89
import { PostHogProvider } from "@/lib/providers/posthog-provider";
@@ -27,12 +28,6 @@ const plusJakartaSans = Plus_Jakarta_Sans({
2728
display: "swap",
2829
});
2930

30-
const splineSansMono = Spline_Sans_Mono({
31-
subsets: ["latin"],
32-
variable: "--font-mono",
33-
display: "swap",
34-
});
35-
3631
export const metadata: Metadata = {
3732
title: "CopilotKit Docs",
3833
description: "Docs, live demos, and integrations for CopilotKit",
@@ -86,10 +81,7 @@ export default function RootLayout({
8681
const REB2B_KEY = process.env.NEXT_PUBLIC_REB2B_KEY;
8782

8883
return (
89-
<html
90-
lang="en"
91-
className={`${plusJakartaSans.variable} ${splineSansMono.variable}`}
92-
>
84+
<html lang="en" className={plusJakartaSans.variable}>
9385
<head>
9486
{REO_KEY ? (
9587
<Script
@@ -130,13 +122,24 @@ export default function RootLayout({
130122
/>
131123
) : null}
132124
</head>
133-
<body className="min-h-screen">
125+
<body>
134126
<AnalyticsClient />
135127
<Suspense fallback={null}>
136128
<PostHogProvider>
137129
<FrameworkProvider knownFrameworks={knownFrameworks}>
130+
{/* Body is a fixed-height (100vh) flex column with hidden
131+
* overflow (see globals.css). Banner + nav sit naturally
132+
* at the top; <main> takes the remaining height and is
133+
* the horizontal flex row that hosts sidebar + the
134+
* scrolling `.docs-content-wrapper`. No sticky positioning
135+
* is needed — chrome stays put because it's outside the
136+
* scroll container. Mirrors canonical `#nd-home-layout`
137+
* (margin: 0 4px; xl: 0 8px 8px 8px). */}
138+
<Banners />
138139
<BrandNav />
139-
<main>{children}</main>
140+
<main className="flex flex-1 min-h-0 overflow-hidden mx-1 xl:mx-2 xl:mb-2">
141+
{children}
142+
</main>
140143
</FrameworkProvider>
141144
</PostHogProvider>
142145
</Suspense>

showcase/shell-docs/src/app/reference/[...slug]/page.tsx

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ export default async function ReferenceSlugPage({
9494
typeof data.description === "string" ? data.description : undefined;
9595

9696
return (
97-
<div className="flex min-h-[calc(100vh-53px)]">
97+
<div className="flex h-full w-full">
9898
{/* Sidebar */}
99-
<SidebarNav className="hidden lg:block w-56 shrink-0 border-r border-[var(--border)] bg-[var(--bg-surface)] overflow-y-auto sticky top-[53px] h-[calc(100vh-53px)]">
99+
<SidebarNav className="hidden lg:block w-56 shrink-0 border-r border-[var(--border)] bg-[var(--bg-surface)] overflow-y-auto h-full">
100100
<nav className="p-4 space-y-6">
101101
<div>
102102
<Link
@@ -139,30 +139,32 @@ export default async function ReferenceSlugPage({
139139
</SidebarNav>
140140

141141
{/* Main content */}
142-
<article className="flex-1 min-w-0 max-w-3xl mx-auto px-6 py-10">
143-
<div className="mb-8">
144-
<div className="text-xs text-[var(--text-muted)] mb-2">
145-
<Link
146-
href="/reference"
147-
className="hover:text-[var(--text-secondary)]"
148-
>
149-
Reference
150-
</Link>
151-
{" / "}
152-
<span className="capitalize">{slug[0]}</span>
142+
<div className="flex-1 min-w-0 overflow-y-auto">
143+
<article className="max-w-3xl mx-auto px-6 py-10">
144+
<div className="mb-8">
145+
<div className="text-xs text-[var(--text-muted)] mb-2">
146+
<Link
147+
href="/reference"
148+
className="hover:text-[var(--text-secondary)]"
149+
>
150+
Reference
151+
</Link>
152+
{" / "}
153+
<span className="capitalize">{slug[0]}</span>
154+
</div>
155+
<h1 className="text-2xl font-bold text-[var(--text)]">{title}</h1>
156+
{description && (
157+
<p className="text-sm text-[var(--text-muted)] mt-1">
158+
{description}
159+
</p>
160+
)}
153161
</div>
154-
<h1 className="text-2xl font-bold text-[var(--text)]">{title}</h1>
155-
{description && (
156-
<p className="text-sm text-[var(--text-muted)] mt-1">
157-
{description}
158-
</p>
159-
)}
160-
</div>
161162

162-
<div className="reference-content prose-sm">
163-
<MDXRemote source={cleanedContent} components={mdxComponents} />
164-
</div>
165-
</article>
163+
<div className="reference-content prose-sm">
164+
<MDXRemote source={cleanedContent} components={mdxComponents} />
165+
</div>
166+
</article>
167+
</div>
166168
</div>
167169
);
168170
}

showcase/shell-docs/src/app/reference/page.tsx

Lines changed: 53 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -31,59 +31,63 @@ export default function ReferencePage() {
3131
}
3232

3333
return (
34-
<div className="mx-auto max-w-4xl px-6 py-12">
35-
<h1 className="text-2xl font-bold text-[var(--text)] mb-2">
36-
API Reference
37-
</h1>
38-
<p className="text-[var(--text-muted)] text-sm mb-10">{intro}</p>
34+
<div className="flex-1 min-w-0 overflow-y-auto">
35+
<div className="mx-auto max-w-4xl px-6 py-12">
36+
<h1 className="text-2xl font-bold text-[var(--text)] mb-2">
37+
API Reference
38+
</h1>
39+
<p className="text-[var(--text-muted)] text-sm mb-10">{intro}</p>
3940

40-
<section className="mb-10">
41-
<h2 className="text-lg font-semibold text-[var(--text)] mb-4">
42-
UI Components
43-
</h2>
44-
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
45-
{components.map((item) => (
46-
<Link
47-
key={item.slug}
48-
href={`/reference/${item.slug}`}
49-
className="block rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] p-4 hover:bg-[var(--bg-elevated)] transition-colors"
50-
>
51-
<div className="font-mono text-sm font-semibold text-[var(--accent)]">
52-
{"<"}
53-
{item.title}
54-
{" />"}
55-
</div>
56-
{item.description && (
57-
<div className="text-xs text-[var(--text-muted)] mt-1">
58-
{item.description}
41+
<section className="mb-10">
42+
<h2 className="text-lg font-semibold text-[var(--text)] mb-4">
43+
UI Components
44+
</h2>
45+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
46+
{components.map((item) => (
47+
<Link
48+
key={item.slug}
49+
href={`/reference/${item.slug}`}
50+
className="block rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] p-4 hover:bg-[var(--bg-elevated)] transition-colors"
51+
>
52+
<div className="font-mono text-sm font-semibold text-[var(--accent)]">
53+
{"<"}
54+
{item.title}
55+
{" />"}
5956
</div>
60-
)}
61-
</Link>
62-
))}
63-
</div>
64-
</section>
57+
{item.description && (
58+
<div className="text-xs text-[var(--text-muted)] mt-1">
59+
{item.description}
60+
</div>
61+
)}
62+
</Link>
63+
))}
64+
</div>
65+
</section>
6566

66-
<section>
67-
<h2 className="text-lg font-semibold text-[var(--text)] mb-4">Hooks</h2>
68-
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
69-
{hooks.map((item) => (
70-
<Link
71-
key={item.slug}
72-
href={`/reference/${item.slug}`}
73-
className="block rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] p-4 hover:bg-[var(--bg-elevated)] transition-colors"
74-
>
75-
<div className="font-mono text-sm font-semibold text-[var(--accent)]">
76-
{item.title}()
77-
</div>
78-
{item.description && (
79-
<div className="text-xs text-[var(--text-muted)] mt-1">
80-
{item.description}
67+
<section>
68+
<h2 className="text-lg font-semibold text-[var(--text)] mb-4">
69+
Hooks
70+
</h2>
71+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
72+
{hooks.map((item) => (
73+
<Link
74+
key={item.slug}
75+
href={`/reference/${item.slug}`}
76+
className="block rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] p-4 hover:bg-[var(--bg-elevated)] transition-colors"
77+
>
78+
<div className="font-mono text-sm font-semibold text-[var(--accent)]">
79+
{item.title}()
8180
</div>
82-
)}
83-
</Link>
84-
))}
85-
</div>
86-
</section>
81+
{item.description && (
82+
<div className="text-xs text-[var(--text-muted)] mt-1">
83+
{item.description}
84+
</div>
85+
)}
86+
</Link>
87+
))}
88+
</div>
89+
</section>
90+
</div>
8791
</div>
8892
);
8993
}

0 commit comments

Comments
 (0)