Skip to content

Commit

Permalink
feat: support navbar dropdown button (dotnet#8694)
Browse files Browse the repository at this point in the history
  • Loading branch information
yufeih authored and p-kostov committed Jun 28, 2024
1 parent ab8ded8 commit 3783892
Show file tree
Hide file tree
Showing 41 changed files with 199 additions and 139 deletions.
8 changes: 5 additions & 3 deletions samples/seed/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
- name: Articles
href: articles/
- name: API Documentation
href: obj/api/
- name: REST API
href: restapi/
items:
- name: .NET API
href: obj/api/
- name: REST API
href: restapi/
40 changes: 32 additions & 8 deletions templates/modern/src/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ export type NavItem = {
href: URL
}

export type NavItemContainer = {
name: string
items: NavItem[]
}

/**
* @returns active navbar items
*/
Expand All @@ -23,13 +28,27 @@ export async function renderNavbar(): Promise<NavItem[]> {
const navItems = await loadNavItems()
const activeItem = findActiveItem(navItems)

const menuItem = item => {
const current = (item === activeItem ? 'page' : false)
const active = (item === activeItem ? 'active' : null)
return html`<li class='nav-item'><a class='nav-link ${active}' aria-current=${current} href=${item.href}>${breakWordLit(item.name)}</a></li>`
}

const menu = html`
<ul class='navbar-nav'>${
navItems.map(item => {
const current = (item === activeItem ? 'page' : false)
const active = (item === activeItem ? 'active' : null)
return html`
<li class='nav-item'><a class='nav-link ${active}' aria-current=${current} href=${item.href}>${breakWordLit(item.name)}</a></li>`
if ('items' in item) {
const active = item.items.some(i => i === activeItem) ? 'active' : null
return html`
<li class='nav-item dropdown'>
<a class='nav-link dropdown-toggle ${active}' href='#' role='button' data-bs-toggle='dropdown' aria-expanded='false'>
${breakWordLit(item.name)}
</a>
<ul class='dropdown-menu'>${item.items.map(menuItem)}</ul>
</li>`
} else {
return menuItem(item)
}
})
}</ul>`

Expand All @@ -43,15 +62,20 @@ export async function renderNavbar(): Promise<NavItem[]> {

return activeItem ? [activeItem] : []

async function loadNavItems(): Promise<NavItem[]> {
async function loadNavItems(): Promise<(NavItem | NavItemContainer)[]> {
const navrel = meta('docfx:navrel')
if (!navrel) {
return []
}

const navUrl = new URL(navrel.replace(/.html$/gi, '.json'), window.location.href)
const { items } = await fetch(navUrl).then(res => res.json())
return items.map(a => ({ name: a.name, href: new URL(a.href, navUrl) }))
return items.map((a: NavItem | NavItemContainer) => {
if ('items' in a) {
return { name: a.name, items: a.items.map(i => ({ name: i.name, href: new URL(i.href, navUrl) })) }
}
return { name: a.name, href: new URL(a.href, navUrl) }
})
}

function githubLink() {
Expand Down Expand Up @@ -113,11 +137,11 @@ function inThisArticleForManagedReference(): TemplateResult {
}
}

function findActiveItem(items: NavItem[]): NavItem {
function findActiveItem(items: (NavItem | NavItemContainer)[]): NavItem {
const url = new URL(window.location.href)
let activeItem: NavItem
let maxPrefix = 0
for (const item of items) {
for (const item of items.map(i => 'items' in i ? i.items : i).flat()) {
const prefix = commonUrlPrefix(url, item.href)
if (prefix > maxPrefix) {
maxPrefix = prefix
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,30 @@
},
{
"name": "API Documentation",
"href": "api/BuildFromAssembly.html",
"tocHref": "api/toc.html",
"topicHref": "api/BuildFromAssembly.html",
"topicUid": "BuildFromAssembly",
"level": 2.0,
"items": [],
"leaf": true
},
{
"name": "REST API",
"href": "restapi/petstore.html",
"tocHref": "restapi/toc.html",
"topicHref": "restapi/petstore.html",
"level": 2.0,
"items": [],
"leaf": true
"items": [
{
"name": ".NET API",
"href": "api/BuildFromAssembly.html",
"tocHref": "api/toc.html",
"topicHref": "api/BuildFromAssembly.html",
"topicUid": "BuildFromAssembly",
"level": 3.0,
"items": [],
"leaf": true
},
{
"name": "REST API",
"href": "restapi/petstore.html",
"tocHref": "restapi/toc.html",
"topicHref": "restapi/petstore.html",
"level": 3.0,
"items": [],
"leaf": true
}
],
"topicHref": null,
"tocHref": null,
"level": 2.0
}
],
"_appName": "Seed",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"content": "{\"items\":[{\"name\":\"Home\",\"href\":\"index.html\",\"topicHref\":\"index.html\"},{\"name\":\"Articles\",\"href\":\"articles/docfx_getting_started.html\",\"tocHref\":\"articles/toc.html\",\"topicHref\":\"articles/docfx_getting_started.html\"},{\"name\":\"API Documentation\",\"href\":\"api/BuildFromAssembly.html\",\"tocHref\":\"api/toc.html\",\"topicHref\":\"api/BuildFromAssembly.html\",\"topicUid\":\"BuildFromAssembly\"},{\"name\":\"REST API\",\"href\":\"restapi/petstore.html\",\"tocHref\":\"restapi/toc.html\",\"topicHref\":\"restapi/petstore.html\"}]}"
"content": "{\"items\":[{\"name\":\"Home\",\"href\":\"index.html\",\"topicHref\":\"index.html\"},{\"name\":\"Articles\",\"href\":\"articles/docfx_getting_started.html\",\"tocHref\":\"articles/toc.html\",\"topicHref\":\"articles/docfx_getting_started.html\"},{\"name\":\"API Documentation\",\"items\":[{\"name\":\".NET API\",\"href\":\"api/BuildFromAssembly.html\",\"tocHref\":\"api/toc.html\",\"topicHref\":\"api/BuildFromAssembly.html\",\"topicUid\":\"BuildFromAssembly\"},{\"name\":\"REST API\",\"href\":\"restapi/petstore.html\",\"tocHref\":\"restapi/toc.html\",\"topicHref\":\"restapi/petstore.html\"}]}]}"
}
25 changes: 15 additions & 10 deletions test/docfx.Snapshot.Tests/SamplesTest.Seed/toc.verified.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@
},
{
"name": "API Documentation",
"href": "api/BuildFromAssembly.html",
"tocHref": "api/toc.html",
"topicHref": "api/BuildFromAssembly.html",
"topicUid": "BuildFromAssembly"
},
{
"name": "REST API",
"href": "restapi/petstore.html",
"tocHref": "restapi/toc.html",
"topicHref": "restapi/petstore.html"
"items": [
{
"name": ".NET API",
"href": "api/BuildFromAssembly.html",
"tocHref": "api/toc.html",
"topicHref": "api/BuildFromAssembly.html",
"topicUid": "BuildFromAssembly"
},
{
"name": "REST API",
"href": "restapi/petstore.html",
"tocHref": "restapi/toc.html",
"topicHref": "restapi/petstore.html"
}
]
}
]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,13 @@
<input class="form-control" id="search-query" type="search" placeholder="Search" autocomplete="off" aria-label="Search">
</form>

<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/index.html">Home</a></li>
<li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/articles/docfx_getting_started.html">Articles</a></li>
<li class="nav-item"><a class="nav-link active" aria-current="page" href="http://localhost:8089/api/BuildFromAssembly.html">API Documentation</a></li>
<li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/restapi/petstore.html">REST API</a></li></ul> <form class="icons"><a title="GitHub" class="btn border-0" href="https://github.com/dotnet/docfx"><i class="bi bi-github"></i></a>
<ul class="navbar-nav"><li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/index.html">Home</a></li><li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/articles/docfx_getting_started.html">Articles</a></li>
<li class="nav-item dropdown">
<a href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false" class="nav-link dropdown-toggle active">
API Documentation
</a>
<ul class="dropdown-menu"><li class="nav-item"><a class="nav-link active" aria-current="page" href="http://localhost:8089/api/BuildFromAssembly.html">.NET API</a></li><li class="nav-item"><a class="nav-link " aria-current="false" href="http://localhost:8089/restapi/petstore.html">REST API</a></li></ul>
</li></ul> <form class="icons"><a title="GitHub" class="btn border-0" href="https://github.com/dotnet/docfx"><i class="bi bi-github"></i></a>
<div class="dropdown">
<a title="Change theme" class="btn border-0 dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-circle-half"></i>
Expand Down Expand Up @@ -467,7 +469,7 @@ <h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>

<nav id="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="http://localhost:8089/api/BuildFromAssembly.html">API Documentation</a></li><li class="breadcrumb-item"><a href="http://localhost:8089/api/BuildFromProject.html">Build<wbr>From<wbr>Project</a></li>
<li class="breadcrumb-item"><a href="http://localhost:8089/api/BuildFromAssembly.html">.NET API</a></li><li class="breadcrumb-item"><a href="http://localhost:8089/api/BuildFromProject.html">Build<wbr>From<wbr>Project</a></li>
</ol></nav>
</div>

Expand Down
Loading

0 comments on commit 3783892

Please sign in to comment.