@agenetix/docs 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/LICENSE +21 -0
- package/README.md +282 -0
- package/dist/components/BlogCard.d.ts +7 -0
- package/dist/components/BlogCard.d.ts.map +1 -0
- package/dist/components/BlogCard.js +10 -0
- package/dist/components/BlogCard.js.map +1 -0
- package/dist/components/BlogCategories.d.ts +8 -0
- package/dist/components/BlogCategories.d.ts.map +1 -0
- package/dist/components/BlogCategories.js +23 -0
- package/dist/components/BlogCategories.js.map +1 -0
- package/dist/components/BlogDirectoryPage.d.ts +10 -0
- package/dist/components/BlogDirectoryPage.d.ts.map +1 -0
- package/dist/components/BlogDirectoryPage.js +9 -0
- package/dist/components/BlogDirectoryPage.js.map +1 -0
- package/dist/components/BlogPagination.d.ts +10 -0
- package/dist/components/BlogPagination.d.ts.map +1 -0
- package/dist/components/BlogPagination.js +23 -0
- package/dist/components/BlogPagination.js.map +1 -0
- package/dist/components/BlogPostPage.d.ts +11 -0
- package/dist/components/BlogPostPage.d.ts.map +1 -0
- package/dist/components/BlogPostPage.js +17 -0
- package/dist/components/BlogPostPage.js.map +1 -0
- package/dist/components/BlogSearch.d.ts +7 -0
- package/dist/components/BlogSearch.d.ts.map +1 -0
- package/dist/components/BlogSearch.js +5 -0
- package/dist/components/BlogSearch.js.map +1 -0
- package/dist/components/CopyPageButton.d.ts +4 -0
- package/dist/components/CopyPageButton.d.ts.map +1 -0
- package/dist/components/CopyPageButton.js +71 -0
- package/dist/components/CopyPageButton.js.map +1 -0
- package/dist/components/DocsHomePage.d.ts +12 -0
- package/dist/components/DocsHomePage.d.ts.map +1 -0
- package/dist/components/DocsHomePage.js +45 -0
- package/dist/components/DocsHomePage.js.map +1 -0
- package/dist/components/DocsLayout.d.ts +3 -0
- package/dist/components/DocsLayout.d.ts.map +1 -0
- package/dist/components/DocsLayout.js +6 -0
- package/dist/components/DocsLayout.js.map +1 -0
- package/dist/components/DocsPage.d.ts +14 -0
- package/dist/components/DocsPage.d.ts.map +1 -0
- package/dist/components/DocsPage.js +16 -0
- package/dist/components/DocsPage.js.map +1 -0
- package/dist/components/DocsPageMobileToc.d.ts +6 -0
- package/dist/components/DocsPageMobileToc.d.ts.map +1 -0
- package/dist/components/DocsPageMobileToc.js +15 -0
- package/dist/components/DocsPageMobileToc.js.map +1 -0
- package/dist/components/DocsSearch.d.ts +8 -0
- package/dist/components/DocsSearch.d.ts.map +1 -0
- package/dist/components/DocsSearch.js +44 -0
- package/dist/components/DocsSearch.js.map +1 -0
- package/dist/components/DocsSearchCommand.d.ts +9 -0
- package/dist/components/DocsSearchCommand.d.ts.map +1 -0
- package/dist/components/DocsSearchCommand.js +43 -0
- package/dist/components/DocsSearchCommand.js.map +1 -0
- package/dist/components/DocsSearchPalette.d.ts +11 -0
- package/dist/components/DocsSearchPalette.d.ts.map +1 -0
- package/dist/components/DocsSearchPalette.js +28 -0
- package/dist/components/DocsSearchPalette.js.map +1 -0
- package/dist/components/DocsSearchResults.d.ts +13 -0
- package/dist/components/DocsSearchResults.d.ts.map +1 -0
- package/dist/components/DocsSearchResults.js +26 -0
- package/dist/components/DocsSearchResults.js.map +1 -0
- package/dist/components/DocsSearchTrigger.d.ts +6 -0
- package/dist/components/DocsSearchTrigger.d.ts.map +1 -0
- package/dist/components/DocsSearchTrigger.js +7 -0
- package/dist/components/DocsSearchTrigger.js.map +1 -0
- package/dist/components/DocsShell.d.ts +3 -0
- package/dist/components/DocsShell.d.ts.map +1 -0
- package/dist/components/DocsShell.js +98 -0
- package/dist/components/DocsShell.js.map +1 -0
- package/dist/components/DocsSidebar.d.ts +10 -0
- package/dist/components/DocsSidebar.d.ts.map +1 -0
- package/dist/components/DocsSidebar.js +48 -0
- package/dist/components/DocsSidebar.js.map +1 -0
- package/dist/components/DocsToc.d.ts +6 -0
- package/dist/components/DocsToc.d.ts.map +1 -0
- package/dist/components/DocsToc.js +42 -0
- package/dist/components/DocsToc.js.map +1 -0
- package/dist/components/HeadingLinks.d.ts +2 -0
- package/dist/components/HeadingLinks.d.ts.map +1 -0
- package/dist/components/HeadingLinks.js +54 -0
- package/dist/components/HeadingLinks.js.map +1 -0
- package/dist/components/MobileDocsChrome.d.ts +9 -0
- package/dist/components/MobileDocsChrome.d.ts.map +1 -0
- package/dist/components/MobileDocsChrome.js +6 -0
- package/dist/components/MobileDocsChrome.js.map +1 -0
- package/dist/components/StickyAside.d.ts +7 -0
- package/dist/components/StickyAside.d.ts.map +1 -0
- package/dist/components/StickyAside.js +5 -0
- package/dist/components/StickyAside.js.map +1 -0
- package/dist/components/blog-utils.d.ts +8 -0
- package/dist/components/blog-utils.d.ts.map +1 -0
- package/dist/components/blog-utils.js +28 -0
- package/dist/components/blog-utils.js.map +1 -0
- package/dist/components/mdx/Accordion.d.ts +13 -0
- package/dist/components/mdx/Accordion.d.ts.map +1 -0
- package/dist/components/mdx/Accordion.js +8 -0
- package/dist/components/mdx/Accordion.js.map +1 -0
- package/dist/components/mdx/Banner.d.ts +12 -0
- package/dist/components/mdx/Banner.d.ts.map +1 -0
- package/dist/components/mdx/Banner.js +10 -0
- package/dist/components/mdx/Banner.js.map +1 -0
- package/dist/components/mdx/Callout.d.ts +9 -0
- package/dist/components/mdx/Callout.d.ts.map +1 -0
- package/dist/components/mdx/Callout.js +11 -0
- package/dist/components/mdx/Callout.js.map +1 -0
- package/dist/components/mdx/Card.d.ts +16 -0
- package/dist/components/mdx/Card.d.ts.map +1 -0
- package/dist/components/mdx/Card.js +13 -0
- package/dist/components/mdx/Card.js.map +1 -0
- package/dist/components/mdx/CodeBlock.d.ts +11 -0
- package/dist/components/mdx/CodeBlock.d.ts.map +1 -0
- package/dist/components/mdx/CodeBlock.js +61 -0
- package/dist/components/mdx/CodeBlock.js.map +1 -0
- package/dist/components/mdx/CopyCodeButton.d.ts +4 -0
- package/dist/components/mdx/CopyCodeButton.d.ts.map +1 -0
- package/dist/components/mdx/CopyCodeButton.js +18 -0
- package/dist/components/mdx/CopyCodeButton.js.map +1 -0
- package/dist/components/mdx/Files.d.ts +19 -0
- package/dist/components/mdx/Files.d.ts.map +1 -0
- package/dist/components/mdx/Files.js +11 -0
- package/dist/components/mdx/Files.js.map +1 -0
- package/dist/components/mdx/InlineToc.d.ts +12 -0
- package/dist/components/mdx/InlineToc.d.ts.map +1 -0
- package/dist/components/mdx/InlineToc.js +26 -0
- package/dist/components/mdx/InlineToc.js.map +1 -0
- package/dist/components/mdx/Mermaid.d.ts +9 -0
- package/dist/components/mdx/Mermaid.d.ts.map +1 -0
- package/dist/components/mdx/Mermaid.js +63 -0
- package/dist/components/mdx/Mermaid.js.map +1 -0
- package/dist/components/mdx/Steps.d.ts +12 -0
- package/dist/components/mdx/Steps.d.ts.map +1 -0
- package/dist/components/mdx/Steps.js +8 -0
- package/dist/components/mdx/Steps.js.map +1 -0
- package/dist/components/mdx/Tabs.d.ts +22 -0
- package/dist/components/mdx/Tabs.d.ts.map +1 -0
- package/dist/components/mdx/Tabs.js +27 -0
- package/dist/components/mdx/Tabs.js.map +1 -0
- package/dist/components/mdx/index.d.ts +11 -0
- package/dist/components/mdx/index.d.ts.map +1 -0
- package/dist/components/mdx/index.js +11 -0
- package/dist/components/mdx/index.js.map +1 -0
- package/dist/components/mdx/lazy.d.ts +11 -0
- package/dist/components/mdx/lazy.d.ts.map +1 -0
- package/dist/components/mdx/lazy.js +9 -0
- package/dist/components/mdx/lazy.js.map +1 -0
- package/dist/components/useDocsSearch.d.ts +27 -0
- package/dist/components/useDocsSearch.d.ts.map +1 -0
- package/dist/components/useDocsSearch.js +119 -0
- package/dist/components/useDocsSearch.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/mdx.d.ts +14 -0
- package/dist/mdx.d.ts.map +1 -0
- package/dist/mdx.js +107 -0
- package/dist/mdx.js.map +1 -0
- package/dist/server/blog.d.ts +3 -0
- package/dist/server/blog.d.ts.map +1 -0
- package/dist/server/blog.js +552 -0
- package/dist/server/blog.js.map +1 -0
- package/dist/server/docs.d.ts +5 -0
- package/dist/server/docs.d.ts.map +1 -0
- package/dist/server/docs.js +389 -0
- package/dist/server/docs.js.map +1 -0
- package/dist/server/search.d.ts +3 -0
- package/dist/server/search.d.ts.map +1 -0
- package/dist/server/search.js +216 -0
- package/dist/server/search.js.map +1 -0
- package/dist/styles.css +3337 -0
- package/dist/theme-provider.d.ts +19 -0
- package/dist/theme-provider.d.ts.map +1 -0
- package/dist/theme-provider.js +54 -0
- package/dist/theme-provider.js.map +1 -0
- package/dist/theme.d.ts +11 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +602 -0
- package/dist/theme.js.map +1 -0
- package/dist/types.d.ts +379 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +34 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +85 -0
- package/dist/utils.js.map +1 -0
- package/package.json +133 -0
- package/styles.css +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MCP Stack
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# MCP Stack Docs
|
|
2
|
+
|
|
3
|
+
`@agenetix/docs` is an App Router-native MDX docs library for Next.js.
|
|
4
|
+
|
|
5
|
+
It is built for teams that want documentation content in the repo while still getting SEO-friendly prerendered routes, locale-aware file conventions, search, heading extraction, mobile-friendly docs UX, and a configurable docs shell that can either stay simple or plug into a richer app chrome.
|
|
6
|
+
|
|
7
|
+
This repository contains both the published package and the example site that dogfoods it:
|
|
8
|
+
|
|
9
|
+
- `src` contains the library source
|
|
10
|
+
- `tests` contains Vitest coverage
|
|
11
|
+
- `site` is the example Next.js app and the package's own docs/showcase
|
|
12
|
+
|
|
13
|
+
## Preview
|
|
14
|
+
|
|
15
|
+
<p align="center">
|
|
16
|
+
<img src=".github/assets/docs-page.png" alt="MCP Stack Docs docs page screenshot" width="49%" />
|
|
17
|
+
<img src=".github/assets/theme-studio.png" alt="MCP Stack Docs theme studio screenshot" width="49%" />
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
The example site ships with a polished docs shell and an optional live theme studio for tuning presets, density, surface styles, and accent behavior.
|
|
21
|
+
|
|
22
|
+
## Why use it
|
|
23
|
+
|
|
24
|
+
- Keep docs as repo-local MDX instead of a separate CMS
|
|
25
|
+
- Build navigation, route resolution, metadata, headings, and search from one `createDocsSource(...)` call
|
|
26
|
+
- Render docs with App Router-friendly primitives like `DocsLayout`, `DocsPage`, and `DocsHomePage`
|
|
27
|
+
- Ship a polished baseline with `DocsSearch`, `DocsSidebar`, `DocsToc`, `HeadingLinks`, and `MobileDocsChrome`
|
|
28
|
+
- Support locale-specific files like `getting-started/en.mdx`, `getting-started/es.mdx`, and `getting-started/zh.mdx`
|
|
29
|
+
- Restyle the shell with a nested theme object or a live theme provider
|
|
30
|
+
- Use bundled MDX building blocks such as banners, callouts, cards, tabs, steps, files, accordions, and code blocks
|
|
31
|
+
|
|
32
|
+
## Requirements
|
|
33
|
+
|
|
34
|
+
- Node.js `>=20`
|
|
35
|
+
- Next.js `>=15.5.0 <17`
|
|
36
|
+
- React `^19`
|
|
37
|
+
- React DOM `^19`
|
|
38
|
+
|
|
39
|
+
## Install
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install @agenetix/docs
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then import the shared stylesheet once in your docs layout:
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import "@agenetix/docs/styles.css";
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
### 1. Create a docs source
|
|
54
|
+
|
|
55
|
+
Create `lib/docs.ts`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import path from "node:path";
|
|
59
|
+
import { createDocsSource } from "@agenetix/docs";
|
|
60
|
+
|
|
61
|
+
export const docsSource = createDocsSource({
|
|
62
|
+
contentDir: path.join(process.cwd(), "content/docs"),
|
|
63
|
+
basePath: "/docs",
|
|
64
|
+
defaultLocale: "en",
|
|
65
|
+
locales: ["en", "es", "zh"],
|
|
66
|
+
hideDefaultLocaleInUrl: true,
|
|
67
|
+
sectionOrder: ["", "guides", "reference"],
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`docsSource` becomes the single source of truth for route resolution, navigation, metadata, headings, and search.
|
|
72
|
+
|
|
73
|
+
### 2. Create the docs layout
|
|
74
|
+
|
|
75
|
+
Create `app/docs/layout.tsx`:
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { DocsLayout } from "@agenetix/docs";
|
|
79
|
+
import "@agenetix/docs/styles.css";
|
|
80
|
+
import { docsSource } from "@/lib/docs";
|
|
81
|
+
import { searchDocsAction } from "@/app/doc-actions";
|
|
82
|
+
|
|
83
|
+
export default function Layout({
|
|
84
|
+
children,
|
|
85
|
+
}: {
|
|
86
|
+
children: React.ReactNode;
|
|
87
|
+
}) {
|
|
88
|
+
return (
|
|
89
|
+
<DocsLayout
|
|
90
|
+
navigation={docsSource.getNavigation()}
|
|
91
|
+
searchAction={searchDocsAction}
|
|
92
|
+
>
|
|
93
|
+
{children}
|
|
94
|
+
</DocsLayout>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 3. Create the docs route
|
|
100
|
+
|
|
101
|
+
Create `app/docs/[[...slug]]/page.tsx`:
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { notFound, redirect } from "next/navigation";
|
|
105
|
+
import { DocsHomePage, DocsPage } from "@agenetix/docs";
|
|
106
|
+
import { docsSource } from "@/lib/docs";
|
|
107
|
+
|
|
108
|
+
interface PageProps {
|
|
109
|
+
params: Promise<{ slug?: string[] }>;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function generateStaticParams() {
|
|
113
|
+
return docsSource.getStaticParams();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export async function generateMetadata({ params }: PageProps) {
|
|
117
|
+
const { slug } = await params;
|
|
118
|
+
return docsSource.getMetadata(slug);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export default async function DocsRoutePage({ params }: PageProps) {
|
|
122
|
+
const { slug } = await params;
|
|
123
|
+
const resolved = docsSource.resolveRoute(slug);
|
|
124
|
+
|
|
125
|
+
if (resolved.type === "redirect" && resolved.href) {
|
|
126
|
+
redirect(resolved.href);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (resolved.type !== "entry" || !resolved.entry) {
|
|
130
|
+
notFound();
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (resolved.entry.isHome) {
|
|
134
|
+
return (
|
|
135
|
+
<DocsHomePage
|
|
136
|
+
entry={resolved.entry}
|
|
137
|
+
navigation={docsSource.getNavigation()}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<DocsPage
|
|
144
|
+
entry={resolved.entry}
|
|
145
|
+
previousEntry={resolved.previousEntry}
|
|
146
|
+
nextEntry={resolved.nextEntry}
|
|
147
|
+
backHref={docsSource.getHref()}
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 4. Add your first doc
|
|
154
|
+
|
|
155
|
+
Create `content/docs/getting-started/en.mdx`:
|
|
156
|
+
|
|
157
|
+
```mdx
|
|
158
|
+
---
|
|
159
|
+
title: "Getting Started"
|
|
160
|
+
description: "Your first MCP Stack Docs page"
|
|
161
|
+
order: 0
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
Welcome to your docs.
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
At that point, your app can render a static docs section from repo-local MDX under `/docs`.
|
|
168
|
+
|
|
169
|
+
### Optional: faster route transitions
|
|
170
|
+
|
|
171
|
+
`DocsPage` streams the MDX body inside a `Suspense` boundary so the shell and title can paint first. For even snappier navigations in large doc sets, add a route-level `loading.tsx` next to your `[[...slug]]` page:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
export default function DocsLoading() {
|
|
175
|
+
return <div className="emcydocs-prose emcydocs-mdx-loading" aria-busy="true" />;
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Navigation passed to `DocsLayout` should come from `docsSource.getNavigation()` — it returns metadata-only items (no MDX bodies).
|
|
180
|
+
|
|
181
|
+
## Theme system
|
|
182
|
+
|
|
183
|
+
`DocsLayout` accepts a nested `theme` object for static theming, and it can also read live theme state from `DocsThemeProvider` when you want a runtime switcher, persisted preferences, or a theme studio.
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
import {
|
|
187
|
+
DocsLayout,
|
|
188
|
+
DocsThemeProvider,
|
|
189
|
+
type DocsThemeConfig,
|
|
190
|
+
} from "@agenetix/docs";
|
|
191
|
+
import { docsSource } from "@/lib/docs";
|
|
192
|
+
|
|
193
|
+
const docsTheme: DocsThemeConfig = {
|
|
194
|
+
color: {
|
|
195
|
+
preset: "ocean",
|
|
196
|
+
mode: "dark",
|
|
197
|
+
accentHue: 188,
|
|
198
|
+
accentStrength: "bold",
|
|
199
|
+
surfaceStyle: "elevated",
|
|
200
|
+
},
|
|
201
|
+
layout: {
|
|
202
|
+
density: "compact",
|
|
203
|
+
layoutWidth: "1480px",
|
|
204
|
+
contentWidth: "50rem",
|
|
205
|
+
sidebarWidth: "272px",
|
|
206
|
+
tocWidth: "232px",
|
|
207
|
+
},
|
|
208
|
+
shape: {
|
|
209
|
+
radius: "xl",
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export default function Layout({
|
|
214
|
+
children,
|
|
215
|
+
}: {
|
|
216
|
+
children: React.ReactNode;
|
|
217
|
+
}) {
|
|
218
|
+
return (
|
|
219
|
+
<DocsThemeProvider initialTheme={docsTheme}>
|
|
220
|
+
<DocsLayout navigation={docsSource.getNavigation()}>
|
|
221
|
+
{children}
|
|
222
|
+
</DocsLayout>
|
|
223
|
+
</DocsThemeProvider>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
If you do not need live editing, pass the same object directly to `DocsLayout` via `theme={docsTheme}` and skip the provider entirely.
|
|
229
|
+
|
|
230
|
+
## What ships today
|
|
231
|
+
|
|
232
|
+
- Source builders: `createDocsSource`, `extractHeadings`
|
|
233
|
+
- Docs shell primitives: `DocsLayout`, `DocsPage`, `DocsHomePage`, `DocsSearch`, `DocsSidebar`, `DocsToc`, `HeadingLinks`, `MobileDocsChrome`
|
|
234
|
+
- Theme primitives: `DocsThemeProvider`, `useDocsTheme()`, `resolveDocsTheme(theme)`
|
|
235
|
+
- MDX helpers and components: `DocsMdx`, `getDefaultMdxComponents()`, plus banners, callouts, cards, tabs, steps, file trees, accordions, and code blocks
|
|
236
|
+
- Optional blog primitives: `createBlogSource`, `BlogDirectoryPage`, `BlogPostPage`, `BlogSearch`, and related components
|
|
237
|
+
- Shared stylesheet: `@agenetix/docs/styles.css`
|
|
238
|
+
|
|
239
|
+
## Local development
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
npm install
|
|
243
|
+
npm run dev
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
This starts:
|
|
247
|
+
|
|
248
|
+
- the library TypeScript build in watch mode
|
|
249
|
+
- the example site in `site` at `http://localhost:4003`
|
|
250
|
+
|
|
251
|
+
The example site is both a development sandbox and the canonical reference for how the package is wired into a real Next.js app.
|
|
252
|
+
|
|
253
|
+
## Useful scripts
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm run build:lib
|
|
257
|
+
npm run build:site
|
|
258
|
+
npm run lint
|
|
259
|
+
npm run test
|
|
260
|
+
npm run typecheck
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Dogfooding in SqlOS
|
|
264
|
+
|
|
265
|
+
From `sqlos/web`, use a local file dependency:
|
|
266
|
+
|
|
267
|
+
```json
|
|
268
|
+
{
|
|
269
|
+
"dependencies": {
|
|
270
|
+
"@agenetix/docs": "file:../../emcydocs"
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The SqlOS repo also includes helper scripts to switch between a local file dependency and a published npm version.
|
|
276
|
+
|
|
277
|
+
## Release flow
|
|
278
|
+
|
|
279
|
+
- Merge to `main` with passing CI
|
|
280
|
+
- Tag a release like `v0.1.0`
|
|
281
|
+
- Push the tag
|
|
282
|
+
- GitHub Actions rebuilds, retests, and publishes `@agenetix/docs` to npm
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BlogCardCopy, BlogEntryMeta } from "../types";
|
|
2
|
+
export default function BlogCard({ post, copy, locale, }: {
|
|
3
|
+
post: BlogEntryMeta;
|
|
4
|
+
copy?: Partial<BlogCardCopy>;
|
|
5
|
+
locale?: string;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=BlogCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogCard.d.ts","sourceRoot":"","sources":["../../src/components/BlogCard.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG5D,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,IAAI,EACJ,IAAI,EACJ,MAAM,GACP,EAAE;IACD,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CA+CA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import Image from "next/image";
|
|
4
|
+
import { formatBlogDate } from "./blog-utils";
|
|
5
|
+
export default function BlogCard({ post, copy, locale, }) {
|
|
6
|
+
const readMoreLabel = copy?.readMoreLabel ?? "Read more";
|
|
7
|
+
const readingTimeSuffix = copy?.readingTimeSuffix ?? "min read";
|
|
8
|
+
return (_jsx("article", { className: "emcydocs-blog-card", children: _jsxs(Link, { href: post.href, className: "emcydocs-blog-card-link", children: [post.image ? (_jsx("div", { className: "emcydocs-blog-card-image-wrap", children: _jsx(Image, { src: post.image, alt: post.imageAlt || post.title, className: "emcydocs-blog-card-image", fill: true, sizes: "(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw", unoptimized: true }) })) : null, _jsxs("div", { className: "emcydocs-blog-card-body", children: [_jsxs("div", { className: "emcydocs-blog-card-meta", children: [_jsx("span", { className: "emcydocs-blog-card-category", children: post.category }), _jsx("span", { children: formatBlogDate(post.publishedAt, locale) }), _jsxs("span", { children: [post.readingTimeMinutes, " ", readingTimeSuffix] })] }), _jsx("h3", { children: post.title }), post.description ? _jsx("p", { children: post.description }) : null, post.tags.length > 0 ? (_jsx("div", { className: "emcydocs-blog-card-tags", children: post.tags.slice(0, 3).map((tag) => (_jsx("span", { className: "emcydocs-blog-card-tag", children: tag }, tag))) })) : null, _jsx("span", { className: "emcydocs-blog-card-cta", children: readMoreLabel })] })] }) }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=BlogCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogCard.js","sourceRoot":"","sources":["../../src/components/BlogCard.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAC/B,IAAI,EACJ,IAAI,EACJ,MAAM,GAKP;IACC,MAAM,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,WAAW,CAAC;IACzD,MAAM,iBAAiB,GAAG,IAAI,EAAE,iBAAiB,IAAI,UAAU,CAAC;IAEhE,OAAO,CACL,kBAAS,SAAS,EAAC,oBAAoB,YACrC,MAAC,IAAI,IAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAC,yBAAyB,aACvD,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CACZ,cAAK,SAAS,EAAC,+BAA+B,YAC5C,KAAC,KAAK,IACJ,GAAG,EAAE,IAAI,CAAC,KAAK,EACf,GAAG,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,EAChC,SAAS,EAAC,0BAA0B,EACpC,IAAI,QACJ,KAAK,EAAC,0DAA0D,EAChE,WAAW,SACX,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAER,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAK,SAAS,EAAC,yBAAyB,aACtC,eAAM,SAAS,EAAC,6BAA6B,YAAE,IAAI,CAAC,QAAQ,GAAQ,EACpE,yBAAO,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,GAAQ,EACvD,2BACG,IAAI,CAAC,kBAAkB,OAAG,iBAAiB,IACvC,IACH,EAEN,uBAAK,IAAI,CAAC,KAAK,GAAM,EACpB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,sBAAI,IAAI,CAAC,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,EAEnD,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,cAAK,SAAS,EAAC,yBAAyB,YACrC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAClC,eAAgB,SAAS,EAAC,wBAAwB,YAC/C,GAAG,IADK,GAAG,CAEP,CACR,CAAC,GACE,CACP,CAAC,CAAC,CAAC,IAAI,EAER,eAAM,SAAS,EAAC,wBAAwB,YAAE,aAAa,GAAQ,IAC3D,IACD,GACC,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default function BlogCategories({ baseHref, categories, selectedCategory, allCategoriesLabel, query, }: {
|
|
2
|
+
baseHref: string;
|
|
3
|
+
categories: string[];
|
|
4
|
+
selectedCategory: string;
|
|
5
|
+
allCategoriesLabel: string;
|
|
6
|
+
query?: string;
|
|
7
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=BlogCategories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogCategories.d.ts","sourceRoot":"","sources":["../../src/components/BlogCategories.tsx"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,2CAgCA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { buildBlogDirectoryHref } from "./blog-utils";
|
|
4
|
+
export default function BlogCategories({ baseHref, categories, selectedCategory, allCategoriesLabel, query, }) {
|
|
5
|
+
const options = [
|
|
6
|
+
{ value: "all", label: allCategoriesLabel },
|
|
7
|
+
...categories.map((category) => ({ value: category, label: category })),
|
|
8
|
+
];
|
|
9
|
+
return (_jsx("div", { className: "emcydocs-blog-categories", role: "list", children: options.map((option) => {
|
|
10
|
+
const isActive = option.value === selectedCategory;
|
|
11
|
+
return (_jsx(Link, { href: buildBlogDirectoryHref({
|
|
12
|
+
baseHref,
|
|
13
|
+
query,
|
|
14
|
+
category: option.value,
|
|
15
|
+
}), className: [
|
|
16
|
+
"emcydocs-blog-category-chip",
|
|
17
|
+
isActive ? "is-active" : "",
|
|
18
|
+
]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(" "), children: option.label }, `${option.value}-${option.label}`));
|
|
21
|
+
}) }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=BlogCategories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogCategories.js","sourceRoot":"","sources":["../../src/components/BlogCategories.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,GAON;IACC,MAAM,OAAO,GAAG;QACd,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE;QAC3C,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;KACxE,CAAC;IAEF,OAAO,CACL,cAAK,SAAS,EAAC,0BAA0B,EAAC,IAAI,EAAC,MAAM,YAClD,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,KAAK,gBAAgB,CAAC;YAEnD,OAAO,CACL,KAAC,IAAI,IAEH,IAAI,EAAE,sBAAsB,CAAC;oBAC3B,QAAQ;oBACR,KAAK;oBACL,QAAQ,EAAE,MAAM,CAAC,KAAK;iBACvB,CAAC,EACF,SAAS,EAAE;oBACT,6BAA6B;oBAC7B,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;iBAC5B;qBACE,MAAM,CAAC,OAAO,CAAC;qBACf,IAAI,CAAC,GAAG,CAAC,YAEX,MAAM,CAAC,KAAK,IAbR,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAcjC,CACR,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BlogCardCopy, BlogDirectoryCopy, BlogDirectoryResponse, BlogPaginationCopy } from "../types";
|
|
2
|
+
export default function BlogDirectoryPage({ directory, baseHref, copy, cardCopy, paginationCopy, locale, }: {
|
|
3
|
+
directory: BlogDirectoryResponse;
|
|
4
|
+
baseHref: string;
|
|
5
|
+
copy: BlogDirectoryCopy;
|
|
6
|
+
cardCopy?: Partial<BlogCardCopy>;
|
|
7
|
+
paginationCopy?: Partial<BlogPaginationCopy>;
|
|
8
|
+
locale?: string;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=BlogDirectoryPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogDirectoryPage.d.ts","sourceRoot":"","sources":["../../src/components/BlogDirectoryPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAMlB,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,MAAM,GACP,EAAE;IACD,SAAS,EAAE,qBAAqB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CA8DA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import BlogCard from "./BlogCard";
|
|
3
|
+
import BlogCategories from "./BlogCategories";
|
|
4
|
+
import BlogPagination from "./BlogPagination";
|
|
5
|
+
import BlogSearch from "./BlogSearch";
|
|
6
|
+
export default function BlogDirectoryPage({ directory, baseHref, copy, cardCopy, paginationCopy, locale, }) {
|
|
7
|
+
return (_jsxs("div", { className: "emcydocs-blog-directory", children: [_jsx("section", { className: "emcydocs-blog-directory-hero", children: _jsxs("div", { children: [_jsx("h1", { children: copy.title }), copy.description ? _jsx("p", { children: copy.description }) : null] }) }), _jsxs("section", { className: "emcydocs-blog-directory-controls", children: [_jsxs("div", { className: "emcydocs-blog-directory-panel", children: [_jsx("div", { className: "emcydocs-blog-directory-heading", children: _jsx("h2", { children: copy.categoriesLabel }) }), _jsx(BlogCategories, { baseHref: baseHref, categories: directory.categories, selectedCategory: directory.selectedCategory, allCategoriesLabel: copy.allCategoriesLabel, query: directory.query })] }), _jsxs("div", { className: "emcydocs-blog-directory-panel", children: [_jsx("div", { className: "emcydocs-blog-directory-heading", children: _jsx("h2", { children: copy.searchLabel }) }), _jsx(BlogSearch, { actionHref: baseHref, query: directory.query, category: directory.selectedCategory, placeholder: copy.searchPlaceholder })] })] }), directory.items.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("section", { className: "emcydocs-blog-grid", children: directory.items.map((post) => (_jsx(BlogCard, { post: post, copy: cardCopy, locale: locale }, `${post.slug}-${post.locale}`))) }), _jsx(BlogPagination, { baseHref: baseHref, page: directory.page, totalPages: directory.totalPages, query: directory.query, category: directory.selectedCategory, copy: paginationCopy })] })) : (_jsxs("section", { className: "emcydocs-blog-empty", children: [_jsx("h2", { children: copy.noResultsTitle }), _jsx("p", { children: copy.noResultsDescription })] }))] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=BlogDirectoryPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogDirectoryPage.js","sourceRoot":"","sources":["../../src/components/BlogDirectoryPage.tsx"],"names":[],"mappings":";AAMA,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAC9C,OAAO,UAAU,MAAM,cAAc,CAAC;AAEtC,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,MAAM,GAQP;IACC,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,kBAAS,SAAS,EAAC,8BAA8B,YAC/C,0BACE,uBAAK,IAAI,CAAC,KAAK,GAAM,EACpB,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,sBAAI,IAAI,CAAC,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,IAChD,GACE,EAEV,mBAAS,SAAS,EAAC,kCAAkC,aACnD,eAAK,SAAS,EAAC,+BAA+B,aAC5C,cAAK,SAAS,EAAC,iCAAiC,YAC9C,uBAAK,IAAI,CAAC,eAAe,GAAM,GAC3B,EACN,KAAC,cAAc,IACb,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,SAAS,CAAC,UAAU,EAChC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,EAC5C,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAC3C,KAAK,EAAE,SAAS,CAAC,KAAK,GACtB,IACE,EAEN,eAAK,SAAS,EAAC,+BAA+B,aAC5C,cAAK,SAAS,EAAC,iCAAiC,YAC9C,uBAAK,IAAI,CAAC,WAAW,GAAM,GACvB,EACN,KAAC,UAAU,IACT,UAAU,EAAE,QAAQ,EACpB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,QAAQ,EAAE,SAAS,CAAC,gBAAgB,EACpC,WAAW,EAAE,IAAI,CAAC,iBAAiB,GACnC,IACE,IACE,EAET,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC5B,8BACE,kBAAS,SAAS,EAAC,oBAAoB,YACpC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC7B,KAAC,QAAQ,IAAqC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,IAAzE,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAgD,CAC7F,CAAC,GACM,EAEV,KAAC,cAAc,IACb,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,UAAU,EAAE,SAAS,CAAC,UAAU,EAChC,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,QAAQ,EAAE,SAAS,CAAC,gBAAgB,EACpC,IAAI,EAAE,cAAc,GACpB,IACD,CACJ,CAAC,CAAC,CAAC,CACF,mBAAS,SAAS,EAAC,qBAAqB,aACtC,uBAAK,IAAI,CAAC,cAAc,GAAM,EAC9B,sBAAI,IAAI,CAAC,oBAAoB,GAAK,IAC1B,CACX,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BlogPaginationCopy } from "../types";
|
|
2
|
+
export default function BlogPagination({ baseHref, page, totalPages, query, category, copy, }: {
|
|
3
|
+
baseHref: string;
|
|
4
|
+
page: number;
|
|
5
|
+
totalPages: number;
|
|
6
|
+
query?: string;
|
|
7
|
+
category?: string;
|
|
8
|
+
copy?: Partial<BlogPaginationCopy>;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
//# sourceMappingURL=BlogPagination.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogPagination.d.ts","sourceRoot":"","sources":["../../src/components/BlogPagination.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,KAAK,EACL,QAAQ,EACR,IAAI,GACL,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACpC,kDAgDA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import { buildBlogDirectoryHref } from "./blog-utils";
|
|
4
|
+
export default function BlogPagination({ baseHref, page, totalPages, query, category, copy, }) {
|
|
5
|
+
if (totalPages <= 1) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
const previousLabel = copy?.previousLabel ?? "Previous";
|
|
9
|
+
const nextLabel = copy?.nextLabel ?? "Next";
|
|
10
|
+
const pageLabel = copy?.pageLabel ?? "Page";
|
|
11
|
+
return (_jsxs("nav", { className: "emcydocs-blog-pagination", "aria-label": "Blog pagination", children: [page > 1 ? (_jsx(Link, { href: buildBlogDirectoryHref({
|
|
12
|
+
baseHref,
|
|
13
|
+
query,
|
|
14
|
+
category,
|
|
15
|
+
page: page - 1,
|
|
16
|
+
}), className: "emcydocs-blog-pagination-link", children: previousLabel })) : (_jsx("span", { className: "emcydocs-blog-pagination-link is-disabled", children: previousLabel })), _jsxs("span", { className: "emcydocs-blog-pagination-status", children: [pageLabel, " ", page, " / ", totalPages] }), page < totalPages ? (_jsx(Link, { href: buildBlogDirectoryHref({
|
|
17
|
+
baseHref,
|
|
18
|
+
query,
|
|
19
|
+
category,
|
|
20
|
+
page: page + 1,
|
|
21
|
+
}), className: "emcydocs-blog-pagination-link", children: nextLabel })) : (_jsx("span", { className: "emcydocs-blog-pagination-link is-disabled", children: nextLabel }))] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=BlogPagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogPagination.js","sourceRoot":"","sources":["../../src/components/BlogPagination.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,KAAK,EACL,QAAQ,EACR,IAAI,GAQL;IACC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,EAAE,aAAa,IAAI,UAAU,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,MAAM,CAAC;IAC5C,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,IAAI,MAAM,CAAC;IAE5C,OAAO,CACL,eAAK,SAAS,EAAC,0BAA0B,gBAAY,iBAAiB,aACnE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CACV,KAAC,IAAI,IACH,IAAI,EAAE,sBAAsB,CAAC;oBAC3B,QAAQ;oBACR,KAAK;oBACL,QAAQ;oBACR,IAAI,EAAE,IAAI,GAAG,CAAC;iBACf,CAAC,EACF,SAAS,EAAC,+BAA+B,YAExC,aAAa,GACT,CACR,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,2CAA2C,YAAE,aAAa,GAAQ,CACnF,EAED,gBAAM,SAAS,EAAC,iCAAiC,aAC9C,SAAS,OAAG,IAAI,SAAK,UAAU,IAC3B,EAEN,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CACnB,KAAC,IAAI,IACH,IAAI,EAAE,sBAAsB,CAAC;oBAC3B,QAAQ;oBACR,KAAK;oBACL,QAAQ;oBACR,IAAI,EAAE,IAAI,GAAG,CAAC;iBACf,CAAC,EACF,SAAS,EAAC,+BAA+B,YAExC,SAAS,GACL,CACR,CAAC,CAAC,CAAC,CACF,eAAM,SAAS,EAAC,2CAA2C,YAAE,SAAS,GAAQ,CAC/E,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentType } from "react";
|
|
2
|
+
import type { BlogEntry, BlogEntryMeta, BlogPostPageCopy } from "../types";
|
|
3
|
+
export default function BlogPostPage({ entry, suggestedEntries, copy, locale, backHref, components, }: {
|
|
4
|
+
entry: BlogEntry;
|
|
5
|
+
suggestedEntries?: BlogEntryMeta[];
|
|
6
|
+
copy: BlogPostPageCopy;
|
|
7
|
+
locale?: string;
|
|
8
|
+
backHref: string;
|
|
9
|
+
components?: Record<string, ComponentType<any>>;
|
|
10
|
+
}): Promise<import("react/jsx-runtime").JSX.Element>;
|
|
11
|
+
//# sourceMappingURL=BlogPostPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogPostPage.d.ts","sourceRoot":"","sources":["../../src/components/BlogPostPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,KAAK,EAAgB,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAKzF,wBAA8B,YAAY,CAAC,EACzC,KAAK,EACL,gBAAqB,EACrB,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,UAAU,GACX,EAAE;IACD,KAAK,EAAE,SAAS,CAAC;IACjB,gBAAgB,CAAC,EAAE,aAAa,EAAE,CAAC;IACnC,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;CACjD,oDA4GA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import Link from "next/link";
|
|
3
|
+
import Image from "next/image";
|
|
4
|
+
import { DocsMdx } from "../mdx";
|
|
5
|
+
import { formatBlogDate } from "./blog-utils";
|
|
6
|
+
import BlogCard from "./BlogCard";
|
|
7
|
+
export default async function BlogPostPage({ entry, suggestedEntries = [], copy, locale, backHref, components, }) {
|
|
8
|
+
const formattedPublishedDate = formatBlogDate(entry.publishedAt, locale);
|
|
9
|
+
const formattedUpdatedDate = formatBlogDate(entry.updatedAt, locale);
|
|
10
|
+
const showUpdated = Boolean(entry.updatedAt && entry.updatedAt !== entry.publishedAt);
|
|
11
|
+
const cardCopy = {
|
|
12
|
+
readMoreLabel: copy.readMoreLabel,
|
|
13
|
+
readingTimeSuffix: copy.readingTimeSuffix,
|
|
14
|
+
};
|
|
15
|
+
return (_jsxs("div", { className: "emcydocs-blog-post", children: [_jsxs("article", { className: "emcydocs-blog-post-article", children: [_jsx(Link, { href: backHref, className: "emcydocs-blog-back-link", children: copy.backLabel }), _jsxs("header", { className: "emcydocs-blog-post-header", children: [_jsxs("div", { className: "emcydocs-blog-post-meta", children: [_jsx("span", { className: "emcydocs-blog-post-category", children: entry.category }), _jsxs("span", { children: [copy.publishedOnLabel, " ", formattedPublishedDate] }), _jsxs("span", { children: [entry.readingTimeMinutes, " ", copy.readingTimeSuffix] })] }), _jsx("h1", { children: entry.title }), entry.description ? _jsx("p", { children: entry.description }) : null, _jsxs("div", { className: "emcydocs-blog-author", children: [entry.authorImage ? (_jsx(Image, { src: entry.authorImage, alt: entry.author, className: "emcydocs-blog-author-image", width: 48, height: 48, unoptimized: true })) : (_jsx("div", { className: "emcydocs-blog-author-image is-fallback", "aria-hidden": "true", children: entry.author.charAt(0).toUpperCase() })), _jsxs("div", { className: "emcydocs-blog-author-copy", children: [_jsx("span", { children: copy.writtenByLabel }), _jsx("strong", { children: entry.author }), entry.authorRole ? _jsx("p", { children: entry.authorRole }) : null, showUpdated ? (_jsxs("p", { children: [copy.updatedOnLabel, " ", formattedUpdatedDate] })) : null] })] })] }), entry.image ? (_jsx("div", { className: "emcydocs-blog-post-image-wrap", children: _jsx(Image, { src: entry.image, alt: entry.imageAlt || entry.title, className: "emcydocs-blog-post-image", fill: true, sizes: "100vw", unoptimized: true }) })) : null, _jsx("div", { className: "emcydocs-blog-post-content", children: _jsx(DocsMdx, { entry: entry, components: components }) }), entry.tags.length > 0 ? (_jsxs("footer", { className: "emcydocs-blog-post-footer", children: [_jsx("span", { children: copy.tagsLabel }), _jsx("div", { className: "emcydocs-blog-post-tags", children: entry.tags.map((tag) => (_jsx("span", { className: "emcydocs-blog-post-tag", children: tag }, tag))) })] })) : null] }), suggestedEntries.length > 0 ? (_jsxs("section", { className: "emcydocs-blog-suggested", children: [_jsx("div", { className: "emcydocs-blog-suggested-header", children: _jsxs("div", { children: [_jsx("h2", { children: copy.suggestedLabel }), copy.suggestedDescription ? _jsx("p", { children: copy.suggestedDescription }) : null] }) }), _jsx("div", { className: "emcydocs-blog-grid", children: suggestedEntries.map((post) => (_jsx(BlogCard, { post: post, copy: cardCopy, locale: locale }, `${post.slug}-${post.locale}`))) })] })) : null] }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=BlogPostPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogPostPage.js","sourceRoot":"","sources":["../../src/components/BlogPostPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogSearch.d.ts","sourceRoot":"","sources":["../../src/components/BlogSearch.tsx"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,UAAU,EACV,KAAK,EACL,QAAQ,EACR,WAAW,GACZ,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB,2CAyBA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export default function BlogSearch({ actionHref, query, category, placeholder, }) {
|
|
3
|
+
return (_jsxs("form", { action: actionHref, method: "get", className: "emcydocs-blog-search-form", children: [_jsxs("div", { className: "emcydocs-blog-search-input-wrap", children: [_jsxs("svg", { className: "emcydocs-blog-search-icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("path", { d: "M21 21l-4.35-4.35" })] }), _jsx("input", { type: "search", name: "q", defaultValue: query, placeholder: placeholder, className: "emcydocs-blog-search-input" })] }), category && category !== "all" ? _jsx("input", { type: "hidden", name: "category", value: category }) : null] }));
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=BlogSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlogSearch.js","sourceRoot":"","sources":["../../src/components/BlogSearch.tsx"],"names":[],"mappings":";AAAA,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,UAAU,EACV,KAAK,EACL,QAAQ,EACR,WAAW,GAMZ;IACC,OAAO,CACL,gBAAM,MAAM,EAAE,UAAU,EAAE,MAAM,EAAC,KAAK,EAAC,SAAS,EAAC,2BAA2B,aAC1E,eAAK,SAAS,EAAC,iCAAiC,aAC9C,eACE,SAAS,EAAC,2BAA2B,EACrC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,aAEf,iBAAQ,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,GAAG,EAChC,eAAM,CAAC,EAAC,mBAAmB,GAAG,IAC1B,EACN,gBACE,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,GAAG,EACR,YAAY,EAAE,KAAK,EACnB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAC,4BAA4B,GACtC,IACE,EACL,QAAQ,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,gBAAO,IAAI,EAAC,QAAQ,EAAC,IAAI,EAAC,UAAU,EAAC,KAAK,EAAE,QAAQ,GAAI,CAAC,CAAC,CAAC,IAAI,IAC5F,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CopyPageButton.d.ts","sourceRoot":"","sources":["../../src/components/CopyPageButton.tsx"],"names":[],"mappings":"AAMA,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,KAAmB,GACpB,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,2CAwJA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
export default function CopyPageButton({ label = "Copy page", }) {
|
|
5
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
6
|
+
const [copyState, setCopyState] = useState("idle");
|
|
7
|
+
const ref = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
if (!isOpen)
|
|
10
|
+
return;
|
|
11
|
+
const handle = (e) => {
|
|
12
|
+
if (ref.current && !ref.current.contains(e.target)) {
|
|
13
|
+
setIsOpen(false);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
document.addEventListener("pointerdown", handle);
|
|
17
|
+
return () => document.removeEventListener("pointerdown", handle);
|
|
18
|
+
}, [isOpen]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (copyState === "idle")
|
|
21
|
+
return;
|
|
22
|
+
const id = window.setTimeout(() => setCopyState("idle"), 2000);
|
|
23
|
+
return () => window.clearTimeout(id);
|
|
24
|
+
}, [copyState]);
|
|
25
|
+
const copyLink = async () => {
|
|
26
|
+
try {
|
|
27
|
+
await navigator.clipboard.writeText(window.location.href);
|
|
28
|
+
setCopyState("copied-link");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
window.prompt("Copy link", window.location.href);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const copyMarkdown = async () => {
|
|
35
|
+
const article = document.querySelector(".emcydocs-article");
|
|
36
|
+
if (!article)
|
|
37
|
+
return;
|
|
38
|
+
const title = article.querySelector("h1")?.textContent ?? "";
|
|
39
|
+
const desc = article.querySelector(".emcydocs-page-header > p")?.textContent ?? "";
|
|
40
|
+
const prose = article.querySelector(".emcydocs-prose");
|
|
41
|
+
const text = prose?.textContent ?? "";
|
|
42
|
+
const md = [
|
|
43
|
+
title && `# ${title}`,
|
|
44
|
+
desc && `\n${desc}`,
|
|
45
|
+
text && `\n${text}`,
|
|
46
|
+
`\nSource: ${window.location.href}`,
|
|
47
|
+
]
|
|
48
|
+
.filter(Boolean)
|
|
49
|
+
.join("\n");
|
|
50
|
+
try {
|
|
51
|
+
await navigator.clipboard.writeText(md);
|
|
52
|
+
setCopyState("copied-page");
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
window.prompt("Copy content", md.slice(0, 500));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const buttonLabel = copyState === "copied-link"
|
|
59
|
+
? "Copied link!"
|
|
60
|
+
: copyState === "copied-page"
|
|
61
|
+
? "Copied!"
|
|
62
|
+
: label;
|
|
63
|
+
return (_jsxs("div", { ref: ref, className: "emcydocs-copymenu", children: [_jsxs("button", { type: "button", className: "emcydocs-copymenu-trigger", onClick: () => setIsOpen((o) => !o), "aria-expanded": isOpen, children: [_jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }), _jsx("path", { d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" })] }), _jsx("span", { children: buttonLabel }), _jsx("svg", { className: "emcydocs-copymenu-chevron", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", "data-open": isOpen, children: _jsx("polyline", { points: "6 9 12 15 18 9" }) })] }), isOpen ? (_jsxs("div", { className: "emcydocs-copymenu-panel", children: [_jsxs("button", { type: "button", className: "emcydocs-copymenu-item", onClick: () => {
|
|
64
|
+
copyLink();
|
|
65
|
+
setIsOpen(false);
|
|
66
|
+
}, children: [_jsx("span", { className: "emcydocs-copymenu-icon", children: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71" }), _jsx("path", { d: "M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71" })] }) }), _jsxs("span", { className: "emcydocs-copymenu-text", children: [_jsx("span", { className: "emcydocs-copymenu-title", children: "Copy link" }), _jsx("span", { className: "emcydocs-copymenu-desc", children: "Share this page URL" })] })] }), _jsxs("button", { type: "button", className: "emcydocs-copymenu-item", onClick: () => {
|
|
67
|
+
copyMarkdown();
|
|
68
|
+
setIsOpen(false);
|
|
69
|
+
}, children: [_jsx("span", { className: "emcydocs-copymenu-icon", children: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }), _jsx("path", { d: "M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" })] }) }), _jsxs("span", { className: "emcydocs-copymenu-text", children: [_jsx("span", { className: "emcydocs-copymenu-title", children: "Copy page" }), _jsx("span", { className: "emcydocs-copymenu-desc", children: "Copy as Markdown for LLMs" })] })] }), _jsxs("a", { href: `https://claude.ai/new?q=${encodeURIComponent(`Read this documentation page and answer my questions about it: ${typeof window !== "undefined" ? window.location.href : ""}`)}`, target: "_blank", rel: "noopener noreferrer", className: "emcydocs-copymenu-item", onClick: () => setIsOpen(false), children: [_jsx("span", { className: "emcydocs-copymenu-icon emcydocs-copymenu-icon-accent", children: _jsxs("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [_jsx("path", { d: "M12 2a10 10 0 1010 10A10 10 0 0012 2z" }), _jsx("path", { d: "M12 16v.01" }), _jsx("path", { d: "M12 8v4" })] }) }), _jsxs("span", { className: "emcydocs-copymenu-text", children: [_jsxs("span", { className: "emcydocs-copymenu-title", children: ["Ask Claude", _jsx("svg", { className: "emcydocs-copymenu-external", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M7 17L17 7M17 7H7M17 7v10" }) })] }), _jsx("span", { className: "emcydocs-copymenu-desc", children: "Ask questions about this page" })] })] })] })) : null] }));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=CopyPageButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CopyPageButton.js","sourceRoot":"","sources":["../../src/components/CopyPageButton.tsx"],"names":[],"mappings":"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"}
|