| /** |
| * Copyright (c) Facebook, Inc. and its affiliates. |
| * |
| * This source code is licensed under the MIT license found in the |
| * LICENSE file in the root directory of this source tree. |
| */ |
| |
| import React, {type ReactNode, useState, useCallback} from 'react'; |
| import clsx from 'clsx'; |
| import {prefersReducedMotion, ThemeClassNames} from '@docusaurus/theme-common'; |
| import {useDocsSidebar} from '@docusaurus/theme-common/internal'; |
| import {useLocation} from '@docusaurus/router'; |
| import DocSidebar from '@theme/DocSidebar'; |
| import ExpandButton from '@theme/DocPage/Layout/Sidebar/ExpandButton'; |
| import type {Props} from '@theme/DocPage/Layout/Sidebar'; |
| |
| import styles from './styles.module.css'; |
| |
| // Reset sidebar state when sidebar changes |
| // Use React key to unmount/remount the children |
| // See https://github.com/facebook/docusaurus/issues/3414 |
| function ResetOnSidebarChange({children}: {children: ReactNode}) { |
| const sidebar = useDocsSidebar(); |
| return ( |
| <React.Fragment key={sidebar?.name ?? 'noSidebar'}> |
| {children} |
| </React.Fragment> |
| ); |
| } |
| |
| export default function DocPageLayoutSidebar({ |
| sidebar, |
| hiddenSidebarContainer, |
| setHiddenSidebarContainer, |
| }: Props): JSX.Element { |
| const {pathname} = useLocation(); |
| |
| const [hiddenSidebar, setHiddenSidebar] = useState(false); |
| const toggleSidebar = useCallback(() => { |
| if (hiddenSidebar) { |
| setHiddenSidebar(false); |
| } |
| // onTransitionEnd won't fire when sidebar animation is disabled |
| // fixes https://github.com/facebook/docusaurus/issues/8918 |
| if (!hiddenSidebar && prefersReducedMotion()) { |
| setHiddenSidebar(true); |
| } |
| setHiddenSidebarContainer((value) => !value); |
| }, [setHiddenSidebarContainer, hiddenSidebar]); |
| |
| return ( |
| <aside |
| className={clsx( |
| ThemeClassNames.docs.docSidebarContainer, |
| styles.docSidebarContainer, |
| hiddenSidebarContainer && styles.docSidebarContainerHidden, |
| )} |
| onTransitionEnd={(e) => { |
| if (!e.currentTarget.classList.contains(styles.docSidebarContainer!)) { |
| return; |
| } |
| |
| if (hiddenSidebarContainer) { |
| setHiddenSidebar(true); |
| } |
| }}> |
| <ResetOnSidebarChange> |
| <div |
| className={clsx( |
| styles.sidebarViewport, |
| hiddenSidebar && styles.sidebarViewportHidden, |
| )}> |
| <DocSidebar |
| sidebar={sidebar} |
| path={pathname} |
| onCollapse={toggleSidebar} |
| isHidden={hiddenSidebar} |
| /> |
| {hiddenSidebar && <ExpandButton toggleSidebar={toggleSidebar} />} |
| </div> |
| </ResetOnSidebarChange> |
| </aside> |
| ); |
| } |