reallysimpledocs 1.0.0-beta.5 → 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 +52 -32
- package/package.json +7 -4
- package/src/astro/index.js +18 -0
- package/src/astro/preview-scripts.js +140 -0
- package/src/astro/preview-source.js +68 -8
- package/src/astro/rehype-basecoat-tables.js +62 -0
- package/src/css/custom.css +49 -129
- package/src/css/styles/luma.css +4 -6
- package/src/css/styles/lyra.css +4 -6
- package/src/css/styles/maia.css +4 -6
- package/src/css/styles/mira.css +4 -6
- package/src/css/styles/nova.css +4 -6
- package/src/css/styles/rhea.css +4 -6
- package/src/css/styles/sera.css +4 -6
- package/src/css/styles/vega.css +4 -6
- package/src/runtime/components/BaseLayout.astro +20 -19
- package/src/runtime/components/CommandDialog.astro +24 -5
- package/src/runtime/components/DefaultHead.astro +20 -30
- package/src/runtime/components/DocsLayout.astro +0 -16
- package/src/runtime/components/ThemeToggle.astro +1 -1
- package/src/runtime/components/mdx/Code.astro +22 -14
- package/src/runtime/components/mdx/CodeGroup.astro +109 -15
- package/src/runtime/components/mdx/Preview.astro +1 -1
- package/src/runtime/lib/code-meta.js +8 -0
- package/src/runtime/lib/docs.js +11 -17
- package/src/runtime/lib/html.js +9 -0
- package/src/runtime/lib/markdown-export.js +111 -3
package/src/css/custom.css
CHANGED
|
@@ -28,10 +28,15 @@
|
|
|
28
28
|
> p a,
|
|
29
29
|
> li a,
|
|
30
30
|
> dl a,
|
|
31
|
-
> table
|
|
32
|
-
>
|
|
31
|
+
> .table-container a,
|
|
32
|
+
[role="listitem"] > p > a,
|
|
33
|
+
[role="listitem"] > li > a {
|
|
33
34
|
@apply underline underline-offset-2 decoration-muted-foreground/50 hover:decoration-foreground/50 transition-all;
|
|
34
35
|
}
|
|
36
|
+
b,
|
|
37
|
+
strong {
|
|
38
|
+
@apply font-semibold;
|
|
39
|
+
}
|
|
35
40
|
code:not(pre > code) {
|
|
36
41
|
@apply relative rounded-md bg-muted px-[0.3rem] py-[0.2rem] font-mono text-[13px];
|
|
37
42
|
}
|
|
@@ -76,10 +81,6 @@
|
|
|
76
81
|
@apply mt-4 border-b-0 pb-0 pl-8 my-0;
|
|
77
82
|
}
|
|
78
83
|
}
|
|
79
|
-
b,
|
|
80
|
-
strong {
|
|
81
|
-
@apply font-semibold;
|
|
82
|
-
}
|
|
83
84
|
> p,
|
|
84
85
|
> blockquote,
|
|
85
86
|
> ul,
|
|
@@ -94,29 +95,10 @@
|
|
|
94
95
|
> *:last-child {
|
|
95
96
|
@apply !mb-0;
|
|
96
97
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
tbody {
|
|
103
|
-
@apply [&_tr:last-child]:border-0;
|
|
104
|
-
}
|
|
105
|
-
tfoot {
|
|
106
|
-
@apply bg-muted/50 border-t font-medium [&>tr]:last:border-b-0;
|
|
107
|
-
}
|
|
108
|
-
tr {
|
|
109
|
-
@apply hover:bg-muted/50 border-b transition-colors;
|
|
110
|
-
}
|
|
111
|
-
th {
|
|
112
|
-
@apply text-foreground h-10 px-2 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px];
|
|
113
|
-
}
|
|
114
|
-
td {
|
|
115
|
-
@apply p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px];
|
|
116
|
-
}
|
|
117
|
-
caption {
|
|
118
|
-
@apply text-muted-foreground mt-4 text-sm;
|
|
119
|
-
}
|
|
98
|
+
|
|
99
|
+
> .table-container .table th,
|
|
100
|
+
> .table-container .table td {
|
|
101
|
+
@apply whitespace-normal;
|
|
120
102
|
}
|
|
121
103
|
}
|
|
122
104
|
|
|
@@ -184,20 +166,28 @@ html.dark .astro-code span {
|
|
|
184
166
|
@apply text-amber-700 dark:text-amber-300;
|
|
185
167
|
}
|
|
186
168
|
|
|
187
|
-
.code-
|
|
188
|
-
|
|
169
|
+
.code-frame,
|
|
170
|
+
.tabs-frame {
|
|
171
|
+
@apply relative my-6 w-full max-w-full rounded-lg;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.code-frame > header {
|
|
175
|
+
@apply flex h-10 items-center gap-2 overflow-x-auto rounded-t-[inherit] border-b bg-muted px-3 text-sm font-medium dark:bg-muted/50;
|
|
176
|
+
scrollbar-width: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.tabs-frame > header {
|
|
180
|
+
@apply flex items-center gap-2 overflow-x-auto rounded-t-[inherit] border-b bg-muted px-3 py-0.5 text-sm font-medium dark:bg-muted/50;
|
|
181
|
+
scrollbar-width: none;
|
|
189
182
|
}
|
|
190
183
|
|
|
191
|
-
.code-
|
|
192
|
-
.
|
|
193
|
-
|
|
194
|
-
@apply flex h-10 items-center gap-2 border-b border-border bg-muted/50 px-3 text-sm font-medium;
|
|
184
|
+
.code-frame > header::-webkit-scrollbar,
|
|
185
|
+
.tabs-frame > header::-webkit-scrollbar {
|
|
186
|
+
display: none;
|
|
195
187
|
}
|
|
196
188
|
|
|
197
|
-
.code-block
|
|
198
|
-
|
|
199
|
-
.preview > header > :first-child {
|
|
200
|
-
@apply mr-auto;
|
|
189
|
+
.code-block {
|
|
190
|
+
@apply relative my-6 w-full max-w-full overflow-hidden rounded-lg;
|
|
201
191
|
}
|
|
202
192
|
|
|
203
193
|
.code-block > pre {
|
|
@@ -213,103 +203,28 @@ html.dark .astro-code span {
|
|
|
213
203
|
}
|
|
214
204
|
|
|
215
205
|
.code-block > button {
|
|
216
|
-
@apply absolute right-2.5 top-2.5 z-10;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
.code-block button,
|
|
220
|
-
.code-group button[aria-label="Copy code"],
|
|
221
|
-
.preview button[aria-label="Copy code"] {
|
|
222
|
-
@apply flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground outline-none hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&_svg]:size-4;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.code-block > button {
|
|
226
|
-
@apply bg-background/80 shadow-xs backdrop-blur-sm hover:bg-accent/80 dark:bg-background/60 dark:hover:bg-accent/70;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.code-block > header > button,
|
|
230
|
-
.code-group > header > button,
|
|
231
|
-
.preview > header > button {
|
|
232
|
-
@apply ml-auto;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
.code-group {
|
|
236
|
-
@apply relative my-6 w-full max-w-full overflow-hidden rounded-lg;
|
|
206
|
+
@apply absolute right-2.5 top-2.5 z-10 [&_svg]:size-4 flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground outline-none bg-muted/50 dark:bg-muted/25 backdrop-blur-sm hover:text-foreground transition-colors;
|
|
237
207
|
}
|
|
238
208
|
|
|
239
|
-
.code-
|
|
240
|
-
|
|
209
|
+
.code-frame > .code-block,
|
|
210
|
+
.tabs-frame > [data-code-panel] .code-block {
|
|
211
|
+
@apply my-0 min-w-0 rounded-none rounded-b-[inherit];
|
|
241
212
|
}
|
|
242
213
|
|
|
243
|
-
.
|
|
244
|
-
@apply
|
|
214
|
+
.tabs-frame {
|
|
215
|
+
@apply overflow-visible;
|
|
245
216
|
}
|
|
246
217
|
|
|
247
|
-
.code-
|
|
248
|
-
@apply
|
|
218
|
+
.code-frame {
|
|
219
|
+
@apply overflow-hidden;
|
|
249
220
|
}
|
|
250
221
|
|
|
251
|
-
.
|
|
252
|
-
@apply
|
|
222
|
+
.tabs-frame > [role="tabpanel"] {
|
|
223
|
+
@apply rounded-b-[inherit];
|
|
253
224
|
}
|
|
254
225
|
|
|
255
|
-
.
|
|
256
|
-
@apply
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.preview {
|
|
260
|
-
@apply relative my-6 max-w-full overflow-visible rounded-lg;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.preview::before {
|
|
264
|
-
@apply pointer-events-none absolute inset-0 z-10 border border-border;
|
|
265
|
-
border-radius: inherit;
|
|
266
|
-
content: "";
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.preview > header > .tabs {
|
|
270
|
-
@apply my-0 min-w-0 max-w-full gap-0;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.preview > header {
|
|
274
|
-
@apply relative z-0 rounded-t-[inherit];
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
.preview > header > .tabs > nav {
|
|
278
|
-
@apply h-full justify-start rounded-none bg-transparent p-0;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
.preview > [role="tabpanel"] {
|
|
282
|
-
@apply border-t-0;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.preview > [data-code-panel] {
|
|
286
|
-
@apply overflow-hidden rounded-b-[inherit];
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.preview > [data-code-panel] .code-block {
|
|
290
|
-
@apply my-0 min-w-0 rounded-none;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
.preview > header > button[aria-label="Copy code"] {
|
|
294
|
-
display: none;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
.preview:has(> [data-code-panel]:not([hidden]))
|
|
298
|
-
> header
|
|
299
|
-
> button[aria-label="Copy code"] {
|
|
300
|
-
display: flex;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
.preview > [data-preview-panel] {
|
|
304
|
-
@apply flex min-h-64 items-center justify-center p-6;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
.preview > [data-preview-panel] :where(ul, ol) {
|
|
308
|
-
@apply m-0;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
.preview > [data-preview-panel] :where(li) {
|
|
312
|
-
@apply mt-0;
|
|
226
|
+
.tabs-frame > [data-preview-panel] {
|
|
227
|
+
@apply flex min-h-64 items-center justify-center p-6 bg-muted/50 dark:bg-muted/25;
|
|
313
228
|
}
|
|
314
229
|
|
|
315
230
|
.steps {
|
|
@@ -353,11 +268,15 @@ html.dark .astro-code span {
|
|
|
353
268
|
}
|
|
354
269
|
|
|
355
270
|
.steps > section > * + * {
|
|
356
|
-
@apply mt-
|
|
271
|
+
@apply mt-3;
|
|
357
272
|
}
|
|
358
273
|
|
|
359
274
|
.steps > section > h3 + * {
|
|
360
|
-
@apply mt-
|
|
275
|
+
@apply mt-2;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.steps > section > :where(.code-frame, .code-block, .tabs-frame) {
|
|
279
|
+
@apply my-3;
|
|
361
280
|
}
|
|
362
281
|
|
|
363
282
|
.steps > section > * {
|
|
@@ -375,7 +294,8 @@ html.dark .astro-code span {
|
|
|
375
294
|
.prose > .alert,
|
|
376
295
|
.prose > .docs-card,
|
|
377
296
|
.prose > .grid,
|
|
378
|
-
.prose > .tabs
|
|
297
|
+
.prose > .tabs,
|
|
298
|
+
.prose > .tabs-frame {
|
|
379
299
|
@apply my-6;
|
|
380
300
|
}
|
|
381
301
|
|
package/src/css/styles/luma.css
CHANGED
package/src/css/styles/lyra.css
CHANGED
package/src/css/styles/maia.css
CHANGED
package/src/css/styles/mira.css
CHANGED
package/src/css/styles/nova.css
CHANGED
package/src/css/styles/rhea.css
CHANGED
package/src/css/styles/sera.css
CHANGED
package/src/css/styles/vega.css
CHANGED
|
@@ -23,29 +23,12 @@ const absoluteAssetUrl = (value) => {
|
|
|
23
23
|
const path = assetPath(value);
|
|
24
24
|
return path.startsWith("http") ? path : `${siteUrl}${path}`;
|
|
25
25
|
};
|
|
26
|
+
const bodyAttrs = config.bodyAttrs || {};
|
|
26
27
|
---
|
|
27
28
|
|
|
28
29
|
<!doctype html>
|
|
29
30
|
<html lang="en">
|
|
30
31
|
<head>
|
|
31
|
-
<DefaultHead
|
|
32
|
-
config={config}
|
|
33
|
-
site={site}
|
|
34
|
-
title={title}
|
|
35
|
-
description={metaDescription}
|
|
36
|
-
pagePath={pagePath}
|
|
37
|
-
metaTitle={metaTitle}
|
|
38
|
-
absoluteUrl={absoluteUrl}
|
|
39
|
-
/>
|
|
40
|
-
<Head
|
|
41
|
-
config={config}
|
|
42
|
-
site={site}
|
|
43
|
-
title={title}
|
|
44
|
-
description={metaDescription}
|
|
45
|
-
pagePath={pagePath}
|
|
46
|
-
metaTitle={metaTitle}
|
|
47
|
-
absoluteUrl={absoluteUrl}
|
|
48
|
-
/>
|
|
49
32
|
<meta charset="utf-8" />
|
|
50
33
|
<meta http-equiv="Content-Language" content="en" />
|
|
51
34
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
@@ -69,8 +52,26 @@ const absoluteAssetUrl = (value) => {
|
|
|
69
52
|
<meta name="twitter:description" content={metaDescription} />
|
|
70
53
|
{socialImage && <meta name="twitter:image" content={absoluteAssetUrl(socialImage)} />}
|
|
71
54
|
{site.author?.x && <meta name="twitter:creator" content={site.author.x} />}
|
|
55
|
+
<DefaultHead
|
|
56
|
+
config={config}
|
|
57
|
+
site={site}
|
|
58
|
+
title={title}
|
|
59
|
+
description={metaDescription}
|
|
60
|
+
pagePath={pagePath}
|
|
61
|
+
metaTitle={metaTitle}
|
|
62
|
+
absoluteUrl={absoluteUrl}
|
|
63
|
+
/>
|
|
64
|
+
<Head
|
|
65
|
+
config={config}
|
|
66
|
+
site={site}
|
|
67
|
+
title={title}
|
|
68
|
+
description={metaDescription}
|
|
69
|
+
pagePath={pagePath}
|
|
70
|
+
metaTitle={metaTitle}
|
|
71
|
+
absoluteUrl={absoluteUrl}
|
|
72
|
+
/>
|
|
72
73
|
</head>
|
|
73
|
-
<body>
|
|
74
|
+
<body {...bodyAttrs}>
|
|
74
75
|
<slot />
|
|
75
76
|
</body>
|
|
76
77
|
</html>
|
|
@@ -212,18 +212,33 @@ const { indexUrl = routeFilePath(config.routeBase, "search-index.json") } = Astr
|
|
|
212
212
|
refreshCommand();
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
function renderEmpty() {
|
|
216
|
+
if (!menu) return;
|
|
217
|
+
delete menu.dataset.loading;
|
|
218
|
+
menu.innerHTML = "";
|
|
219
|
+
refreshCommand();
|
|
220
|
+
}
|
|
221
|
+
|
|
215
222
|
async function loadIndex() {
|
|
216
223
|
if (state.index) return state;
|
|
217
224
|
if (!indexUrl) throw new Error("Missing ReallySimpleDocs search index URL.");
|
|
218
225
|
if (!state.loadPromise) {
|
|
219
226
|
renderLoading();
|
|
220
227
|
state.loadPromise = fetch(indexUrl)
|
|
221
|
-
.then((response) =>
|
|
228
|
+
.then((response) => {
|
|
229
|
+
if (!response.ok) throw new Error(`Failed to load search index: ${response.status}`);
|
|
230
|
+
return response.json();
|
|
231
|
+
})
|
|
222
232
|
.then((data) => {
|
|
223
233
|
state.documents = data.documents || [];
|
|
224
234
|
state.bySlug = new Map(state.documents.map((doc) => [doc.slug, doc]));
|
|
225
235
|
state.index = lunr.Index.load(data.index);
|
|
226
236
|
return state;
|
|
237
|
+
})
|
|
238
|
+
.catch((error) => {
|
|
239
|
+
state.loadPromise = null;
|
|
240
|
+
renderEmpty();
|
|
241
|
+
throw error;
|
|
227
242
|
});
|
|
228
243
|
}
|
|
229
244
|
return state.loadPromise;
|
|
@@ -253,10 +268,14 @@ const { indexUrl = routeFilePath(config.routeBase, "search-index.json") } = Astr
|
|
|
253
268
|
}
|
|
254
269
|
|
|
255
270
|
async function refreshResults() {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
271
|
+
try {
|
|
272
|
+
await loadIndex();
|
|
273
|
+
const query = input?.value || "";
|
|
274
|
+
const results = search(query).slice(0, MAX_RESULTS);
|
|
275
|
+
renderItems(results, query.trim() ? "Results" : "Docs", query);
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.error("[search] Failed to load index:", error);
|
|
278
|
+
}
|
|
260
279
|
}
|
|
261
280
|
|
|
262
281
|
window.rsdOpenCommandSearch = async () => {
|
|
@@ -8,7 +8,11 @@ import basecoatJsUrl from "basecoat-css/all.min?url";
|
|
|
8
8
|
(() => {
|
|
9
9
|
try {
|
|
10
10
|
const stored = localStorage.getItem("themeMode");
|
|
11
|
-
if (
|
|
11
|
+
if (
|
|
12
|
+
stored
|
|
13
|
+
? stored === "dark"
|
|
14
|
+
: matchMedia("(prefers-color-scheme: dark)").matches
|
|
15
|
+
) {
|
|
12
16
|
document.documentElement.classList.add("dark");
|
|
13
17
|
}
|
|
14
18
|
} catch (_) {}
|
|
@@ -34,37 +38,22 @@ import basecoatJsUrl from "basecoat-css/all.min?url";
|
|
|
34
38
|
if (!ok) throw new Error("Copy failed");
|
|
35
39
|
};
|
|
36
40
|
|
|
37
|
-
const activePanelCode = (root) => root.querySelector(':scope > [role="tabpanel"]:not([hidden]) code');
|
|
38
|
-
|
|
39
41
|
const initCopyCode = (codeBlock) => {
|
|
40
42
|
if (codeBlock.dataset.copyCodeInitialized) return;
|
|
41
43
|
const codeEl = codeBlock.querySelector(":scope > code");
|
|
42
44
|
if (!codeEl) return;
|
|
43
45
|
|
|
44
|
-
let
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (frame) target = frame.querySelector(":scope > header");
|
|
48
|
-
|
|
49
|
-
const preview = codeBlock.closest(".preview");
|
|
50
|
-
const previewCodePanel = preview?.querySelector(":scope > [data-code-panel]");
|
|
51
|
-
if (!frame && previewCodePanel?.contains(codeBlock)) {
|
|
52
|
-
frame = preview;
|
|
53
|
-
target = frame.querySelector(":scope > header");
|
|
54
|
-
getCode = () => codeEl;
|
|
55
|
-
}
|
|
56
|
-
|
|
46
|
+
let frame = codeBlock.parentElement?.classList.contains("code-block")
|
|
47
|
+
? codeBlock.parentElement
|
|
48
|
+
: null;
|
|
57
49
|
if (!frame) {
|
|
58
|
-
frame =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
codeBlock.parentNode.insertBefore(frame, codeBlock);
|
|
63
|
-
frame.appendChild(codeBlock);
|
|
64
|
-
}
|
|
50
|
+
frame = document.createElement("div");
|
|
51
|
+
frame.className = "code-block";
|
|
52
|
+
codeBlock.parentNode.insertBefore(frame, codeBlock);
|
|
53
|
+
frame.appendChild(codeBlock);
|
|
65
54
|
}
|
|
66
55
|
|
|
67
|
-
target
|
|
56
|
+
const target = frame;
|
|
68
57
|
if (target.querySelector(":scope > button[aria-label='Copy code']")) {
|
|
69
58
|
codeBlock.dataset.copyCodeInitialized = "true";
|
|
70
59
|
return;
|
|
@@ -72,14 +61,11 @@ import basecoatJsUrl from "basecoat-css/all.min?url";
|
|
|
72
61
|
|
|
73
62
|
const button = document.createElement("button");
|
|
74
63
|
button.type = "button";
|
|
75
|
-
button.className = "btn";
|
|
76
|
-
button.dataset.variant = "ghost";
|
|
77
|
-
button.dataset.size = "icon-xs";
|
|
78
64
|
button.setAttribute("aria-label", "Copy code");
|
|
79
65
|
button.innerHTML = copyIcon;
|
|
80
66
|
|
|
81
67
|
button.addEventListener("click", async () => {
|
|
82
|
-
const text = (
|
|
68
|
+
const text = (codeEl.textContent || "").replace(/\n$/, "");
|
|
83
69
|
if (!text) return;
|
|
84
70
|
|
|
85
71
|
try {
|
|
@@ -99,11 +85,15 @@ import basecoatJsUrl from "basecoat-css/all.min?url";
|
|
|
99
85
|
};
|
|
100
86
|
|
|
101
87
|
const initCopyButtons = (root = document) => {
|
|
102
|
-
root
|
|
88
|
+
root
|
|
89
|
+
.querySelectorAll("pre:has(> code):not([data-copy-code-initialized])")
|
|
90
|
+
.forEach(initCopyCode);
|
|
103
91
|
};
|
|
104
92
|
|
|
105
93
|
if (document.readyState === "loading") {
|
|
106
|
-
document.addEventListener("DOMContentLoaded", () => initCopyButtons(), {
|
|
94
|
+
document.addEventListener("DOMContentLoaded", () => initCopyButtons(), {
|
|
95
|
+
once: true,
|
|
96
|
+
});
|
|
107
97
|
} else {
|
|
108
98
|
initCopyButtons();
|
|
109
99
|
}
|
|
@@ -4,7 +4,6 @@ import ArrowLeft from "lucide-static/icons/arrow-left.svg?raw";
|
|
|
4
4
|
import ArrowRight from "lucide-static/icons/arrow-right.svg?raw";
|
|
5
5
|
import Check from "lucide-static/icons/check.svg?raw";
|
|
6
6
|
import Copy from "lucide-static/icons/copy.svg?raw";
|
|
7
|
-
import Menu from "lucide-static/icons/menu.svg?raw";
|
|
8
7
|
import PanelLeft from "lucide-static/icons/panel-left.svg?raw";
|
|
9
8
|
import Search from "lucide-static/icons/search.svg?raw";
|
|
10
9
|
import ClaudeLogo from "../../icons/logos/claude.svg?raw";
|
|
@@ -100,21 +99,6 @@ const actionItems = [
|
|
|
100
99
|
|
|
101
100
|
<ContentHeader site={site} page={page} />
|
|
102
101
|
<ThemeToggle />
|
|
103
|
-
|
|
104
|
-
<div class="sm:hidden">
|
|
105
|
-
<button
|
|
106
|
-
type="button"
|
|
107
|
-
class="btn peer group"
|
|
108
|
-
data-variant="ghost"
|
|
109
|
-
data-size="icon-sm"
|
|
110
|
-
aria-label="Toggle sidebar"
|
|
111
|
-
aria-expanded="false"
|
|
112
|
-
aria-controls="sidebar"
|
|
113
|
-
onclick="document.getElementById('sidebar')?.toggle()"
|
|
114
|
-
>
|
|
115
|
-
<Fragment set:html={Menu} />
|
|
116
|
-
</button>
|
|
117
|
-
</div>
|
|
118
102
|
</div>
|
|
119
103
|
</header>
|
|
120
104
|
|
|
@@ -1,25 +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
9
|
|
|
9
10
|
function decodeSlotText(value) {
|
|
10
|
-
|
|
11
|
+
const text = String(value || "")
|
|
11
12
|
.replace(/^<p>/, "")
|
|
12
|
-
.replace(/<\/p>$/, "")
|
|
13
|
-
|
|
14
|
-
.replace(/>/g, ">")
|
|
15
|
-
.replace(/&/g, "&")
|
|
16
|
-
.replace(/"/g, '"')
|
|
17
|
-
.replace(/'/g, "'")
|
|
18
|
-
.trim();
|
|
13
|
+
.replace(/<\/p>$/, "");
|
|
14
|
+
return decodeHtml(text).trim();
|
|
19
15
|
}
|
|
20
16
|
---
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
{
|
|
19
|
+
title ? (
|
|
20
|
+
<div class:list={["code-frame", className]} data-code-title={title}>
|
|
21
|
+
<header>
|
|
22
|
+
<span>{title}</span>
|
|
23
|
+
</header>
|
|
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
|
+
}
|