diff --git a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts index 258b9b22c285..1722952b86ea 100644 --- a/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts +++ b/packages/docusaurus-plugin-content-docs/src/plugin-content-docs.d.ts @@ -34,6 +34,7 @@ declare module '@docusaurus/plugin-content-docs-types' { export type PropSidebarItemCategory = PropsSidebarItemBase & { type: 'category'; label: string; + link?: object; items: PropSidebarItem[]; collapsed?: boolean; }; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars.ts b/packages/docusaurus-plugin-content-docs/src/sidebars.ts index 2353a642b54e..e50766932c31 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars.ts @@ -97,7 +97,7 @@ function assertItem( function assertIsCategory( item: unknown, ): asserts item is SidebarItemCategoryJSON { - assertItem(item, ['items', 'label', 'collapsed', 'customProps']); + assertItem(item, ['items', 'label', 'collapsed', 'link', 'customProps']); if (typeof item.label !== 'string') { throw new Error( `Error loading ${JSON.stringify(item)}. "label" must be a string.`, diff --git a/packages/docusaurus-plugin-content-docs/src/types.ts b/packages/docusaurus-plugin-content-docs/src/types.ts index be171ee7793f..6fcded13711c 100644 --- a/packages/docusaurus-plugin-content-docs/src/types.ts +++ b/packages/docusaurus-plugin-content-docs/src/types.ts @@ -108,6 +108,7 @@ export type SidebarItemCategory = SidebarItemBase & { label: string; items: SidebarItem[]; collapsed: boolean; + link?: object; }; export type SidebarItem = diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx index c78a6a99119e..37dd821924dd 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx @@ -32,6 +32,10 @@ function usePrevious(value) { return ref.current; } +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + const isActiveSidebarItem = (item, activePath) => { if (item.type === 'link') { return isSamePath(item.href, activePath); @@ -49,6 +53,7 @@ function DocSidebarItemCategory({ onItemClick, collapsible, activePath, + link, ...props }) { const {items, label} = item; @@ -64,6 +69,7 @@ function DocSidebarItemCategory({ } return isActive ? false : item.collapsed; }); + const [initialLink, setInitialLink] = useState(''); const menuListRef = useRef(null); const [menuListHeight, setMenuListHeight] = useState( @@ -81,17 +87,36 @@ function DocSidebarItemCategory({ if (justBecameActive && collapsed) { setCollapsed(false); } + + if (link) { + if (Object.hasOwnProperty.call(link, 'type')) { + switch (link.type) { + case 'doc': + setInitialLink(link.id); + break; + case 'link': + setInitialLink(link.href); + break; + default: + setInitialLink(''); + break; + } + } + } }, [isActive, wasActive, collapsed]); const handleItemClick = useCallback( - (e) => { - e.preventDefault(); - + async (e) => { + if (!collapsed) { + e.preventDefault(); + } if (!menuListHeight) { handleMenuListHeight(); } - - setTimeout(() => setCollapsed((state) => !state), 100); + setCollapsed((state) => { + return !state; + }); + await sleep(100); }, [menuListHeight], ); @@ -106,17 +131,26 @@ function DocSidebarItemCategory({ 'menu__list-item--collapsed': collapsed, })} key={label}> - {label} - +
    { e.target.blur(); setShowResponsiveSidebar(false); diff --git a/packages/docusaurus-theme-classic/src/types.d.ts b/packages/docusaurus-theme-classic/src/types.d.ts index b4d5866db195..20d59e7352b9 100644 --- a/packages/docusaurus-theme-classic/src/types.d.ts +++ b/packages/docusaurus-theme-classic/src/types.d.ts @@ -77,7 +77,7 @@ declare module '@theme/DocSidebar' { export type Props = { readonly path: string; - readonly sidebar: readonly PropSidebarItem[]; + readonly sidebar: PropSidebarItem[]; readonly sidebarCollapsible?: boolean; readonly onCollapse: () => void; readonly isHidden: boolean; diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index f83ea28561f8..07c65a1be6c2 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -282,6 +282,7 @@ const LocaleConfigs = isI18nStaging ], themeConfig: { hideableSidebar: true, + sidebarCollapsible: true, colorMode: { defaultMode: 'light', disableSwitch: false, diff --git a/website/sidebars.js b/website/sidebars.js index 5d3c53828594..db2adffd60a7 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -15,12 +15,14 @@ module.exports = { { type: 'category', label: 'Getting Started', + link: {type: 'link', href: 'https://google.com'}, collapsed: false, items: ['installation', 'configuration', 'typescript-support'], }, { type: 'category', label: 'Guides', + link: {type: 'doc', id: 'creating-pages'}, items: [ 'guides/creating-pages', {