Skip to content

Commit ab26f9c

Browse files
Merge branch 'main' into exports_field
2 parents 85347ab + 1cc8904 commit ab26f9c

6 files changed

Lines changed: 144 additions & 89 deletions

File tree

_components/Breadcrumbs.tsx

Lines changed: 101 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,143 @@
11
import type { Sidebar as Sidebar_, SidebarItem } from "../types.ts";
22

3-
function generateCrumbs(
3+
function buildBreadcrumbPath(
44
url: string,
55
title: string,
66
items: SidebarItem[],
7-
current: SidebarItem[] = [],
8-
): SidebarItem[] {
7+
breadcrumbPath: SidebarItem[] = [],
8+
): SidebarItem[] | null {
99
for (const item of items) {
10-
const foundTargetPage = item.href === url;
11-
12-
if (foundTargetPage) {
13-
current.push({ title: title });
14-
return current;
10+
// Check if this is the target page
11+
if (item.href === url) {
12+
return [...breadcrumbPath, { title }];
1513
}
1614

17-
if (item.items) {
18-
const childItems: SidebarItem[] = [];
19-
generateCrumbs(url, title, item.items, childItems);
15+
// If item has children, search recursively
16+
if (item.items && item.items.length > 0) {
17+
const childPath = buildBreadcrumbPath(
18+
url,
19+
title,
20+
item.items,
21+
[...breadcrumbPath, { title: item.title, href: item.href }],
22+
);
2023

21-
if (childItems.length > 0) {
22-
if (item.href) {
23-
current.push({ title: item.title, href: item.href });
24-
}
25-
current.push(...childItems);
26-
return current;
24+
if (childPath) {
25+
return childPath;
2726
}
2827
}
2928
}
3029

31-
return current;
30+
return null;
3231
}
3332

34-
export default function (props: {
33+
export default function Breadcrumbs(props: {
3534
title: string;
3635
sidebar: Sidebar_;
3736
url: string;
38-
sectionTitle: string;
39-
sectionHref: string;
40-
}, helpers: Lume.Helpers) {
41-
const crumbs: SidebarItem[] = [];
37+
}) {
38+
let breadcrumbs: SidebarItem[] = [];
39+
40+
// Extract the top-level section from the URL (e.g., "runtime", "deploy")
41+
const topLevelSection = props.url.split("/").filter(Boolean)[0];
4242

43+
// Define section name mappings for better display
44+
const sectionNames: Record<string, string> = {
45+
"runtime": "Runtime",
46+
"services": "Services",
47+
"deploy": "Deploy",
48+
"subhosting": "Subhosting",
49+
"examples": "Examples",
50+
"lint": "Lint",
51+
"api": "API Reference",
52+
};
53+
54+
// Search through all sidebar sections to find the breadcrumb path
4355
for (const section of props.sidebar) {
56+
// Check if the current URL is a top-level section
4457
if (section.href === props.url) {
45-
crumbs.push({ title: props.title });
58+
// If this page IS the section, just show the page title
59+
breadcrumbs = [{ title: props.title }];
4660
break;
4761
}
4862

49-
const rootItem = { title: section.title, href: section.href };
50-
const potentialCrumbs = generateCrumbs(
51-
props.url,
52-
props.title,
53-
section?.items || [],
54-
[rootItem],
55-
);
63+
// Search within section items if they exist
64+
if (section.items) {
65+
const foundPath = buildBreadcrumbPath(
66+
props.url,
67+
props.title,
68+
section.items,
69+
[], // Start with empty path, we'll add section as base
70+
);
5671

57-
if (potentialCrumbs.length > 1) {
58-
crumbs.push(...potentialCrumbs);
59-
break;
72+
if (foundPath) {
73+
// Add the top-level section as the base breadcrumb
74+
const sectionDisplayName = sectionNames[topLevelSection] ||
75+
(topLevelSection?.charAt(0).toUpperCase() +
76+
topLevelSection?.slice(1)) ||
77+
"Docs";
78+
79+
breadcrumbs = [
80+
{ title: sectionDisplayName, href: `/${topLevelSection}/` },
81+
...foundPath,
82+
];
83+
break;
84+
}
6085
}
6186
}
6287

88+
// If no breadcrumbs found, just show the current page title
89+
if (breadcrumbs.length === 0) {
90+
breadcrumbs = [{ title: props.title }];
91+
}
92+
6393
const linkClasses =
64-
`flex items-center pl-3 py-1.5 underline underline-offset-4 decoration-foreground-tertiary hover:text-foreground-secondary hover:underline-medium hover:bg-foreground-quaternary dark:hover:bg-background-secondary dark:hover:text-foreground-primary rounded transition duration-100 text-xs`;
94+
"flex items-center pl-3 py-1.5 underline underline-offset-4 decoration-foreground-tertiary hover:text-foreground-secondary hover:underline-medium hover:bg-foreground-quaternary dark:hover:bg-background-secondary dark:hover:text-foreground-primary rounded transition duration-100 text-xs";
6595

6696
const chevronClasses =
67-
`after:w-4 after:h-4 after:[background:url(./img/chevron.svg)_no-repeat_center] after:inline-block after:ml-2`;
97+
"after:w-4 after:h-4 after:[background:url(./img/chevron.svg)_no-repeat_center] after:inline-block after:ml-2";
6898

6999
return (
70100
<nav>
71101
<ul
72-
class="flex flex- items-center text-center mt-2 -ml-3 text-foreground-secondary sm:mt-4"
102+
class="flex items-center text-center mt-2 -ml-3 text-foreground-secondary sm:mt-4"
73103
itemscope
74104
itemtype="https://schema.org/BreadcrumbList"
75105
>
76-
<li
77-
itemprop="itemListElement"
78-
itemscope
79-
itemtype="https://schema.org/ListItem"
80-
>
81-
<a
82-
class={`${linkClasses} ${chevronClasses}`}
83-
itemprop="item"
84-
href={props.sectionHref}
106+
{breadcrumbs.map((crumb, i) => (
107+
<li
108+
key={i}
109+
itemprop="itemListElement"
110+
itemscope
111+
itemtype="https://schema.org/ListItem"
85112
>
86-
<span
87-
itemprop="name"
88-
dangerouslySetInnerHTML={{ __html: props.sectionTitle }}
89-
/>
90-
</a>
91-
<meta itemprop="position" content="1" />
92-
</li>
93-
{crumbs.map((crumb, i) => (
94-
<>
95-
<li
96-
itemprop="itemListElement"
97-
itemscope
98-
itemtype="https://schema.org/ListItem"
99-
>
100-
{crumb.href
101-
? (
102-
<a
103-
href={crumb.href}
104-
itemprop="item"
105-
class={`${linkClasses} ${chevronClasses}`}
106-
>
107-
<span itemprop="name">{crumb.title}</span>
108-
</a>
109-
)
110-
: (
111-
<span
112-
itemprop="name"
113-
class={`flex items-center pl-2 py-1.5 text-xs ${
114-
i < crumbs.length - 1 ? chevronClasses : ""
115-
}`}
116-
dangerouslySetInnerHTML={{
117-
__html: helpers.md(crumb.title, true),
118-
}}
119-
/>
120-
)}
121-
<meta itemprop="position" content={String(i + 2)} />
122-
</li>
123-
</>
113+
{crumb.href
114+
? (
115+
<a
116+
href={crumb.href}
117+
itemprop="item"
118+
class={`${linkClasses} ${
119+
i < breadcrumbs.length - 1 ? chevronClasses : ""
120+
}`}
121+
>
122+
<span itemprop="name">
123+
{typeof crumb.title === "string"
124+
? crumb.title
125+
: crumb.title}
126+
</span>
127+
</a>
128+
)
129+
: (
130+
<span
131+
itemprop="name"
132+
class={`flex items-center pl-2 py-1.5 text-xs ${
133+
i < breadcrumbs.length - 1 ? chevronClasses : ""
134+
}`}
135+
>
136+
{typeof crumb.title === "string" ? crumb.title : crumb.title}
137+
</span>
138+
)}
139+
<meta itemprop="position" content={String(i + 1)} />
140+
</li>
124141
))}
125142
</ul>
126143
</nav>

_includes/doc.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ export default function Doc(data: Lume.Data, helpers: Lume.Helpers) {
4141
title={data.title!}
4242
sidebar={sidebar}
4343
url={data.url}
44-
sectionTitle={data.sectionTitle!}
45-
sectionHref={data.sectionHref!}
4644
/>
4745
)}
4846

deno.lock

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

examples/tutorials/nuxt.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ display a list of dinosaurs and allow you to learn more about each one when you
1515
click on the name.
1616

1717
You can see the
18-
[finished app on GitHub](https://github.com/denoland/tutorial-with-nuxt).
18+
[finished app on GitHub](https://github.com/denoland/examples/tree/main/with-nuxt).
1919

2020
You can see a
21-
[live version of the app on Deno Deploy](https://tutorial-with-nuxt.deno.deno.net/).
21+
[live version of the app on Deno Deploy](https://example-with-nuxt.deno.deno.net/).
2222

2323
:::info Deploy your own
2424

@@ -27,7 +27,7 @@ button below to instantly deploy your own copy of the complete Nuxt dinosaur app
2727
to Deno Deploy. You'll get a live, working application that you can customize
2828
and modify as you learn!
2929

30-
[![Deploy on Deno](https://deno.com/button)](https://app.deno.com/new?clone=https://github.com/denoland/tutorial-with-nuxt)
30+
[![Deploy on Deno](https://deno.com/button)](https://app.deno.com/new?clone=https://github.com/denoland/examples&path=with-nuxt)
3131

3232
:::
3333

runtime/fundamentals/web_dev.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ applications, making your web dev a delightful experience.
1919
that includes modules for common tasks like HTTP servers, file system
2020
operations, and more.
2121

22+
For your vanilla TypeScript, or JavaScript, web applications, you can use the
23+
built-in Deno [HTTP server](/runtime/fundamentals/http_server/). This is a great
24+
way to get started with Deno and build simple web applications without any
25+
additional dependencies.
26+
2227
Most likely, if you're building a more complex application, you'll be
2328
interacting with Deno through a web framework.
2429

styles.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,17 @@ main:has(#example:checked) {
866866

867867
.layout--two-column {
868868
grid-template-columns: minmax(12rem, 1fr) minmax(24rem, 3fr);
869+
870+
@media (min-width: 64rem) {
871+
grid-template-columns:
872+
minmax(12rem, 1fr) minmax(24rem, 3fr) minmax(12rem, 1fr);
873+
}
874+
875+
.content {
876+
@media (min-width: 64rem) {
877+
grid-column: 2 / 4;
878+
}
879+
}
869880
}
870881

871882
.layout:has(.raw-container) {

0 commit comments

Comments
 (0)