radiant-docs 0.1.61 → 0.1.62
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/package.json +1 -1
- package/template/package-lock.json +10 -4
- package/template/package.json +11 -2
- package/template/scripts/generate-proxy-allowed-origins.mjs +14 -6
- package/template/scripts/publish-shiki-platform-assets.mjs +1151 -0
- package/template/src/components/Header.astro +6 -1
- package/template/src/components/NavigationTabList.astro +65 -0
- package/template/src/components/NavigationTabs.astro +109 -0
- package/template/src/components/OpenApiPage.astro +17 -1
- package/template/src/components/Sidebar.astro +2 -2
- package/template/src/components/SidebarDropdown.astro +105 -44
- package/template/src/components/SidebarMenu.astro +3 -0
- package/template/src/components/SidebarSegmented.astro +87 -52
- package/template/src/components/SidebarTabs.astro +86 -0
- package/template/src/components/chat/AssistantDocsWidget.tsx +127 -2
- package/template/src/components/chat/AssistantEmbedPanel.tsx +269 -283
- package/template/src/components/user/Accordion.astro +1 -1
- package/template/src/components/user/Callout.astro +2 -2
- package/template/src/components/user/CodeBlock.astro +58 -7
- package/template/src/components/user/CodeGroup.astro +52 -1
- package/template/src/components/user/Column.astro +1 -1
- package/template/src/components/user/Step.astro +1 -1
- package/template/src/components/user/Tabs.astro +1 -1
- package/template/src/generated/shiki-platform-assets.json +24 -0
- package/template/src/layouts/Layout.astro +111 -8
- package/template/src/lib/assistant-panel-config.ts +59 -0
- package/template/src/lib/assistant-shiki-client.ts +506 -0
- package/template/src/lib/mdx/remark-resolve-internal-links.ts +334 -17
- package/template/src/lib/routes.ts +66 -24
- package/template/src/styles/global.css +12 -0
|
@@ -108,7 +108,7 @@ const hasTitle = typeof resolvedTitle === "string" && resolvedTitle.length > 0;
|
|
|
108
108
|
{resolvedTitle}
|
|
109
109
|
</div>
|
|
110
110
|
</div>
|
|
111
|
-
<div class="prose-rules
|
|
111
|
+
<div class="prose-rules max-w-none! text-sm! leading-6! text-neutral-700 dark:text-neutral-300">
|
|
112
112
|
<slot />
|
|
113
113
|
</div>
|
|
114
114
|
</>
|
|
@@ -129,7 +129,7 @@ const hasTitle = typeof resolvedTitle === "string" && resolvedTitle.length > 0;
|
|
|
129
129
|
class="mt-0.5 shrink-0 border border-white"
|
|
130
130
|
/>
|
|
131
131
|
) : null}
|
|
132
|
-
<div class="prose-rules
|
|
132
|
+
<div class="prose-rules max-w-none! min-w-0 flex-1 text-sm! leading-6! text-neutral-700 dark:text-neutral-300">
|
|
133
133
|
<slot />
|
|
134
134
|
</div>
|
|
135
135
|
</div>
|
|
@@ -258,7 +258,7 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
258
258
|
? ' data-rd-code-line-highlighted="true"'
|
|
259
259
|
: "";
|
|
260
260
|
|
|
261
|
-
return `<span class="flex min-w-full"${lineHighlightAttribute}>${lineNumberHtml}<span class="${lineContentClass}">${tokenHtml}</span></span>`;
|
|
261
|
+
return `<span class="flex w-max min-w-full"${lineHighlightAttribute}>${lineNumberHtml}<span class="${lineContentClass}">${tokenHtml}</span></span>`;
|
|
262
262
|
})
|
|
263
263
|
.join("");
|
|
264
264
|
---
|
|
@@ -339,7 +339,7 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
339
339
|
|
|
340
340
|
<div
|
|
341
341
|
class:list={[
|
|
342
|
-
"relative min-w-0 border-[0.5px] overflow-hidden border-(--rd-code-tab-edge-border)",
|
|
342
|
+
"relative min-w-0 border-[0.5px] overflow-hidden border-(--rd-code-tab-edge-border) bg-(--rd-code-surface)",
|
|
343
343
|
parsedFlushTop ? "rounded-b-xl" : "rounded-xl",
|
|
344
344
|
parsedFlushTop && "border-t-0",
|
|
345
345
|
parsedShowFilename && "border-t-0 rounded-t-none",
|
|
@@ -349,10 +349,10 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
349
349
|
>
|
|
350
350
|
{
|
|
351
351
|
!parsedInCodeGroup && !parsedShowFilename ? (
|
|
352
|
-
<div class="pointer-events-none absolute right-2 top-2 z-20">
|
|
352
|
+
<div class="pointer-events-none absolute right-2 top-2 z-20 [@media(pointer:coarse)]:pointer-events-auto">
|
|
353
353
|
<button
|
|
354
354
|
type="button"
|
|
355
|
-
class="pointer-events-none inline-flex size-7 appearance-none items-center justify-center rounded-md bg-(--rd-code-surface)/40 backdrop-blur-sm text-neutral-500/80 outline-none ring-0 transition-colors duration-150 hover:text-neutral-700 focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 cursor-pointer group-hover/prose-code:pointer-events-auto group-focus-within/prose-code:pointer-events-auto dark:text-neutral-400 dark:hover:text-neutral-200 relative before:absolute before:inset-1 hover:before:inset-0 before:rounded-md hover:before:bg-neutral-900/4 dark:hover:before:bg-white/4 before:duration-150"
|
|
355
|
+
class="pointer-events-none inline-flex size-7 appearance-none items-center justify-center rounded-md bg-(--rd-code-surface)/40 backdrop-blur-sm text-neutral-500/80 outline-none ring-0 transition-colors duration-150 hover:text-neutral-700 focus:outline-none focus-visible:outline-none focus:ring-0 focus-visible:ring-0 cursor-pointer group-hover/prose-code:pointer-events-auto group-focus-within/prose-code:pointer-events-auto [@media(pointer:coarse)]:pointer-events-auto dark:text-neutral-400 dark:hover:text-neutral-200 relative before:absolute before:inset-1 hover:before:inset-0 before:rounded-md hover:before:bg-neutral-900/4 dark:hover:before:bg-white/4 before:duration-150"
|
|
356
356
|
data-rd-copy-trigger="true"
|
|
357
357
|
data-rd-copy-content={encodedRaw}
|
|
358
358
|
aria-label="Copy code"
|
|
@@ -390,10 +390,10 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
390
390
|
|
|
391
391
|
<div
|
|
392
392
|
data-rd-code-scroll-area
|
|
393
|
-
class="relative overflow-x-auto [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90"
|
|
393
|
+
class="relative overflow-x-auto overscroll-x-contain bg-(--rd-code-surface) [scrollbar-width:thin] [scrollbar-color:var(--color-neutral-300)_transparent] [&::-webkit-scrollbar]:h-1.5 [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:bg-neutral-300/70 hover:[&::-webkit-scrollbar-thumb]:bg-neutral-300/90 dark:[scrollbar-color:var(--color-neutral-700)_transparent] dark:[&::-webkit-scrollbar-thumb]:bg-neutral-700/70 dark:hover:[&::-webkit-scrollbar-thumb]:bg-neutral-700/90"
|
|
394
394
|
>
|
|
395
395
|
<pre
|
|
396
|
-
class="relative m-0 min-w-full bg-(--rd-code-surface) p-0 text-[13px] leading-6"><code data-rd-code-theme class="block min-w-full py-2.5 font-mono text-neutral-800 dark:text-neutral-200"><Fragment set:html={renderedCodeLinesHtml} /></code></pre>
|
|
396
|
+
class="relative m-0 w-max min-w-full bg-(--rd-code-surface) p-0 text-[13px] leading-6"><code data-rd-code-theme class="block w-max min-w-full py-2.5 font-mono text-neutral-800 dark:text-neutral-200"><Fragment set:html={renderedCodeLinesHtml} /></code></pre>
|
|
397
397
|
</div>
|
|
398
398
|
</div>
|
|
399
399
|
</div>
|
|
@@ -432,6 +432,52 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
432
432
|
checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
|
|
433
433
|
};
|
|
434
434
|
|
|
435
|
+
const fallbackCopy = (text) => {
|
|
436
|
+
try {
|
|
437
|
+
const textarea = document.createElement("textarea");
|
|
438
|
+
textarea.value = text;
|
|
439
|
+
textarea.setAttribute("readonly", "");
|
|
440
|
+
textarea.style.position = "fixed";
|
|
441
|
+
textarea.style.top = "0";
|
|
442
|
+
textarea.style.left = "0";
|
|
443
|
+
textarea.style.width = "1px";
|
|
444
|
+
textarea.style.height = "1px";
|
|
445
|
+
textarea.style.padding = "0";
|
|
446
|
+
textarea.style.border = "0";
|
|
447
|
+
textarea.style.opacity = "0";
|
|
448
|
+
textarea.style.fontSize = "16px";
|
|
449
|
+
textarea.style.pointerEvents = "none";
|
|
450
|
+
document.body.appendChild(textarea);
|
|
451
|
+
|
|
452
|
+
try {
|
|
453
|
+
textarea.focus({ preventScroll: true });
|
|
454
|
+
} catch {
|
|
455
|
+
textarea.focus();
|
|
456
|
+
}
|
|
457
|
+
textarea.select();
|
|
458
|
+
textarea.setSelectionRange(0, textarea.value.length);
|
|
459
|
+
|
|
460
|
+
const copied = document.execCommand("copy");
|
|
461
|
+
document.body.removeChild(textarea);
|
|
462
|
+
return copied;
|
|
463
|
+
} catch {
|
|
464
|
+
return false;
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
const copyToClipboard = async (text) => {
|
|
469
|
+
try {
|
|
470
|
+
if (navigator.clipboard?.writeText) {
|
|
471
|
+
await navigator.clipboard.writeText(text);
|
|
472
|
+
return true;
|
|
473
|
+
}
|
|
474
|
+
} catch {
|
|
475
|
+
// Fallback below when the async Clipboard API is unavailable or blocked.
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return fallbackCopy(text);
|
|
479
|
+
};
|
|
480
|
+
|
|
435
481
|
copyButtons.forEach((button) => {
|
|
436
482
|
let timeoutId = null;
|
|
437
483
|
button.addEventListener("click", async () => {
|
|
@@ -440,7 +486,12 @@ const renderedCodeLinesHtml = normalizedTokenLines
|
|
|
440
486
|
const copyValue = decodeURIComponent(encodedCopyValue);
|
|
441
487
|
|
|
442
488
|
try {
|
|
443
|
-
await
|
|
489
|
+
const copied = await copyToClipboard(copyValue);
|
|
490
|
+
if (!copied) {
|
|
491
|
+
setCopiedState(button, false);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
|
|
444
495
|
setCopiedState(button, true);
|
|
445
496
|
|
|
446
497
|
if (timeoutId) window.clearTimeout(timeoutId);
|
|
@@ -130,6 +130,52 @@ import CodeTabEdge from "../ui/CodeTabEdge.astro";
|
|
|
130
130
|
checkIcon.classList.add("scale-50", "opacity-0", "rotate-6");
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
const fallbackCopy = (text) => {
|
|
134
|
+
try {
|
|
135
|
+
const textarea = document.createElement("textarea");
|
|
136
|
+
textarea.value = text;
|
|
137
|
+
textarea.setAttribute("readonly", "");
|
|
138
|
+
textarea.style.position = "fixed";
|
|
139
|
+
textarea.style.top = "0";
|
|
140
|
+
textarea.style.left = "0";
|
|
141
|
+
textarea.style.width = "1px";
|
|
142
|
+
textarea.style.height = "1px";
|
|
143
|
+
textarea.style.padding = "0";
|
|
144
|
+
textarea.style.border = "0";
|
|
145
|
+
textarea.style.opacity = "0";
|
|
146
|
+
textarea.style.fontSize = "16px";
|
|
147
|
+
textarea.style.pointerEvents = "none";
|
|
148
|
+
document.body.appendChild(textarea);
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
textarea.focus({ preventScroll: true });
|
|
152
|
+
} catch {
|
|
153
|
+
textarea.focus();
|
|
154
|
+
}
|
|
155
|
+
textarea.select();
|
|
156
|
+
textarea.setSelectionRange(0, textarea.value.length);
|
|
157
|
+
|
|
158
|
+
const copied = document.execCommand("copy");
|
|
159
|
+
document.body.removeChild(textarea);
|
|
160
|
+
return copied;
|
|
161
|
+
} catch {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const copyToClipboard = async (text) => {
|
|
167
|
+
try {
|
|
168
|
+
if (navigator.clipboard?.writeText) {
|
|
169
|
+
await navigator.clipboard.writeText(text);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
} catch {
|
|
173
|
+
// Fallback below when the async Clipboard API is unavailable or blocked.
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return fallbackCopy(text);
|
|
177
|
+
};
|
|
178
|
+
|
|
133
179
|
const tabs = codeItems.map((itemElement, index) => {
|
|
134
180
|
const filename =
|
|
135
181
|
itemElement.getAttribute("data-rd-tab-filename") ??
|
|
@@ -411,7 +457,12 @@ import CodeTabEdge from "../ui/CodeTabEdge.astro";
|
|
|
411
457
|
const copyValue = decodeURIComponent(encodedCopyValue);
|
|
412
458
|
|
|
413
459
|
try {
|
|
414
|
-
await
|
|
460
|
+
const copied = await copyToClipboard(copyValue);
|
|
461
|
+
if (!copied) {
|
|
462
|
+
setCopiedState(copyButton, false);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
|
|
415
466
|
setCopiedState(copyButton, true);
|
|
416
467
|
|
|
417
468
|
if (timeoutId) window.clearTimeout(timeoutId);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"assetVersion": "shiki-3.23.0-c5695a7656dd",
|
|
3
|
+
"counts": {
|
|
4
|
+
"languages": 347,
|
|
5
|
+
"themes": 66
|
|
6
|
+
},
|
|
7
|
+
"manifest": {
|
|
8
|
+
"bytes": 172640,
|
|
9
|
+
"module": "manifest.json",
|
|
10
|
+
"sha256": "d8ce64a7c4247eac90030e4dd92a9ac00f1de67114e0ac6c5e003e810c8e9cfb"
|
|
11
|
+
},
|
|
12
|
+
"packageVersions": {
|
|
13
|
+
"@shikijs/core": "3.23.0",
|
|
14
|
+
"@shikijs/engine-javascript": "3.23.0",
|
|
15
|
+
"@shikijs/langs": "3.23.0",
|
|
16
|
+
"@shikijs/themes": "3.23.0",
|
|
17
|
+
"shiki": "3.23.0"
|
|
18
|
+
},
|
|
19
|
+
"prefix": "_platform/shiki",
|
|
20
|
+
"runtime": {
|
|
21
|
+
"engine": "javascript-regexp",
|
|
22
|
+
"module": "runtime.mjs"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -4,6 +4,7 @@ import Sidebar from "../components/Sidebar.astro";
|
|
|
4
4
|
import { getConfig } from "../lib/validation";
|
|
5
5
|
import Header from "../components/Header.astro";
|
|
6
6
|
import Footer from "../components/Footer.astro";
|
|
7
|
+
import NavigationTabs from "../components/NavigationTabs.astro";
|
|
7
8
|
import AssistantDocsWidget from "../components/chat/AssistantDocsWidget.astro";
|
|
8
9
|
import { ClientRouter } from "astro:transitions";
|
|
9
10
|
import { prependBasePath, stripBasePath } from "../lib/base-path";
|
|
@@ -18,6 +19,8 @@ interface Props {
|
|
|
18
19
|
pageDescription?: string;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
type TabsPresentation = "topbar" | "sidebar";
|
|
23
|
+
|
|
21
24
|
function normalizeRoutePath(routePath: string): string {
|
|
22
25
|
if (!routePath || routePath === "/") return "/";
|
|
23
26
|
if (!routePath.startsWith("/")) routePath = `/${routePath}`;
|
|
@@ -66,6 +69,12 @@ const orgTier =
|
|
|
66
69
|
Number.isFinite(parsedOrgTier) && parsedOrgTier > 0 ? parsedOrgTier : 1;
|
|
67
70
|
const isDev = import.meta.env.DEV;
|
|
68
71
|
const askAiEnabled = isDev || orgTier >= 3;
|
|
72
|
+
const navigationTabs = config.navigation.tabs as
|
|
73
|
+
| (typeof config.navigation.tabs & { presentation?: TabsPresentation })
|
|
74
|
+
| undefined;
|
|
75
|
+
const hasNavigationTabs =
|
|
76
|
+
Array.isArray(navigationTabs?.items) && navigationTabs.items.length > 0;
|
|
77
|
+
const tabsPresentation = navigationTabs?.presentation ?? "topbar";
|
|
69
78
|
---
|
|
70
79
|
|
|
71
80
|
<!doctype html>
|
|
@@ -73,7 +82,7 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
73
82
|
<head>
|
|
74
83
|
<style is:inline is:global set:html={neutralPaletteCss}></style>
|
|
75
84
|
<style is:inline is:global set:html={fontCss}></style>
|
|
76
|
-
<ClientRouter />
|
|
85
|
+
<ClientRouter fallback="swap" />
|
|
77
86
|
<script is:inline>
|
|
78
87
|
const applyTheme = () => {
|
|
79
88
|
const modeParam = new URLSearchParams(window.location.search).get(
|
|
@@ -192,6 +201,71 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
192
201
|
}
|
|
193
202
|
})();
|
|
194
203
|
</script>
|
|
204
|
+
<script is:inline>
|
|
205
|
+
(() => {
|
|
206
|
+
const root = document.documentElement;
|
|
207
|
+
let viewportFrameId = null;
|
|
208
|
+
|
|
209
|
+
const syncVisualViewport = () => {
|
|
210
|
+
viewportFrameId = null;
|
|
211
|
+
|
|
212
|
+
const viewport = window.visualViewport;
|
|
213
|
+
const width =
|
|
214
|
+
viewport && Number.isFinite(viewport.width)
|
|
215
|
+
? viewport.width
|
|
216
|
+
: window.innerWidth;
|
|
217
|
+
const height =
|
|
218
|
+
viewport && Number.isFinite(viewport.height)
|
|
219
|
+
? viewport.height
|
|
220
|
+
: window.innerHeight;
|
|
221
|
+
const offsetLeft =
|
|
222
|
+
viewport && Number.isFinite(viewport.offsetLeft)
|
|
223
|
+
? viewport.offsetLeft
|
|
224
|
+
: 0;
|
|
225
|
+
const offsetTop =
|
|
226
|
+
viewport && Number.isFinite(viewport.offsetTop)
|
|
227
|
+
? viewport.offsetTop
|
|
228
|
+
: 0;
|
|
229
|
+
|
|
230
|
+
root.style.setProperty(
|
|
231
|
+
"--rd-visual-viewport-left",
|
|
232
|
+
`${Math.max(0, offsetLeft)}px`,
|
|
233
|
+
);
|
|
234
|
+
root.style.setProperty(
|
|
235
|
+
"--rd-visual-viewport-top",
|
|
236
|
+
`${Math.max(0, offsetTop)}px`,
|
|
237
|
+
);
|
|
238
|
+
root.style.setProperty(
|
|
239
|
+
"--rd-visual-viewport-width",
|
|
240
|
+
`${Math.max(1, width)}px`,
|
|
241
|
+
);
|
|
242
|
+
root.style.setProperty(
|
|
243
|
+
"--rd-visual-viewport-height",
|
|
244
|
+
`${Math.max(1, height)}px`,
|
|
245
|
+
);
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const scheduleVisualViewportSync = () => {
|
|
249
|
+
if (viewportFrameId !== null) return;
|
|
250
|
+
viewportFrameId = window.requestAnimationFrame(syncVisualViewport);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
scheduleVisualViewportSync();
|
|
254
|
+
window.visualViewport?.addEventListener(
|
|
255
|
+
"resize",
|
|
256
|
+
scheduleVisualViewportSync,
|
|
257
|
+
);
|
|
258
|
+
window.visualViewport?.addEventListener(
|
|
259
|
+
"scroll",
|
|
260
|
+
scheduleVisualViewportSync,
|
|
261
|
+
);
|
|
262
|
+
window.addEventListener("resize", scheduleVisualViewportSync);
|
|
263
|
+
window.addEventListener(
|
|
264
|
+
"orientationchange",
|
|
265
|
+
scheduleVisualViewportSync,
|
|
266
|
+
);
|
|
267
|
+
})();
|
|
268
|
+
</script>
|
|
195
269
|
{
|
|
196
270
|
fontPreloads.map((font) => (
|
|
197
271
|
<link
|
|
@@ -233,12 +307,10 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
233
307
|
<body
|
|
234
308
|
class="bg-background text-neutral-900 dark:text-white"
|
|
235
309
|
x-data="{ open: false }"
|
|
236
|
-
x-bind:class="open ? 'overflow-hidden
|
|
310
|
+
x-bind:class="open ? 'overflow-hidden' : ''"
|
|
237
311
|
>
|
|
238
312
|
<!-- Edges -->
|
|
239
|
-
<div
|
|
240
|
-
class="fixed top-1 inset-x-1 h-16 -z-10 bg-background-dark"
|
|
241
|
-
>
|
|
313
|
+
<div class="fixed top-1 inset-x-1 h-16 -z-10 bg-background-dark">
|
|
242
314
|
<div class="bg-background w-full h-full rounded-t-2xl"></div>
|
|
243
315
|
</div>
|
|
244
316
|
<div
|
|
@@ -252,10 +324,21 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
252
324
|
|
|
253
325
|
<!-- Header -->
|
|
254
326
|
<Header showAskAiTrigger={askAiEnabled} />
|
|
327
|
+
{
|
|
328
|
+
hasNavigationTabs ? (
|
|
329
|
+
<NavigationTabs
|
|
330
|
+
tabs={navigationTabs!}
|
|
331
|
+
presentation={tabsPresentation}
|
|
332
|
+
/>
|
|
333
|
+
) : null
|
|
334
|
+
}
|
|
255
335
|
|
|
256
336
|
<!-- Desktop Sidebar -->
|
|
257
337
|
<div
|
|
258
|
-
class=
|
|
338
|
+
class:list={[
|
|
339
|
+
"bg-background w-[283px] ml-[5px] fixed inset-y-0 hidden lg:block border-r border-r-border-light",
|
|
340
|
+
hasNavigationTabs ? "mt-[112px]" : "mt-17",
|
|
341
|
+
]}
|
|
259
342
|
data-pagefind-ignore
|
|
260
343
|
>
|
|
261
344
|
<Sidebar />
|
|
@@ -265,7 +348,7 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
265
348
|
<div
|
|
266
349
|
x-show="open"
|
|
267
350
|
x-cloak
|
|
268
|
-
class="
|
|
351
|
+
class="rd-mobile-menu bg-background fixed lg:hidden z-50 overflow-y-auto overscroll-contain [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
|
|
269
352
|
x-transition.opacity
|
|
270
353
|
>
|
|
271
354
|
<Sidebar askAiEnabled={askAiEnabled} />
|
|
@@ -275,11 +358,31 @@ const askAiEnabled = isDev || orgTier >= 3;
|
|
|
275
358
|
<div
|
|
276
359
|
class="mx-1 mt-1 px-4 sm:px-6 lg:pl-[calc(288px+32px)] pt-16 lg:pr-8 bg-background"
|
|
277
360
|
>
|
|
278
|
-
<main class="mx-auto pt-16 pb-
|
|
361
|
+
<main class="mx-auto pt-16 pb-20 min-h-[calc(100vh-64px)]">
|
|
279
362
|
<slot />
|
|
280
363
|
</main>
|
|
281
364
|
<Footer askAiEnabled={askAiEnabled} />
|
|
282
365
|
</div>
|
|
283
366
|
{askAiEnabled ? <AssistantDocsWidget /> : null}
|
|
367
|
+
<style is:global>
|
|
368
|
+
:root {
|
|
369
|
+
--rd-visual-viewport-left: 0px;
|
|
370
|
+
--rd-visual-viewport-top: 0px;
|
|
371
|
+
--rd-visual-viewport-width: 100vw;
|
|
372
|
+
--rd-visual-viewport-height: 100dvh;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.rd-mobile-menu {
|
|
376
|
+
--rd-mobile-menu-top-offset: 68px;
|
|
377
|
+
left: calc(var(--rd-visual-viewport-left) + 5px);
|
|
378
|
+
top: calc(
|
|
379
|
+
var(--rd-visual-viewport-top) + var(--rd-mobile-menu-top-offset)
|
|
380
|
+
);
|
|
381
|
+
width: calc(var(--rd-visual-viewport-width) - 10px);
|
|
382
|
+
height: calc(
|
|
383
|
+
var(--rd-visual-viewport-height) - var(--rd-mobile-menu-top-offset)
|
|
384
|
+
);
|
|
385
|
+
}
|
|
386
|
+
</style>
|
|
284
387
|
</body>
|
|
285
388
|
</html>
|
|
@@ -4,7 +4,13 @@ import {
|
|
|
4
4
|
} from "./assistant-chrome";
|
|
5
5
|
import { withBasePath } from "./base-path";
|
|
6
6
|
import { getAssistantLauncherIconConfig } from "./assistant-embed-script";
|
|
7
|
+
import type { AssistantShikiRuntimeConfig } from "./assistant-shiki-client";
|
|
7
8
|
import type { DocsConfig } from "./validation";
|
|
9
|
+
import shikiPlatformAssets from "../generated/shiki-platform-assets.json";
|
|
10
|
+
import {
|
|
11
|
+
DEFAULT_SHIKI_DARK_THEME,
|
|
12
|
+
DEFAULT_SHIKI_LIGHT_THEME,
|
|
13
|
+
} from "radiant-docs-validator/shiki-theme-config";
|
|
8
14
|
|
|
9
15
|
export type AssistantPanelRuntimeConfig = {
|
|
10
16
|
apiPath: string;
|
|
@@ -26,8 +32,60 @@ export type AssistantPanelRuntimeConfig = {
|
|
|
26
32
|
emptyStateQuestions?: string[];
|
|
27
33
|
devProxyToken?: string;
|
|
28
34
|
chrome: AssistantChromeConfig;
|
|
35
|
+
shiki?: AssistantShikiRuntimeConfig;
|
|
29
36
|
};
|
|
30
37
|
|
|
38
|
+
function normalizeStaticAssetHost(value: unknown): string {
|
|
39
|
+
const rawValue = typeof value === "string" ? value.trim() : "";
|
|
40
|
+
if (!rawValue) return "";
|
|
41
|
+
|
|
42
|
+
const normalizedHost = rawValue.replace(/\/+$/, "");
|
|
43
|
+
return /^https?:\/\//i.test(normalizedHost)
|
|
44
|
+
? normalizedHost
|
|
45
|
+
: `https://${normalizedHost}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function joinUrl(baseUrl: string, path: string): string {
|
|
49
|
+
return `${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getConfiguredCodeSyntaxThemes(
|
|
53
|
+
config: DocsConfig,
|
|
54
|
+
): AssistantShikiRuntimeConfig["syntaxThemes"] {
|
|
55
|
+
const configuredSyntaxTheme = config.theme?.code?.syntaxTheme;
|
|
56
|
+
|
|
57
|
+
if (typeof configuredSyntaxTheme === "string") {
|
|
58
|
+
return {
|
|
59
|
+
light: configuredSyntaxTheme,
|
|
60
|
+
dark: configuredSyntaxTheme,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
light: configuredSyntaxTheme?.light ?? DEFAULT_SHIKI_LIGHT_THEME,
|
|
66
|
+
dark: configuredSyntaxTheme?.dark ?? DEFAULT_SHIKI_DARK_THEME,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function getAssistantShikiRuntimeConfig(
|
|
71
|
+
config: DocsConfig,
|
|
72
|
+
): AssistantShikiRuntimeConfig | undefined {
|
|
73
|
+
const staticAssetHost = normalizeStaticAssetHost(
|
|
74
|
+
import.meta.env.STATIC_ASSET_HOST ?? process.env.STATIC_ASSET_HOST,
|
|
75
|
+
);
|
|
76
|
+
if (!staticAssetHost) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
assetBaseUrl: joinUrl(
|
|
82
|
+
staticAssetHost,
|
|
83
|
+
`${shikiPlatformAssets.prefix}/${shikiPlatformAssets.assetVersion}`,
|
|
84
|
+
),
|
|
85
|
+
syntaxThemes: getConfiguredCodeSyntaxThemes(config),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
31
89
|
export function getAssistantPanelRuntimeConfig(
|
|
32
90
|
config: DocsConfig,
|
|
33
91
|
): AssistantPanelRuntimeConfig {
|
|
@@ -76,5 +134,6 @@ export function getAssistantPanelRuntimeConfig(
|
|
|
76
134
|
emptyStateQuestions: assistantConfig?.questions,
|
|
77
135
|
devProxyToken: isDev ? assistantDevProxySecret : undefined,
|
|
78
136
|
chrome: getAssistantChromeConfig(config),
|
|
137
|
+
shiki: getAssistantShikiRuntimeConfig(config),
|
|
79
138
|
};
|
|
80
139
|
}
|