docs: added show/hide sidebar button (#4150)
* docs: added show/hide sidebar button * added check for browser * fix build error * solve build errors
This commit is contained in:
@@ -1,24 +1,27 @@
|
||||
import React from "react"
|
||||
import React, { useContext } from "react"
|
||||
import clsx from "clsx"
|
||||
import { useDocsSidebar } from "@docusaurus/theme-common/internal"
|
||||
import type { Props } from "@theme/DocPage/Layout/Main"
|
||||
import { SidebarContext } from "@site/src/context/sidebar"
|
||||
|
||||
export default function DocPageLayoutMain({
|
||||
hiddenSidebarContainer,
|
||||
children,
|
||||
}: Props): JSX.Element {
|
||||
export default function DocPageLayoutMain({ children }: Props): JSX.Element {
|
||||
const sidebar = useDocsSidebar()
|
||||
const sidebarContext = useContext(SidebarContext)
|
||||
return (
|
||||
<main
|
||||
className={clsx(
|
||||
"tw-flex tw-flex-col tw-w-full lg:tw-flex-grow lg:tw-max-w-[calc(100%-320px)]",
|
||||
(hiddenSidebarContainer || !sidebar) && "lg:tw-max-w-[calc(100%-30px)]"
|
||||
"tw-flex tw-flex-col tw-w-full lg:tw-flex-grow",
|
||||
(sidebarContext?.hiddenSidebarContainer || !sidebar) &&
|
||||
"lg:tw-max-w-[calc(100%-30px)]",
|
||||
!sidebarContext?.hiddenSidebarContainer &&
|
||||
"xxl:tw-max-w-[1119px] lg:tw-max-w-[calc(100%-321px)]"
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"container padding-top--md tw-px-0",
|
||||
hiddenSidebarContainer && "lg:tw-max-w-main-content-hidden-sidebar"
|
||||
sidebarContext?.hiddenSidebarContainer &&
|
||||
"lg:tw-max-w-main-content-hidden-sidebar"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, { type ReactNode, useState, useCallback, useRef } from "react"
|
||||
import React, { type ReactNode, useRef, useContext } from "react"
|
||||
import clsx from "clsx"
|
||||
import { 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 { SwitchTransition, CSSTransition } from "react-transition-group"
|
||||
import { SidebarContext } from "@site/src/context/sidebar"
|
||||
|
||||
// Reset sidebar state when sidebar changes
|
||||
// Use React key to unmount/remount the children
|
||||
@@ -23,18 +23,9 @@ function ResetOnSidebarChange({ children }: { children: ReactNode }) {
|
||||
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)
|
||||
}
|
||||
setHiddenSidebarContainer((value) => !value)
|
||||
}, [setHiddenSidebarContainer, hiddenSidebar])
|
||||
|
||||
const sidebarContext = useContext(SidebarContext)
|
||||
const { name } = useDocsSidebar()
|
||||
const sidebarRef = useRef(null)
|
||||
|
||||
@@ -42,8 +33,13 @@ export default function DocPageLayoutSidebar({
|
||||
<aside
|
||||
className={clsx(
|
||||
ThemeClassNames.docs.docSidebarContainer,
|
||||
"lg:tw-block lg:tw-w-sidebar lg:tw-will-change-[width] lg:tw-transition-[width] lg:tw-ease-ease tw-clip tw-hidden tw-duration-200",
|
||||
hiddenSidebarContainer && "lg:tw-w-sidebar-hidden lg:tw-cursor-pointer"
|
||||
"lg:tw-block lg:tw-w-sidebar lg:tw-transition-[left] lg:tw-ease-ease lg:tw-duration-200 lg:tw-left-0 tw-hidden",
|
||||
!hiddenSidebarContainer && "clip",
|
||||
hiddenSidebarContainer &&
|
||||
"lg:tw-fixed lg:tw-left-[-100%] lg:tw-rounded lg:tw-border-0 lg:tw-border-medusa-border-strong lg:dark:tw-border-medusa-border-strong-dark",
|
||||
hiddenSidebarContainer &&
|
||||
sidebarContext?.floatingSidebar &&
|
||||
"lg:!tw-left-0.5 lg:tw-top-[65px] lg:tw-z-20 lg:tw-bg-docs-bg lg:dark:tw-bg-docs-bg-dark lg:tw-shadow-flyout lg:dark:tw-shadow-flyout-dark"
|
||||
)}
|
||||
onTransitionEnd={(e) => {
|
||||
if (
|
||||
@@ -55,7 +51,24 @@ export default function DocPageLayoutSidebar({
|
||||
}
|
||||
|
||||
if (hiddenSidebarContainer) {
|
||||
setHiddenSidebar(true)
|
||||
sidebarContext?.setHiddenSidebar(true)
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setTimeout(() => {
|
||||
if (!document.querySelector(".sidebar-toggler:hover")) {
|
||||
sidebarContext?.setFloatingSidebar(false)
|
||||
}
|
||||
}, 100)
|
||||
}}
|
||||
onMouseUp={(e) => {
|
||||
const target = e.target as Element
|
||||
console.log("here", target.classList)
|
||||
if (
|
||||
target.classList.contains("menu__list-item") ||
|
||||
target.parentElement.classList.contains("menu__list-item")
|
||||
) {
|
||||
sidebarContext?.setFloatingSidebar(false)
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -80,12 +93,9 @@ export default function DocPageLayoutSidebar({
|
||||
<DocSidebar
|
||||
sidebar={sidebar}
|
||||
path={pathname}
|
||||
onCollapse={toggleSidebar}
|
||||
isHidden={hiddenSidebar}
|
||||
onCollapse={sidebarContext?.onCollapse}
|
||||
isHidden={sidebarContext?.hiddenSidebar}
|
||||
/>
|
||||
{hiddenSidebar && (
|
||||
<ExpandButton toggleSidebar={toggleSidebar} />
|
||||
)}
|
||||
</div>
|
||||
</ResetOnSidebarChange>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import React, { useContext } from "react"
|
||||
import { useDocsSidebar } from "@docusaurus/theme-common/internal"
|
||||
import Layout from "@theme/Layout"
|
||||
import BackToTopButton from "@theme/BackToTopButton"
|
||||
import DocPageLayoutSidebar from "@theme/DocPage/Layout/Sidebar"
|
||||
import DocPageLayoutMain from "@theme/DocPage/Layout/Main"
|
||||
import type { Props } from "@theme/DocPage/Layout"
|
||||
import { SidebarContext } from "@site/src/context/sidebar"
|
||||
import clsx from "clsx"
|
||||
|
||||
export default function DocPageLayout({ children }: Props): JSX.Element {
|
||||
const sidebar = useDocsSidebar()
|
||||
const sidebarContext = useContext(SidebarContext)
|
||||
return (
|
||||
<Layout wrapperClassName={clsx("tw-flex tw-flex-[1_0_auto]")}>
|
||||
<BackToTopButton />
|
||||
<div className={clsx("tw-flex tw-w-full tw-flex-[1_0]")}>
|
||||
{sidebar && (
|
||||
<DocPageLayoutSidebar
|
||||
sidebar={sidebar.items}
|
||||
hiddenSidebarContainer={sidebarContext?.hiddenSidebarContainer}
|
||||
setHiddenSidebarContainer={
|
||||
sidebarContext?.setHiddenSidebarContainer
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<DocPageLayoutMain
|
||||
hiddenSidebarContainer={sidebarContext?.hiddenSidebarContainer}
|
||||
>
|
||||
{children}
|
||||
</DocPageLayoutMain>
|
||||
</div>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import React, { useCallback, useEffect, useState } from "react"
|
||||
import clsx from "clsx"
|
||||
import {
|
||||
HtmlClassNameProvider,
|
||||
ThemeClassNames,
|
||||
PageMetadata,
|
||||
prefersReducedMotion,
|
||||
} from "@docusaurus/theme-common"
|
||||
import {
|
||||
docVersionSearchTag,
|
||||
@@ -15,6 +16,7 @@ import DocPageLayout from "@theme/DocPage/Layout"
|
||||
import NotFound from "@theme/NotFound"
|
||||
import SearchMetadata from "@theme/SearchMetadata"
|
||||
import type { Props } from "@theme/DocPage"
|
||||
import { SidebarContext } from "@site/src/context/sidebar"
|
||||
|
||||
function DocPageMetadata(props: Props): JSX.Element {
|
||||
const { versionMetadata } = props
|
||||
@@ -43,6 +45,52 @@ export default function DocPage(props: Props): JSX.Element {
|
||||
return <NotFound />
|
||||
}
|
||||
const { docElement, sidebarName, sidebarItems } = currentDocRouteMetadata
|
||||
|
||||
const [hiddenSidebar, setHiddenSidebar] = useState(false)
|
||||
const [hiddenSidebarContainer, setHiddenSidebarContainer] = useState(false)
|
||||
const [floatingSidebar, setFloatingSidebar] = 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])
|
||||
|
||||
useEffect(() => {
|
||||
function isEditingContent(event: KeyboardEvent) {
|
||||
const element = event.target as HTMLElement
|
||||
const tagName = element.tagName
|
||||
return (
|
||||
element.isContentEditable ||
|
||||
tagName === "INPUT" ||
|
||||
tagName === "SELECT" ||
|
||||
tagName === "TEXTAREA"
|
||||
)
|
||||
}
|
||||
|
||||
function sidebarShortcut(e: KeyboardEvent) {
|
||||
if (
|
||||
(e.metaKey || e.ctrlKey) &&
|
||||
e.key.toLowerCase() === "i" &&
|
||||
!isEditingContent(e)
|
||||
) {
|
||||
e.preventDefault()
|
||||
toggleSidebar()
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", sidebarShortcut)
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", sidebarShortcut)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<DocPageMetadata {...props} />
|
||||
@@ -57,7 +105,19 @@ export default function DocPage(props: Props): JSX.Element {
|
||||
>
|
||||
<DocsVersionProvider version={versionMetadata}>
|
||||
<DocsSidebarProvider name={sidebarName} items={sidebarItems}>
|
||||
<DocPageLayout>{docElement}</DocPageLayout>
|
||||
<SidebarContext.Provider
|
||||
value={{
|
||||
hiddenSidebar,
|
||||
setHiddenSidebar,
|
||||
hiddenSidebarContainer,
|
||||
setHiddenSidebarContainer,
|
||||
floatingSidebar,
|
||||
setFloatingSidebar,
|
||||
onCollapse: toggleSidebar,
|
||||
}}
|
||||
>
|
||||
<DocPageLayout>{docElement}</DocPageLayout>
|
||||
</SidebarContext.Provider>
|
||||
</DocsSidebarProvider>
|
||||
</DocsVersionProvider>
|
||||
</HtmlClassNameProvider>
|
||||
|
||||
Reference in New Issue
Block a user