@next-library/theme 1.0.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/README.md +565 -0
- package/dist/client.js +3465 -0
- package/dist/client.js.map +1 -0
- package/dist/index.js +4157 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +1486 -0
- package/dist/server.js.map +1 -0
- package/package.json +117 -0
- package/src/style.css +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
# @next-library/theme
|
|
2
|
+
|
|
3
|
+
Complete UI theme package for Next.js documentation framework. This package provides ready-made React components built on top of [`@next-library/core`](../core/README.md).
|
|
4
|
+
|
|
5
|
+
> **Looking for core utilities only?** Check out [`@next-library/core`](../core/README.md) which provides content management, i18n, and SEO utilities without UI components.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🎨 **Complete UI Components** - Layout, navigation, markdown rendering, and more
|
|
10
|
+
- 🌍 **Multi-language Support** - Built-in translations for 20+ languages
|
|
11
|
+
- 📱 **Responsive Design** - Mobile-first with drawer navigation and responsive breadcrumbs
|
|
12
|
+
- 🎯 **Type-Safe** - Full TypeScript support
|
|
13
|
+
- ⚡ **Server/Client Separation** - Optimized for Next.js App Router
|
|
14
|
+
- 🎭 **Theme Support** - Dark mode with `next-themes`
|
|
15
|
+
- 📝 **Rich Markdown** - Syntax highlighting, math, diagrams, callouts
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Using npm
|
|
21
|
+
npm install @next-library/theme @next-library/core
|
|
22
|
+
|
|
23
|
+
# Using pnpm
|
|
24
|
+
pnpm add @next-library/theme @next-library/core
|
|
25
|
+
|
|
26
|
+
# Using yarn
|
|
27
|
+
yarn add @next-library/theme @next-library/core
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Required peer dependencies:**
|
|
31
|
+
- `next-themes` - For theme switching (dark/light mode)
|
|
32
|
+
- `@tailwindcss/typography` - For markdown prose styling
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add next-themes @tailwindcss/typography
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
### 1. Set Up Tailwind CSS v4
|
|
41
|
+
|
|
42
|
+
The theme package uses Tailwind CSS v4 with `@source` directives (Nextra-style approach). Create or update your `globals.css`:
|
|
43
|
+
|
|
44
|
+
```css
|
|
45
|
+
/* app/globals.css */
|
|
46
|
+
@import 'tailwindcss';
|
|
47
|
+
@plugin "@tailwindcss/typography";
|
|
48
|
+
|
|
49
|
+
/* Import theme package styles to scan for Tailwind classes */
|
|
50
|
+
@import '@next-library/theme/style';
|
|
51
|
+
|
|
52
|
+
@custom-variant dark (&:is(.dark *));
|
|
53
|
+
|
|
54
|
+
:root {
|
|
55
|
+
/* Your CSS variables */
|
|
56
|
+
--background: oklch(1 0 0);
|
|
57
|
+
--foreground: oklch(0.145 0 0);
|
|
58
|
+
/* ... more variables */
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.dark {
|
|
62
|
+
--background: oklch(0.145 0 0);
|
|
63
|
+
--foreground: oklch(0.985 0 0);
|
|
64
|
+
/* ... more variables */
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Important:** The `@import '@next-library/theme/style'` line tells Tailwind where to scan for classes used in the theme components.
|
|
69
|
+
|
|
70
|
+
### 2. Set Up Theme Provider
|
|
71
|
+
|
|
72
|
+
Create a theme provider wrapper:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// app/providers.tsx
|
|
76
|
+
'use client';
|
|
77
|
+
|
|
78
|
+
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
|
79
|
+
import { ReactNode } from 'react';
|
|
80
|
+
|
|
81
|
+
export function ThemeProvider({ children }: { children: ReactNode }) {
|
|
82
|
+
return (
|
|
83
|
+
<NextThemesProvider attribute="class" defaultTheme="system" enableSystem>
|
|
84
|
+
{children}
|
|
85
|
+
</NextThemesProvider>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Wrap your app in `app/layout.tsx`:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// app/layout.tsx
|
|
94
|
+
import { ThemeProvider } from './providers';
|
|
95
|
+
|
|
96
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
97
|
+
return (
|
|
98
|
+
<html lang="en" suppressHydrationWarning>
|
|
99
|
+
<body>
|
|
100
|
+
<ThemeProvider>
|
|
101
|
+
{children}
|
|
102
|
+
</ThemeProvider>
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 3. Use Components
|
|
110
|
+
|
|
111
|
+
#### Server Components
|
|
112
|
+
|
|
113
|
+
Import server components from `@next-library/theme/server`:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// app/[locale]/layout.tsx
|
|
117
|
+
import { DocumentationLayout } from '@next-library/theme/server';
|
|
118
|
+
|
|
119
|
+
export default function LocaleLayout({ children, params }) {
|
|
120
|
+
const { locale } = await params;
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<DocumentationLayout language={locale}>
|
|
124
|
+
{children}
|
|
125
|
+
</DocumentationLayout>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Client Components
|
|
131
|
+
|
|
132
|
+
Import client components from `@next-library/theme/client`:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// components/my-component.tsx
|
|
136
|
+
'use client';
|
|
137
|
+
|
|
138
|
+
import { LanguageSwitcher, ThemeSwitcher } from '@next-library/theme/client';
|
|
139
|
+
|
|
140
|
+
export function MyComponent() {
|
|
141
|
+
return (
|
|
142
|
+
<div>
|
|
143
|
+
<LanguageSwitcher availableLocales={['en', 'fr', 'de']} />
|
|
144
|
+
<ThemeSwitcher />
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Component Exports
|
|
151
|
+
|
|
152
|
+
### Server Components (`@next-library/theme/server`)
|
|
153
|
+
|
|
154
|
+
- `DocumentationLayout` - Main layout wrapper
|
|
155
|
+
- `NavigationBar` - Top navigation bar
|
|
156
|
+
- `LeftSidebar` - Left sidebar navigation
|
|
157
|
+
- `RightSidebar` - Right sidebar (TOC, contributors)
|
|
158
|
+
- `DocumentationFooter` - Footer component
|
|
159
|
+
- `StructuredData` - JSON-LD structured data renderer
|
|
160
|
+
|
|
161
|
+
### Client Components (`@next-library/theme/client`)
|
|
162
|
+
|
|
163
|
+
**Navigation:**
|
|
164
|
+
- `Banner` - Top banner component
|
|
165
|
+
- `Logo` - Logo component
|
|
166
|
+
- `TopCategories` - Top category navigation
|
|
167
|
+
- `SearchBar` - Search input with keyboard shortcuts
|
|
168
|
+
- `ThemeSwitcher` - Dark/light theme toggle
|
|
169
|
+
- `LanguageSwitcher` - Language selection dropdown
|
|
170
|
+
- `MobileMenu` - Mobile navigation drawer
|
|
171
|
+
- `GithubStar` - GitHub star button
|
|
172
|
+
- `GithubLink` - GitHub repository link
|
|
173
|
+
- `Breadcrumbs` - Breadcrumb navigation
|
|
174
|
+
- `BreadcrumbToggle` - Responsive breadcrumb overflow
|
|
175
|
+
- `FolderCards` - Grid of folder cards
|
|
176
|
+
- `SidebarNavigation` - Sidebar navigation tree
|
|
177
|
+
- `TableOfContents` - Table of contents
|
|
178
|
+
- `GithubContributors` - Contributors list
|
|
179
|
+
- `LevelElevator` - Current level indicator
|
|
180
|
+
- `AnchorLinkHandler` - Anchor link copying
|
|
181
|
+
|
|
182
|
+
**Markdown:**
|
|
183
|
+
- `MarkdownRenderer` - Markdown content renderer
|
|
184
|
+
- `CopyPageButton` - Copy page content button with ChatGPT/Claude integration
|
|
185
|
+
- `PageHeader` - Page title with copy button
|
|
186
|
+
- `FallbackLocaleWarning` - Warning for fallback locale content
|
|
187
|
+
|
|
188
|
+
**UI Primitives:**
|
|
189
|
+
- `Button`, `Card`, `Avatar`, `Collapsible`, `Drawer`, `DropdownMenu`, `Select`, `Separator`, `Sheet`, `Tooltip`, `Input`, `Skeleton`
|
|
190
|
+
- Sidebar components (`SidebarProvider`, `SidebarContent`, `SidebarMenu`, etc.)
|
|
191
|
+
- Breadcrumb components (`Breadcrumb`, `BreadcrumbItem`, etc.)
|
|
192
|
+
|
|
193
|
+
**Tracking:**
|
|
194
|
+
- `CookieBanner` - Cookie consent banner
|
|
195
|
+
|
|
196
|
+
**Hooks:**
|
|
197
|
+
- `useMediaQuery` - Media query hook
|
|
198
|
+
- `useIsMobile` - Mobile detection hook
|
|
199
|
+
|
|
200
|
+
## Complete Example
|
|
201
|
+
|
|
202
|
+
### Layout Structure
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// app/[locale]/layout.tsx
|
|
206
|
+
import { DocumentationLayout } from '@next-library/theme/server';
|
|
207
|
+
|
|
208
|
+
export default async function LocaleLayout({
|
|
209
|
+
children,
|
|
210
|
+
params
|
|
211
|
+
}: {
|
|
212
|
+
children: React.ReactNode;
|
|
213
|
+
params: Promise<{ locale: string }>;
|
|
214
|
+
}) {
|
|
215
|
+
const { locale } = await params;
|
|
216
|
+
|
|
217
|
+
return (
|
|
218
|
+
<DocumentationLayout language={locale}>
|
|
219
|
+
{children}
|
|
220
|
+
</DocumentationLayout>
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Documentation Page Layout
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// app/[locale]/docs/[[...slug]]/layout.tsx
|
|
229
|
+
import { NavigationBar, LeftSidebar, RightSidebar } from '@next-library/theme/server';
|
|
230
|
+
import { Breadcrumbs, AnchorLinkHandler } from '@next-library/theme/client';
|
|
231
|
+
import { extractPageData, getSupportedLocales, type Locale } from '@next-library/core';
|
|
232
|
+
|
|
233
|
+
export default async function DocsLayout({
|
|
234
|
+
children,
|
|
235
|
+
params
|
|
236
|
+
}: {
|
|
237
|
+
children: React.ReactNode;
|
|
238
|
+
params: Promise<{ locale: string; slug?: string[] }>;
|
|
239
|
+
}) {
|
|
240
|
+
const { locale: rawLocale, slug } = await params;
|
|
241
|
+
const supportedLocales = getSupportedLocales();
|
|
242
|
+
const locale = (supportedLocales.includes(rawLocale) ? rawLocale : 'en') as Locale;
|
|
243
|
+
const safeSlug = Array.isArray(slug) ? slug : [];
|
|
244
|
+
|
|
245
|
+
const pageData = extractPageData(locale, safeSlug);
|
|
246
|
+
|
|
247
|
+
return (
|
|
248
|
+
<div>
|
|
249
|
+
{/* Mobile Navigation */}
|
|
250
|
+
<NavigationBar
|
|
251
|
+
language={locale}
|
|
252
|
+
className="block lg:hidden"
|
|
253
|
+
pageData={pageData}
|
|
254
|
+
/>
|
|
255
|
+
|
|
256
|
+
{/* Main Content Layout */}
|
|
257
|
+
<div className="flex flex-row gap-12 w-full lg:w-[95vw] mx-auto pt-10">
|
|
258
|
+
{/* Left Sidebar */}
|
|
259
|
+
<LeftSidebar
|
|
260
|
+
data={pageData}
|
|
261
|
+
className="sticky top-28 hidden lg:flex lg:flex-[2] max-w-xs"
|
|
262
|
+
/>
|
|
263
|
+
|
|
264
|
+
{/* Main Content */}
|
|
265
|
+
<main className="flex flex-col lg:gap-8 gap-4 flex-1 w-full lg:flex-[6] px-4 lg:px-0">
|
|
266
|
+
<Breadcrumbs data={pageData} locale={locale} />
|
|
267
|
+
{children}
|
|
268
|
+
</main>
|
|
269
|
+
|
|
270
|
+
{/* Right Sidebar */}
|
|
271
|
+
<RightSidebar
|
|
272
|
+
data={pageData}
|
|
273
|
+
className="sticky top-28 hidden lg:flex lg:flex-[1.5] max-w-xs"
|
|
274
|
+
/>
|
|
275
|
+
|
|
276
|
+
{/* Anchor Link Handler */}
|
|
277
|
+
<AnchorLinkHandler locale={locale} />
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Documentation Page
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
// app/[locale]/docs/[[...slug]]/page.tsx
|
|
288
|
+
import { PageHeader, MarkdownRenderer, FallbackLocaleWarning } from '@next-library/theme';
|
|
289
|
+
import { extractPageData, generateArticleSchema, generateBreadcrumbSchema, generateCollectionPageSchema, getSupportedLocales, fetchRawFileContent } from '@next-library/core';
|
|
290
|
+
import { StructuredData } from '@next-library/theme/server';
|
|
291
|
+
import { notFound } from 'next/navigation';
|
|
292
|
+
|
|
293
|
+
export default async function DocPage({
|
|
294
|
+
params
|
|
295
|
+
}: {
|
|
296
|
+
params: Promise<{ locale: string; slug?: string[] }>;
|
|
297
|
+
}) {
|
|
298
|
+
const { locale: rawLocale, slug } = await params;
|
|
299
|
+
const supportedLocales = getSupportedLocales();
|
|
300
|
+
const locale = supportedLocales.includes(rawLocale) ? rawLocale : 'en';
|
|
301
|
+
const safeSlug = Array.isArray(slug) ? slug : [];
|
|
302
|
+
|
|
303
|
+
const pageData = extractPageData(locale, safeSlug);
|
|
304
|
+
const { node } = pageData;
|
|
305
|
+
|
|
306
|
+
if (!node) {
|
|
307
|
+
notFound();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Fetch markdown content from GitHub
|
|
311
|
+
const rawMarkdown = await fetchRawFileContent(node.githubPath!);
|
|
312
|
+
|
|
313
|
+
// Generate structured data
|
|
314
|
+
const articleSchema = generateArticleSchema({ /* ... */ });
|
|
315
|
+
const breadcrumbSchema = generateBreadcrumbSchema(pageData.navigation.breadcrumbs);
|
|
316
|
+
const collectionPageSchema = generateCollectionPageSchema({ /* ... */ });
|
|
317
|
+
|
|
318
|
+
const schemas = [articleSchema, breadcrumbSchema, collectionPageSchema]
|
|
319
|
+
.filter(Boolean)
|
|
320
|
+
.map(schema => JSON.stringify(schema, null, 0).replace(/</g, '\\u003c'))
|
|
321
|
+
.join('\n');
|
|
322
|
+
|
|
323
|
+
return (
|
|
324
|
+
<div>
|
|
325
|
+
{/* Structured Data */}
|
|
326
|
+
{schemas && (
|
|
327
|
+
<script
|
|
328
|
+
type="application/ld+json"
|
|
329
|
+
dangerouslySetInnerHTML={{ __html: schemas }}
|
|
330
|
+
/>
|
|
331
|
+
)}
|
|
332
|
+
|
|
333
|
+
{/* Page Header with Copy Button */}
|
|
334
|
+
<PageHeader
|
|
335
|
+
title={node.title}
|
|
336
|
+
markdown={rawMarkdown}
|
|
337
|
+
pageUrl={`https://example.com/${locale}/docs/${safeSlug.join('/')}`}
|
|
338
|
+
websiteTitle="My Documentation"
|
|
339
|
+
locale={locale}
|
|
340
|
+
/>
|
|
341
|
+
|
|
342
|
+
{/* Fallback Warning */}
|
|
343
|
+
{node.fallback && (
|
|
344
|
+
<FallbackLocaleWarning locale={locale} />
|
|
345
|
+
)}
|
|
346
|
+
|
|
347
|
+
{/* Markdown Content */}
|
|
348
|
+
<MarkdownRenderer markdown={rawMarkdown} />
|
|
349
|
+
</div>
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## Internationalization
|
|
355
|
+
|
|
356
|
+
The theme package includes translations for 20+ languages. Components automatically use translations based on the `locale` prop:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import { CopyPageButton } from '@next-library/theme/client';
|
|
360
|
+
|
|
361
|
+
// Uses default translations for locale
|
|
362
|
+
<CopyPageButton
|
|
363
|
+
sourceCode={markdown}
|
|
364
|
+
locale="fr" // French translations will be used
|
|
365
|
+
/>
|
|
366
|
+
|
|
367
|
+
// Override specific translations
|
|
368
|
+
<CopyPageButton
|
|
369
|
+
sourceCode={markdown}
|
|
370
|
+
locale="fr"
|
|
371
|
+
translations={{
|
|
372
|
+
copyPage: 'Copier la page',
|
|
373
|
+
copied: 'Copié',
|
|
374
|
+
}}
|
|
375
|
+
/>
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Supported Locales
|
|
379
|
+
|
|
380
|
+
- English (en)
|
|
381
|
+
- French (fr)
|
|
382
|
+
- German (de)
|
|
383
|
+
- Spanish (es)
|
|
384
|
+
- Arabic (ar) - RTL support
|
|
385
|
+
- Chinese (zh)
|
|
386
|
+
- Japanese (ja)
|
|
387
|
+
- Korean (ko)
|
|
388
|
+
- Portuguese (pt)
|
|
389
|
+
- Italian (it)
|
|
390
|
+
- Russian (ru)
|
|
391
|
+
- Dutch (nl)
|
|
392
|
+
- Swedish (sv)
|
|
393
|
+
- Norwegian (no)
|
|
394
|
+
- Danish (da)
|
|
395
|
+
- Finnish (fi)
|
|
396
|
+
- Polish (pl)
|
|
397
|
+
- Turkish (tr)
|
|
398
|
+
- Hebrew (he) - RTL support
|
|
399
|
+
- Hindi (hi)
|
|
400
|
+
|
|
401
|
+
### Custom Translations
|
|
402
|
+
|
|
403
|
+
All components accept an optional `translations` prop to override default translations:
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
interface ComponentTranslations {
|
|
407
|
+
// Component-specific translation keys
|
|
408
|
+
copyPage?: string;
|
|
409
|
+
copied?: string;
|
|
410
|
+
// ... more keys
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Styling
|
|
415
|
+
|
|
416
|
+
### Tailwind CSS v4
|
|
417
|
+
|
|
418
|
+
The theme uses Tailwind CSS v4 with `@source` directives. Make sure to import the theme style file in your `globals.css`:
|
|
419
|
+
|
|
420
|
+
```css
|
|
421
|
+
@import '@next-library/theme/style';
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
This tells Tailwind where to scan for classes used in theme components.
|
|
425
|
+
|
|
426
|
+
### CSS Variables
|
|
427
|
+
|
|
428
|
+
The theme uses CSS variables for theming. Define your variables in `globals.css`:
|
|
429
|
+
|
|
430
|
+
```css
|
|
431
|
+
:root {
|
|
432
|
+
--background: oklch(1 0 0);
|
|
433
|
+
--foreground: oklch(0.145 0 0);
|
|
434
|
+
--primary: oklch(0.205 0 0);
|
|
435
|
+
/* ... more variables */
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.dark {
|
|
439
|
+
--background: oklch(0.145 0 0);
|
|
440
|
+
--foreground: oklch(0.985 0 0);
|
|
441
|
+
/* ... more variables */
|
|
442
|
+
}
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Customization
|
|
446
|
+
|
|
447
|
+
You can customize component styles by:
|
|
448
|
+
|
|
449
|
+
1. **Overriding CSS variables** - Change theme colors via CSS variables
|
|
450
|
+
2. **Using className prop** - Most components accept `className` for additional styling
|
|
451
|
+
3. **Tailwind classes** - All components use Tailwind, so you can override with utility classes
|
|
452
|
+
|
|
453
|
+
## Component Props
|
|
454
|
+
|
|
455
|
+
### DocumentationLayout
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
interface DocumentationLayoutProps {
|
|
459
|
+
children: React.ReactNode;
|
|
460
|
+
language?: Locale;
|
|
461
|
+
bannerMessage?: React.ReactNode | null;
|
|
462
|
+
websiteTitle?: string;
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
### NavigationBar
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
interface NavigationBarProps {
|
|
470
|
+
language: Locale;
|
|
471
|
+
className?: string;
|
|
472
|
+
pageData?: PageData;
|
|
473
|
+
websiteTitle?: string;
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### PageHeader
|
|
478
|
+
|
|
479
|
+
```typescript
|
|
480
|
+
interface PageHeaderProps {
|
|
481
|
+
title: string;
|
|
482
|
+
markdown: string;
|
|
483
|
+
pageUrl?: string;
|
|
484
|
+
websiteTitle?: string;
|
|
485
|
+
className?: string;
|
|
486
|
+
locale?: Locale;
|
|
487
|
+
translations?: CopyPageButtonTranslations;
|
|
488
|
+
showCopyButton?: boolean;
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### CopyPageButton
|
|
493
|
+
|
|
494
|
+
```typescript
|
|
495
|
+
interface CopyPageButtonProps {
|
|
496
|
+
sourceCode: string;
|
|
497
|
+
pageUrl?: string;
|
|
498
|
+
websiteTitle?: string;
|
|
499
|
+
className?: string;
|
|
500
|
+
locale?: Locale;
|
|
501
|
+
translations?: CopyPageButtonTranslations;
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
The `CopyPageButton` includes integration with ChatGPT and Claude:
|
|
506
|
+
- **Copy page** - Copies markdown content to clipboard
|
|
507
|
+
- **Open in ChatGPT** - Opens ChatGPT with prefilled message including website title and URL
|
|
508
|
+
- **Open in Claude** - Opens Claude with prefilled message including website title and URL
|
|
509
|
+
|
|
510
|
+
## Server/Client Separation
|
|
511
|
+
|
|
512
|
+
The theme package properly separates server and client components:
|
|
513
|
+
|
|
514
|
+
- **Server components** are imported from `@next-library/theme/server`
|
|
515
|
+
- **Client components** are imported from `@next-library/theme/client`
|
|
516
|
+
- Server components can import client components (they're externalized in the build)
|
|
517
|
+
|
|
518
|
+
This ensures optimal performance with Next.js App Router.
|
|
519
|
+
|
|
520
|
+
## TypeScript Support
|
|
521
|
+
|
|
522
|
+
The package is fully typed. Import types as needed:
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
import type {
|
|
526
|
+
DocumentationLayoutProps,
|
|
527
|
+
NavigationBarProps,
|
|
528
|
+
PageHeaderProps,
|
|
529
|
+
CopyPageButtonProps,
|
|
530
|
+
} from '@next-library/theme/server';
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
## Examples
|
|
534
|
+
|
|
535
|
+
See the [`example`](../../example/) directory for a complete working example.
|
|
536
|
+
|
|
537
|
+
## API Reference
|
|
538
|
+
|
|
539
|
+
### Server Components
|
|
540
|
+
|
|
541
|
+
- `DocumentationLayout` - Main layout wrapper
|
|
542
|
+
- `NavigationBar` - Top navigation
|
|
543
|
+
- `LeftSidebar` - Left sidebar navigation
|
|
544
|
+
- `RightSidebar` - Right sidebar (TOC, contributors)
|
|
545
|
+
- `DocumentationFooter` - Footer
|
|
546
|
+
- `StructuredData` - JSON-LD renderer
|
|
547
|
+
|
|
548
|
+
### Client Components
|
|
549
|
+
|
|
550
|
+
See the [Component Exports](#component-exports) section above for the complete list.
|
|
551
|
+
|
|
552
|
+
## Contributing
|
|
553
|
+
|
|
554
|
+
Contributions are welcome! Please see our [contributing guide](../../CONTRIBUTING.md) for details.
|
|
555
|
+
|
|
556
|
+
## License
|
|
557
|
+
|
|
558
|
+
MIT
|
|
559
|
+
|
|
560
|
+
## Support
|
|
561
|
+
|
|
562
|
+
- [Documentation](https://docs.example.com)
|
|
563
|
+
- [GitHub Issues](https://github.com/your-org/your-library/issues)
|
|
564
|
+
- [Discussions](https://github.com/your-org/your-library/discussions)
|
|
565
|
+
|