-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New custom component for rendering the client outputs (#1818)
New features - Always show the typespec above - sync the tabs - just defining the code blocks without the extra `TabItem` <img width="790" alt="image" src="https://github.com/user-attachments/assets/3780ed65-5792-46d7-a524-c69ca5eaa59e">
- Loading branch information
1 parent
8c661a2
commit b255746
Showing
35 changed files
with
744 additions
and
1,366 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,7 @@ words: | |
- rpaasoneboxacr | ||
- rpass | ||
- SERVICERP | ||
- seti | ||
- tcgc | ||
- userrp | ||
- vnet | ||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
--- | ||
import type { Language } from "./process-client"; | ||
export interface Props { | ||
lang: Language; | ||
} | ||
if (!Astro.props.lang) { | ||
throw new Error("Missing required prop: lang"); | ||
} | ||
--- | ||
|
||
<client-tab-item data-language={Astro.props.lang}> | ||
<slot /> | ||
</client-tab-item> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
import { TabItem, Tabs } from "@astrojs/starlight/components"; | ||
import { processContent } from "./process-client.js"; | ||
const content = await Astro.slots.render("default"); | ||
const result = processContent(content); | ||
--- | ||
|
||
<Fragment set:html={result.typespec} /> | ||
|
||
<Tabs syncKey="client-outputs"> | ||
{ | ||
result.outputs.map((value) => { | ||
return ( | ||
<TabItem label={value.label} icon={value.icon as any}> | ||
<Fragment set:html={value.html} /> | ||
</TabItem> | ||
); | ||
}) | ||
} | ||
</Tabs> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { default as ClientTabItem } from "./client-tab-item.astro"; | ||
export { default as ClientTabs } from "./client-tabs.astro"; | ||
export type { Language } from "./process-client.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import type { Element, ElementContent } from "hast"; | ||
import { toHtml } from "hast-util-to-html"; | ||
import { rehype } from "rehype"; | ||
import { CONTINUE, EXIT, visit } from "unist-util-visit"; | ||
|
||
/** | ||
* Update this list to register a new language | ||
* For icons see https://starlight.astro.build/reference/icons/#all-icons | ||
*/ | ||
const KnownLanguages = { | ||
python: { | ||
label: "Python", | ||
icon: "seti:python", | ||
}, | ||
csharp: { | ||
label: "CSharp", | ||
icon: "seti:c-sharp", | ||
}, | ||
typescript: { | ||
label: "TypeScript", | ||
icon: "seti:typescript", | ||
}, | ||
java: { | ||
label: "Java", | ||
icon: "seti:java", | ||
}, | ||
go: { | ||
label: "Go", | ||
icon: "seti:go", | ||
}, | ||
tcgc: { | ||
label: "tcgc", | ||
icon: "seti:json", | ||
}, | ||
} as const; | ||
|
||
export type Language = keyof typeof KnownLanguages; | ||
|
||
function getLanguage(node: ElementContent): Language | "typespec" { | ||
const language = (node as any).properties.dataLanguage as string; | ||
if (!language) { | ||
throw new Error(`Missing language data code block: ${toHtml(node)}`); | ||
} | ||
if (language !== "typespec" && !KnownLanguages[language as Language]) { | ||
throw new Error(`Unknown language '${language}' used in code block in <ClientTabs>`); | ||
} | ||
|
||
return language as any; | ||
} | ||
|
||
function getLanguageForCodeBlock(el: ElementContent): Language | "typespec" { | ||
let resolved; | ||
visit(el, "element", (node) => { | ||
if (node.tagName !== "pre" || !node.properties) { | ||
return CONTINUE; | ||
} | ||
const language = node.properties.dataLanguage as string; | ||
if (!language) { | ||
throw new Error("Missing language code code block"); | ||
} | ||
if (language !== "typespec" && !KnownLanguages[language as Language]) { | ||
throw new Error(`Unknown language '${language}' used in code block in <ClientTabs>`); | ||
} | ||
|
||
resolved = language; | ||
return EXIT; | ||
}); | ||
if (!resolved) { | ||
throw new Error("Couldn't find language"); | ||
} | ||
return resolved; | ||
} | ||
|
||
const tabsProcessor = rehype() | ||
.data("settings", { fragment: true }) | ||
.use(() => { | ||
return (tree: Element, file) => { | ||
const results: any[] = (file.data.results = []); | ||
for (const item of tree.children) { | ||
if (item.type === "element" && item.tagName === "client-tab-item") { | ||
const language = getLanguage(item); | ||
results.push({ language, html: toHtml(item.children) }); | ||
} else if ( | ||
item.type === "element" && | ||
(item.properties.className as any)?.includes("expressive-code") | ||
) { | ||
const language = getLanguageForCodeBlock(item); | ||
results.push({ language, html: toHtml(item) }); | ||
} else { | ||
throw new Error( | ||
`Unexpected item should only have code blocks or ClientTabItem but got:\n${toHtml(item)}`, | ||
); | ||
} | ||
} | ||
}; | ||
}); | ||
|
||
export interface Result { | ||
typespec: string; | ||
outputs: Array<{ | ||
language: Language; | ||
label: string; | ||
icon?: string; | ||
html: string; | ||
}>; | ||
} | ||
export function processContent(html: string): Result { | ||
const file = tabsProcessor.processSync({ value: html }); | ||
const codeBlocks = file.data.results as any[]; | ||
let typespec; | ||
const outputs: Result["outputs"] = []; | ||
for (const item of codeBlocks) { | ||
if (item.language === "typespec") { | ||
typespec = item.html; | ||
} else { | ||
outputs.push({ | ||
language: item.language as any, | ||
label: KnownLanguages[item.language as Language].label, | ||
icon: KnownLanguages[item.language as Language].icon, | ||
html: item.html, | ||
}); | ||
} | ||
} | ||
if (typespec === undefined) { | ||
throw new Error("Missing typespec code block"); | ||
} | ||
|
||
return { typespec, outputs }; | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.