mirror of
https://github.com/wavetermdev/docusaurus-og.git
synced 2026-08-05 13:46:35 -07:00
fix sidebar's expand/collapse bug, remove default expand and collapse buttons, and link mobile sidebar to header's toggle button.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
import { useLocation } from '@docusaurus/router'
|
||||
import { ThemeClassNames } from '@docusaurus/theme-common'
|
||||
import { useDocsSidebar } from '@docusaurus/theme-common/internal'
|
||||
import {
|
||||
globalStore,
|
||||
selectHiddenSidebar,
|
||||
} from '@site/src/containers/GlobalStore'
|
||||
import type { Props } from '@theme/DocPage/Layout/Sidebar'
|
||||
import DocSidebar from '@theme/DocSidebar'
|
||||
import clsx from 'clsx'
|
||||
import React, { ReactNode } from 'react'
|
||||
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 }: Props): JSX.Element {
|
||||
const { pathname } = useLocation()
|
||||
const dispatch = globalStore.useDispatch()
|
||||
const hiddenSidebar = globalStore.useSelector(selectHiddenSidebar)
|
||||
|
||||
return (
|
||||
<aside
|
||||
className={clsx(
|
||||
ThemeClassNames.docs.docSidebarContainer,
|
||||
styles.docSidebarContainer,
|
||||
hiddenSidebar && styles.docSidebarContainerHidden,
|
||||
)}
|
||||
onTransitionEnd={(e) => {
|
||||
if (!e.currentTarget.classList.contains(styles.docSidebarContainer!)) {
|
||||
return
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ResetOnSidebarChange>
|
||||
<DocSidebar
|
||||
sidebar={sidebar}
|
||||
path={pathname}
|
||||
onCollapse={() => dispatch.setHiddenSidebar(true)}
|
||||
isHidden={hiddenSidebar}
|
||||
/>
|
||||
</ResetOnSidebarChange>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
:root {
|
||||
--doc-sidebar-width: 300px;
|
||||
--doc-sidebar-hidden-width: 30px;
|
||||
}
|
||||
|
||||
.docSidebarContainer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 997px) {
|
||||
.docSidebarContainer {
|
||||
display: block;
|
||||
width: var(--doc-sidebar-width);
|
||||
margin-top: calc(-1 * var(--ifm-navbar-height));
|
||||
will-change: width;
|
||||
transition: width var(--ifm-transition-fast) ease;
|
||||
clip-path: inset(0);
|
||||
}
|
||||
|
||||
.docSidebarContainerHidden {
|
||||
width: var(--doc-sidebar-hidden-width);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { useThemeConfig } from '@docusaurus/theme-common'
|
||||
import type { Props } from '@theme/DocSidebar/Desktop'
|
||||
import Content from '@theme/DocSidebar/Desktop/Content'
|
||||
import Logo from '@theme/Logo'
|
||||
import clsx from 'clsx'
|
||||
import React from 'react'
|
||||
import styles from './styles.module.css'
|
||||
|
||||
function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }: Props) {
|
||||
const {
|
||||
navbar: { hideOnScroll },
|
||||
docs: {},
|
||||
} = useThemeConfig()
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
styles.sidebar,
|
||||
hideOnScroll && styles.sidebarWithHideableNavbar,
|
||||
isHidden && styles.sidebarHidden,
|
||||
)}
|
||||
>
|
||||
{hideOnScroll && <Logo tabIndex={-1} className={styles.sidebarLogo} />}
|
||||
<Content path={path} sidebar={sidebar} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(DocSidebarDesktop)
|
||||
@@ -0,0 +1,43 @@
|
||||
@media (min-width: 997px) {
|
||||
.sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 100vh;
|
||||
height: 100%;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
padding-top: var(--ifm-navbar-height);
|
||||
width: var(--doc-sidebar-width);
|
||||
transition: opacity 50ms ease;
|
||||
}
|
||||
|
||||
.sidebarWithHideableNavbar {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.sidebarHidden {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.sidebarLogo {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
margin: 0 var(--ifm-navbar-padding-horizontal);
|
||||
min-height: var(--ifm-navbar-height);
|
||||
max-height: var(--ifm-navbar-height);
|
||||
color: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.sidebarLogo img {
|
||||
margin-right: 0.5rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebarLogo {
|
||||
display: none;
|
||||
}
|
||||
@@ -31,31 +31,47 @@ function NavbarItems({ items }: { items: NavbarItemConfig[] }): JSX.Element {
|
||||
)
|
||||
}
|
||||
|
||||
const SidebarToggleButton: React.FC<{
|
||||
className: string
|
||||
onToggle: () => void
|
||||
shown: boolean
|
||||
}> = ({ className, onToggle, shown }) => {
|
||||
return (
|
||||
<button
|
||||
onClick={onToggle}
|
||||
className={clsx(styles.sidebarButton, !shown && styles.expand, className)}
|
||||
>
|
||||
{shown ? <ChevronIcon /> : <HamburgerIcon />}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
export default function NavbarContent(): JSX.Element {
|
||||
const mobileSidebar = useNavbarMobileSidebar()
|
||||
|
||||
const items = useNavbarItems()
|
||||
|
||||
const dispatch = globalStore.useDispatch()
|
||||
const hiddenDesktopSidebar = globalStore.useSelector(selectHiddenSidebar)
|
||||
|
||||
const localeDropdown = items.find((item) => item.type === 'localeDropdown')
|
||||
const links = items.filter(
|
||||
(item) => item.type === 'doc' || !!(item as any).to,
|
||||
)
|
||||
|
||||
const mobileSidebar = useNavbarMobileSidebar()
|
||||
|
||||
const dispatch = globalStore.useDispatch()
|
||||
const hiddenDesktopSidebar = globalStore.useSelector(selectHiddenSidebar)
|
||||
|
||||
return (
|
||||
<div className={clsx('row', styles.root)}>
|
||||
<div className="col col--2">
|
||||
<button
|
||||
onClick={dispatch.toggleSidebar}
|
||||
className={clsx(
|
||||
styles.sidebarButton,
|
||||
hiddenDesktopSidebar && styles.expand,
|
||||
)}
|
||||
>
|
||||
{!hiddenDesktopSidebar ? <ChevronIcon /> : <HamburgerIcon />}
|
||||
</button>
|
||||
<SidebarToggleButton
|
||||
onToggle={mobileSidebar.toggle}
|
||||
shown={mobileSidebar.shown}
|
||||
className={styles.mobile}
|
||||
/>
|
||||
<SidebarToggleButton
|
||||
onToggle={dispatch.toggleSidebar}
|
||||
shown={!hiddenDesktopSidebar}
|
||||
className={styles.desktop}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={clsx('col', styles.headerMiddle)}>
|
||||
|
||||
@@ -145,3 +145,15 @@ Hide color mode toggle in small viewports
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'up') {
|
||||
.sidebarButton.mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@include utils.responsive('lg', 'down') {
|
||||
.sidebarButton.desktop {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
.navbar-sidebar__brand {
|
||||
--ifm-navbar-padding-horizontal: 1rem;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
--ifm-navbar-height: 3.875rem;
|
||||
--ifm-navbar-background-color: none;
|
||||
--ifm-navbar-shadow: none;
|
||||
--ifm-navbar-padding-horizontal: 0px;
|
||||
--ifm-navbar-padding-vertical: 8px;
|
||||
--ifm-navbar-padding-vertical: 0.5rem;
|
||||
|
||||
background: none;
|
||||
}
|
||||
|
||||
:root {
|
||||
|
||||
Reference in New Issue
Block a user