Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 33 additions & 47 deletions src/components/LibraryLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ import {
getLibraryLayoutVersion,
getLibraryTabLinkOptions,
getMenuGroupInitialOpenState,
isChartsCatalogTarget,
} from './library-layout-navigation'
import {
customToolTabs,
isCustomToolTarget,
type CustomToolTabId,
} from '~/libraries/custom-tool-tabs'

// Number of days a doc page is flagged as "New"/"Updated" in the sidebar.
const RECENCY_WINDOW_DAYS = 7
Expand Down Expand Up @@ -674,18 +678,6 @@ const useMenuConfig = ({
const currentFramework = useCurrentFramework(frameworks)
const statsAvailable =
getLibrary(libraryId as LibraryId).statsAvailable !== false
const chartsExamplesMenuItems: MenuItem['children'] = [
{
label: 'Examples',
to: '/charts/catalog',
tab: 'home',
},
{
label: 'Examples',
to: '/charts/catalog',
tab: 'examples',
},
]

const localMenu: MenuItem = {
label: 'Menu',
Expand All @@ -694,7 +686,6 @@ const useMenuConfig = ({
label: 'Home',
to: '..',
},
...(libraryId === 'charts' ? chartsExamplesMenuItems : []),
{
label: 'Blog',
to: '/$libraryId/$version/docs/blog',
Expand Down Expand Up @@ -826,13 +817,7 @@ export function LibraryLayout({
const LibraryIcon = libraryIcons[libraryId] ?? fallbackLibraryIcon
const libraryGroupColor = categoryTextColor[categoryOf(libraryId)]

const isExample = matches.some(
(d) =>
d.pathname.includes('/examples/') ||
d.routeId.startsWith('/_library/charts/catalog'),
)

const isNpmStats = matches.some((d) => d.pathname.includes('/docs/npm-stats'))
const docsTab = matches.find((d) => d.staticData.docsTab)?.staticData.docsTab

// The library blog already lists posts, so the "Latest Posts" rail widget is
// redundant there — hide it on the blog while keeping it on other docs pages.
Expand Down Expand Up @@ -866,30 +851,29 @@ export function LibraryLayout({
const tabbedMenuConfig = React.useMemo(() => {
const tabs = getTabbedMenuConfig(menuConfig)

return libraryId === 'charts'
? tabs.map((tab) =>
tab.id === 'examples'
? {
...tab,
firstItem: {
label: 'Examples',
to: '/charts/catalog',
tab: 'examples',
},
}
: tab,
)
: tabs
const extraTabs: Array<{
id: CustomToolTabId
label: string
groups: MenuItem[]
firstItem: MenuItem['children'][number]
}> = (customToolTabs[libraryId] ?? []).map((tool) => ({
id: tool.id,
label: tool.label,
groups: [],
firstItem: { label: tool.label, to: tool.to },
}))

return [...tabs, ...extraTabs]
}, [libraryId, menuConfig])

const activeTabId = React.useMemo(() => {
return getActiveDocsNavTabId({
isExample,
tabIdOverride: docsTab?.id,
menuConfig,
pathname: lastMatch.pathname,
relativePathname,
})
}, [isExample, lastMatch.pathname, menuConfig, relativePathname])
}, [docsTab?.id, lastMatch.pathname, menuConfig, relativePathname])

const visibleMenuConfig = React.useMemo(() => {
return (
Expand Down Expand Up @@ -928,11 +912,12 @@ export function LibraryLayout({

const groupInitialOpenState = React.useMemo(() => {
return getMenuGroupInitialOpenState(
libraryId,
visibleMenuConfig,
_splat,
lastMatch.pathname,
)
}, [lastMatch.pathname, visibleMenuConfig, _splat])
}, [libraryId, lastMatch.pathname, visibleMenuConfig, _splat])

const [openGroups, setOpenGroups] = React.useState(groupInitialOpenState)

Expand Down Expand Up @@ -1006,7 +991,7 @@ export function LibraryLayout({
? ({ libraryId, version } as never)
: undefined
const isHomeLink = child.to === '..'
const isChartsExamplesLink = isChartsCatalogTarget(child.to)
const isCustomToolLink = isCustomToolTarget(libraryId, child.to)
const frameworkDocsTarget = getFrameworkDocsLinkTarget(child.to)

const recency = getDocRecency(child.addedAt, child.updatedAt)
Expand Down Expand Up @@ -1094,14 +1079,12 @@ export function LibraryLayout({
) : (
<Link
from={
isChartsExamplesLink
? undefined
: '/$libraryId/$version/docs'
isCustomToolLink ? undefined : '/$libraryId/$version/docs'
}
to={child.to}
params={linkParams}
onClick={closeMobileMenu}
preload={isChartsExamplesLink ? false : 'intent'}
preload={isCustomToolLink ? false : 'intent'}
activeOptions={{
exact: true,
includeHash: false,
Expand Down Expand Up @@ -1208,7 +1191,9 @@ export function LibraryLayout({
params={linkOptions.params as never}
onClick={closeMobileMenu}
preload={
isChartsCatalogTarget(target.to) ? false : 'intent'
isCustomToolTarget(libraryId, target.to)
? false
: 'intent'
}
aria-current={isActive ? 'page' : undefined}
className={twMerge(
Expand Down Expand Up @@ -1392,7 +1377,9 @@ export function LibraryLayout({
from={linkOptions.from as never}
to={linkOptions.to as never}
params={linkOptions.params as never}
preload={isChartsCatalogTarget(target.to) ? false : 'intent'}
preload={
isCustomToolTarget(libraryId, target.to) ? false : 'intent'
}
activeOptions={{
exact: true,
includeHash: false,
Expand Down Expand Up @@ -1491,8 +1478,7 @@ export function LibraryLayout({
!isLandingPage && 'px-4 md:px-8',

!isLandingPage &&
!isExample &&
!isNpmStats &&
!docsTab?.fullBleed &&
!isFullWidth &&
'mx-auto w-[900px]',
)}
Expand Down
12 changes: 8 additions & 4 deletions src/components/library-layout-navigation.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { isCustomToolTarget } from '~/libraries/custom-tool-tabs'
import type { LibraryId } from '~/libraries/ids'
import type { MenuItem } from '~/utils/config'

export function isChartsCatalogTarget(to: string) {
Expand All @@ -22,15 +24,15 @@ export function getLibraryTabLinkOptions({
version,
to,
}: {
libraryId: string
libraryId: LibraryId
version: string
to: string
}) {
const isHomeTarget = to === '..'

return {
from:
isHomeTarget || isChartsCatalogTarget(to)
isHomeTarget || isCustomToolTarget(libraryId, to)
? undefined
: '/$libraryId/$version/docs',
to: isHomeTarget ? `/${libraryId}/${version}` : to,
Expand All @@ -46,6 +48,7 @@ function normalizeMenuPath(path: string) {
}

export function isMenuTargetActive(
libraryId: LibraryId,
to: string,
relativePathname: string | undefined,
pathname: string,
Expand All @@ -55,12 +58,13 @@ export function isMenuTargetActive(
}

return (
isChartsCatalogTarget(to) &&
isCustomToolTarget(libraryId, to) &&
normalizeMenuPath(to) === normalizeMenuPath(pathname)
)
}

export function getMenuGroupInitialOpenState(
libraryId: LibraryId,
groups: MenuItem[],
relativePathname: string | undefined,
pathname: string,
Expand All @@ -69,7 +73,7 @@ export function getMenuGroupInitialOpenState(

groups.forEach((group, index) => {
const isChildActive = group.children.some((child) =>
isMenuTargetActive(child.to, relativePathname, pathname),
isMenuTargetActive(libraryId, child.to, relativePathname, pathname),
)
const key = `${index}:${String(group.label)}`

Expand Down
28 changes: 28 additions & 0 deletions src/libraries/custom-tool-tabs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { LibraryId } from './ids'
import type { FileRouteTypes } from '~/routeTree.gen'

// A "custom tool tab" is a page bolted onto a library's docs nav bar that isn't sourced from the library's docs/config.json
export type CustomToolTabId = 'catalog' | 'theme-editor'

export type CustomToolTab = {
id: CustomToolTabId
label: string
to: FileRouteTypes['fullPaths']
}

export const customToolTabs: Partial<Record<LibraryId, CustomToolTab[]>> = {
charts: [{ id: 'catalog', label: 'Examples', to: '/charts/catalog' }],
// highlight: [
// {
// id: "theme-editor",
// label: "Theme Editor",
// to: "/highlight/$version/theme-editor",
// },
// ],
}

export function isCustomToolTarget(libraryId: LibraryId, to: string) {
return (customToolTabs[libraryId] ?? []).some(
(tab) => to === tab.to || to.startsWith(`${tab.to}/`),
)
}
Loading
Loading