update docusaurus to v2.0.0-beta.5

Signed-off-by: jffarge <jf@dagger.io>
This commit is contained in:
jffarge
2021-09-07 11:34:59 +02:00
parent 3ef1196cb6
commit 15648e42ac
13 changed files with 541 additions and 560 deletions

View File

@@ -6,19 +6,30 @@
*/
import React, {useCallback, useState, useEffect} from 'react';
import clsx from 'clsx';
import Translate from '@docusaurus/Translate';
import SearchBar from '@theme/SearchBar';
import Toggle from '@theme/Toggle';
import useThemeContext from '@theme/hooks/useThemeContext';
import {useThemeConfig} from '@docusaurus/theme-common';
import {
useThemeConfig,
useMobileSecondaryMenuRenderer,
usePrevious,
} from '@docusaurus/theme-common';
import useHideableNavbar from '@theme/hooks/useHideableNavbar';
import useLockBodyScroll from '@theme/hooks/useLockBodyScroll';
import useWindowSize, {windowSizes} from '@theme/hooks/useWindowSize';
import useWindowSize from '@theme/hooks/useWindowSize';
import {useActivePlugin} from '@theme/hooks/useDocs';
import NavbarItem from '@theme/NavbarItem';
import Logo from '@theme/Logo';
import IconMenu from '@theme/IconMenu';
import styles from './styles.module.css'; // retrocompatible with v1
const DefaultNavItemPosition = 'right'; // If split links by left/right
const DefaultNavItemPosition = 'right';
function useNavbarItems() {
// TODO temporary casting until ThemeConfig type is improved
return useThemeConfig().navbar.items;
} // If split links by left/right
// if position is unspecified, fallback to right (as v1)
function splitNavItemsByPosition(items) {
@@ -34,54 +45,173 @@ function splitNavItemsByPosition(items) {
};
}
function Navbar() {
function useMobileSidebar() {
const windowSize = useWindowSize(); // Mobile sidebar not visible on hydration: can avoid SSR rendering
const shouldRender = windowSize === 'mobile'; // || windowSize === 'ssr';
const [shown, setShown] = useState(false);
const toggle = useCallback(() => {
setShown((s) => !s);
}, []);
useEffect(() => {
if (windowSize === 'desktop') {
setShown(false);
}
}, [windowSize]);
return {
shouldRender,
toggle,
shown,
};
}
function useColorModeToggle() {
const {
navbar: {items, hideOnScroll, style},
colorMode: {disableSwitch: disableColorModeSwitch},
colorMode: {disableSwitch},
} = useThemeConfig();
const [sidebarShown, setSidebarShown] = useState(false);
const {isDarkTheme, setLightTheme, setDarkTheme} = useThemeContext();
const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);
useLockBodyScroll(sidebarShown);
const showSidebar = useCallback(() => {
setSidebarShown(true);
}, [setSidebarShown]);
const hideSidebar = useCallback(() => {
setSidebarShown(false);
}, [setSidebarShown]);
const onToggleChange = useCallback(
const toggle = useCallback(
(e) => (e.target.checked ? setDarkTheme() : setLightTheme()),
[setLightTheme, setDarkTheme],
);
const windowSize = useWindowSize();
return {
isDarkTheme,
toggle,
disabled: disableSwitch,
};
}
function useSecondaryMenu({sidebarShown, toggleSidebar}) {
const content = useMobileSecondaryMenuRenderer()?.({
toggleSidebar,
});
const previousContent = usePrevious(content);
const [shown, setShown] = useState(() => {
// /!\ content is set with useEffect,
// so it's not available on mount anyway
// "return !!content" => always returns false
return false;
}); // When content is become available for the first time (set in useEffect)
// we set this content to be shown!
useEffect(() => {
if (windowSize === windowSizes.desktop) {
setSidebarShown(false);
const contentBecameAvailable = content && !previousContent;
if (contentBecameAvailable) {
setShown(true);
}
}, [windowSize]);
}, [content, previousContent]);
const hasContent = !!content; // On sidebar close, secondary menu is set to be shown on next re-opening
// (if any secondary menu content available)
useEffect(() => {
if (!hasContent) {
setShown(false);
return;
}
if (!sidebarShown) {
setShown(true);
}
}, [sidebarShown, hasContent]);
const hide = useCallback(() => {
setShown(false);
}, []);
return {
shown,
hide,
content,
};
}
function NavbarMobileSidebar({sidebarShown, toggleSidebar}) {
useLockBodyScroll(sidebarShown);
const items = useNavbarItems();
const colorModeToggle = useColorModeToggle();
const secondaryMenu = useSecondaryMenu({
sidebarShown,
toggleSidebar,
});
return (
<div className="navbar-sidebar">
<div className="navbar-sidebar__brand">
<Logo
className="navbar__brand"
imageClassName="navbar__logo"
titleClassName="navbar__title"
/>
{!colorModeToggle.disabled && sidebarShown && (
<Toggle
checked={colorModeToggle.isDarkTheme}
onChange={colorModeToggle.toggle}
/>
)}
</div>
<div
className={clsx('navbar-sidebar__items', {
'navbar-sidebar__items--show-secondary': secondaryMenu.shown,
})}>
<div className="navbar-sidebar__item menu">
<ul className="menu__list">
{items.map((item, i) => (
<NavbarItem mobile {...item} onClick={toggleSidebar} key={i} />
))}
</ul>
</div>
<div className="navbar-sidebar__item menu">
{items.length > 0 && (
<button
type="button"
className="clean-btn navbar-sidebar__back"
onClick={secondaryMenu.hide}>
<Translate
id="theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel"
description="The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)">
Back to main menu
</Translate>
</button>
)}
{secondaryMenu.content}
</div>
</div>
</div>
);
}
function Navbar() {
const {
navbar: {hideOnScroll, style},
} = useThemeConfig();
const mobileSidebar = useMobileSidebar();
const colorModeToggle = useColorModeToggle();
const activeDocPlugin = useActivePlugin();
const {navbarRef, isNavbarVisible} = useHideableNavbar(hideOnScroll);
const items = useNavbarItems();
const hasSearchNavbarItem = items.some((item) => item.type === 'search');
const {leftItems, rightItems} = splitNavItemsByPosition(items);
const algoliaSearch = rightItems.shift()
return (
<nav
ref={navbarRef}
className={clsx('navbar', 'navbar--fixed-top', {
'navbar--dark': style === 'dark',
'navbar--primary': style === 'primary',
'navbar-sidebar--show': sidebarShown,
'navbar-sidebar--show': mobileSidebar.shown,
[styles.navbarHideable]: hideOnScroll,
[styles.navbarHidden]: hideOnScroll && !isNavbarVisible,
})}>
<div className="navbar__inner">
<div className="navbar__items">
{items != null && items.length !== 0 && (
{(items?.length > 0 || activeDocPlugin) && (
<button
aria-label="Navigation bar toggle"
className="navbar__toggle clean-btn"
type="button"
tabIndex={0}
onClick={showSidebar}
onKeyDown={showSidebar}>
onClick={mobileSidebar.toggle}
onKeyDown={mobileSidebar.toggle}>
<IconMenu />
</button>
)}
@@ -95,52 +225,40 @@ function Navbar() {
))}
</div>
<div className="navbar__items navbar__items--right">
<NavbarItem {...algoliaSearch} key={999} />
{!disableColorModeSwitch && (
<Toggle
className={styles.displayOnlyInLargeViewport}
checked={isDarkTheme}
onChange={onToggleChange}
/>
)}
{rightItems.map((item, i) => (
<NavbarItem {...item} key={i} />
))}
{!hasSearchNavbarItem && <SearchBar />}
{rightItems.map((item, i) => {
if(item.type === "search") {
return (
<React.Fragment key={i}>
<NavbarItem {...item} />
{!colorModeToggle.disabled && (
<Toggle
className={styles.toggle}
checked={colorModeToggle.isDarkTheme}
onChange={colorModeToggle.toggle}
/>
)}
</React.Fragment>
)
} else {
return <NavbarItem {...item} key={i} />
}
})}
</div>
</div>
<div
role="presentation"
className="navbar-sidebar__backdrop"
onClick={hideSidebar}
onClick={mobileSidebar.toggle}
/>
<div className="navbar-sidebar">
<div className="navbar-sidebar__brand">
<Logo
className="navbar__brand"
imageClassName="navbar__logo"
titleClassName="navbar__title"
onClick={hideSidebar}
/>
{!disableColorModeSwitch && sidebarShown && (
<Toggle checked={isDarkTheme} onChange={onToggleChange} />
)}
</div>
<div className="navbar-sidebar__items">
<div className="menu">
<ul className="menu__list">
{items.map((item, i) => (
<NavbarItem
mobile
{...item} // TODO fix typing
onClick={hideSidebar}
key={i}
/>
))}
</ul>
</div>
</div>
</div>
{mobileSidebar.shouldRender && (
<NavbarMobileSidebar
sidebarShown={mobileSidebar.shown}
toggleSidebar={mobileSidebar.toggle}
/>
)}
</nav>
);
}