@tenphi/starlight 0.1.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/client/appearance.js +1 -1
- package/dist/client/appearance.js.map +1 -1
- package/dist/client/search.js +14 -1
- package/dist/client/search.js.map +1 -1
- package/dist/components/MobileNavigationTabs.astro +40 -0
- package/dist/components/NavigationTree.astro +98 -0
- package/dist/icons/arrow-left.svg +1 -0
- package/dist/icons/arrow-right.svg +1 -0
- package/dist/icons/chevron-down.svg +1 -0
- package/dist/icons/chevron-right.svg +1 -0
- package/dist/icons/close.svg +1 -0
- package/dist/icons/contrast.svg +1 -0
- package/dist/icons/copy.svg +1 -0
- package/dist/icons/device-desktop.svg +1 -0
- package/dist/icons/menu.svg +1 -0
- package/dist/icons/moon.svg +1 -0
- package/dist/icons/search.svg +1 -0
- package/dist/icons/sun.svg +1 -0
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +312 -35
- package/dist/index.js.map +1 -1
- package/dist/navigation-CC0dlAL8.js +78 -0
- package/dist/navigation-CC0dlAL8.js.map +1 -0
- package/dist/navigation.d.ts +21 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +2 -0
- package/dist/overrides/Header.astro +49 -0
- package/dist/overrides/Sidebar.astro +42 -0
- package/dist/routes/DocsPage.astro +72 -43
- package/dist/styles.css +1223 -68
- package/package.json +9 -6
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/navigation.ts
|
|
2
|
+
function resolveNavigationLayout(navigation) {
|
|
3
|
+
const items = Array.isArray(navigation) ? navigation : navigation?.items;
|
|
4
|
+
const configuredTabs = Array.isArray(navigation) ? [] : navigation?.tabs ?? [];
|
|
5
|
+
const fallbackSidebarGroup = items !== void 0 ? 0 : void 0;
|
|
6
|
+
let sidebarGroup = fallbackSidebarGroup === void 0 ? 0 : 1;
|
|
7
|
+
const tabs = configuredTabs.map((tab) => ({
|
|
8
|
+
...tab,
|
|
9
|
+
...tab.items !== void 0 ? { sidebarGroup: sidebarGroup++ } : {}
|
|
10
|
+
}));
|
|
11
|
+
return {
|
|
12
|
+
...fallbackSidebarGroup !== void 0 ? { fallbackSidebarGroup } : {},
|
|
13
|
+
...items !== void 0 ? { items } : {},
|
|
14
|
+
tabs,
|
|
15
|
+
sectioned: tabs.some((tab) => tab.sidebarGroup !== void 0)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function navigationItemsForPath(layout, pathname) {
|
|
19
|
+
const active = activeNavigationTab(layout.tabs, pathname);
|
|
20
|
+
return active >= 0 && layout.tabs[active]?.items !== void 0 ? layout.tabs[active].items : layout.items;
|
|
21
|
+
}
|
|
22
|
+
/** Pick one tab, preferring its own URL before routes owned by its sidebar. */
|
|
23
|
+
function activeNavigationTab(tabs, pathname) {
|
|
24
|
+
const current = normalizeNavigationPath(pathname);
|
|
25
|
+
let winner = -1;
|
|
26
|
+
let winningScore = -1;
|
|
27
|
+
for (const [index, tab] of tabs.entries()) {
|
|
28
|
+
const score = Math.max(linkMatchScore(tab.link, current, 3e4), navigationMatchScore(tab.items ?? [], current));
|
|
29
|
+
if (score > winningScore) {
|
|
30
|
+
winner = index;
|
|
31
|
+
winningScore = score;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return winningScore >= 0 ? winner : -1;
|
|
35
|
+
}
|
|
36
|
+
function navigationPath(pathname, base = "/") {
|
|
37
|
+
const normalizedBase = normalizeNavigationPath(base);
|
|
38
|
+
return normalizeNavigationPath(normalizedBase !== "/" && (pathname === normalizedBase || pathname.startsWith(`${normalizedBase}/`)) ? pathname.slice(normalizedBase.length) || "/" : pathname);
|
|
39
|
+
}
|
|
40
|
+
function normalizeNavigationPath(path) {
|
|
41
|
+
const normalized = `/${(path.split(/[?#]/, 1)[0]?.replace(/\\/g, "/") ?? "/").replace(/^\/+|\/+$/g, "")}`;
|
|
42
|
+
return normalized === "/" ? normalized : normalized.replace(/\/$/, "");
|
|
43
|
+
}
|
|
44
|
+
function navigationMatchScore(items, current) {
|
|
45
|
+
let score = -1;
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
if (typeof item === "string") {
|
|
48
|
+
if (normalizeNavigationPath(item) === current) score = Math.max(score, 2e4);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if ("items" in item) {
|
|
52
|
+
score = Math.max(score, navigationMatchScore(item.items, current));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if ("autogenerate" in item) {
|
|
56
|
+
score = Math.max(score, directoryMatchScore(item.autogenerate.directory, current));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
score = Math.max(score, linkMatchScore(item.link, current, 2e4));
|
|
60
|
+
}
|
|
61
|
+
return score;
|
|
62
|
+
}
|
|
63
|
+
function linkMatchScore(link, current, base) {
|
|
64
|
+
if (!link.startsWith("/")) return -1;
|
|
65
|
+
const target = normalizeNavigationPath(link);
|
|
66
|
+
if (target === current) return base + 1e3 + target.length;
|
|
67
|
+
if (target !== "/" && current.startsWith(`${target}/`)) return base + target.length;
|
|
68
|
+
return -1;
|
|
69
|
+
}
|
|
70
|
+
function directoryMatchScore(directory, current) {
|
|
71
|
+
const target = normalizeNavigationPath(directory);
|
|
72
|
+
if (target === "/") return 1e4;
|
|
73
|
+
return current === target || current.startsWith(`${target}/`) ? 1e4 + target.length : -1;
|
|
74
|
+
}
|
|
75
|
+
//#endregion
|
|
76
|
+
export { resolveNavigationLayout as a, normalizeNavigationPath as i, navigationItemsForPath as n, navigationPath as r, activeNavigationTab as t };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=navigation-CC0dlAL8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-CC0dlAL8.js","names":[],"sources":["../src/navigation.ts"],"sourcesContent":["import type { DocsConfig, NavigationItem, NavigationTab } from \"@tenphi/docs\";\n\nexport interface ResolvedNavigationTab extends NavigationTab {\n /** Index of the tab's resolved Starlight sidebar group. */\n sidebarGroup?: number;\n}\n\nexport interface ResolvedNavigationLayout {\n fallbackSidebarGroup?: number;\n items?: NavigationItem[];\n tabs: ResolvedNavigationTab[];\n sectioned: boolean;\n}\n\nexport function resolveNavigationLayout(\n navigation: DocsConfig[\"navigation\"],\n): ResolvedNavigationLayout {\n const items = Array.isArray(navigation) ? navigation : navigation?.items;\n const configuredTabs = Array.isArray(navigation)\n ? []\n : (navigation?.tabs ?? []);\n const fallbackSidebarGroup = items !== undefined ? 0 : undefined;\n let sidebarGroup = fallbackSidebarGroup === undefined ? 0 : 1;\n const tabs = configuredTabs.map((tab) => ({\n ...tab,\n ...(tab.items !== undefined ? { sidebarGroup: sidebarGroup++ } : {}),\n }));\n\n return {\n ...(fallbackSidebarGroup !== undefined ? { fallbackSidebarGroup } : {}),\n ...(items !== undefined ? { items } : {}),\n tabs,\n sectioned: tabs.some((tab) => tab.sidebarGroup !== undefined),\n };\n}\n\nexport function navigationItemsForPath(\n layout: ResolvedNavigationLayout,\n pathname: string,\n): NavigationItem[] | undefined {\n const active = activeNavigationTab(layout.tabs, pathname);\n return active >= 0 && layout.tabs[active]?.items !== undefined\n ? layout.tabs[active].items\n : layout.items;\n}\n\n/** Pick one tab, preferring its own URL before routes owned by its sidebar. */\nexport function activeNavigationTab(\n tabs: NavigationTab[],\n pathname: string,\n): number {\n const current = normalizeNavigationPath(pathname);\n let winner = -1;\n let winningScore = -1;\n\n for (const [index, tab] of tabs.entries()) {\n const score = Math.max(\n linkMatchScore(tab.link, current, 30_000),\n navigationMatchScore(tab.items ?? [], current),\n );\n if (score > winningScore) {\n winner = index;\n winningScore = score;\n }\n }\n\n return winningScore >= 0 ? winner : -1;\n}\n\nexport function navigationPath(pathname: string, base = \"/\"): string {\n const normalizedBase = normalizeNavigationPath(base);\n const withoutBase =\n normalizedBase !== \"/\" &&\n (pathname === normalizedBase || pathname.startsWith(`${normalizedBase}/`))\n ? pathname.slice(normalizedBase.length) || \"/\"\n : pathname;\n return normalizeNavigationPath(withoutBase);\n}\n\nexport function normalizeNavigationPath(path: string): string {\n const clean = path.split(/[?#]/, 1)[0]?.replace(/\\\\/g, \"/\") ?? \"/\";\n const normalized = `/${clean.replace(/^\\/+|\\/+$/g, \"\")}`;\n return normalized === \"/\" ? normalized : normalized.replace(/\\/$/, \"\");\n}\n\nfunction navigationMatchScore(\n items: NavigationItem[],\n current: string,\n): number {\n let score = -1;\n for (const item of items) {\n if (typeof item === \"string\") {\n if (normalizeNavigationPath(item) === current)\n score = Math.max(score, 20_000);\n continue;\n }\n if (\"items\" in item) {\n score = Math.max(score, navigationMatchScore(item.items, current));\n continue;\n }\n if (\"autogenerate\" in item) {\n score = Math.max(\n score,\n directoryMatchScore(item.autogenerate.directory, current),\n );\n continue;\n }\n score = Math.max(score, linkMatchScore(item.link, current, 20_000));\n }\n return score;\n}\n\nfunction linkMatchScore(link: string, current: string, base: number): number {\n if (!link.startsWith(\"/\")) return -1;\n const target = normalizeNavigationPath(link);\n if (target === current) return base + 1_000 + target.length;\n if (target !== \"/\" && current.startsWith(`${target}/`)) {\n return base + target.length;\n }\n return -1;\n}\n\nfunction directoryMatchScore(directory: string, current: string): number {\n const target = normalizeNavigationPath(directory);\n if (target === \"/\") return 10_000;\n return current === target || current.startsWith(`${target}/`)\n ? 10_000 + target.length\n : -1;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DocsConfig, NavigationItem, NavigationTab } from "@tenphi/docs";
|
|
2
|
+
//#region src/navigation.d.ts
|
|
3
|
+
interface ResolvedNavigationTab extends NavigationTab {
|
|
4
|
+
/** Index of the tab's resolved Starlight sidebar group. */
|
|
5
|
+
sidebarGroup?: number;
|
|
6
|
+
}
|
|
7
|
+
interface ResolvedNavigationLayout {
|
|
8
|
+
fallbackSidebarGroup?: number;
|
|
9
|
+
items?: NavigationItem[];
|
|
10
|
+
tabs: ResolvedNavigationTab[];
|
|
11
|
+
sectioned: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function resolveNavigationLayout(navigation: DocsConfig["navigation"]): ResolvedNavigationLayout;
|
|
14
|
+
declare function navigationItemsForPath(layout: ResolvedNavigationLayout, pathname: string): NavigationItem[] | undefined;
|
|
15
|
+
/** Pick one tab, preferring its own URL before routes owned by its sidebar. */
|
|
16
|
+
declare function activeNavigationTab(tabs: NavigationTab[], pathname: string): number;
|
|
17
|
+
declare function navigationPath(pathname: string, base?: string): string;
|
|
18
|
+
declare function normalizeNavigationPath(path: string): string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { ResolvedNavigationLayout, ResolvedNavigationTab, activeNavigationTab, navigationItemsForPath, navigationPath, normalizeNavigationPath, resolveNavigationLayout };
|
|
21
|
+
//# sourceMappingURL=navigation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","names":[],"sources":["../src/navigation.ts"],"mappings":";;UAEiB,8BAA8B;;EAE7C;;UAGe;EACf;EACA,QAAQ;EACR,MAAM;EACN;;iBAGc,wBACd,YAAY,2BACX;iBAoBa,uBACd,QAAQ,0BACR,mBACC;;iBAQa,oBACd,MAAM,iBACN;iBAoBc,eAAe,kBAAkB;iBAUjC,wBAAwB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as resolveNavigationLayout, i as normalizeNavigationPath, n as navigationItemsForPath, r as navigationPath, t as activeNavigationTab } from "./navigation-CC0dlAL8.js";
|
|
2
|
+
export { activeNavigationTab, navigationItemsForPath, navigationPath, normalizeNavigationPath, resolveNavigationLayout };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
import config from "virtual:starlight/user-config";
|
|
3
|
+
import LanguageSelect from "virtual:starlight/components/LanguageSelect";
|
|
4
|
+
import Search from "virtual:starlight/components/Search";
|
|
5
|
+
import SiteTitle from "virtual:starlight/components/SiteTitle";
|
|
6
|
+
import SocialIcons from "virtual:starlight/components/SocialIcons";
|
|
7
|
+
import ThemeSelect from "virtual:starlight/components/ThemeSelect";
|
|
8
|
+
import { layout } from "virtual:cookbook/layout";
|
|
9
|
+
import { activeNavigationTab, navigationPath } from "../navigation.js";
|
|
10
|
+
|
|
11
|
+
const shouldRenderSearch =
|
|
12
|
+
config.pagefind ||
|
|
13
|
+
config.components.Search !== "@astrojs/starlight/components/Search.astro";
|
|
14
|
+
const base = import.meta.env.BASE_URL.replace(/\/$/, "");
|
|
15
|
+
const currentPath = navigationPath(Astro.url.pathname, base || "/");
|
|
16
|
+
const activeTab = activeNavigationTab(layout.tabs, currentPath);
|
|
17
|
+
|
|
18
|
+
function tabHref(link: string): string {
|
|
19
|
+
return link.startsWith("/") ? `${base}${link}` || "/" : link;
|
|
20
|
+
}
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<div class:list={["td-header", { "td-header--with-tabs": layout.tabs.length }]}>
|
|
24
|
+
<div class="td-header__primary">
|
|
25
|
+
<div class="td-header__title"><SiteTitle /></div>
|
|
26
|
+
<div class="td-header__search print:hidden">
|
|
27
|
+
{shouldRenderSearch && <Search />}
|
|
28
|
+
</div>
|
|
29
|
+
<div class="td-header__tools sl-hidden md:sl-flex print:hidden">
|
|
30
|
+
<div class="td-header__social"><SocialIcons /></div>
|
|
31
|
+
<ThemeSelect />
|
|
32
|
+
<LanguageSelect />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
{
|
|
36
|
+
layout.tabs.length > 0 && (
|
|
37
|
+
<nav class="td-top-tabs print:hidden" aria-label="Primary">
|
|
38
|
+
{layout.tabs.map((tab, index) => (
|
|
39
|
+
<a
|
|
40
|
+
href={tabHref(tab.link)}
|
|
41
|
+
aria-current={index === activeTab ? "page" : undefined}
|
|
42
|
+
>
|
|
43
|
+
{tab.label}
|
|
44
|
+
</a>
|
|
45
|
+
))}
|
|
46
|
+
</nav>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
</div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MobileMenuFooter from "virtual:starlight/components/MobileMenuFooter";
|
|
3
|
+
import { layout } from "virtual:cookbook/layout";
|
|
4
|
+
import SidebarPersister from "@astrojs/starlight/components/SidebarPersister.astro";
|
|
5
|
+
import SidebarSublist from "@astrojs/starlight/components/SidebarSublist.astro";
|
|
6
|
+
import MobileNavigationTabs from "../components/MobileNavigationTabs.astro";
|
|
7
|
+
import { activeNavigationTab, navigationPath } from "../navigation.js";
|
|
8
|
+
|
|
9
|
+
const fullSidebar = Astro.locals.starlightRoute.sidebar;
|
|
10
|
+
const currentPath = navigationPath(
|
|
11
|
+
Astro.url.pathname,
|
|
12
|
+
import.meta.env.BASE_URL,
|
|
13
|
+
);
|
|
14
|
+
const activeTab = activeNavigationTab(layout.tabs, currentPath);
|
|
15
|
+
const groupIndex =
|
|
16
|
+
(activeTab >= 0 ? layout.tabs[activeTab]?.sidebarGroup : undefined) ??
|
|
17
|
+
layout.fallbackSidebarGroup;
|
|
18
|
+
const selectedGroup = layout.sectioned
|
|
19
|
+
? groupIndex === undefined
|
|
20
|
+
? undefined
|
|
21
|
+
: fullSidebar[groupIndex]
|
|
22
|
+
: undefined;
|
|
23
|
+
const sidebar =
|
|
24
|
+
selectedGroup?.type === "group"
|
|
25
|
+
? selectedGroup.entries
|
|
26
|
+
: layout.sectioned
|
|
27
|
+
? []
|
|
28
|
+
: fullSidebar;
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
<MobileNavigationTabs
|
|
32
|
+
base={import.meta.env.BASE_URL}
|
|
33
|
+
currentPath={Astro.url.pathname}
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
<SidebarPersister>
|
|
37
|
+
<SidebarSublist sublist={sidebar} />
|
|
38
|
+
</SidebarPersister>
|
|
39
|
+
|
|
40
|
+
<div class="md:sl-hidden">
|
|
41
|
+
<MobileMenuFooter />
|
|
42
|
+
</div>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { createMarkdownProcessor } from "@astrojs/markdown-remark";
|
|
3
|
-
import { content } from "virtual:
|
|
4
|
-
import "virtual:
|
|
3
|
+
import { content } from "virtual:cookbook/config";
|
|
4
|
+
import { layout } from "virtual:cookbook/layout";
|
|
5
|
+
import MobileNavigationTabs from "../components/MobileNavigationTabs.astro";
|
|
6
|
+
import NavigationTree from "../components/NavigationTree.astro";
|
|
7
|
+
import { activeNavigationTab, navigationItemsForPath } from "../navigation.js";
|
|
8
|
+
import "virtual:cookbook/theme.css";
|
|
5
9
|
import "../styles.css";
|
|
6
10
|
|
|
7
11
|
export const prerender = true;
|
|
@@ -26,6 +30,10 @@ export async function getStaticPaths() {
|
|
|
26
30
|
const { entry, routes, html, site, base, search } = Astro.props;
|
|
27
31
|
const withBase = (route) =>
|
|
28
32
|
`${base === "/" ? "" : `/${base.replace(/^\/+|\/+$/g, "")}`}${route}` || "/";
|
|
33
|
+
const activeTab = activeNavigationTab(layout.tabs, entry.route);
|
|
34
|
+
const navigationItems =
|
|
35
|
+
navigationItemsForPath(layout, entry.route) ??
|
|
36
|
+
routes.map((route) => route.route);
|
|
29
37
|
---
|
|
30
38
|
|
|
31
39
|
<!doctype html>
|
|
@@ -47,32 +55,62 @@ const withBase = (route) =>
|
|
|
47
55
|
data-tasty-anatomy="Header"
|
|
48
56
|
data-docs-base={base}
|
|
49
57
|
>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
<div class="td-shell__header-primary">
|
|
59
|
+
<a href={withBase("/")}>{site.title ?? "Documentation"}</a>
|
|
60
|
+
<div class="td-shell__actions">
|
|
61
|
+
<label class="td-appearance-control" title="Color theme">
|
|
62
|
+
<span class="td-visually-hidden">Color theme</span>
|
|
63
|
+
<select data-docs-theme aria-label="Color theme">
|
|
64
|
+
<option value="system">System theme</option>
|
|
65
|
+
<option value="light">Light theme</option>
|
|
66
|
+
<option value="dark">Dark theme</option>
|
|
67
|
+
</select>
|
|
68
|
+
</label>
|
|
69
|
+
<label
|
|
70
|
+
class="td-appearance-control td-appearance-control--contrast"
|
|
71
|
+
title="Contrast"
|
|
72
|
+
>
|
|
73
|
+
<span class="td-visually-hidden">Contrast</span>
|
|
74
|
+
<select data-docs-contrast aria-label="Contrast">
|
|
75
|
+
<option value="system">System contrast</option>
|
|
76
|
+
<option value="normal">Normal contrast</option>
|
|
77
|
+
<option value="more">High contrast</option>
|
|
78
|
+
</select>
|
|
79
|
+
</label>
|
|
80
|
+
{
|
|
81
|
+
search && (
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
data-docs-search-open
|
|
85
|
+
aria-haspopup="dialog"
|
|
86
|
+
aria-keyshortcuts="Control+K"
|
|
87
|
+
>
|
|
88
|
+
<span>Search</span>
|
|
89
|
+
<kbd data-docs-search-shortcut>
|
|
90
|
+
<>
|
|
91
|
+
<kbd>Ctrl</kbd>
|
|
92
|
+
<kbd>K</kbd>
|
|
93
|
+
</>
|
|
94
|
+
</kbd>
|
|
95
|
+
</button>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
</div>
|
|
75
99
|
</div>
|
|
100
|
+
{
|
|
101
|
+
layout.tabs.length > 0 && (
|
|
102
|
+
<nav class="td-top-tabs" aria-label="Primary">
|
|
103
|
+
{layout.tabs.map((tab, index) => (
|
|
104
|
+
<a
|
|
105
|
+
href={tab.link.startsWith("/") ? withBase(tab.link) : tab.link}
|
|
106
|
+
aria-current={index === activeTab ? "page" : undefined}
|
|
107
|
+
>
|
|
108
|
+
{tab.label}
|
|
109
|
+
</a>
|
|
110
|
+
))}
|
|
111
|
+
</nav>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
76
114
|
</header>
|
|
77
115
|
<div class="td-shell__layout">
|
|
78
116
|
<nav
|
|
@@ -80,22 +118,13 @@ const withBase = (route) =>
|
|
|
80
118
|
aria-label="Documentation"
|
|
81
119
|
data-tasty-anatomy="Sidebar"
|
|
82
120
|
>
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
route.route === entry.route ? "page" : undefined
|
|
91
|
-
}
|
|
92
|
-
>
|
|
93
|
-
{route.title}
|
|
94
|
-
</a>
|
|
95
|
-
</li>
|
|
96
|
-
))
|
|
97
|
-
}
|
|
98
|
-
</ul>
|
|
121
|
+
<MobileNavigationTabs base={base} currentPath={entry.route} />
|
|
122
|
+
<NavigationTree
|
|
123
|
+
items={navigationItems}
|
|
124
|
+
routes={routes}
|
|
125
|
+
current={entry.route}
|
|
126
|
+
base={base}
|
|
127
|
+
/>
|
|
99
128
|
</nav>
|
|
100
129
|
<main
|
|
101
130
|
id="main-content"
|