blodemd 0.0.8 → 0.0.10
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 +25 -9
- package/dev-server/app/[[...slug]]/page.tsx +1 -0
- package/dev-server/app/favicon.ico +0 -0
- package/dev-server/next.config.js +11 -13
- package/dev-server/package.json +1 -1
- package/dev-server/tsconfig.json +3 -0
- package/dist/cli.mjs +869 -184
- package/dist/cli.mjs.map +1 -1
- package/docs/app/globals.css +1 -1
- package/docs/components/animate-ui/primitives/buttons/button.tsx +14 -0
- package/docs/components/api/api-playground.tsx +255 -80
- package/docs/components/api/api-reference.tsx +11 -1
- package/docs/components/docs/contextual-menu.tsx +227 -142
- package/docs/components/docs/copy-page-menu.tsx +148 -85
- package/docs/components/docs/doc-header.tsx +13 -3
- package/docs/components/docs/doc-shell.tsx +25 -14
- package/docs/components/docs/mobile-nav.tsx +0 -6
- package/docs/components/mdx/code-group.tsx +171 -62
- package/docs/components/mdx/steps.tsx +1 -1
- package/docs/components/mdx/tabs.tsx +131 -26
- package/docs/components/ui/copy-button.tsx +122 -0
- package/docs/components/ui/input.tsx +0 -1
- package/docs/components/ui/search.tsx +241 -132
- package/docs/components/ui/site-footer.tsx +39 -0
- package/docs/lib/config.ts +7 -0
- package/docs/lib/content-root.ts +33 -0
- package/docs/lib/content-source.ts +70 -0
- package/docs/lib/contextual-options.ts +20 -0
- package/docs/lib/docs-runtime.tsx +595 -0
- package/docs/lib/edge-config.ts +95 -0
- package/docs/lib/env.ts +22 -0
- package/docs/lib/openapi-proxy.ts +88 -0
- package/docs/lib/platform-config.ts +6 -0
- package/docs/lib/routes.ts +39 -0
- package/docs/lib/supabase.ts +13 -0
- package/docs/lib/tenancy.ts +350 -0
- package/docs/lib/tenant-headers.ts +14 -0
- package/docs/lib/tenant-static.ts +529 -0
- package/docs/lib/tenant-utility-context.ts +62 -0
- package/docs/lib/tenants.ts +68 -0
- package/docs/lib/use-mobile.ts +19 -0
- package/package.json +3 -2
- package/packages/@repo/common/dist/index.d.ts +7 -0
- package/packages/@repo/common/dist/index.d.ts.map +1 -1
- package/packages/@repo/common/dist/index.js +42 -0
- package/packages/@repo/common/src/index.ts +50 -0
- package/packages/@repo/contracts/dist/project.d.ts +1 -1
- package/packages/@repo/contracts/dist/project.js +1 -1
- package/packages/@repo/contracts/src/project.ts +1 -1
- package/packages/@repo/models/dist/docs-config.d.ts +194 -29
- package/packages/@repo/models/dist/docs-config.d.ts.map +1 -1
- package/packages/@repo/models/dist/docs-config.js +3 -28
- package/packages/@repo/models/src/docs-config.ts +5 -31
- package/packages/@repo/previewing/dist/blob-source.d.ts.map +1 -1
- package/packages/@repo/previewing/dist/blob-source.js +7 -2
- package/packages/@repo/previewing/dist/fs-source.d.ts.map +1 -1
- package/packages/@repo/previewing/dist/fs-source.js +2 -3
- package/packages/@repo/previewing/dist/index.d.ts.map +1 -1
- package/packages/@repo/previewing/dist/index.js +20 -50
- package/packages/@repo/previewing/src/blob-source.ts +7 -4
- package/packages/@repo/previewing/src/fs-source.ts +2 -3
- package/packages/@repo/previewing/src/index.ts +29 -64
- package/packages/@repo/validation/dist/index.d.ts +2 -2
- package/packages/@repo/validation/dist/index.d.ts.map +1 -1
- package/packages/@repo/validation/dist/index.js +2 -2
- package/packages/@repo/validation/package.json +1 -0
- package/packages/@repo/validation/src/{mintlify-docs-schema.json → blodemd-docs-schema.json} +346 -1794
- package/packages/@repo/validation/src/index.ts +4 -4
|
@@ -11,12 +11,20 @@ import {
|
|
|
11
11
|
import type React from "react";
|
|
12
12
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
13
13
|
|
|
14
|
+
import {
|
|
15
|
+
Popover,
|
|
16
|
+
PopoverContent,
|
|
17
|
+
PopoverTrigger,
|
|
18
|
+
} from "@/components/ui/popover";
|
|
19
|
+
|
|
14
20
|
interface CopyPageMenuProps {
|
|
15
21
|
content?: string;
|
|
16
22
|
contentUrl?: string;
|
|
17
23
|
title: string;
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
type CopyStatus = "copied" | "error" | "idle";
|
|
27
|
+
|
|
20
28
|
const LEADING_H1_REGEX = /^#\s+([^\r\n]+)(?:\r?\n(?:\r?\n)?)?/;
|
|
21
29
|
|
|
22
30
|
const stripMatchingLeadingH1 = (source: string, title: string) => {
|
|
@@ -43,6 +51,37 @@ const formatMarkdownForCopy = (source: string, title: string) => {
|
|
|
43
51
|
return `# ${title}\n\n${content}`;
|
|
44
52
|
};
|
|
45
53
|
|
|
54
|
+
const getCopyLabel = (copyStatus: CopyStatus) => {
|
|
55
|
+
switch (copyStatus) {
|
|
56
|
+
case "copied": {
|
|
57
|
+
return "Copied";
|
|
58
|
+
}
|
|
59
|
+
case "error": {
|
|
60
|
+
return "Copy failed";
|
|
61
|
+
}
|
|
62
|
+
default: {
|
|
63
|
+
return "Copy page";
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const getCopyDescription = (copyStatus: CopyStatus) => {
|
|
69
|
+
switch (copyStatus) {
|
|
70
|
+
case "copied": {
|
|
71
|
+
return "Copied page markdown to clipboard";
|
|
72
|
+
}
|
|
73
|
+
case "error": {
|
|
74
|
+
return "Clipboard access was blocked or the page markdown could not be loaded";
|
|
75
|
+
}
|
|
76
|
+
default: {
|
|
77
|
+
return "Copy page as Markdown for LLMs";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const getCopyIcon = (copyStatus: CopyStatus) =>
|
|
83
|
+
copyStatus === "copied" ? Checkmark1Icon : CopySimpleIcon;
|
|
84
|
+
|
|
46
85
|
const MenuItem = ({
|
|
47
86
|
children,
|
|
48
87
|
href,
|
|
@@ -50,11 +89,11 @@ const MenuItem = ({
|
|
|
50
89
|
}: {
|
|
51
90
|
children: React.ReactNode;
|
|
52
91
|
href?: string;
|
|
53
|
-
onSelect?: () => void;
|
|
92
|
+
onSelect?: () => Promise<void> | void;
|
|
54
93
|
}) =>
|
|
55
94
|
href ? (
|
|
56
95
|
<a
|
|
57
|
-
className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm transition-colors hover:bg-secondary/25"
|
|
96
|
+
className="flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm transition-colors hover:bg-secondary/25 focus-visible:bg-secondary/25 focus-visible:outline-none"
|
|
58
97
|
href={href}
|
|
59
98
|
onClick={onSelect}
|
|
60
99
|
rel="noopener noreferrer"
|
|
@@ -64,7 +103,7 @@ const MenuItem = ({
|
|
|
64
103
|
</a>
|
|
65
104
|
) : (
|
|
66
105
|
<button
|
|
67
|
-
className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm transition-colors hover:bg-secondary/25"
|
|
106
|
+
className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left text-sm transition-colors hover:bg-secondary/25 focus-visible:bg-secondary/25 focus-visible:outline-none"
|
|
68
107
|
onClick={onSelect}
|
|
69
108
|
type="button"
|
|
70
109
|
>
|
|
@@ -98,47 +137,48 @@ export const CopyPageMenu = ({
|
|
|
98
137
|
contentUrl,
|
|
99
138
|
title,
|
|
100
139
|
}: CopyPageMenuProps) => {
|
|
101
|
-
const
|
|
102
|
-
const [
|
|
140
|
+
const resetTimerRef = useRef<number | null>(null);
|
|
141
|
+
const [copyStatus, setCopyStatus] = useState<CopyStatus>("idle");
|
|
142
|
+
const [fetchedContent, setFetchedContent] = useState<string | null>(null);
|
|
103
143
|
const [menuOpen, setMenuOpen] = useState(false);
|
|
104
144
|
const [pageUrl, setPageUrl] = useState("");
|
|
105
|
-
const [resolvedContent, setResolvedContent] = useState(content ?? "");
|
|
106
|
-
|
|
107
|
-
useEffect(() => {
|
|
108
|
-
setPageUrl(window.location.href);
|
|
109
|
-
}, []);
|
|
110
|
-
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
if (content !== undefined) {
|
|
113
|
-
setResolvedContent(content);
|
|
114
|
-
}
|
|
115
|
-
}, [content]);
|
|
116
|
-
|
|
117
|
-
useEffect(() => {
|
|
118
|
-
if (!menuOpen) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
145
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
146
|
+
useEffect(
|
|
147
|
+
() => () => {
|
|
148
|
+
if (resetTimerRef.current !== null) {
|
|
149
|
+
window.clearTimeout(resetTimerRef.current);
|
|
125
150
|
}
|
|
126
|
-
|
|
127
|
-
|
|
151
|
+
},
|
|
152
|
+
[]
|
|
153
|
+
);
|
|
128
154
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
setPageUrl(
|
|
157
|
+
new URL(contentUrl ?? window.location.href, window.location.href).href
|
|
158
|
+
);
|
|
159
|
+
}, [contentUrl]);
|
|
132
160
|
|
|
133
161
|
const closeMenu = useCallback(() => {
|
|
134
162
|
setMenuOpen(false);
|
|
135
163
|
}, []);
|
|
136
164
|
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
165
|
+
const setTemporaryCopyStatus = useCallback(
|
|
166
|
+
(nextStatus: "copied" | "error") => {
|
|
167
|
+
if (resetTimerRef.current !== null) {
|
|
168
|
+
window.clearTimeout(resetTimerRef.current);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
setCopyStatus(nextStatus);
|
|
172
|
+
resetTimerRef.current = window.setTimeout(() => {
|
|
173
|
+
setCopyStatus("idle");
|
|
174
|
+
resetTimerRef.current = null;
|
|
175
|
+
}, 2000);
|
|
176
|
+
},
|
|
177
|
+
[]
|
|
178
|
+
);
|
|
140
179
|
|
|
141
180
|
const getContent = useCallback(async () => {
|
|
181
|
+
const resolvedContent = content ?? fetchedContent;
|
|
142
182
|
if (resolvedContent) {
|
|
143
183
|
return resolvedContent;
|
|
144
184
|
}
|
|
@@ -157,68 +197,89 @@ export const CopyPageMenu = ({
|
|
|
157
197
|
}
|
|
158
198
|
|
|
159
199
|
const nextContent = await response.text();
|
|
160
|
-
|
|
200
|
+
setFetchedContent(nextContent);
|
|
161
201
|
return nextContent;
|
|
162
|
-
}, [contentUrl,
|
|
202
|
+
}, [content, contentUrl, fetchedContent]);
|
|
163
203
|
|
|
164
204
|
const handleCopy = useCallback(async () => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
205
|
+
try {
|
|
206
|
+
// iOS Safari loses the user gesture context after any async gap (e.g. a
|
|
207
|
+
// fetch). To keep clipboard access working, we call clipboard.write()
|
|
208
|
+
// synchronously within the gesture and pass a Promise to ClipboardItem
|
|
209
|
+
// so the content resolves later while the gesture context stays alive.
|
|
210
|
+
const blobPromise = (async () => {
|
|
211
|
+
const nextContent = await getContent();
|
|
212
|
+
const markdown = formatMarkdownForCopy(nextContent, title);
|
|
213
|
+
return new Blob([markdown], { type: "text/plain" });
|
|
214
|
+
})();
|
|
215
|
+
|
|
216
|
+
if (typeof ClipboardItem === "undefined") {
|
|
217
|
+
const blob = await blobPromise;
|
|
218
|
+
await navigator.clipboard.writeText(await blob.text());
|
|
219
|
+
} else {
|
|
220
|
+
await navigator.clipboard.write([
|
|
221
|
+
new ClipboardItem({ "text/plain": blobPromise }),
|
|
222
|
+
]);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
setTemporaryCopyStatus("copied");
|
|
226
|
+
closeMenu();
|
|
227
|
+
} catch {
|
|
228
|
+
setTemporaryCopyStatus("error");
|
|
229
|
+
}
|
|
230
|
+
}, [closeMenu, getContent, setTemporaryCopyStatus, title]);
|
|
172
231
|
|
|
173
232
|
const chatgptUrl = pageUrl
|
|
174
233
|
? `https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read from ${pageUrl} so I can ask questions about it.`)}`
|
|
175
|
-
:
|
|
234
|
+
: undefined;
|
|
176
235
|
const claudeUrl = pageUrl
|
|
177
236
|
? `https://claude.ai/new?q=${encodeURIComponent(`Read from ${pageUrl} so I can ask questions about it.`)}`
|
|
178
|
-
:
|
|
237
|
+
: undefined;
|
|
238
|
+
const copyLabel = getCopyLabel(copyStatus);
|
|
239
|
+
const copyDescription = getCopyDescription(copyStatus);
|
|
240
|
+
const CopyIcon = getCopyIcon(copyStatus);
|
|
179
241
|
|
|
180
242
|
return (
|
|
181
|
-
<
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
</
|
|
214
|
-
<div>
|
|
215
|
-
|
|
216
|
-
<div className="text-xs text-muted-foreground">
|
|
217
|
-
Copy page as Markdown for LLMs
|
|
218
|
-
</div>
|
|
243
|
+
<Popover onOpenChange={setMenuOpen} open={menuOpen}>
|
|
244
|
+
<div className="flex shrink-0 items-center">
|
|
245
|
+
<button
|
|
246
|
+
className="inline-flex items-center gap-2 rounded-l-xl border border-r-0 border-border px-3 py-1.5 text-sm font-medium transition-colors hover:bg-secondary/25"
|
|
247
|
+
onClick={handleCopy}
|
|
248
|
+
type="button"
|
|
249
|
+
>
|
|
250
|
+
<CopyIcon aria-hidden="true" className="size-[18px]" />
|
|
251
|
+
<span>{copyLabel}</span>
|
|
252
|
+
</button>
|
|
253
|
+
|
|
254
|
+
<PopoverTrigger asChild>
|
|
255
|
+
<button
|
|
256
|
+
aria-expanded={menuOpen}
|
|
257
|
+
aria-label="More actions"
|
|
258
|
+
className="inline-flex items-center self-stretch rounded-r-xl border border-border px-2 transition-colors hover:bg-secondary/25"
|
|
259
|
+
type="button"
|
|
260
|
+
>
|
|
261
|
+
<ChevronDownSmallIcon
|
|
262
|
+
aria-hidden="true"
|
|
263
|
+
className="size-[18px] text-muted-foreground"
|
|
264
|
+
/>
|
|
265
|
+
</button>
|
|
266
|
+
</PopoverTrigger>
|
|
267
|
+
</div>
|
|
268
|
+
|
|
269
|
+
<PopoverContent align="end" className="w-[280px] rounded-xl p-1">
|
|
270
|
+
<MenuItem onSelect={handleCopy}>
|
|
271
|
+
<MenuIcon>
|
|
272
|
+
<CopyIcon aria-hidden="true" className="size-[18px]" />
|
|
273
|
+
</MenuIcon>
|
|
274
|
+
<div>
|
|
275
|
+
<div className="font-medium">{copyLabel}</div>
|
|
276
|
+
<div className="text-xs text-muted-foreground">
|
|
277
|
+
{copyDescription}
|
|
219
278
|
</div>
|
|
220
|
-
</
|
|
279
|
+
</div>
|
|
280
|
+
</MenuItem>
|
|
221
281
|
|
|
282
|
+
{chatgptUrl ? (
|
|
222
283
|
<MenuItem href={chatgptUrl} onSelect={closeMenu}>
|
|
223
284
|
<MenuIcon>
|
|
224
285
|
<OpenaiIcon aria-hidden="true" className="size-[18px]" />
|
|
@@ -233,7 +294,9 @@ export const CopyPageMenu = ({
|
|
|
233
294
|
</div>
|
|
234
295
|
</div>
|
|
235
296
|
</MenuItem>
|
|
297
|
+
) : null}
|
|
236
298
|
|
|
299
|
+
{claudeUrl ? (
|
|
237
300
|
<MenuItem href={claudeUrl} onSelect={closeMenu}>
|
|
238
301
|
<MenuIcon>
|
|
239
302
|
<ClaudeaiIcon aria-hidden="true" className="size-[18px]" />
|
|
@@ -248,8 +311,8 @@ export const CopyPageMenu = ({
|
|
|
248
311
|
</div>
|
|
249
312
|
</div>
|
|
250
313
|
</MenuItem>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
</
|
|
314
|
+
) : null}
|
|
315
|
+
</PopoverContent>
|
|
316
|
+
</Popover>
|
|
254
317
|
);
|
|
255
318
|
};
|
|
@@ -9,6 +9,8 @@ import type { NavEntry, NavTab } from "@/lib/navigation";
|
|
|
9
9
|
import { isExternalHref, resolveHref, toDocHref } from "@/lib/routes";
|
|
10
10
|
import { cn } from "@/lib/utils";
|
|
11
11
|
|
|
12
|
+
const EMPTY_NAV: NavEntry[] = [];
|
|
13
|
+
|
|
12
14
|
const Dropdown = ({
|
|
13
15
|
label,
|
|
14
16
|
items,
|
|
@@ -102,7 +104,7 @@ export const DocHeader = ({
|
|
|
102
104
|
basePath,
|
|
103
105
|
tabs,
|
|
104
106
|
activeTabIndex,
|
|
105
|
-
nav =
|
|
107
|
+
nav = EMPTY_NAV,
|
|
106
108
|
}: {
|
|
107
109
|
config: SiteConfig;
|
|
108
110
|
basePath: string;
|
|
@@ -117,6 +119,10 @@ export const DocHeader = ({
|
|
|
117
119
|
const [primaryLanguage] = languages;
|
|
118
120
|
const searchDisabled = config.features?.search === false;
|
|
119
121
|
const themeToggleDisabled = config.features?.themeToggle === false;
|
|
122
|
+
const logoHref = config.logo?.href ?? toDocHref("index", basePath);
|
|
123
|
+
const logoIsExternal = Boolean(
|
|
124
|
+
config.logo?.href && isExternalHref(config.logo.href)
|
|
125
|
+
);
|
|
120
126
|
|
|
121
127
|
return (
|
|
122
128
|
<header className="sticky top-0 z-50 w-full bg-background">
|
|
@@ -132,7 +138,9 @@ export const DocHeader = ({
|
|
|
132
138
|
/>
|
|
133
139
|
<Link
|
|
134
140
|
className="flex items-center gap-2.5"
|
|
135
|
-
href={
|
|
141
|
+
href={logoHref}
|
|
142
|
+
rel={logoIsExternal ? "noopener noreferrer" : undefined}
|
|
143
|
+
target={logoIsExternal ? "_blank" : undefined}
|
|
136
144
|
>
|
|
137
145
|
{config.logo?.light ? (
|
|
138
146
|
<Image
|
|
@@ -186,7 +194,9 @@ export const DocHeader = ({
|
|
|
186
194
|
))}
|
|
187
195
|
</nav>
|
|
188
196
|
<div className="ml-auto flex items-center gap-2 md:flex-1 md:justify-end">
|
|
189
|
-
{searchDisabled ? null :
|
|
197
|
+
{searchDisabled ? null : (
|
|
198
|
+
<Search basePath={basePath} key={basePath} />
|
|
199
|
+
)}
|
|
190
200
|
{primaryVersion ? (
|
|
191
201
|
<Dropdown
|
|
192
202
|
basePath={basePath}
|
|
@@ -27,13 +27,21 @@ import { themeStylesFromConfig } from "@/lib/theme";
|
|
|
27
27
|
import type { TocItem } from "@/lib/toc";
|
|
28
28
|
import { cn } from "@/lib/utils";
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
scripts
|
|
32
|
-
strategy
|
|
33
|
-
|
|
34
|
-
scripts
|
|
30
|
+
const DocScripts = ({
|
|
31
|
+
scripts,
|
|
32
|
+
strategy = "afterInteractive",
|
|
33
|
+
}: {
|
|
34
|
+
scripts?: string[];
|
|
35
|
+
strategy?: "afterInteractive" | "lazyOnload";
|
|
36
|
+
}) => {
|
|
37
|
+
if (!scripts?.length) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return scripts.map((script) => (
|
|
35
42
|
<Script key={script} src={script} strategy={strategy} />
|
|
36
|
-
))
|
|
43
|
+
));
|
|
44
|
+
};
|
|
37
45
|
|
|
38
46
|
const Breadcrumbs = ({
|
|
39
47
|
basePath,
|
|
@@ -134,9 +142,10 @@ export const DocShell = ({
|
|
|
134
142
|
(toc.length > 0 || (contextual && contextualDisplay === "toc"));
|
|
135
143
|
|
|
136
144
|
const contextualTocItems =
|
|
137
|
-
contextual && contextualDisplay === "toc"
|
|
145
|
+
contextual && contextualDisplay === "toc" ? (
|
|
138
146
|
<ContextualTocItems
|
|
139
147
|
content={rawContent}
|
|
148
|
+
key={`toc-${currentPath}`}
|
|
140
149
|
options={contextual.options}
|
|
141
150
|
pagePath={currentPath}
|
|
142
151
|
title={pageTitle}
|
|
@@ -144,9 +153,10 @@ export const DocShell = ({
|
|
|
144
153
|
) : null;
|
|
145
154
|
|
|
146
155
|
const headerContextualMenu =
|
|
147
|
-
contextual && contextualDisplay === "header"
|
|
156
|
+
contextual && contextualDisplay === "header" ? (
|
|
148
157
|
<ContextualMenu
|
|
149
158
|
content={rawContent}
|
|
159
|
+
key={`header-${currentPath}`}
|
|
150
160
|
options={contextual.options}
|
|
151
161
|
pagePath={currentPath}
|
|
152
162
|
title={pageTitle}
|
|
@@ -175,8 +185,8 @@ export const DocShell = ({
|
|
|
175
185
|
<div className="flex flex-col gap-2">
|
|
176
186
|
<Breadcrumbs basePath={basePath} breadcrumbs={breadcrumbs} />
|
|
177
187
|
<div className="flex flex-col gap-2">
|
|
178
|
-
<div className="flex items-
|
|
179
|
-
<h1 className="scroll-m-24 text-3xl font-semibold tracking-tight sm:text-3xl">
|
|
188
|
+
<div className="flex flex-col items-start gap-3 sm:flex-row sm:justify-between">
|
|
189
|
+
<h1 className="min-w-0 scroll-m-24 text-3xl font-semibold tracking-tight sm:text-3xl">
|
|
180
190
|
{pageTitle}
|
|
181
191
|
{deprecated ? (
|
|
182
192
|
<span className="ml-3 inline-flex translate-y-[-2px] items-center rounded-md bg-yellow-100 px-2 py-0.5 align-middle text-xs font-medium text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-300">
|
|
@@ -188,8 +198,9 @@ export const DocShell = ({
|
|
|
188
198
|
(rawContent === undefined &&
|
|
189
199
|
markdownHref === undefined ? null : (
|
|
190
200
|
<CopyPageMenu
|
|
191
|
-
content={rawContent}
|
|
201
|
+
content={markdownHref ? undefined : rawContent}
|
|
192
202
|
contentUrl={markdownHref}
|
|
203
|
+
key={`copy-${currentPath}`}
|
|
193
204
|
title={pageTitle}
|
|
194
205
|
/>
|
|
195
206
|
))}
|
|
@@ -201,7 +212,7 @@ export const DocShell = ({
|
|
|
201
212
|
) : null}
|
|
202
213
|
</div>
|
|
203
214
|
</div>
|
|
204
|
-
<div className="grid gap-4.5 leading-relaxed [&_blockquote]:border-l-3 [&_blockquote]:border-primary [&_blockquote]:pl-3.5 [&_blockquote]:text-muted-foreground [&_h2]:mt-10 [&_h2]:mb-3 [&_h2]:text-2xl [&_h2]:font-bold [&_h3]:mt-8 [&_h3]:mb-2 [&_h3]:text-[1.375rem] [&_h3]:font-semibold [&_h4]:mt-6 [&_h4]:mb-2 [&_h4]:text-base [&_h4]:font-semibold [&_ol]:list-decimal [&_ol]:pl-
|
|
215
|
+
<div className="grid min-w-0 grid-cols-1 gap-4.5 leading-relaxed [&_blockquote]:border-l-3 [&_blockquote]:border-primary [&_blockquote]:pl-3.5 [&_blockquote]:text-muted-foreground [&_h2]:mt-10 [&_h2]:mb-3 [&_h2]:text-2xl [&_h2]:font-bold [&_h3]:mt-8 [&_h3]:mb-2 [&_h3]:text-[1.375rem] [&_h3]:font-semibold [&_h4]:mt-6 [&_h4]:mb-2 [&_h4]:text-base [&_h4]:font-semibold [&_ol]:list-decimal [&_ol]:pl-6 [&_table]:w-full [&_table]:border-collapse [&_table]:text-sm [&_td]:border-b [&_td]:border-border [&_td]:px-2.5 [&_td]:py-2 [&_td]:text-left [&_th]:border-b [&_th]:border-border [&_th]:px-2.5 [&_th]:py-2 [&_th]:text-left [&_ul]:list-disc [&_ul]:pl-6">
|
|
205
216
|
{content}
|
|
206
217
|
</div>
|
|
207
218
|
{!hideFooterPagination && (prevPage || nextPage) ? (
|
|
@@ -275,7 +286,7 @@ export const DocShell = ({
|
|
|
275
286
|
>
|
|
276
287
|
Skip to content
|
|
277
288
|
</a>
|
|
278
|
-
{
|
|
289
|
+
<DocScripts scripts={config.scripts?.head} />
|
|
279
290
|
<DocHeader
|
|
280
291
|
activeTabIndex={activeTabIndex}
|
|
281
292
|
basePath={basePath}
|
|
@@ -307,7 +318,7 @@ export const DocShell = ({
|
|
|
307
318
|
</div>
|
|
308
319
|
)}
|
|
309
320
|
</div>
|
|
310
|
-
{
|
|
321
|
+
<DocScripts scripts={config.scripts?.body} strategy="lazyOnload" />
|
|
311
322
|
</div>
|
|
312
323
|
);
|
|
313
324
|
};
|
|
@@ -108,9 +108,6 @@ export const MobileNav = ({
|
|
|
108
108
|
</div>
|
|
109
109
|
<span className="sr-only">Toggle Menu</span>
|
|
110
110
|
</div>
|
|
111
|
-
<span className="flex h-8 items-center text-lg font-medium leading-none">
|
|
112
|
-
Menu
|
|
113
|
-
</span>
|
|
114
111
|
</Button>
|
|
115
112
|
</PopoverTrigger>
|
|
116
113
|
<PopoverContent
|
|
@@ -164,9 +161,6 @@ export const MobileNav = ({
|
|
|
164
161
|
) : null}
|
|
165
162
|
{globalLinks.length > 0 ? (
|
|
166
163
|
<div className="flex flex-col gap-4">
|
|
167
|
-
<div className="text-sm font-medium text-muted-foreground">
|
|
168
|
-
Menu
|
|
169
|
-
</div>
|
|
170
164
|
<div className="flex flex-col gap-3">
|
|
171
165
|
{globalLinks.map((link) => (
|
|
172
166
|
<MobileLink
|