reallysimpledocs 1.0.0-beta.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -39
- package/package.json +11 -11
- package/src/astro/index.js +64 -98
- package/src/astro/preview-scripts.js +140 -0
- package/src/astro/preview-source.js +150 -0
- package/src/astro/rehype-basecoat-tables.js +62 -0
- package/src/components/index.js +1 -0
- package/src/css/custom.css +197 -58
- package/src/css/styles/luma.css +9 -0
- package/src/css/styles/lyra.css +9 -0
- package/src/css/styles/maia.css +9 -0
- package/src/css/styles/mira.css +9 -0
- package/src/css/styles/nova.css +9 -0
- package/src/css/styles/rhea.css +9 -0
- package/src/css/styles/sera.css +9 -0
- package/src/css/styles/vega.css +9 -0
- package/src/runtime/components/BaseLayout.astro +22 -28
- package/src/runtime/components/CommandDialog.astro +52 -35
- package/src/runtime/components/DefaultContentHeader.astro +0 -17
- package/src/runtime/components/DefaultHead.astro +110 -0
- package/src/runtime/components/DefaultHeadContent.astro +2 -0
- package/src/runtime/components/DefaultSidebarHeader.astro +1 -1
- package/src/runtime/components/DocsLayout.astro +99 -166
- package/src/runtime/components/DropdownMenu.astro +1 -1
- package/src/runtime/components/ThemeToggle.astro +21 -0
- package/src/runtime/components/mdx/Callout.astro +2 -32
- package/src/runtime/components/mdx/Card.astro +3 -8
- package/src/runtime/components/mdx/CardGrid.astro +1 -1
- package/src/runtime/components/mdx/Code.astro +21 -27
- package/src/runtime/components/mdx/CodeGroup.astro +114 -24
- package/src/runtime/components/mdx/Preview.astro +7 -13
- package/src/runtime/components/mdx/Steps.astro +1 -5
- package/src/runtime/components/mdx/Tab.astro +6 -0
- package/src/runtime/components/mdx/Tabs.astro +7 -7
- package/src/runtime/lib/code-meta.js +8 -0
- package/src/runtime/lib/docs.js +141 -119
- package/src/runtime/lib/highlight.js +1 -14
- package/src/runtime/lib/html.js +9 -0
- package/src/runtime/lib/macros.js +10 -5
- package/src/runtime/lib/markdown-export.js +240 -169
- package/src/runtime/pages/doc.astro +1 -3
- package/src/runtime/pages/llms-full.txt.ts +2 -2
- package/src/runtime/pages/llms.txt.ts +2 -2
- package/src/runtime/pages/markdown.ts +2 -2
- package/src/runtime/pages/search-index.ts +12 -3
- package/CHANGELOG.md +0 -35
- package/src/css/overrides.css +0 -1
- package/src/css/sources.css +0 -1
- package/src/runtime/lib/markdown-exporters/index.js +0 -144
- package/src/runtime/lib/mdx-source.js +0 -19
- package/src/runtime/lib/preview-source-plugin.js +0 -33
- package/src/runtime/scripts/copy-code.js +0 -130
- package/src/site/ContentHeader.astro +0 -33
|
@@ -6,47 +6,26 @@ import Check from "lucide-static/icons/check.svg?raw";
|
|
|
6
6
|
import Copy from "lucide-static/icons/copy.svg?raw";
|
|
7
7
|
import PanelLeft from "lucide-static/icons/panel-left.svg?raw";
|
|
8
8
|
import Search from "lucide-static/icons/search.svg?raw";
|
|
9
|
-
import ChevronRight from "lucide-static/icons/chevron-right.svg?raw";
|
|
10
|
-
import Ellipsis from "lucide-static/icons/ellipsis.svg?raw";
|
|
11
|
-
import ContentHeader from "virtual:reallysimpledocs/components/ContentHeader";
|
|
12
9
|
import ClaudeLogo from "../../icons/logos/claude.svg?raw";
|
|
13
10
|
import CursorLogo from "../../icons/logos/cursor.svg?raw";
|
|
14
11
|
import MarkdownLogo from "../../icons/logos/markdown.svg?raw";
|
|
15
12
|
import OpenAILogo from "../../icons/logos/openai.svg?raw";
|
|
16
13
|
import BaseLayout from "./BaseLayout.astro";
|
|
17
14
|
import CommandDialog from "./CommandDialog.astro";
|
|
15
|
+
import ContentHeader from "virtual:reallysimpledocs/components/ContentHeader";
|
|
18
16
|
import DropdownMenu from "./DropdownMenu.astro";
|
|
19
17
|
import Sidebar from "./Sidebar.astro";
|
|
20
|
-
import
|
|
18
|
+
import ThemeToggle from "./ThemeToggle.astro";
|
|
19
|
+
import { buildMenus, getNavigation } from "../lib/docs.js";
|
|
21
20
|
import { addSvgClass } from "../lib/html.js";
|
|
22
|
-
import { renderDropdownMenu } from "../lib/macros.js";
|
|
23
|
-
import { routeFilePath } from "../lib/paths.js";
|
|
24
21
|
import { getSite } from "../lib/site.js";
|
|
25
22
|
|
|
26
23
|
const { page, headings } = Astro.props;
|
|
27
24
|
const site = getSite(config);
|
|
28
25
|
const navigation = getNavigation(config, page);
|
|
29
|
-
const breadcrumbs = getBreadcrumbs(config, page);
|
|
30
26
|
const { sidebar } = buildMenus(config, page.slug);
|
|
31
|
-
const hasToc = headings.length > 0;
|
|
32
|
-
const searchIndexUrl = routeFilePath(config.routeBase, "search-index.json");
|
|
33
|
-
const chevronRightIcon = addSvgClass(ChevronRight, "size-3.5");
|
|
34
|
-
const ellipsisIcon = addSvgClass(Ellipsis, "size-4");
|
|
35
27
|
const panelLeftIcon = addSvgClass(PanelLeft, "size-4");
|
|
36
28
|
const searchIcon = addSvgClass(Search, "size-4");
|
|
37
|
-
const breadcrumbItems =
|
|
38
|
-
breadcrumbs.length < 2
|
|
39
|
-
? []
|
|
40
|
-
: breadcrumbs.length > 3
|
|
41
|
-
? [
|
|
42
|
-
breadcrumbs[0],
|
|
43
|
-
{
|
|
44
|
-
type: "dropdown",
|
|
45
|
-
items: breadcrumbs.slice(1, -1),
|
|
46
|
-
},
|
|
47
|
-
breadcrumbs.at(-1),
|
|
48
|
-
]
|
|
49
|
-
: breadcrumbs;
|
|
50
29
|
const siteUrl = Astro.site?.toString().replace(/\/$/, "") || site.url || "";
|
|
51
30
|
const pageUrl = `${siteUrl}${page.path}`;
|
|
52
31
|
const llmPrompt = `Read from ${pageUrl} so I can ask questions about it.`;
|
|
@@ -83,11 +62,13 @@ const actionItems = [
|
|
|
83
62
|
---
|
|
84
63
|
|
|
85
64
|
<BaseLayout title={page.title} description={site.description} pagePath={page.path}>
|
|
86
|
-
<CommandDialog
|
|
65
|
+
<CommandDialog />
|
|
87
66
|
<Sidebar menu={sidebar} />
|
|
88
67
|
|
|
89
68
|
<main id="content">
|
|
90
|
-
<header
|
|
69
|
+
<header
|
|
70
|
+
class="sticky inset-x-0 top-0 isolate z-30 flex shrink-0 items-center gap-2 border-b bg-background"
|
|
71
|
+
>
|
|
91
72
|
<div class="flex h-14 w-full items-center justify-between gap-2 px-4">
|
|
92
73
|
<button
|
|
93
74
|
type="button"
|
|
@@ -96,79 +77,28 @@ const actionItems = [
|
|
|
96
77
|
data-tooltip="Toggle sidebar"
|
|
97
78
|
data-side="bottom"
|
|
98
79
|
data-align="start"
|
|
99
|
-
class="btn
|
|
80
|
+
class="btn"
|
|
81
|
+
data-variant="ghost"
|
|
82
|
+
data-size="icon-sm"
|
|
100
83
|
>
|
|
101
84
|
<Fragment set:html={panelLeftIcon} />
|
|
102
85
|
</button>
|
|
103
86
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const current = index === breadcrumbItems.length - 1;
|
|
110
|
-
return (
|
|
111
|
-
<>
|
|
112
|
-
{index > 0 && (
|
|
113
|
-
<li class="shrink-0" aria-hidden="true">
|
|
114
|
-
<Fragment set:html={chevronRightIcon} />
|
|
115
|
-
</li>
|
|
116
|
-
)}
|
|
117
|
-
<li class="inline-flex min-w-0 items-center gap-1.5 overflow-visible">
|
|
118
|
-
{crumb.type === "dropdown" ? (
|
|
119
|
-
<Fragment
|
|
120
|
-
set:html={renderDropdownMenu({
|
|
121
|
-
id: `breadcrumb-${page.slug.replace(/[^a-z0-9_-]/gi, "-")}`,
|
|
122
|
-
trigger: ellipsisIcon,
|
|
123
|
-
items: crumb.items.map((item) => ({
|
|
124
|
-
label: item.label,
|
|
125
|
-
url: item.url,
|
|
126
|
-
})),
|
|
127
|
-
triggerAttrs: {
|
|
128
|
-
class: "flex size-4 items-center justify-center hover:text-foreground cursor-pointer",
|
|
129
|
-
"aria-label": "Show breadcrumb pages",
|
|
130
|
-
},
|
|
131
|
-
popoverAttrs: { "data-align": "start" },
|
|
132
|
-
})}
|
|
133
|
-
/>
|
|
134
|
-
) : current || !crumb.url ? (
|
|
135
|
-
<span class="truncate font-medium text-foreground">{crumb.label}</span>
|
|
136
|
-
) : (
|
|
137
|
-
<a href={crumb.url} class="truncate transition-colors hover:text-foreground">
|
|
138
|
-
{crumb.label}
|
|
139
|
-
</a>
|
|
140
|
-
)}
|
|
141
|
-
</li>
|
|
142
|
-
</>
|
|
143
|
-
);
|
|
144
|
-
})}
|
|
145
|
-
</ol>
|
|
146
|
-
</nav>
|
|
147
|
-
)
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
<button
|
|
151
|
-
type="button"
|
|
152
|
-
class="btn-sm-icon-ghost ml-auto sm:hidden"
|
|
153
|
-
aria-label="Search"
|
|
154
|
-
data-tooltip="Search"
|
|
155
|
-
data-side="bottom"
|
|
87
|
+
<div
|
|
88
|
+
class="input-group h-8 w-full min-w-0 max-w-72 cursor-text sm:ml-auto"
|
|
89
|
+
role="button"
|
|
90
|
+
tabindex="0"
|
|
91
|
+
aria-label="Search docs"
|
|
156
92
|
onclick="window.rsdOpenCommandSearch ? window.rsdOpenCommandSearch() : document.getElementById('command-search')?.showModal()"
|
|
93
|
+
onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); window.rsdOpenCommandSearch ? window.rsdOpenCommandSearch() : document.getElementById('command-search')?.showModal(); }"
|
|
157
94
|
>
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
type="button"
|
|
163
|
-
class="relative hidden h-8 w-full min-w-0 max-w-72 cursor-text items-center gap-x-2 rounded-md border border-input bg-background px-3 py-1 text-base text-muted-foreground outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 dark:bg-input/30 sm:ml-auto sm:flex md:text-sm"
|
|
164
|
-
onclick="window.rsdOpenCommandSearch ? window.rsdOpenCommandSearch() : document.getElementById('command-search')?.showModal()"
|
|
165
|
-
>
|
|
166
|
-
<Fragment set:html={searchIcon} />
|
|
167
|
-
Search...
|
|
168
|
-
<kbd class="kbd ml-auto -mr-1.5">⌘K</kbd>
|
|
169
|
-
</button>
|
|
95
|
+
<input type="text" placeholder="Search..." readonly tabindex="-1" aria-hidden="true" />
|
|
96
|
+
<span data-align="start" aria-hidden="true"><Fragment set:html={searchIcon} /></span>
|
|
97
|
+
<span data-align="end" aria-hidden="true"><kbd class="kbd">⌘K</kbd></span>
|
|
98
|
+
</div>
|
|
170
99
|
|
|
171
|
-
<ContentHeader site={site} page={page}
|
|
100
|
+
<ContentHeader site={site} page={page} />
|
|
101
|
+
<ThemeToggle />
|
|
172
102
|
</div>
|
|
173
103
|
</header>
|
|
174
104
|
|
|
@@ -176,19 +106,20 @@ const actionItems = [
|
|
|
176
106
|
<article class="min-w-0 flex-1 wrap-break-word">
|
|
177
107
|
<div class="mx-auto w-full max-w-2xl flex-1 space-y-10">
|
|
178
108
|
<header class="space-y-2">
|
|
179
|
-
<div class="flex items-start gap-x-2">
|
|
109
|
+
<div class="flex flex-col-reverse items-start gap-3 sm:flex-row sm:gap-x-2">
|
|
180
110
|
<h1 class="mr-auto text-3xl font-semibold tracking-tight sm:text-4xl">{page.title}</h1>
|
|
181
|
-
<div class="
|
|
111
|
+
<div class="flex w-full items-center justify-end gap-x-2 sm:mt-1 sm:w-auto">
|
|
182
112
|
<div role="group" class="button-group">
|
|
183
113
|
<button
|
|
184
114
|
type="button"
|
|
185
|
-
class="btn
|
|
115
|
+
class="btn"
|
|
116
|
+
data-variant="secondary"
|
|
117
|
+
data-size="sm"
|
|
186
118
|
data-md-url={page.markdownPath}
|
|
187
119
|
onclick="copyPageMarkdown(this)"
|
|
188
120
|
>
|
|
189
|
-
<
|
|
190
|
-
|
|
191
|
-
<span>Copy page</span>
|
|
121
|
+
<Fragment set:html={Copy} />
|
|
122
|
+
Copy page
|
|
192
123
|
</button>
|
|
193
124
|
<hr role="separator" />
|
|
194
125
|
<DropdownMenu items={actionItems} />
|
|
@@ -196,7 +127,7 @@ const actionItems = [
|
|
|
196
127
|
<div role="group" class="button-group">
|
|
197
128
|
{
|
|
198
129
|
navigation.prev && (
|
|
199
|
-
<a href={navigation.prev.path} class="btn-
|
|
130
|
+
<a href={navigation.prev.path} class="btn" data-variant="secondary" data-size="icon-sm">
|
|
200
131
|
<span class="sr-only">{navigation.prev.title}</span>
|
|
201
132
|
<Fragment set:html={ArrowLeft} />
|
|
202
133
|
</a>
|
|
@@ -205,7 +136,7 @@ const actionItems = [
|
|
|
205
136
|
{navigation.prev && navigation.next && <hr role="separator" />}
|
|
206
137
|
{
|
|
207
138
|
navigation.next && (
|
|
208
|
-
<a href={navigation.next.path} class="btn-
|
|
139
|
+
<a href={navigation.next.path} class="btn" data-variant="secondary" data-size="icon-sm">
|
|
209
140
|
<span class="sr-only">{navigation.next.title}</span>
|
|
210
141
|
<Fragment set:html={ArrowRight} />
|
|
211
142
|
</a>
|
|
@@ -221,7 +152,7 @@ const actionItems = [
|
|
|
221
152
|
<footer class="mt-12 flex items-center">
|
|
222
153
|
{
|
|
223
154
|
navigation.prev && (
|
|
224
|
-
<a href={navigation.prev.path} class="btn-
|
|
155
|
+
<a href={navigation.prev.path} class="btn mr-auto" data-variant="secondary" data-size="sm">
|
|
225
156
|
<Fragment set:html={ArrowLeft} />
|
|
226
157
|
{navigation.prev.title}
|
|
227
158
|
</a>
|
|
@@ -229,7 +160,7 @@ const actionItems = [
|
|
|
229
160
|
}
|
|
230
161
|
{
|
|
231
162
|
navigation.next && (
|
|
232
|
-
<a href={navigation.next.path} class="btn-
|
|
163
|
+
<a href={navigation.next.path} class="btn ml-auto" data-variant="secondary" data-size="sm">
|
|
233
164
|
{navigation.next.title}
|
|
234
165
|
<Fragment set:html={ArrowRight} />
|
|
235
166
|
</a>
|
|
@@ -238,51 +169,48 @@ const actionItems = [
|
|
|
238
169
|
</footer>
|
|
239
170
|
</div>
|
|
240
171
|
</article>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
)
|
|
258
|
-
}
|
|
172
|
+
<aside class="hidden w-56 xl:block">
|
|
173
|
+
<div class="docs-toc sticky top-20 space-y-2 text-sm [&_a]:text-muted-foreground [&_a]:hover:text-foreground [&_a[aria-current='location']]:text-foreground [&_ol]:space-y-2 [&_ol_ol]:mt-2 [&_ol_ol]:pl-3" data-docs-toc>
|
|
174
|
+
<h2 class="flex items-center gap-1 font-medium">
|
|
175
|
+
On this page
|
|
176
|
+
</h2>
|
|
177
|
+
<ol>
|
|
178
|
+
{
|
|
179
|
+
headings.map((heading) => (
|
|
180
|
+
<li class={heading.depth === 3 ? "pl-3" : ""}>
|
|
181
|
+
<a href={`#${heading.id}`} data-toc-link>{heading.text}</a>
|
|
182
|
+
</li>
|
|
183
|
+
))
|
|
184
|
+
}
|
|
185
|
+
</ol>
|
|
186
|
+
</div>
|
|
187
|
+
</aside>
|
|
259
188
|
</div>
|
|
260
189
|
</main>
|
|
261
190
|
|
|
262
|
-
<script is:inline>
|
|
263
|
-
async function copyPageMarkdown(button) {
|
|
191
|
+
<script is:inline define:vars={{ checkIcon: Check }}>
|
|
192
|
+
window.copyPageMarkdown = async function copyPageMarkdown(button) {
|
|
264
193
|
const markdownUrl = button?.dataset?.mdUrl;
|
|
265
194
|
if (!markdownUrl) return;
|
|
266
|
-
const
|
|
267
|
-
const
|
|
195
|
+
const icon = button.querySelector("svg");
|
|
196
|
+
const originalIcon = icon?.outerHTML || "";
|
|
268
197
|
|
|
269
198
|
try {
|
|
270
199
|
const response = await fetch(markdownUrl, { credentials: "same-origin", cache: "no-store" });
|
|
271
200
|
if (!response.ok) throw new Error("Failed to fetch markdown");
|
|
272
201
|
const markdown = await response.text();
|
|
273
202
|
await writeToClipboard(markdown);
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
checkIcon.classList.remove("hidden");
|
|
203
|
+
if (icon && checkIcon) {
|
|
204
|
+
icon.outerHTML = checkIcon;
|
|
277
205
|
window.setTimeout(() => {
|
|
278
|
-
|
|
279
|
-
|
|
206
|
+
const currentIcon = button.querySelector("svg");
|
|
207
|
+
if (currentIcon && originalIcon) currentIcon.outerHTML = originalIcon;
|
|
280
208
|
}, 1200);
|
|
281
209
|
}
|
|
282
210
|
} catch (_) {
|
|
283
211
|
window.open(new URL(markdownUrl, window.location.href).toString(), "_blank", "noopener");
|
|
284
212
|
}
|
|
285
|
-
}
|
|
213
|
+
};
|
|
286
214
|
|
|
287
215
|
async function writeToClipboard(text) {
|
|
288
216
|
if (navigator.clipboard?.writeText && window.isSecureContext) {
|
|
@@ -305,55 +233,60 @@ const actionItems = [
|
|
|
305
233
|
|
|
306
234
|
function initDocsToc() {
|
|
307
235
|
const toc = document.querySelector("[data-docs-toc]");
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const links = Array.from(toc.querySelectorAll("[data-toc-link]"));
|
|
311
|
-
const linkById = new Map();
|
|
312
|
-
for (const link of links) {
|
|
313
|
-
const id = decodeURIComponent(link.hash.slice(1));
|
|
314
|
-
if (id) linkById.set(id, link);
|
|
315
|
-
}
|
|
236
|
+
const links = Array.from(toc?.querySelectorAll("[data-toc-link]") || []);
|
|
237
|
+
if (!links.length) return;
|
|
316
238
|
|
|
317
|
-
const
|
|
318
|
-
.map((
|
|
239
|
+
const entries = links
|
|
240
|
+
.map((link) => {
|
|
241
|
+
const id = decodeURIComponent(link.hash.slice(1));
|
|
242
|
+
const heading = id ? document.getElementById(id) : null;
|
|
243
|
+
return heading ? { id, heading, link } : null;
|
|
244
|
+
})
|
|
319
245
|
.filter(Boolean);
|
|
320
|
-
if (!
|
|
246
|
+
if (!entries.length) return;
|
|
321
247
|
|
|
322
|
-
const
|
|
323
|
-
for (const
|
|
324
|
-
const active =
|
|
325
|
-
link.
|
|
326
|
-
if (active) link.setAttribute("aria-current", "location");
|
|
327
|
-
else link.removeAttribute("aria-current");
|
|
248
|
+
const activate = (id) => {
|
|
249
|
+
for (const entry of entries) {
|
|
250
|
+
const active = entry.id === id;
|
|
251
|
+
entry.link.toggleAttribute("data-active", active);
|
|
252
|
+
if (active) entry.link.setAttribute("aria-current", "location");
|
|
253
|
+
else entry.link.removeAttribute("aria-current");
|
|
328
254
|
}
|
|
329
255
|
};
|
|
330
256
|
|
|
331
|
-
const
|
|
332
|
-
const
|
|
333
|
-
let current =
|
|
334
|
-
|
|
335
|
-
|
|
257
|
+
const activeFromScroll = () => {
|
|
258
|
+
const marker = Math.min(window.innerHeight * 0.35, 220);
|
|
259
|
+
let current = entries[0];
|
|
260
|
+
|
|
261
|
+
for (const entry of entries) {
|
|
262
|
+
if (entry.heading.getBoundingClientRect().top <= marker) current = entry;
|
|
336
263
|
else break;
|
|
337
264
|
}
|
|
338
|
-
return current;
|
|
339
|
-
};
|
|
340
265
|
|
|
341
|
-
|
|
342
|
-
|
|
266
|
+
activate(current.id);
|
|
267
|
+
};
|
|
343
268
|
|
|
344
|
-
let
|
|
345
|
-
const
|
|
346
|
-
if (
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
updateActive();
|
|
269
|
+
let frame = 0;
|
|
270
|
+
const queueActiveUpdate = () => {
|
|
271
|
+
if (frame) return;
|
|
272
|
+
frame = window.requestAnimationFrame(() => {
|
|
273
|
+
frame = 0;
|
|
274
|
+
activeFromScroll();
|
|
351
275
|
});
|
|
352
276
|
};
|
|
353
277
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
278
|
+
if ("IntersectionObserver" in window) {
|
|
279
|
+
const observer = new IntersectionObserver(queueActiveUpdate, {
|
|
280
|
+
rootMargin: "-20% 0px -65% 0px",
|
|
281
|
+
threshold: [0, 1],
|
|
282
|
+
});
|
|
283
|
+
for (const entry of entries) observer.observe(entry.heading);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
activeFromScroll();
|
|
287
|
+
window.addEventListener("scroll", queueActiveUpdate, { passive: true });
|
|
288
|
+
window.addEventListener("resize", queueActiveUpdate);
|
|
289
|
+
window.addEventListener("hashchange", () => window.setTimeout(activeFromScroll, 0));
|
|
357
290
|
}
|
|
358
291
|
|
|
359
292
|
initDocsToc();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import Moon from "lucide-static/icons/moon.svg?raw";
|
|
3
|
+
import Sun from "lucide-static/icons/sun.svg?raw";
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<nav class="flex items-center gap-2">
|
|
7
|
+
<button
|
|
8
|
+
type="button"
|
|
9
|
+
aria-label="Toggle dark mode"
|
|
10
|
+
data-tooltip="Toggle dark mode"
|
|
11
|
+
data-side="bottom"
|
|
12
|
+
data-align="end"
|
|
13
|
+
onclick="window.basecoat?.theme.toggle()"
|
|
14
|
+
class="btn"
|
|
15
|
+
data-variant="ghost"
|
|
16
|
+
data-size="icon-sm"
|
|
17
|
+
>
|
|
18
|
+
<span class="hidden dark:block"><Fragment set:html={Sun} /></span>
|
|
19
|
+
<span class="block dark:hidden"><Fragment set:html={Moon} /></span>
|
|
20
|
+
</button>
|
|
21
|
+
</nav>
|
|
@@ -2,22 +2,9 @@
|
|
|
2
2
|
import * as lucideIcons from "lucide-static";
|
|
3
3
|
import { addSvgClass } from "../../lib/html.js";
|
|
4
4
|
|
|
5
|
-
const { type, title = "Note", icon: iconName,
|
|
5
|
+
const { type, title = "Note", icon: iconName, class: className = "" } = Astro.props;
|
|
6
6
|
const normalizedType = String(type || "").toLowerCase();
|
|
7
7
|
const calloutType = normalizedType === "warning" || normalizedType === "destructive" ? normalizedType : "";
|
|
8
|
-
const destructive = calloutType === "destructive";
|
|
9
|
-
const actionLabel = action?.label;
|
|
10
|
-
const actionClass = action?.class || "btn-sm-secondary";
|
|
11
|
-
const actionAttrs = action
|
|
12
|
-
? {
|
|
13
|
-
...action.attrs,
|
|
14
|
-
href: action.href,
|
|
15
|
-
target: action.target,
|
|
16
|
-
rel: action.rel,
|
|
17
|
-
onclick: action.onclick,
|
|
18
|
-
class: actionClass,
|
|
19
|
-
}
|
|
20
|
-
: {};
|
|
21
8
|
|
|
22
9
|
function resolveNamedIcon(name) {
|
|
23
10
|
if (!name || typeof name !== "string") return "";
|
|
@@ -36,29 +23,12 @@ function resolveNamedIcon(name) {
|
|
|
36
23
|
const iconSource = typeof iconName === "string" ? resolveNamedIcon(iconName) : "";
|
|
37
24
|
const icon = addSvgClass(iconSource, "size-4");
|
|
38
25
|
const heading = title;
|
|
39
|
-
const variantClass =
|
|
40
|
-
calloutType === "warning"
|
|
41
|
-
? "[&>svg]:text-amber-700 [&>h3]:text-amber-700 [&>section]:text-amber-700 dark:[&>svg]:text-amber-300 dark:[&>h3]:text-amber-300 dark:[&>section]:text-amber-300"
|
|
42
|
-
: destructive
|
|
43
|
-
? "[&>svg]:text-destructive [&>h3]:text-destructive [&>section]:text-destructive"
|
|
44
|
-
: "";
|
|
45
26
|
---
|
|
46
27
|
|
|
47
|
-
<div class:list={[
|
|
28
|
+
<div class:list={["alert", className]} data-variant={calloutType || undefined}>
|
|
48
29
|
{icon && <Fragment set:html={icon} />}
|
|
49
30
|
<h3>{heading}</h3>
|
|
50
31
|
<section>
|
|
51
32
|
<slot />
|
|
52
33
|
</section>
|
|
53
|
-
{
|
|
54
|
-
actionLabel && (
|
|
55
|
-
<footer>
|
|
56
|
-
{action?.href ? (
|
|
57
|
-
<a {...actionAttrs}>{actionLabel}</a>
|
|
58
|
-
) : (
|
|
59
|
-
<button type="button" {...actionAttrs}>{actionLabel}</button>
|
|
60
|
-
)}
|
|
61
|
-
</footer>
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
34
|
</div>
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
const { title, description, href, class: className = "" } = Astro.props;
|
|
3
3
|
const Tag = href ? "a" : "article";
|
|
4
|
-
const classes = [
|
|
5
|
-
"my-6 block w-full rounded-lg border bg-card p-3 text-card-foreground no-underline",
|
|
6
|
-
href && "transition-colors hover:bg-accent/50 focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
7
|
-
className,
|
|
8
|
-
];
|
|
9
4
|
---
|
|
10
5
|
|
|
11
|
-
<Tag href={href} class:list={
|
|
12
|
-
{title && <h3
|
|
13
|
-
{description && <p
|
|
6
|
+
<Tag href={href} class:list={["docs-card", href && "docs-card-link", className]}>
|
|
7
|
+
{title && <h3>{title}</h3>}
|
|
8
|
+
{description && <p>{description}</p>}
|
|
14
9
|
</Tag>
|
|
@@ -1,39 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { highlightCode } from "../../lib/highlight.js";
|
|
3
|
+
import { decodeHtml } from "../../lib/html.js";
|
|
3
4
|
|
|
4
|
-
const { lang = "text", title, class: className = "" } = Astro.props;
|
|
5
|
+
const { lang = "text", title, code, class: className = "" } = Astro.props;
|
|
5
6
|
const slotHtml = Astro.slots.has("default") ? await Astro.slots.render("default") : "";
|
|
6
|
-
const rawCode = decodeSlotText(slotHtml);
|
|
7
|
+
const rawCode = typeof code === "string" ? code.trim() : decodeSlotText(slotHtml);
|
|
7
8
|
const html = await highlightCode(rawCode, lang);
|
|
8
|
-
const classes = [
|
|
9
|
-
"relative my-6 w-full max-w-full overflow-hidden rounded-lg",
|
|
10
|
-
className,
|
|
11
|
-
];
|
|
12
9
|
|
|
13
10
|
function decodeSlotText(value) {
|
|
14
|
-
|
|
11
|
+
const text = String(value || "")
|
|
15
12
|
.replace(/^<p>/, "")
|
|
16
|
-
.replace(/<\/p>$/, "")
|
|
17
|
-
|
|
18
|
-
.replace(/>/g, ">")
|
|
19
|
-
.replace(/&/g, "&")
|
|
20
|
-
.replace(/"/g, '"')
|
|
21
|
-
.replace(/'/g, "'")
|
|
22
|
-
.trim();
|
|
13
|
+
.replace(/<\/p>$/, "");
|
|
14
|
+
return decodeHtml(text).trim();
|
|
23
15
|
}
|
|
24
16
|
---
|
|
25
17
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
>
|
|
31
|
-
{
|
|
32
|
-
title && (
|
|
33
|
-
<header class="flex h-10 items-center gap-2 border-b border-border/50 bg-muted/50 px-3 text-sm font-medium">
|
|
34
|
-
<span class="mr-auto">{title}</span>
|
|
18
|
+
{
|
|
19
|
+
title ? (
|
|
20
|
+
<div class:list={["code-frame", className]} data-code-title={title}>
|
|
21
|
+
<header>
|
|
22
|
+
<span>{title}</span>
|
|
35
23
|
</header>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
</div>
|
|
24
|
+
<div class="code-block">
|
|
25
|
+
<Fragment set:html={html} />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
) : (
|
|
29
|
+
<div class:list={["code-block", className]}>
|
|
30
|
+
<Fragment set:html={html} />
|
|
31
|
+
</div>
|
|
32
|
+
)
|
|
33
|
+
}
|