From e14f12ec44be79288c8d2ed209eea1030227950e Mon Sep 17 00:00:00 2001 From: Sean Cassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Sun, 18 Aug 2024 01:36:09 +1200 Subject: [PATCH] feat: optionally allow the primary sections of the project sidebar be collapsible (#258) * chore: cleanup imports * feat: docs config schema to accept a `collapsible` boolean * chore: tweak the zod schema and MenuItem type * feat: add the collapsible menu * refactor: correct semantic tags for the list of links * feat: make the details collapsible by default --- app/components/DocsLayout.tsx | 43 +++++++++++++++++++++----------- app/utils/config.ts | 4 +++ tanstack-docs-config.schema.json | 10 ++++++++ 3 files changed, 42 insertions(+), 15 deletions(-) diff --git a/app/components/DocsLayout.tsx b/app/components/DocsLayout.tsx index 9d84c8f8..a425c9b2 100644 --- a/app/components/DocsLayout.tsx +++ b/app/components/DocsLayout.tsx @@ -12,10 +12,9 @@ import { useMatches, useNavigate, useParams, - useRouterState, } from '@tanstack/react-router' import type { AnyOrama, SearchParamsFullText, AnyDocument } from '@orama/orama' -import { SearchBox, SearchButton } from '@orama/searchbox' +import { SearchBox } from '@orama/searchbox' import { Carbon } from '~/components/Carbon' import { Select } from '~/components/Select' import { useLocalStorage } from '~/utils/useLocalStorage' @@ -25,7 +24,7 @@ import type { SelectOption } from '~/components/Select' import type { ConfigSchema, MenuItem } from '~/utils/config' import { create } from 'zustand' import { searchBoxParams, searchButtonParams } from '~/components/Orama' -import { Framework, getFrameworkOptions, getLibrary } from '~/libraries' +import { Framework, getFrameworkOptions } from '~/libraries' import { DocsCalloutQueryGG } from '~/components/DocsCalloutQueryGG' import { DocsCalloutBytes } from '~/components/DocsCalloutBytes' import { ClientOnlySearchButton } from './ClientOnlySearchButton' @@ -179,7 +178,7 @@ const useMenuConfig = ({ config: ConfigSchema repo: string frameworks: Framework[] -}) => { +}): MenuItem[] => { const currentFramework = useCurrentFramework(frameworks) const localMenu: MenuItem = { @@ -211,7 +210,7 @@ const useMenuConfig = ({ return [ localMenu, // Merge the two menus together based on their group labels - ...config.sections.map((section) => { + ...config.sections.map((section): MenuItem | undefined => { const frameworkDocs = section.frameworks?.find( (f) => f.label === currentFramework.framework ) @@ -232,9 +231,11 @@ const useMenuConfig = ({ return { label: section.label, children, + collapsible: section.collapsible ?? false, + defaultCollapsed: section.defaultCollapsed ?? false, } }), - ].filter(Boolean) + ].filter((item) => item !== undefined) } const useFrameworkConfig = ({ frameworks }: { frameworks: Framework[] }) => { @@ -317,8 +318,7 @@ export function DocsLayout({ children, }: DocsLayoutProps) { const { libraryId } = useParams({ - strict: false, - experimental_returnIntersection: true, + from: '/$libraryId/$version/docs', }) const frameworkConfig = useFrameworkConfig({ frameworks }) const versionConfig = useVersionConfig({ versions }) @@ -350,16 +350,29 @@ export function DocsLayout({ const [showBytes, setShowBytes] = useLocalStorage('showBytes', true) const menuItems = menuConfig.map((group, i) => { + const WrapperComp = group.collapsible ? 'details' : 'div' + const LabelComp = group.collapsible ? 'summary' : 'div' + + const isCollapsed = group.defaultCollapsed ?? false + + const detailsProps = group.collapsible ? { open: !isCollapsed } : {} + return ( -