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.
Files changed (53) hide show
  1. package/README.md +59 -39
  2. package/package.json +11 -11
  3. package/src/astro/index.js +64 -98
  4. package/src/astro/preview-scripts.js +140 -0
  5. package/src/astro/preview-source.js +150 -0
  6. package/src/astro/rehype-basecoat-tables.js +62 -0
  7. package/src/components/index.js +1 -0
  8. package/src/css/custom.css +197 -58
  9. package/src/css/styles/luma.css +9 -0
  10. package/src/css/styles/lyra.css +9 -0
  11. package/src/css/styles/maia.css +9 -0
  12. package/src/css/styles/mira.css +9 -0
  13. package/src/css/styles/nova.css +9 -0
  14. package/src/css/styles/rhea.css +9 -0
  15. package/src/css/styles/sera.css +9 -0
  16. package/src/css/styles/vega.css +9 -0
  17. package/src/runtime/components/BaseLayout.astro +22 -28
  18. package/src/runtime/components/CommandDialog.astro +52 -35
  19. package/src/runtime/components/DefaultContentHeader.astro +0 -17
  20. package/src/runtime/components/DefaultHead.astro +110 -0
  21. package/src/runtime/components/DefaultHeadContent.astro +2 -0
  22. package/src/runtime/components/DefaultSidebarHeader.astro +1 -1
  23. package/src/runtime/components/DocsLayout.astro +99 -166
  24. package/src/runtime/components/DropdownMenu.astro +1 -1
  25. package/src/runtime/components/ThemeToggle.astro +21 -0
  26. package/src/runtime/components/mdx/Callout.astro +2 -32
  27. package/src/runtime/components/mdx/Card.astro +3 -8
  28. package/src/runtime/components/mdx/CardGrid.astro +1 -1
  29. package/src/runtime/components/mdx/Code.astro +21 -27
  30. package/src/runtime/components/mdx/CodeGroup.astro +114 -24
  31. package/src/runtime/components/mdx/Preview.astro +7 -13
  32. package/src/runtime/components/mdx/Steps.astro +1 -5
  33. package/src/runtime/components/mdx/Tab.astro +6 -0
  34. package/src/runtime/components/mdx/Tabs.astro +7 -7
  35. package/src/runtime/lib/code-meta.js +8 -0
  36. package/src/runtime/lib/docs.js +141 -119
  37. package/src/runtime/lib/highlight.js +1 -14
  38. package/src/runtime/lib/html.js +9 -0
  39. package/src/runtime/lib/macros.js +10 -5
  40. package/src/runtime/lib/markdown-export.js +240 -169
  41. package/src/runtime/pages/doc.astro +1 -3
  42. package/src/runtime/pages/llms-full.txt.ts +2 -2
  43. package/src/runtime/pages/llms.txt.ts +2 -2
  44. package/src/runtime/pages/markdown.ts +2 -2
  45. package/src/runtime/pages/search-index.ts +12 -3
  46. package/CHANGELOG.md +0 -35
  47. package/src/css/overrides.css +0 -1
  48. package/src/css/sources.css +0 -1
  49. package/src/runtime/lib/markdown-exporters/index.js +0 -144
  50. package/src/runtime/lib/mdx-source.js +0 -19
  51. package/src/runtime/lib/preview-source-plugin.js +0 -33
  52. package/src/runtime/scripts/copy-code.js +0 -130
  53. package/src/site/ContentHeader.astro +0 -33
@@ -0,0 +1,150 @@
1
+ import { toMarkdown } from "mdast-util-to-markdown";
2
+ import { mdxToMarkdown } from "mdast-util-mdx";
3
+ import { parseCodeMeta } from "../runtime/lib/code-meta.js";
4
+
5
+ export function remarkPreviewSource({ docsDir } = {}) {
6
+ const normalizedDocsDir = docsDir ? normalizePath(docsDir).replace(/\/$/, "") : "";
7
+
8
+ return (tree, file) => {
9
+ if (normalizedDocsDir && !isDocsFile(file?.path, normalizedDocsDir)) return;
10
+
11
+ visit(tree, (node, parent, index) => {
12
+ if (node?.type === "code") return codeToMdx(node, parent, index);
13
+ if (node?.type !== "mdxJsxFlowElement") return null;
14
+ if (node.name === "Preview") {
15
+ addPreviewSource(node, file);
16
+ unwrapPreviewMarkdown(node);
17
+ }
18
+ if (node.name === "Tabs") addTabsMetadata(node);
19
+ return null;
20
+ });
21
+ };
22
+ }
23
+
24
+ function isDocsFile(filePath, docsDir) {
25
+ const normalized = normalizePath(filePath || "");
26
+ return normalized === docsDir || normalized.startsWith(`${docsDir}/`);
27
+ }
28
+
29
+ function normalizePath(value) {
30
+ return String(value || "").replaceAll("\\", "/");
31
+ }
32
+
33
+ function addPreviewSource(node, file) {
34
+ node.attributes ||= [];
35
+ if (hasAttr(node, "code")) return;
36
+
37
+ const source = formatPreviewSource(getPreviewSource(node, file) ?? toMarkdown({ type: "root", children: node.children || [] }, { extensions: [mdxToMarkdown()] }));
38
+ node.attributes.push({ type: "mdxJsxAttribute", name: "code", value: source });
39
+ }
40
+
41
+ function getPreviewSource(node, file) {
42
+ const value = String(file?.value || "");
43
+ const start = node?.position?.start?.offset;
44
+ const end = node?.position?.end?.offset;
45
+ if (!Number.isInteger(start) || !Number.isInteger(end) || end <= start) return null;
46
+
47
+ const raw = value.slice(start, end);
48
+ const openEnd = raw.indexOf(">");
49
+ const closeStart = raw.lastIndexOf("</Preview>");
50
+ if (openEnd === -1 || closeStart === -1 || closeStart <= openEnd) return null;
51
+
52
+ return raw.slice(openEnd + 1, closeStart);
53
+ }
54
+
55
+ function formatPreviewSource(source) {
56
+ return String(source || "").trim();
57
+ }
58
+
59
+ function codeToMdx(node, parent, index) {
60
+ if (!parent || !Number.isInteger(index)) return null;
61
+ const title = parseCodeMeta(node.meta).title;
62
+ if (!title) return null;
63
+
64
+ return {
65
+ type: "mdxJsxFlowElement",
66
+ name: "Code",
67
+ attributes: [
68
+ { type: "mdxJsxAttribute", name: "lang", value: node.lang || "text" },
69
+ { type: "mdxJsxAttribute", name: "title", value: title },
70
+ { type: "mdxJsxAttribute", name: "code", value: String(node.value || "") },
71
+ ],
72
+ children: [],
73
+ };
74
+ }
75
+
76
+ function unwrapPreviewMarkdown(node) {
77
+ if (!Array.isArray(node?.children)) return;
78
+
79
+ const preserveDirectParagraphs =
80
+ (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement") && node.name === "Step";
81
+ if (!preserveDirectParagraphs) {
82
+ node.children = node.children.flatMap((child) => (child?.type === "paragraph" ? child.children || [] : [child]));
83
+ }
84
+ for (const child of node.children) {
85
+ if (child?.type === "mdxJsxFlowElement" || child?.type === "mdxJsxTextElement") unwrapPreviewMarkdown(child);
86
+ }
87
+ }
88
+
89
+ function addTabsMetadata(node) {
90
+ node.attributes ||= [];
91
+ if (hasAttr(node, "tabs")) return;
92
+
93
+ const tabNodes = (node.children || []).filter((child) => child?.type === "mdxJsxFlowElement" && child.name === "Tab");
94
+ if (!tabNodes.length) return;
95
+
96
+ const seen = new Map();
97
+ const tabs = tabNodes.map((tab, index) => {
98
+ tab.attributes ||= [];
99
+ const title = getAttr(tab, "title") || `Tab ${index + 1}`;
100
+ const value = uniqueValue(slugify(title) || `tab-${index + 1}`, seen);
101
+ if (!hasAttr(tab, "slot")) {
102
+ tab.attributes.push({ type: "mdxJsxAttribute", name: "slot", value });
103
+ }
104
+ return {
105
+ label: title,
106
+ slot: value,
107
+ };
108
+ });
109
+
110
+ node.attributes.push({
111
+ type: "mdxJsxAttribute",
112
+ name: "tabs",
113
+ value: JSON.stringify(tabs),
114
+ });
115
+ }
116
+
117
+ function visit(node, visitor, parent = null, index = -1) {
118
+ const replacement = visitor(node, parent, index);
119
+ if (replacement && parent && Number.isInteger(index)) {
120
+ parent.children[index] = replacement;
121
+ node = replacement;
122
+ }
123
+ if (!Array.isArray(node?.children)) return;
124
+ for (let childIndex = 0; childIndex < node.children.length; childIndex += 1) {
125
+ visit(node.children[childIndex], visitor, node, childIndex);
126
+ }
127
+ }
128
+
129
+ function getAttr(node, name) {
130
+ const attr = (node.attributes || []).find((item) => item.type === "mdxJsxAttribute" && item.name === name);
131
+ return typeof attr?.value === "string" ? attr.value : "";
132
+ }
133
+
134
+ function hasAttr(node, name) {
135
+ return (node.attributes || []).some((item) => item.type === "mdxJsxAttribute" && item.name === name);
136
+ }
137
+
138
+ function slugify(value) {
139
+ return String(value || "")
140
+ .trim()
141
+ .toLowerCase()
142
+ .replace(/[^a-z0-9]+/g, "-")
143
+ .replace(/^-+|-+$/g, "");
144
+ }
145
+
146
+ function uniqueValue(value, seen) {
147
+ const count = seen.get(value) || 0;
148
+ seen.set(value, count + 1);
149
+ return count ? `${value}-${count + 1}` : value;
150
+ }
@@ -0,0 +1,62 @@
1
+ import rehypeParse from "rehype-parse";
2
+ import rehypeStringify from "rehype-stringify";
3
+ import { unified } from "unified";
4
+
5
+ const containerClass = ["table-container", "scrollbar", "my-6"];
6
+ const tableClass = ["table"];
7
+
8
+ export function rehypeBasecoatTables() {
9
+ return (tree) => {
10
+ transformTables(tree);
11
+ };
12
+ }
13
+
14
+ export async function transformBasecoatTablesHtml(html) {
15
+ const file = await unified()
16
+ .use(rehypeParse, { fragment: true })
17
+ .use(rehypeBasecoatTables)
18
+ .use(rehypeStringify)
19
+ .process(html);
20
+ return String(file);
21
+ }
22
+
23
+ function transformTables(parent) {
24
+ if (!Array.isArray(parent?.children)) return;
25
+
26
+ for (let index = 0; index < parent.children.length; index += 1) {
27
+ const child = parent.children[index];
28
+ if (isElement(child, "table")) {
29
+ addClass(child, tableClass);
30
+ if (isTableContainer(parent)) continue;
31
+ parent.children[index] = {
32
+ type: "element",
33
+ tagName: "div",
34
+ properties: { className: [...containerClass] },
35
+ children: [child],
36
+ };
37
+ continue;
38
+ }
39
+ transformTables(child);
40
+ }
41
+ }
42
+
43
+ function isElement(node, tagName) {
44
+ return node?.type === "element" && node.tagName === tagName;
45
+ }
46
+
47
+ function isTableContainer(node) {
48
+ return isElement(node, "div") && classList(node).includes("table-container");
49
+ }
50
+
51
+ function addClass(node, classes) {
52
+ const merged = new Set([...classList(node), ...classes]);
53
+ node.properties ||= {};
54
+ node.properties.className = [...merged];
55
+ }
56
+
57
+ function classList(node) {
58
+ const value = node?.properties?.className;
59
+ if (Array.isArray(value)) return value.map(String);
60
+ if (typeof value === "string") return value.split(/\s+/).filter(Boolean);
61
+ return [];
62
+ }
@@ -10,4 +10,5 @@ export { default as CodeGroup } from "../runtime/components/mdx/CodeGroup.astro"
10
10
  export { default as Preview } from "../runtime/components/mdx/Preview.astro";
11
11
  export { default as Step } from "../runtime/components/mdx/Step.astro";
12
12
  export { default as Steps } from "../runtime/components/mdx/Steps.astro";
13
+ export { default as Tab } from "../runtime/components/mdx/Tab.astro";
13
14
  export { default as Tabs } from "../runtime/components/mdx/Tabs.astro";
@@ -1,3 +1,5 @@
1
+ @source "../runtime/**/*.{astro,js,ts}";
2
+
1
3
  @theme {
2
4
  --color-search-highlight: oklch(90.5% 0.182 98.111);
3
5
  }
@@ -23,28 +25,29 @@
23
25
  > h1:first-child {
24
26
  @apply hidden;
25
27
  }
26
- > p > a,
27
- > blockquote a,
28
- > :is(ol, ul) a,
28
+ > p a,
29
+ > li a,
29
30
  > dl a,
30
- > table a {
31
+ > .table-container a,
32
+ [role="listitem"] > p > a,
33
+ [role="listitem"] > li > a {
31
34
  @apply underline underline-offset-2 decoration-muted-foreground/50 hover:decoration-foreground/50 transition-all;
32
35
  }
33
- > p code:not(pre > code),
34
- > blockquote code:not(pre > code),
35
- > :is(ol, ul) code:not(pre > code),
36
- > dl code:not(pre > code),
37
- > table code:not(pre > code) {
36
+ b,
37
+ strong {
38
+ @apply font-semibold;
39
+ }
40
+ code:not(pre > code) {
38
41
  @apply relative rounded-md bg-muted px-[0.3rem] py-[0.2rem] font-mono text-[13px];
39
42
  }
40
- > pre {
43
+ pre {
41
44
  @apply rounded-lg;
42
45
  }
43
- > pre > code {
46
+ pre > code {
44
47
  @apply block min-w-full w-max px-4 py-3 text-[13px];
45
48
  }
46
- > pre:has(> code) {
47
- @apply max-w-full overflow-x-auto;
49
+ pre:has(> code) {
50
+ @apply scrollbar max-w-full overflow-x-auto;
48
51
  }
49
52
  > blockquote {
50
53
  @apply border-l-4 border-border pl-4;
@@ -78,18 +81,6 @@
78
81
  @apply mt-4 border-b-0 pb-0 pl-8 my-0;
79
82
  }
80
83
  }
81
- > p b,
82
- > p strong,
83
- > blockquote b,
84
- > blockquote strong,
85
- > :is(ol, ul) b,
86
- > :is(ol, ul) strong,
87
- > dl b,
88
- > dl strong,
89
- > table b,
90
- > table strong {
91
- @apply font-semibold;
92
- }
93
84
  > p,
94
85
  > blockquote,
95
86
  > ul,
@@ -104,36 +95,21 @@
104
95
  > *:last-child {
105
96
  @apply !mb-0;
106
97
  }
107
- > table {
108
- @apply w-full caption-bottom text-sm;
109
- thead {
110
- @apply [&_tr]:border-b;
111
- }
112
- tbody {
113
- @apply [&_tr:last-child]:border-0;
114
- }
115
- tfoot {
116
- @apply bg-muted/50 border-t font-medium [&>tr]:last:border-b-0;
117
- }
118
- tr {
119
- @apply hover:bg-muted/50 border-b transition-colors;
120
- }
121
- th {
122
- @apply text-foreground h-10 px-2 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px];
123
- }
124
- td {
125
- @apply p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px];
126
- }
127
- caption {
128
- @apply text-muted-foreground mt-4 text-sm;
129
- }
98
+
99
+ > .table-container .table th,
100
+ > .table-container .table td {
101
+ @apply whitespace-normal;
130
102
  }
131
103
  }
132
104
 
133
105
  .shiki,
134
106
  .astro-code {
135
107
  @apply bg-muted/50;
136
- background-color: color-mix(in oklab, var(--color-muted) 50%, transparent) !important;
108
+ background-color: color-mix(
109
+ in oklab,
110
+ var(--color-muted) 50%,
111
+ transparent
112
+ ) !important;
137
113
  color: var(--shiki-light);
138
114
  }
139
115
 
@@ -152,22 +128,185 @@ html.dark .astro-code span {
152
128
  color: var(--shiki-dark);
153
129
  }
154
130
 
155
- #command-search > .command {
156
- @apply sm:max-w-2xl;
131
+ [data-search] .command a[role="menuitem"] {
132
+ @apply h-auto min-h-0 flex-col items-start gap-1 overflow-visible whitespace-normal py-2;
133
+ }
134
+
135
+ [data-search] .command a[role="menuitem"] > strong {
136
+ @apply w-full font-medium leading-5;
157
137
  }
158
138
 
159
- [data-search] .command a[role='menuitem'] {
160
- @apply flex-col items-start gap-1;
139
+ [data-search] .command a[role="menuitem"] > span {
140
+ @apply text-muted-foreground line-clamp-2 w-full text-sm font-normal leading-5;
161
141
  }
162
142
 
163
- [data-search] .command a[role='menuitem'] > strong {
143
+ .command mark {
144
+ @apply bg-search-highlight/50 text-foreground dark:bg-search-highlight/25;
145
+ }
146
+
147
+ .docs-card {
148
+ @apply block w-full rounded-lg border bg-card p-3 text-card-foreground no-underline;
149
+ }
150
+
151
+ .docs-card > h3 {
164
152
  @apply font-medium;
165
153
  }
166
154
 
167
- [data-search] .command a[role='menuitem'] > span {
168
- @apply text-muted-foreground line-clamp-2 text-xs font-normal leading-snug;
155
+ .docs-card > p {
156
+ @apply mt-1 text-sm text-muted-foreground;
169
157
  }
170
158
 
171
- .command mark {
172
- @apply bg-search-highlight/50 text-foreground rounded-sm px-0.5 dark:bg-search-highlight/25;
159
+ .docs-card-link {
160
+ @apply transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50;
161
+ }
162
+
163
+ .alert[data-variant="warning"] > svg,
164
+ .alert[data-variant="warning"] > h3,
165
+ .alert[data-variant="warning"] > section {
166
+ @apply text-amber-700 dark:text-amber-300;
167
+ }
168
+
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;
182
+ }
183
+
184
+ .code-frame > header::-webkit-scrollbar,
185
+ .tabs-frame > header::-webkit-scrollbar {
186
+ display: none;
187
+ }
188
+
189
+ .code-block {
190
+ @apply relative my-6 w-full max-w-full overflow-hidden rounded-lg;
191
+ }
192
+
193
+ .code-block > pre {
194
+ @apply scrollbar my-0 max-w-full overflow-x-auto rounded-none border-0;
195
+ }
196
+
197
+ .code-block > pre > code {
198
+ @apply block min-w-full w-max px-4 py-3 text-[13px];
199
+ }
200
+
201
+ .code-block > .shiki {
202
+ @apply my-0 rounded-none border-0;
203
+ }
204
+
205
+ .code-block > button {
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;
207
+ }
208
+
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];
212
+ }
213
+
214
+ .tabs-frame {
215
+ @apply overflow-visible;
216
+ }
217
+
218
+ .code-frame {
219
+ @apply overflow-hidden;
220
+ }
221
+
222
+ .tabs-frame > [role="tabpanel"] {
223
+ @apply rounded-b-[inherit];
224
+ }
225
+
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;
228
+ }
229
+
230
+ .steps {
231
+ @apply mb-12 mt-6 md:ml-4 md:border-l md:pl-8;
232
+ counter-reset: step;
233
+ }
234
+
235
+ .steps > section {
236
+ counter-increment: step;
237
+ }
238
+
239
+ .steps > section + section {
240
+ @apply mt-6;
241
+ }
242
+
243
+ .steps > section > h3 {
244
+ @apply relative mt-12 scroll-m-28 text-lg font-medium tracking-tight;
245
+ }
246
+
247
+ .steps > section + section > h3 {
248
+ @apply mt-0;
249
+ }
250
+
251
+ .steps > section:first-child > h3 {
252
+ @apply mt-0;
253
+ }
254
+
255
+ .steps > section > h3::before {
256
+ @apply mr-4 inline-flex size-7 items-center justify-center rounded-full bg-muted text-sm font-medium text-muted-foreground;
257
+ content: counter(step);
258
+ }
259
+
260
+ @media (width >= 48rem) {
261
+ .steps > section > h3::before {
262
+ position: absolute;
263
+ left: 0;
264
+ top: 0;
265
+ margin-right: 0;
266
+ transform: translateX(-2.875rem);
267
+ }
268
+ }
269
+
270
+ .steps > section > * + * {
271
+ @apply mt-3;
272
+ }
273
+
274
+ .steps > section > h3 + * {
275
+ @apply mt-2;
276
+ }
277
+
278
+ .steps > section > :where(.code-frame, .code-block, .tabs-frame) {
279
+ @apply my-3;
280
+ }
281
+
282
+ .steps > section > * {
283
+ @apply leading-relaxed;
284
+ }
285
+
286
+ .steps > section > *:first-child {
287
+ @apply mt-0;
288
+ }
289
+
290
+ .steps > section > *:last-child {
291
+ @apply mb-0;
292
+ }
293
+
294
+ .prose > .alert,
295
+ .prose > .docs-card,
296
+ .prose > .grid,
297
+ .prose > .tabs,
298
+ .prose > .tabs-frame {
299
+ @apply my-6;
300
+ }
301
+
302
+ .command [role="menu"][data-loading]::before {
303
+ content: none;
304
+ }
305
+
306
+ .command [role="menu"] > [data-rsd-command-loading] {
307
+ @apply flex min-h-16 items-center justify-center gap-2 py-6 text-center text-sm text-muted-foreground;
308
+
309
+ svg {
310
+ @apply size-4 animate-spin;
311
+ }
173
312
  }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-2xl;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[40px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-none;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[32px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-lg;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[40px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-lg;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[32px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-lg;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[36px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-2xl;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[36px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-none;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[40px];
9
+ }
@@ -0,0 +1,9 @@
1
+ .code-frame,
2
+ .code-block,
3
+ .tabs-frame {
4
+ @apply rounded-lg;
5
+ }
6
+
7
+ .code-frame > header {
8
+ @apply h-[40px];
9
+ }
@@ -1,6 +1,7 @@
1
1
  ---
2
- import "virtual:reallysimpledocs/styles.css";
3
2
  import config from "virtual:reallysimpledocs/config";
3
+ import Head from "virtual:reallysimpledocs/components/Head";
4
+ import DefaultHead from "./DefaultHead.astro";
4
5
  import { getSite } from "../lib/site.js";
5
6
 
6
7
  const { title, description, pagePath = "/" } = Astro.props;
@@ -22,33 +23,12 @@ const absoluteAssetUrl = (value) => {
22
23
  const path = assetPath(value);
23
24
  return path.startsWith("http") ? path : `${siteUrl}${path}`;
24
25
  };
26
+ const bodyAttrs = config.bodyAttrs || {};
25
27
  ---
26
28
 
27
29
  <!doctype html>
28
30
  <html lang="en">
29
31
  <head>
30
- <script is:inline>
31
- (() => {
32
- try {
33
- const stored = localStorage.getItem("themeMode");
34
- if (stored ? stored === "dark" : matchMedia("(prefers-color-scheme: dark)").matches) {
35
- document.documentElement.classList.add("dark");
36
- }
37
- } catch (_) {}
38
-
39
- const apply = (dark) => {
40
- document.documentElement.classList.toggle("dark", dark);
41
- try {
42
- localStorage.setItem("themeMode", dark ? "dark" : "light");
43
- } catch (_) {}
44
- };
45
-
46
- document.addEventListener("basecoat:theme", (event) => {
47
- const mode = event.detail?.mode;
48
- apply(mode === "dark" ? true : mode === "light" ? false : !document.documentElement.classList.contains("dark"));
49
- });
50
- })();
51
- </script>
52
32
  <meta charset="utf-8" />
53
33
  <meta http-equiv="Content-Language" content="en" />
54
34
  <meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -72,12 +52,26 @@ const absoluteAssetUrl = (value) => {
72
52
  <meta name="twitter:description" content={metaDescription} />
73
53
  {socialImage && <meta name="twitter:image" content={absoluteAssetUrl(socialImage)} />}
74
54
  {site.author?.x && <meta name="twitter:creator" content={site.author.x} />}
75
- <script>
76
- import "basecoat-css/all.min";
77
- import "../scripts/copy-code.js";
78
- </script>
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
+ />
79
73
  </head>
80
- <body>
74
+ <body {...bodyAttrs}>
81
75
  <slot />
82
76
  </body>
83
77
  </html>