mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 21:27:06 +04:00
91 lines
3.6 KiB
Plaintext
91 lines
3.6 KiB
Plaintext
---
|
|
// Menu tree from shared/data/docs.json.
|
|
import Subheader from '@ui/Subheader.astro'
|
|
import docs from '@data/docs.json'
|
|
import { pathSlug as slug } from '@shared/lib/string-format'
|
|
|
|
interface MenuLeaf {
|
|
title: string
|
|
url: string
|
|
}
|
|
|
|
interface MenuGroup {
|
|
title: string
|
|
/** omitted for groups that only label a set of pages, with no index page of their own */
|
|
url?: string
|
|
children?: MenuLeaf[]
|
|
}
|
|
|
|
interface MenuSection {
|
|
title: string
|
|
children?: MenuGroup[]
|
|
}
|
|
|
|
interface Props {
|
|
/** Page URL in the docs namespace, e.g. "/ui/components/alert". */
|
|
url: string
|
|
}
|
|
|
|
const { url } = Astro.props
|
|
const menu = docs.menu as MenuSection[]
|
|
|
|
/** Collapse target: from the group's url, or from its title when it has none. */
|
|
const groupId = (group: MenuGroup) =>
|
|
`collapse-${slug(group.url ?? group.title)
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9-]+/g, '-')}`
|
|
---
|
|
|
|
<!-- BEGIN DOCS MENU -->
|
|
<nav class="space-y space-y-5" id="menu" aria-label="Documentation">
|
|
{
|
|
menu.map((level1) => (
|
|
<div>
|
|
<Subheader class="mb-2">{level1.title}</Subheader>
|
|
{level1.children && level1.children.length > 0 && (
|
|
<div class="nav nav-vertical">
|
|
{level1.children.map((level2) => {
|
|
const hasChildren = Boolean(level2.children && level2.children.length > 0)
|
|
// Expanded only for the group's own page or one of its direct children —
|
|
// a prefix check would also expand "Introduction" on /ui/getting-started/frameworks/* pages.
|
|
const expanded = url === level2.url || Boolean(level2.children?.some((child) => child.url === url))
|
|
return (
|
|
<div>
|
|
{/* href/data-bs-* only when the element has children; a group
|
|
without an index page toggles from a button instead */}
|
|
{hasChildren && level2.url ? (
|
|
<a class={`nav-link${expanded ? ' active' : ''}`} href={level2.url} data-bs-toggle="collapse" data-bs-target={`#${groupId(level2)}`} aria-expanded={expanded ? 'true' : 'false'} aria-current={url === level2.url ? 'page' : undefined}>
|
|
<span class="nav-link-title">{level2.title}</span> <span class="nav-link-toggle" />
|
|
</a>
|
|
) : hasChildren ? (
|
|
<button type="button" class="nav-link w-100 bg-transparent border-0 text-start" data-bs-toggle="collapse" data-bs-target={`#${groupId(level2)}`} aria-expanded={expanded ? 'true' : 'false'}>
|
|
<span class="nav-link-title">{level2.title}</span> <span class="nav-link-toggle" />
|
|
</button>
|
|
) : (
|
|
<a class={`nav-link${expanded ? ' active' : ''}`} href={level2.url} aria-current={url === level2.url ? 'page' : undefined}>
|
|
<span class="nav-link-title">{level2.title}</span>
|
|
</a>
|
|
)}
|
|
|
|
{hasChildren && (
|
|
<div class={`nav nav-vertical collapse${expanded ? ' show' : ''}`} id={groupId(level2)}>
|
|
{level2.children!.map((level3) => (
|
|
<div>
|
|
<a class={`nav-link${url === level3.url ? ' active' : ''}`} href={level3.url} aria-current={url === level3.url ? 'page' : undefined}>
|
|
<span class="nav-link-title">{level3.title}</span>
|
|
</a>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
))
|
|
}
|
|
</nav>
|
|
<!-- END DOCS MENU -->
|