Skip to content

Commit 1d1777c

Browse files
committed
docs: convert to TypeScript
1 parent eb898a6 commit 1d1777c

21 files changed

Lines changed: 198 additions & 164 deletions

docs/bun.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@
2424
</script>
2525
</head>
2626
<body>
27-
<script type="module" src="/src/index.js"></script>
27+
<script type="module" src="/src/index.ts"></script>
2828
</body>
2929
</html>

docs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"preview": "vite preview"
1212
},
1313
"devDependencies": {
14+
"@types/prismjs": "^1.26.5",
1415
"@roxi/routify": "^3.6.4",
1516
"@sveltejs/vite-plugin-svelte": "^7.0.0",
1617
"carbon-icons-svelte": "^13.3.0",

docs/scripts/generate-md-docs.ts

Lines changed: 53 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,13 @@ const AT_EXAMPLE_RE = /@example/;
9797
const SVELTE_FENCE_RE = /```svelte\s*\n([\s\S]*?)```/;
9898
const ATX_HEADING_RE = /^(#{1,6})(\s+)(.*)$/;
9999

100-
/**
101-
* @param {string} source
102-
*/
103-
function splitFrontmatter(source) {
100+
function splitFrontmatter(source: string) {
104101
const match = source.match(FRONTMATTER_RE);
105102
if (!match) return { frontmatter: null, body: source };
106103
return { frontmatter: match[1], body: source.slice(match[0].length) };
107104
}
108105

109-
/**
110-
* Extract component names from a `components: [...]` YAML flow sequence.
111-
*
112-
* @param {string | null} frontmatter
113-
* @returns {string[]}
114-
*/
115-
function extractComponents(frontmatter) {
106+
function extractComponents(frontmatter: string | null) {
116107
if (!frontmatter) return [];
117108

118109
const keyIdx = frontmatter.search(COMPONENTS_KEY_RE);
@@ -147,34 +138,23 @@ function extractComponents(frontmatter) {
147138
return out;
148139
}
149140

150-
/**
151-
* @param {string} text
152-
*/
153-
function escapeTableCell(text) {
141+
function escapeTableCell(text: unknown) {
154142
return String(text ?? "")
155143
.replace(PIPE_RE, "\\|")
156144
.replace(NEWLINE_RE, "<br />")
157145
.trim();
158146
}
159147

160-
/**
161-
* @param {string[]} headers
162-
* @param {string[][]} rows
163-
*/
164-
function renderMarkdownTable(headers, rows) {
148+
function renderMarkdownTable(headers: string[], rows: string[][]) {
165149
const headerLine = `| ${headers.map(escapeTableCell).join(" | ")} |`;
166150
const sepLine = `| ${headers.map(() => "---").join(" | ")} |`;
167151
const rowLines = rows.map(
168-
(cells) => `| ${cells.map(escapeTableCell).join(" | ")} |`,
152+
(cells: string[]) => `| ${cells.map(escapeTableCell).join(" | ")} |`,
169153
);
170154
return [headerLine, sepLine, ...rowLines].join("\n");
171155
}
172156

173-
/**
174-
* @param {string} description
175-
* @returns {{ mainDescription: string; exampleCode: string | null }}
176-
*/
177-
function parseDescription(description) {
157+
function parseDescription(description: string) {
178158
if (!description) return { mainDescription: "", exampleCode: null };
179159

180160
const exampleIndex = description.search(AT_EXAMPLE_RE);
@@ -190,11 +170,10 @@ function parseDescription(description) {
190170
return { mainDescription, exampleCode };
191171
}
192172

193-
/**
194-
* @param {any} component
195-
* @param {string} componentName
196-
*/
197-
function renderPropsSection(component, componentName) {
173+
function renderPropsSection(
174+
component: ComponentApiEntry,
175+
componentName: string,
176+
) {
198177
const props = Array.isArray(component.props) ? component.props : [];
199178
if (props.length === 0) return "";
200179

@@ -236,16 +215,15 @@ function renderPropsSection(component, componentName) {
236215
)}`;
237216
}
238217

239-
/**
240-
* @param {any} component
241-
* @param {string} componentName
242-
*/
243-
function renderTypedefsSection(component, componentName) {
218+
function renderTypedefsSection(
219+
component: ComponentApiEntry,
220+
componentName: string,
221+
) {
244222
const typedefs = Array.isArray(component.typedefs) ? component.typedefs : [];
245223
if (typedefs.length === 0) return "";
246224

247225
const ts = typedefs
248-
.map((t) => t?.ts)
226+
.map((t: ComponentApiTypedef) => t?.ts)
249227
.filter(Boolean)
250228
.join("\n")
251229
.trim();
@@ -255,15 +233,14 @@ function renderTypedefsSection(component, componentName) {
255233
return `### \`${componentName}\` typedefs\n\n\`\`\`ts\n${ts}\n\`\`\``;
256234
}
257235

258-
/**
259-
* @param {any} component
260-
* @param {string} componentName
261-
*/
262-
function renderSlotsSection(component, componentName) {
236+
function renderSlotsSection(
237+
component: ComponentApiEntry,
238+
componentName: string,
239+
) {
263240
const slots = Array.isArray(component.slots) ? component.slots : [];
264241
if (slots.length === 0) return "";
265242

266-
const rows = slots.map((slot) => {
243+
const rows = slots.map((slot: ComponentApiSlot) => {
267244
const name =
268245
slot?.default || slot?.name == null ? "default" : String(slot.name);
269246
const detail = slot?.slot_props ? String(slot.slot_props) : "";
@@ -273,14 +250,17 @@ function renderSlotsSection(component, componentName) {
273250
return `### \`${componentName}\` slots\n\n${renderMarkdownTable(["Slot", "Detail"], rows)}`;
274251
}
275252

276-
/**
277-
* @param {any} component
278-
* @param {string} componentName
279-
*/
280-
function renderEventsSection(component, componentName) {
253+
function renderEventsSection(
254+
component: ComponentApiEntry,
255+
componentName: string,
256+
) {
281257
const events = Array.isArray(component.events) ? component.events : [];
282-
const forwarded = events.filter((e) => e?.type === "forwarded");
283-
const dispatched = events.filter((e) => e?.type === "dispatched");
258+
const forwarded = events.filter(
259+
(e: ComponentApiEvent) => e?.type === "forwarded",
260+
);
261+
const dispatched = events.filter(
262+
(e: ComponentApiEvent) => e?.type === "dispatched",
263+
);
284264

285265
if (forwarded.length === 0 && dispatched.length === 0) return "";
286266

@@ -289,18 +269,20 @@ function renderEventsSection(component, componentName) {
289269
? ""
290270
: `### \`${componentName}\` forwarded events\n\n${renderMarkdownTable(
291271
["Event"],
292-
forwarded.map((e) => [`\`on:${e.name}\``]),
272+
forwarded.map((e: ComponentApiEvent) => [`\`on:${e.name}\``]),
293273
)}`;
294274

295-
const hasDispatchedDescription = dispatched.some((e) => e?.description);
275+
const hasDispatchedDescription = dispatched.some(
276+
(e: ComponentApiEvent) => e?.description,
277+
);
296278
const dispatchedHeaders = hasDispatchedDescription
297279
? ["Event", "Detail", "Description"]
298280
: ["Event", "Detail"];
299281

300282
const dispatchedRows =
301283
dispatched.length === 0
302284
? null
303-
: dispatched.map((e) => {
285+
: dispatched.map((e: ComponentApiEvent) => {
304286
const base = [
305287
`\`on:${e.name}\``,
306288
e.detail ? `\`${String(e.detail)}\`` : "",
@@ -321,11 +303,10 @@ function renderEventsSection(component, componentName) {
321303
return sections.join("\n\n");
322304
}
323305

324-
/**
325-
* @param {any} component
326-
* @param {string} componentName
327-
*/
328-
function renderRestPropsSection(component, componentName) {
306+
function renderRestPropsSection(
307+
component: ComponentApiEntry,
308+
componentName: string,
309+
) {
329310
const rest = component?.rest_props;
330311
if (!rest) return "";
331312

@@ -336,10 +317,7 @@ function renderRestPropsSection(component, componentName) {
336317
return `### \`${componentName}\` $$restProps\n\n\`${component.moduleName}\` spreads \`$$restProps\` to the \`${rest.name}\` component.`;
337318
}
338319

339-
/**
340-
* @param {string} moduleName
341-
*/
342-
function renderComponentApiMarkdown(moduleName) {
320+
function renderComponentApiMarkdown(moduleName: string) {
343321
const entry = componentApiByModuleName.get(moduleName);
344322
if (!entry) {
345323
throw new Error(`API data not found for component: ${moduleName}`);
@@ -356,15 +334,12 @@ function renderComponentApiMarkdown(moduleName) {
356334
return sections.join("\n\n");
357335
}
358336

359-
/**
360-
* @param {string} body
361-
*/
362-
function inlineFileSources(body) {
337+
function inlineFileSources(body: string) {
363338
const lines = body.split("\n");
364339
const out: string[] = [];
365340

366341
let inFence = false;
367-
const isFence = (line) => line.trimStart().startsWith("```");
342+
const isFence = (line: string) => line.trimStart().startsWith("```");
368343

369344
for (const line of lines) {
370345
if (isFence(line)) {
@@ -489,24 +464,18 @@ function injectImportsIntoSvelteSnippet(code: string): string {
489464
return scriptLines.join("\n") + code.trimStart();
490465
}
491466

492-
/**
493-
* @param {string} body
494-
*/
495-
function fenceInlineSvelte(body) {
467+
function fenceInlineSvelte(body: string) {
496468
const lines = body.split("\n");
497469
const out: string[] = [];
498470

499471
let inCodeFence = false;
500472
let inSvelteFence = false;
501473
let tagDepth = 0;
502474

503-
const isFence = (line) => line.trimStart().startsWith("```");
504-
const isTagLine = (line) => TAG_LINE_RE.test(line);
475+
const isFence = (line: string) => line.trimStart().startsWith("```");
476+
const isTagLine = (line: string) => TAG_LINE_RE.test(line);
505477

506-
/**
507-
* @param {string} line
508-
*/
509-
const applyTagDepth = (line) => {
478+
const applyTagDepth = (line: string) => {
510479
HTML_TAG_RE.lastIndex = 0;
511480
let m = HTML_TAG_RE.exec(line);
512481
while (m) {
@@ -561,9 +530,6 @@ function fenceInlineSvelte(body) {
561530
return out.join("\n");
562531
}
563532

564-
/**
565-
* @param {string} markdown
566-
*/
567533
type MdChunk =
568534
| { type: "line"; line: string }
569535
| {
@@ -574,11 +540,11 @@ type MdChunk =
574540
code: string;
575541
};
576542

577-
async function formatSvelteFences(markdown) {
543+
async function formatSvelteFences(markdown: string) {
578544
const lines = markdown.split("\n");
579545

580546
const chunks: MdChunk[] = [];
581-
const isFenceLine = (line) => line.trimStart().startsWith("```");
547+
const isFenceLine = (line: string) => line.trimStart().startsWith("```");
582548

583549
for (let i = 0; i < lines.length; i++) {
584550
const line = lines[i];
@@ -659,10 +625,7 @@ async function formatSvelteFences(markdown) {
659625
return out.join("\n");
660626
}
661627

662-
/**
663-
* @param {string} markdown
664-
*/
665-
async function formatMarkdown(markdown) {
628+
async function formatMarkdown(markdown: string) {
666629
try {
667630
const formatted = await prettierFormat(markdown, {
668631
parser: "markdown",
@@ -675,18 +638,13 @@ async function formatMarkdown(markdown) {
675638
}
676639
}
677640

678-
/**
679-
* Increase every ATX heading by one level. Does not change lines inside fenced code blocks.
680-
* @param {string} md
681-
* @returns {string}
682-
*/
683-
function shiftMarkdownHeadings(md) {
641+
function shiftMarkdownHeadings(md: string) {
684642
const lines = md.split("\n");
685643
let inFence = false;
686-
const isFence = (line) => line.trimStart().startsWith("```");
644+
const isFence = (line: string) => line.trimStart().startsWith("```");
687645

688646
return lines
689-
.map((line) => {
647+
.map((line: string) => {
690648
if (isFence(line)) {
691649
inFence = !inFence;
692650
return line;
@@ -698,12 +656,7 @@ function shiftMarkdownHeadings(md) {
698656
.join("\n");
699657
}
700658

701-
/**
702-
* Generate llm.txt content from component list
703-
* @param {string[]} componentNames
704-
* @returns {string}
705-
*/
706-
function generateLlmTxt(componentNames) {
659+
function generateLlmTxt(componentNames: string[]) {
707660
const sorted = [...componentNames].sort();
708661
const links = sorted.map(
709662
(name) => `- [${name}](${BASE_URL}/components/${name}.md)`,

docs/src/App.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<script context="module">
1+
<script lang="ts" context="module">
22
import { createRouter, Router } from "@roxi/routify";
33
import routes from "../.routify/routes.default.js";
44

0 commit comments

Comments
 (0)