From fa9f3c72eb7beafc63f3ed271dfa4ecae3383b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 15 Jun 2026 22:45:46 +0200 Subject: [PATCH] docs: show difficulty on example cards Surface each example's difficulty (beginner/intermediate/advanced, from the script's @difficulty tag) as a small colored dot on the landing page cards, wired through the same generator path as the descriptions. Only examples declare a difficulty, so tutorials and videos stay unbadged. --- _components/LandingPage.tsx | 6 +++++- examples/_components/LearningList.tsx | 20 ++++++++++++++++++++ examples/index.page.tsx | 13 ++++++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/_components/LandingPage.tsx b/_components/LandingPage.tsx index 022e1d454..9f808e226 100644 --- a/_components/LandingPage.tsx +++ b/_components/LandingPage.tsx @@ -27,7 +27,10 @@ function FeaturedStar() { } export default function LandingPage( - { descriptions }: { descriptions?: Record }, + { descriptions, difficulties }: { + descriptions?: Record; + difficulties?: Record; + }, ) { const counts = { example: 0, tutorial: 0, video: 0 }; for (const category of sidebar) { @@ -43,6 +46,7 @@ export default function LandingPage( title={item.title} items={item.items} descriptions={descriptions} + difficulties={difficulties} isReference={cookbookCategories.includes(item.title)} /> ); diff --git a/examples/_components/LearningList.tsx b/examples/_components/LearningList.tsx index d38970d6d..0397cb51a 100644 --- a/examples/_components/LearningList.tsx +++ b/examples/_components/LearningList.tsx @@ -14,11 +14,18 @@ export function TypeIcon({ type }: { type: string }) { } } +const difficultyDot: Record = { + beginner: "bg-green-500", + intermediate: "bg-yellow-500", + advanced: "bg-red-500", +}; + export function LearningList( props: { title: string; items: SidebarItem[]; descriptions?: Record; + difficulties?: Record; isReference?: boolean; }, ) { @@ -41,6 +48,7 @@ export function LearningList(
    {props.items.map((item) => { const description = props.descriptions?.[item.href]; + const difficulty = props.difficulties?.[item.href]; return (
  • )} + {difficulty && ( + + + {difficulty} + + )}
  • ); diff --git a/examples/index.page.tsx b/examples/index.page.tsx index 76b3d59e5..21be22b9b 100644 --- a/examples/index.page.tsx +++ b/examples/index.page.tsx @@ -38,6 +38,9 @@ export default function* ( // One-sentence description per item href, sourced from the example // scripts' doc comments and the tutorial/video pages' frontmatter. const descriptions: Record = {}; + // Difficulty per example href, from the script's @difficulty tag. Only + // examples declare one; tutorials and videos are left without a badge. + const difficulties: Record = {}; for (const file of walkSync("./examples/scripts/", { exts: [".ts"] })) { const content = Deno.readTextFileSync(file.path); @@ -47,6 +50,9 @@ export default function* ( if (description) { descriptions[`/examples/${label}/`] = description; } + if (parsed.difficulty) { + difficulties[`/examples/${label}/`] = parsed.difficulty; + } } for (const page of data.search.pages("url^=/examples/")) { @@ -59,6 +65,11 @@ export default function* ( yield { url: `/examples/`, title: `Deno examples and tutorials`, - content: , + content: ( + + ), }; }