radiant-docs 0.1.39 → 0.1.41

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.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/template/astro.config.mjs +38 -7
  3. package/template/package-lock.json +19 -7
  4. package/template/package.json +3 -3
  5. package/template/public/favicon.svg +16 -8
  6. package/template/scripts/generate-robots-txt.mjs +29 -1
  7. package/template/scripts/remove-assistant-for-non-pro.mjs +28 -0
  8. package/template/scripts/stamp-image-versions.mjs +59 -33
  9. package/template/src/components/Footer.astro +2 -1
  10. package/template/src/components/Header.astro +10 -8
  11. package/template/src/components/LogoLink.astro +2 -1
  12. package/template/src/components/MdxPage.astro +15 -4
  13. package/template/src/components/PagePagination.astro +61 -0
  14. package/template/src/components/SidebarDropdown.astro +12 -8
  15. package/template/src/components/SidebarGroup.astro +1 -1
  16. package/template/src/components/SidebarMenu.astro +1 -1
  17. package/template/src/components/SidebarSegmented.astro +6 -5
  18. package/template/src/components/TableOfContents.astro +4 -13
  19. package/template/src/components/chat/AskAiWidget.tsx +274 -39
  20. package/template/src/components/chat/AssistantDocsWidget.astro +16 -0
  21. package/template/src/components/chat/AssistantDocsWidget.tsx +402 -0
  22. package/template/src/components/chat/AssistantEmbedPanel.tsx +1693 -0
  23. package/template/src/components/chat/AssistantEmbedPanelPage.astro +95 -0
  24. package/template/src/components/endpoint/PlaygroundForm.astro +2 -1
  25. package/template/src/components/user/Callout.astro +10 -4
  26. package/template/src/components/user/CodeBlock.astro +1 -1
  27. package/template/src/components/user/CodeGroup.astro +16 -1
  28. package/template/src/components/user/ComponentPreviewBlock.astro +1 -0
  29. package/template/src/components/user/Image.astro +43 -53
  30. package/template/src/layouts/Layout.astro +104 -35
  31. package/template/src/lib/assistant-chrome-defaults.ts +74 -0
  32. package/template/src/lib/assistant-chrome.ts +39 -0
  33. package/template/src/lib/assistant-embed-script.ts +897 -0
  34. package/template/src/lib/assistant-panel-config.ts +80 -0
  35. package/template/src/lib/base-path.ts +98 -0
  36. package/template/src/lib/component-error.ts +49 -10
  37. package/template/src/lib/favicon.ts +31 -0
  38. package/template/src/lib/mdx/remark-resolve-internal-links.ts +128 -18
  39. package/template/src/lib/pagefind.ts +62 -14
  40. package/template/src/lib/routes.ts +49 -1
  41. package/template/src/lib/static-asset-url.ts +3 -1
  42. package/template/src/lib/theme-css.ts +176 -0
  43. package/template/src/lib/utils.ts +12 -4
  44. package/template/src/lib/validation.ts +754 -37
  45. package/template/src/pages/-/assistant/embed.js.ts +15 -0
  46. package/template/src/pages/-/assistant/panel.astro +5 -0
  47. package/template/src/pages/404.astro +6 -5
  48. package/template/src/pages/[...slug].astro +68 -6
  49. package/template/src/styles/global.css +62 -1
@@ -0,0 +1,402 @@
1
+ import type { JSX } from "preact";
2
+ import { useEffect, useState } from "preact/hooks";
3
+ import AssistantEmbedPanel, { AssistantPanelIcon } from "./AssistantEmbedPanel";
4
+ import {
5
+ DEFAULT_ASSISTANT_CHROME_CONFIG,
6
+ type AssistantChromeConfig,
7
+ } from "../../lib/assistant-chrome-defaults";
8
+
9
+ type AssistantDocsWidgetProps = {
10
+ apiPath: string;
11
+ docsTitle: string;
12
+ isChatAvailable: boolean;
13
+ canSendChatRequest: boolean;
14
+ launcherThemeColor?: string;
15
+ launcherThemeColors?: {
16
+ light: string;
17
+ dark: string;
18
+ };
19
+ launcherIconColor?: string;
20
+ launcherIconColors?: {
21
+ light: string;
22
+ dark: string;
23
+ };
24
+ launcherIconImageSrc?: string;
25
+ emptyStateHeading?: string;
26
+ emptyStateQuestions?: string[];
27
+ devProxyToken?: string;
28
+ chrome?: AssistantChromeConfig;
29
+ };
30
+
31
+ type AssistantOpenRequestWindow = Window & {
32
+ __assistantOpenRequested?: boolean;
33
+ };
34
+
35
+ export default function AssistantDocsWidget({
36
+ apiPath,
37
+ docsTitle,
38
+ isChatAvailable,
39
+ canSendChatRequest,
40
+ launcherThemeColor,
41
+ launcherThemeColors,
42
+ launcherIconColor,
43
+ launcherIconColors,
44
+ launcherIconImageSrc,
45
+ emptyStateHeading,
46
+ emptyStateQuestions,
47
+ devProxyToken,
48
+ chrome,
49
+ }: AssistantDocsWidgetProps) {
50
+ const [isOpen, setIsOpen] = useState(false);
51
+ const [openSignal, setOpenSignal] = useState(0);
52
+ const chromeConfig = chrome ?? DEFAULT_ASSISTANT_CHROME_CONFIG;
53
+ const numericZIndex =
54
+ Number.parseInt(chromeConfig.zIndex, 10) ||
55
+ Number.parseInt(DEFAULT_ASSISTANT_CHROME_CONFIG.zIndex, 10);
56
+ const launcherThemeColorLight =
57
+ launcherThemeColors?.light ?? launcherThemeColor ?? "#171717";
58
+ const launcherThemeColorDark =
59
+ launcherThemeColors?.dark ?? launcherThemeColor ?? "#171717";
60
+ const launcherIconColorLight =
61
+ launcherIconColors?.light ?? launcherIconColor ?? "#ffffff";
62
+ const launcherIconColorDark =
63
+ launcherIconColors?.dark ?? launcherIconColor ?? "#ffffff";
64
+ const rootStyle = {
65
+ "--assistant-docs-theme-light": launcherThemeColorLight,
66
+ "--assistant-docs-theme-dark": launcherThemeColorDark,
67
+ "--assistant-docs-icon-color-light": launcherIconColorLight,
68
+ "--assistant-docs-icon-color-dark": launcherIconColorDark,
69
+ "--assistant-docs-z-index": String(numericZIndex),
70
+ "--assistant-docs-launcher-z-index": String(numericZIndex + 1),
71
+ "--assistant-docs-mobile-panel-z-index": String(numericZIndex + 2),
72
+ "--assistant-docs-offset-x": chromeConfig.offsetX,
73
+ "--assistant-docs-offset-y": chromeConfig.offsetY,
74
+ "--assistant-docs-mobile-offset-x": chromeConfig.mobileOffsetX,
75
+ "--assistant-docs-mobile-offset-y": chromeConfig.mobileOffsetY,
76
+ "--assistant-docs-launcher-size": chromeConfig.launcherSize,
77
+ "--assistant-docs-launcher-icon-size": chromeConfig.launcherIconSize,
78
+ "--assistant-docs-launcher-shadow": chromeConfig.launcherShadow,
79
+ "--assistant-docs-panel-width": chromeConfig.panelWidth,
80
+ "--assistant-docs-panel-height": chromeConfig.panelHeight,
81
+ "--assistant-docs-panel-gap": chromeConfig.panelGap,
82
+ "--assistant-docs-panel-radius": chromeConfig.panelRadius,
83
+ "--assistant-docs-panel-border": chromeConfig.panelBorder,
84
+ "--assistant-docs-panel-background": chromeConfig.panelBackground,
85
+ "--assistant-docs-panel-dark-border": chromeConfig.panelDarkBorder,
86
+ "--assistant-docs-panel-dark-background": chromeConfig.panelDarkBackground,
87
+ "--assistant-docs-panel-backdrop-blur": chromeConfig.panelBackdropBlur,
88
+ "--assistant-docs-panel-shadow": chromeConfig.panelShadow,
89
+ "--assistant-docs-panel-dark-shadow": chromeConfig.panelDarkShadow,
90
+ "--assistant-docs-panel-open-scale": chromeConfig.panelOpenScale,
91
+ "--assistant-docs-panel-open-duration": chromeConfig.panelOpenDuration,
92
+ "--assistant-docs-panel-open-timing": chromeConfig.panelOpenTiming,
93
+ "--assistant-docs-panel-close-duration": chromeConfig.panelCloseDuration,
94
+ "--assistant-docs-panel-close-timing": chromeConfig.panelCloseTiming,
95
+ } as JSX.CSSProperties;
96
+
97
+ const openPanel = () => {
98
+ setIsOpen((wasOpen) => {
99
+ if (!wasOpen) {
100
+ setOpenSignal((previous) => previous + 1);
101
+ }
102
+ return true;
103
+ });
104
+ };
105
+
106
+ const closePanel = () => {
107
+ setIsOpen(false);
108
+ };
109
+
110
+ useEffect(() => {
111
+ const handleOpen = () => {
112
+ (window as AssistantOpenRequestWindow).__assistantOpenRequested = false;
113
+ openPanel();
114
+ };
115
+
116
+ window.addEventListener("ask-ai:open", handleOpen);
117
+ if ((window as AssistantOpenRequestWindow).__assistantOpenRequested) {
118
+ handleOpen();
119
+ }
120
+
121
+ return () => {
122
+ window.removeEventListener("ask-ai:open", handleOpen);
123
+ };
124
+ }, []);
125
+
126
+ return (
127
+ <div
128
+ data-pagefind-ignore
129
+ className="assistant-docs-widget"
130
+ data-side={chromeConfig.side}
131
+ style={rootStyle}
132
+ >
133
+ <div
134
+ className="assistant-docs-panel-shell"
135
+ data-state={isOpen ? "open" : "closed"}
136
+ >
137
+ <AssistantEmbedPanel
138
+ apiPath={apiPath}
139
+ docsTitle={docsTitle}
140
+ isChatAvailable={isChatAvailable}
141
+ canSendChatRequest={canSendChatRequest}
142
+ launcherThemeColor={launcherThemeColor}
143
+ launcherThemeColors={launcherThemeColors}
144
+ launcherIconColor={launcherIconColor}
145
+ launcherIconColors={launcherIconColors}
146
+ launcherIconImageSrc={launcherIconImageSrc}
147
+ emptyStateHeading={emptyStateHeading}
148
+ emptyStateQuestions={emptyStateQuestions}
149
+ devProxyToken={devProxyToken}
150
+ panelSurface="inline"
151
+ linkTarget="current"
152
+ allowApiPathQueryOverride={false}
153
+ openSignal={openSignal}
154
+ onRequestClose={closePanel}
155
+ />
156
+ </div>
157
+
158
+ <button
159
+ type="button"
160
+ className="assistant-docs-launcher"
161
+ data-open={String(isOpen)}
162
+ onClick={() => {
163
+ if (isOpen) {
164
+ closePanel();
165
+ return;
166
+ }
167
+ openPanel();
168
+ }}
169
+ aria-label={isOpen ? "Close chat" : "Open chat"}
170
+ title={isOpen ? "Close chat" : "Open chat"}
171
+ >
172
+ <AssistantPanelIcon
173
+ color={launcherIconColor}
174
+ imageSrc={launcherIconImageSrc}
175
+ className="assistant-docs-launcher-icon assistant-docs-launcher-mark"
176
+ />
177
+ <svg
178
+ className="assistant-docs-launcher-icon assistant-docs-launcher-chevron"
179
+ viewBox="0 0 24 24"
180
+ fill="none"
181
+ stroke="currentColor"
182
+ strokeWidth="2.4"
183
+ strokeLinecap="round"
184
+ strokeLinejoin="round"
185
+ aria-hidden="true"
186
+ >
187
+ <path d="m6 9 6 6 6-6" />
188
+ </svg>
189
+ </button>
190
+
191
+ <style>{`
192
+ @keyframes assistant-docs-launcher-enter {
193
+ 0% {
194
+ opacity: 0;
195
+ transform: translateY(3px) scale(.96);
196
+ }
197
+ 46% {
198
+ opacity: 1;
199
+ transform: translateY(0) scale(1.012);
200
+ }
201
+ 72% {
202
+ opacity: 1;
203
+ transform: translateY(0) scale(.998);
204
+ }
205
+ 100% {
206
+ opacity: 1;
207
+ transform: translateY(0) scale(1);
208
+ }
209
+ }
210
+
211
+ .assistant-docs-launcher {
212
+ --assistant-docs-theme: var(--assistant-docs-theme-light);
213
+ --assistant-docs-icon-color: var(--assistant-docs-icon-color-light);
214
+ position: fixed;
215
+ bottom: var(--assistant-docs-offset-y);
216
+ z-index: var(--assistant-docs-launcher-z-index);
217
+ display: inline-flex;
218
+ width: var(--assistant-docs-launcher-size);
219
+ height: var(--assistant-docs-launcher-size);
220
+ align-items: center;
221
+ justify-content: center;
222
+ padding: 0;
223
+ border: 0;
224
+ border-radius: 999px;
225
+ color: var(--assistant-docs-icon-color);
226
+ background: linear-gradient(
227
+ to bottom,
228
+ color-mix(in oklab, var(--assistant-docs-theme) 88%, white),
229
+ color-mix(in oklab, var(--assistant-docs-theme) 90%, black)
230
+ );
231
+ box-shadow: var(--assistant-docs-launcher-shadow);
232
+ cursor: pointer;
233
+ animation: assistant-docs-launcher-enter 460ms linear backwards;
234
+ transition: transform 180ms ease, opacity 160ms ease;
235
+ transform-origin: center center;
236
+ }
237
+
238
+ html.dark .assistant-docs-launcher,
239
+ html[data-theme="dark"] .assistant-docs-launcher {
240
+ --assistant-docs-theme: var(--assistant-docs-theme-dark);
241
+ --assistant-docs-icon-color: var(--assistant-docs-icon-color-dark);
242
+ }
243
+
244
+ .assistant-docs-widget[data-side="right"] .assistant-docs-launcher {
245
+ right: var(--assistant-docs-offset-x);
246
+ }
247
+
248
+ .assistant-docs-widget[data-side="left"] .assistant-docs-launcher {
249
+ left: var(--assistant-docs-offset-x);
250
+ }
251
+
252
+ .assistant-docs-launcher:hover {
253
+ opacity: .96;
254
+ transform: translateY(-1px) scale(1.03);
255
+ }
256
+
257
+ .assistant-docs-launcher:active {
258
+ transform: translateY(0) scale(.96);
259
+ }
260
+
261
+ .assistant-docs-launcher-icon {
262
+ position: absolute;
263
+ width: var(--assistant-docs-launcher-icon-size);
264
+ height: var(--assistant-docs-launcher-icon-size);
265
+ pointer-events: none;
266
+ transform-origin: center;
267
+ transition: opacity 150ms ease,
268
+ transform 180ms cubic-bezier(.2, .8, .2, 1);
269
+ }
270
+
271
+ .assistant-docs-launcher-icon img,
272
+ .assistant-docs-launcher-icon svg {
273
+ display: block;
274
+ width: 100%;
275
+ height: 100%;
276
+ object-fit: contain;
277
+ }
278
+
279
+ .assistant-docs-launcher-mark {
280
+ opacity: 1;
281
+ transform: scale(1);
282
+ }
283
+
284
+ .assistant-docs-launcher-chevron {
285
+ opacity: 0;
286
+ transform: scale(.55);
287
+ }
288
+
289
+ .assistant-docs-launcher[data-open="true"] .assistant-docs-launcher-mark {
290
+ opacity: 0;
291
+ transform: scale(.55);
292
+ }
293
+
294
+ .assistant-docs-launcher[data-open="true"] .assistant-docs-launcher-chevron {
295
+ opacity: 1;
296
+ transform: scale(1);
297
+ }
298
+
299
+ .assistant-docs-panel-shell {
300
+ position: fixed;
301
+ bottom: calc(
302
+ var(--assistant-docs-offset-y) +
303
+ var(--assistant-docs-launcher-size) +
304
+ var(--assistant-docs-panel-gap)
305
+ );
306
+ z-index: var(--assistant-docs-z-index);
307
+ box-sizing: border-box;
308
+ width: min(var(--assistant-docs-panel-width), calc(100vw - 32px));
309
+ height: min(var(--assistant-docs-panel-height), calc(100dvh - 32px));
310
+ overflow: hidden;
311
+ border: var(--assistant-docs-panel-border);
312
+ border-radius: var(--assistant-docs-panel-radius);
313
+ background: var(--assistant-docs-panel-background);
314
+ box-shadow: var(--assistant-docs-panel-shadow);
315
+ -webkit-backdrop-filter: blur(var(--assistant-docs-panel-backdrop-blur));
316
+ backdrop-filter: blur(var(--assistant-docs-panel-backdrop-blur));
317
+ opacity: 1;
318
+ pointer-events: auto;
319
+ transform: scale(1);
320
+ transform-origin: bottom right;
321
+ transition-property: transform, opacity, display;
322
+ transition-duration: var(--assistant-docs-panel-open-duration);
323
+ transition-timing-function: var(--assistant-docs-panel-open-timing);
324
+ transition-behavior: allow-discrete;
325
+ }
326
+
327
+ .dark .assistant-docs-panel-shell {
328
+ border: var(--assistant-docs-panel-dark-border);
329
+ background: var(--assistant-docs-panel-dark-background);
330
+ box-shadow: var(--assistant-docs-panel-dark-shadow);
331
+ }
332
+
333
+ .assistant-docs-widget[data-side="right"] .assistant-docs-panel-shell {
334
+ right: var(--assistant-docs-offset-x);
335
+ transform-origin: bottom right;
336
+ }
337
+
338
+ .assistant-docs-widget[data-side="left"] .assistant-docs-panel-shell {
339
+ left: var(--assistant-docs-offset-x);
340
+ transform-origin: bottom left;
341
+ }
342
+
343
+ @starting-style {
344
+ .assistant-docs-panel-shell[data-state="open"] {
345
+ opacity: 0;
346
+ transform: scale(var(--assistant-docs-panel-open-scale));
347
+ }
348
+ }
349
+
350
+ .assistant-docs-panel-shell[data-state="closed"] {
351
+ display: none;
352
+ opacity: 0;
353
+ pointer-events: none;
354
+ transform: scale(var(--assistant-docs-panel-open-scale));
355
+ transition-property: transform, opacity, display;
356
+ transition-duration: var(--assistant-docs-panel-close-duration);
357
+ transition-timing-function: var(--assistant-docs-panel-close-timing);
358
+ transition-behavior: allow-discrete;
359
+ }
360
+
361
+ @media (max-width: ${chromeConfig.mobileBreakpoint}) {
362
+ .assistant-docs-panel-shell {
363
+ inset: 0 !important;
364
+ z-index: var(--assistant-docs-mobile-panel-z-index) !important;
365
+ width: 100vw !important;
366
+ height: 100dvh !important;
367
+ border: 0 !important;
368
+ border-radius: 0 !important;
369
+ }
370
+
371
+ .assistant-docs-panel-shell > div {
372
+ border-radius: 0;
373
+ }
374
+
375
+ .assistant-docs-launcher {
376
+ bottom: var(--assistant-docs-mobile-offset-y) !important;
377
+ }
378
+
379
+ .assistant-docs-widget[data-side="right"] .assistant-docs-launcher {
380
+ right: var(--assistant-docs-mobile-offset-x) !important;
381
+ }
382
+
383
+ .assistant-docs-widget[data-side="left"] .assistant-docs-launcher {
384
+ left: var(--assistant-docs-mobile-offset-x) !important;
385
+ }
386
+ }
387
+
388
+ @media (prefers-reduced-motion: reduce) {
389
+ .assistant-docs-launcher {
390
+ animation: none !important;
391
+ }
392
+
393
+ .assistant-docs-launcher,
394
+ .assistant-docs-launcher-icon,
395
+ .assistant-docs-panel-shell {
396
+ transition: none !important;
397
+ }
398
+ }
399
+ `}</style>
400
+ </div>
401
+ );
402
+ }