From 9b5152c79d79e703f931cb84fbf89c298ecf6ec7 Mon Sep 17 00:00:00 2001 From: Adrian Kahali Date: Fri, 15 May 2026 14:33:51 -0400 Subject: [PATCH] feat: add sidebar title option --- src/bach/breadcrumbs.ts | 12 +++++++----- src/bach/content.ts | 15 ++++++++++++++- src/bach/schemas/api.ts | 1 + src/bach/schemas/docs.ts | 1 + src/bach/site.ts | 14 +++++++++++--- src/bach/tree.ts | 18 ++++++++++++++++-- src/bach/types.ts | 1 + src/components/sidebar-tree-view.tsx | 2 +- 8 files changed, 52 insertions(+), 12 deletions(-) diff --git a/src/bach/breadcrumbs.ts b/src/bach/breadcrumbs.ts index a47f6e4..ce2a6f0 100644 --- a/src/bach/breadcrumbs.ts +++ b/src/bach/breadcrumbs.ts @@ -11,7 +11,8 @@ export async function searchPagesForBreadcrumbs( pagePath: string, pages: PageItem[], prefix: { label: string; href: string }[], - titleMap: Map + titleMap: Map, + sidebarTitleMap: Map ): Promise<{ label: string; href: string }[] | null> { const normalizedTarget = normalizePagePath(pagePath) @@ -40,11 +41,11 @@ export async function searchPagesForBreadcrumbs( return groupPrefix } } else { - const firstChildHref = findFirstHref(buildPages(item.pages, 0, '', titleMap, new Map())) + const firstChildHref = findFirstHref(buildPages(item.pages, 0, '', titleMap, new Map(), sidebarTitleMap)) groupPrefix.push({ label: item.group, href: firstChildHref ?? '/' }) } - const result = await searchPagesForBreadcrumbs(pagePath, item.pages, groupPrefix, titleMap) + const result = await searchPagesForBreadcrumbs(pagePath, item.pages, groupPrefix, titleMap, sidebarTitleMap) if (result) return result } } @@ -63,12 +64,13 @@ export async function buildBreadcrumbs( config: DocsConfig, entryId: string, pageTitle: string, - titleMap: Map + titleMap: Map, + sidebarTitleMap: Map ): Promise<{ label: string; href: string }[]> { const pagePath = normalizeEntryId(entryId) for (const tab of config.navigation.tabs) { - const crumbs = await searchPagesForBreadcrumbs(pagePath, tab.pages, [], titleMap) + const crumbs = await searchPagesForBreadcrumbs(pagePath, tab.pages, [], titleMap, sidebarTitleMap) if (crumbs) { // Remove the active page itself — breadcrumbs show only the parent path return crumbs.slice(0, -1) diff --git a/src/bach/content.ts b/src/bach/content.ts index 290f1c3..a56effb 100644 --- a/src/bach/content.ts +++ b/src/bach/content.ts @@ -55,6 +55,10 @@ export function buildSidebarEntryMap( entries.map((entry) => ({ id: entry.id, title: entry.data.title, + sidebarTitle: + 'sidebarTitle' in entry.data && typeof entry.data.sidebarTitle === 'string' + ? entry.data.sidebarTitle + : undefined, method: 'method' in entry.data && typeof entry.data.method === 'string' ? entry.data.method : undefined, sortOrder: 'sortOrder' in entry.data && typeof entry.data.sortOrder === 'number' ? entry.data.sortOrder : undefined, @@ -74,6 +78,7 @@ export function buildSidebarEntryMap( export function buildCollectionsSidebarData(allEntries: Map) { const titleMap = new Map() const methodMap = new Map() + const sidebarTitleMap = new Map() const articles: ArticleEntry[] = [] for (const [, entries] of allEntries) { @@ -86,6 +91,14 @@ export function buildCollectionsSidebarData(allEntries: Map methodMap: Map + sidebarTitleMap: Map articles: ArticleEntry[] defaultEntriesBySlug: Map } @@ -49,9 +50,9 @@ export class BachSite { const defaultCollection = getDefaultCollection(this._config) const allEntries = await loadCollections(this._config) - const { titleMap, methodMap, articles } = buildCollectionsSidebarData(allEntries) + const { titleMap, methodMap, sidebarTitleMap, articles } = buildCollectionsSidebarData(allEntries) const collectionsMap = buildSidebarEntryMap(allEntries) - const sidebar = await buildSidebarTree(this._config, titleMap, methodMap, collectionsMap) + const sidebar = await buildSidebarTree(this._config, titleMap, methodMap, sidebarTitleMap, collectionsMap) const defaultEntriesBySlug = new Map() for (const entry of allEntries.get(defaultCollection) ?? []) { @@ -64,6 +65,7 @@ export class BachSite { sidebar, titleMap, methodMap, + sidebarTitleMap, articles, defaultEntriesBySlug, } @@ -89,7 +91,13 @@ export class BachSite { if (isApi) { breadcrumbs = [{ label: apiData!.apiLabel }] } else { - breadcrumbs = await buildBreadcrumbs(siteContext.config, entry.id, title, siteContext.titleMap) + breadcrumbs = await buildBreadcrumbs( + siteContext.config, + entry.id, + title, + siteContext.titleMap, + siteContext.sidebarTitleMap + ) } const { prev, next } = getAdjacentPages(sidebarTree, pathname) diff --git a/src/bach/tree.ts b/src/bach/tree.ts index a4f76f9..8ee3900 100644 --- a/src/bach/tree.ts +++ b/src/bach/tree.ts @@ -49,6 +49,7 @@ function _collectFromPages(pages: PageItem( parentPath: string, titleMap: Map, methodMap: Map, + sidebarTitleMap: Map, collectionsMap?: Map ): SidebarNode[] { const nodes: SidebarNode[] = [] @@ -81,6 +83,7 @@ export function buildPages( const articleNode: SidebarArticleNode = { type: 'article', title, + sidebarTitle: sidebarTitleMap.get(normalizedPath), href, path: normalizedPath, method: methodMap.get(normalizedPath), @@ -113,6 +116,7 @@ export function buildPages( children: sortedEntries.map((entry) => ({ type: 'article', title: entry.title, + sidebarTitle: entry.sidebarTitle, href: `/${entry.id}`, path: entry.id, method: entry.method, @@ -136,7 +140,15 @@ export function buildPages( childrenPages = item.pages } - const children = buildPages(childrenPages, depth + 1, groupPath, titleMap, methodMap, collectionsMap) + const children = buildPages( + childrenPages, + depth + 1, + groupPath, + titleMap, + methodMap, + sidebarTitleMap, + collectionsMap + ) const categoryNode: SidebarCategoryNode = { type: 'category', @@ -195,9 +207,11 @@ export async function buildSidebarTree( config: DocsConfig, titleMap: Map, methodMap?: Map, + sidebarTitleMap?: Map, collectionsMap?: Map ): Promise { const _methodMap = methodMap ?? new Map() + const _sidebarTitleMap = sidebarTitleMap ?? new Map() const tabs: TabInfo[] = [] const trees: Record = {} @@ -205,7 +219,7 @@ export async function buildSidebarTree( for (const tabItem of config.navigation.tabs) { const tabSlug = slugify(tabItem.tab) - const tabTree = buildPages(tabItem.pages, 0, '', titleMap, _methodMap, collectionsMap) + const tabTree = buildPages(tabItem.pages, 0, '', titleMap, _methodMap, _sidebarTitleMap, collectionsMap) const firstHref = findFirstHref(tabTree) ?? '/' diff --git a/src/bach/types.ts b/src/bach/types.ts index e37069f..a7ab5c2 100644 --- a/src/bach/types.ts +++ b/src/bach/types.ts @@ -23,6 +23,7 @@ export interface SidebarCategoryNode { export interface SidebarArticleNode { type: 'article' title: string + sidebarTitle?: string href: string path: string method?: string diff --git a/src/components/sidebar-tree-view.tsx b/src/components/sidebar-tree-view.tsx index fbf5b10..db49646 100644 --- a/src/components/sidebar-tree-view.tsx +++ b/src/components/sidebar-tree-view.tsx @@ -136,7 +136,7 @@ function ChildNode({ : 'text-stone-600 hover:bg-black/5 hover:text-stone-900 dark:text-stone-400 dark:hover:bg-white/5 dark:hover:text-stone-100' }`} > - {node.title} + {node.sidebarTitle ?? node.title} {node.method && }