From e97dc0d37e18d0d14c695d099e46f12ab445ea8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Thu, 10 Mar 2022 16:55:30 +0100 Subject: [PATCH] refactor(theme-classic): split sidebar into smaller parts (#6844) Co-authored-by: Joshua Chen --- .../src/theme-classic.d.ts | 36 +++++ .../Desktop/CollapseButton/index.tsx | 38 ++++++ .../Desktop/CollapseButton/styles.module.css | 44 ++++++ .../DocSidebar/Desktop/Content/index.tsx | 55 ++++++++ .../Desktop/Content/styles.module.css | 17 +++ .../src/theme/DocSidebar/Desktop/index.tsx | 38 ++++++ .../DocSidebar/Desktop/styles.module.css | 50 +++++++ .../src/theme/DocSidebar/Mobile/index.tsx | 51 +++++++ .../src/theme/DocSidebar/index.tsx | 127 +----------------- .../src/theme/DocSidebar/styles.module.css | 107 --------------- project-words.txt | 1 + .../theme/DocSidebar/Desktop/Content/index.js | 30 +++++ 12 files changed, 366 insertions(+), 228 deletions(-) create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/styles.module.css create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/index.tsx create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/styles.module.css create mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/Mobile/index.tsx delete mode 100644 packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css create mode 100644 website/src/theme/DocSidebar/Desktop/Content/index.js diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index a5653f8edc..e6b4359b7a 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -180,6 +180,42 @@ declare module '@theme/DocSidebar' { export default function DocSidebar(props: Props): JSX.Element; } +declare module '@theme/DocSidebar/Mobile' { + import type {Props as DocSidebarProps} from '@theme/DocSidebar'; + + export interface Props extends DocSidebarProps {} + + export default function DocSidebarMobile(props: Props): JSX.Element; +} + +declare module '@theme/DocSidebar/Desktop' { + import type {Props as DocSidebarProps} from '@theme/DocSidebar'; + + export interface Props extends DocSidebarProps {} + + export default function DocSidebarDesktop(props: Props): JSX.Element; +} + +declare module '@theme/DocSidebar/Desktop/Content' { + import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; + + export interface Props { + readonly className?: string; + readonly path: string; + readonly sidebar: readonly PropSidebarItem[]; + } + + export default function CollapseButton(props: Props): JSX.Element; +} + +declare module '@theme/DocSidebar/Desktop/CollapseButton' { + export interface Props { + onClick: React.MouseEventHandler; + } + + export default function CollapseButton(props: Props): JSX.Element; +} + declare module '@theme/DocSidebarItem' { import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/index.tsx new file mode 100644 index 0000000000..c902ac90d6 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/index.tsx @@ -0,0 +1,38 @@ +/** + * 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 from 'react'; +import clsx from 'clsx'; +import IconArrow from '@theme/IconArrow'; +import {translate} from '@docusaurus/Translate'; +import type {Props} from '@theme/DocSidebar/Desktop/CollapseButton'; + +import styles from './styles.module.css'; + +export default function CollapseButton({onClick}: Props): JSX.Element { + return ( + + ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css new file mode 100644 index 0000000000..4e225b0bdd --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/CollapseButton/styles.module.css @@ -0,0 +1,44 @@ +/** + * 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. + */ + +:root { + --collapse-button-bg-color-dark: #2e333a; +} + +@media (min-width: 997px) { + .collapseSidebarButton { + display: block !important; + background-color: var(--ifm-button-background-color); + height: 40px; + position: sticky; + bottom: 0; + border-radius: 0; + border: 1px solid var(--ifm-toc-border-color); + } + + .collapseSidebarButtonIcon { + transform: rotate(180deg); + margin-top: 4px; + } + + [dir='rtl'] .collapseSidebarButtonIcon { + transform: rotate(0); + } + + [data-theme='dark'] .collapseSidebarButton { + background-color: var(--collapse-button-bg-color-dark); + } + + [data-theme='dark'] .collapseSidebarButton:hover, + [data-theme='dark'] .collapseSidebarButton:focus { + background-color: var(--ifm-color-emphasis-200); + } +} + +.collapseSidebarButton { + display: none; +} diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/index.tsx new file mode 100644 index 0000000000..f72a9c27a3 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/index.tsx @@ -0,0 +1,55 @@ +/** + * 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, {useState} from 'react'; +import clsx from 'clsx'; +import { + ThemeClassNames, + useAnnouncementBar, + useScrollPosition, +} from '@docusaurus/theme-common'; +import DocSidebarItems from '@theme/DocSidebarItems'; +import type {Props} from '@theme/DocSidebar/Desktop/Content'; + +import styles from './styles.module.css'; + +function useShowAnnouncementBar() { + const {isActive} = useAnnouncementBar(); + const [showAnnouncementBar, setShowAnnouncementBar] = useState(isActive); + + useScrollPosition( + ({scrollY}) => { + if (isActive) { + setShowAnnouncementBar(scrollY === 0); + } + }, + [isActive], + ); + return isActive && showAnnouncementBar; +} + +export default function DocSidebarDesktopContent({ + path, + sidebar, + className, +}: Props): JSX.Element { + const showAnnouncementBar = useShowAnnouncementBar(); + + return ( + + ); +} diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/styles.module.css new file mode 100644 index 0000000000..1ee104b73a --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/Content/styles.module.css @@ -0,0 +1,17 @@ +/** + * 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. + */ + +@media (min-width: 997px) { + .menu { + flex-grow: 1; + padding: 0.5rem; + } + + .menuWithAnnouncementBar { + margin-bottom: var(--docusaurus-announcement-bar-height); + } +} diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/index.tsx new file mode 100644 index 0000000000..b2b9357d91 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/index.tsx @@ -0,0 +1,38 @@ +/** + * 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 from 'react'; +import clsx from 'clsx'; +import {useThemeConfig} from '@docusaurus/theme-common'; +import Logo from '@theme/Logo'; +import CollapseButton from '@theme/DocSidebar/Desktop/CollapseButton'; +import Content from '@theme/DocSidebar/Desktop/Content'; +import type {Props} from '@theme/DocSidebar/Desktop'; + +import styles from './styles.module.css'; + +function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}: Props) { + const { + navbar: {hideOnScroll}, + hideableSidebar, + } = useThemeConfig(); + + return ( +
+ {hideOnScroll && } + + {hideableSidebar && } +
+ ); +} + +export default React.memo(DocSidebarDesktop); diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/styles.module.css new file mode 100644 index 0000000000..8d7734af15 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Desktop/styles.module.css @@ -0,0 +1,50 @@ +/** + * 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. + */ + +@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; +} diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/Mobile/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Mobile/index.tsx new file mode 100644 index 0000000000..30f23afbf8 --- /dev/null +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/Mobile/index.tsx @@ -0,0 +1,51 @@ +/** + * 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 from 'react'; +import clsx from 'clsx'; +import { + MobileSecondaryMenuFiller, + type MobileSecondaryMenuComponent, + ThemeClassNames, +} from '@docusaurus/theme-common'; +import DocSidebarItems from '@theme/DocSidebarItems'; +import type {Props} from '@theme/DocSidebar/Mobile'; + +// eslint-disable-next-line react/function-component-definition +const DocSidebarMobileSecondaryMenu: MobileSecondaryMenuComponent = ({ + toggleSidebar, + sidebar, + path, +}) => ( +
    + { + // Mobile sidebar should only be closed if the category has a link + if (item.type === 'category' && item.href) { + toggleSidebar(); + } + if (item.type === 'link') { + toggleSidebar(); + } + }} + level={1} + /> +
+); + +function DocSidebarMobile(props: Props) { + return ( + + ); +} + +export default React.memo(DocSidebarMobile); diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx index 5e727e2c46..5bbd9e2eb7 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.tsx @@ -5,126 +5,11 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useState} from 'react'; -import clsx from 'clsx'; -import { - useThemeConfig, - useAnnouncementBar, - MobileSecondaryMenuFiller, - type MobileSecondaryMenuComponent, - ThemeClassNames, - useScrollPosition, - useWindowSize, -} from '@docusaurus/theme-common'; -import Logo from '@theme/Logo'; -import IconArrow from '@theme/IconArrow'; -import {translate} from '@docusaurus/Translate'; -import DocSidebarItems from '@theme/DocSidebarItems'; +import React from 'react'; +import {useWindowSize} from '@docusaurus/theme-common'; import type {Props} from '@theme/DocSidebar'; - -import styles from './styles.module.css'; - -function useShowAnnouncementBar() { - const {isActive} = useAnnouncementBar(); - const [showAnnouncementBar, setShowAnnouncementBar] = useState(isActive); - - useScrollPosition( - ({scrollY}) => { - if (isActive) { - setShowAnnouncementBar(scrollY === 0); - } - }, - [isActive], - ); - return isActive && showAnnouncementBar; -} - -function HideableSidebarButton({onClick}: {onClick: React.MouseEventHandler}) { - return ( - - ); -} - -function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}: Props) { - const showAnnouncementBar = useShowAnnouncementBar(); - const { - navbar: {hideOnScroll}, - hideableSidebar, - } = useThemeConfig(); - - return ( -
- {hideOnScroll && } - - {hideableSidebar && } -
- ); -} - -// eslint-disable-next-line react/function-component-definition -const DocSidebarMobileSecondaryMenu: MobileSecondaryMenuComponent = ({ - toggleSidebar, - sidebar, - path, -}) => ( -
    - { - // Mobile sidebar should only be closed if the category has a link - if (item.type === 'category' && item.href) { - toggleSidebar(); - } - if (item.type === 'link') { - toggleSidebar(); - } - }} - level={1} - /> -
-); - -function DocSidebarMobile(props: Props) { - return ( - - ); -} - -const DocSidebarDesktopMemo = React.memo(DocSidebarDesktop); -const DocSidebarMobileMemo = React.memo(DocSidebarMobile); +import DocSidebarDesktop from '@theme/DocSidebar/Desktop'; +import DocSidebarMobile from '@theme/DocSidebar/Mobile'; export default function DocSidebar(props: Props): JSX.Element { const windowSize = useWindowSize(); @@ -138,8 +23,8 @@ export default function DocSidebar(props: Props): JSX.Element { return ( <> - {shouldRenderSidebarDesktop && } - {shouldRenderSidebarMobile && } + {shouldRenderSidebarDesktop && } + {shouldRenderSidebarMobile && } ); } diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css deleted file mode 100644 index 101dcd45d5..0000000000 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css +++ /dev/null @@ -1,107 +0,0 @@ -/** - * 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. - */ - -:root { - --collapse-button-bg-color-dark: #2e333a; -} - -@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; - } - - .menu { - flex-grow: 1; - padding: 0.5rem; - } - - .menuWithAnnouncementBar { - margin-bottom: var(--docusaurus-announcement-bar-height); - } - - .collapseSidebarButton { - display: block !important; - background-color: var(--ifm-button-background-color); - height: 40px; - position: sticky; - bottom: 0; - border-radius: 0; - border: 1px solid var(--ifm-toc-border-color); - } - - .collapseSidebarButtonIcon { - transform: rotate(180deg); - margin-top: 4px; - } - - [dir='rtl'] .collapseSidebarButtonIcon { - transform: rotate(0); - } - - [data-theme='dark'] .collapseSidebarButton { - background-color: var(--collapse-button-bg-color-dark); - } - - [data-theme='dark'] .collapseSidebarButton:hover, - [data-theme='dark'] .collapseSidebarButton:focus { - background-color: var(--ifm-color-emphasis-200); - } -} - -.sidebarLogo, -.collapseSidebarButton { - display: none; -} - -.sidebarMenuIcon { - vertical-align: middle; -} - -.sidebarMenuCloseIcon { - display: inline-flex; - justify-content: center; - align-items: center; - height: 24px; - font-size: 1.5rem; - font-weight: var(--ifm-font-weight-bold); - line-height: 0.9; - width: 24px; -} diff --git a/project-words.txt b/project-words.txt index 7b4d8c4c10..f3b7bb87e3 100644 --- a/project-words.txt +++ b/project-words.txt @@ -38,6 +38,7 @@ chedeau cheng clément clsx +codeql codespaces codesandbox contravariance diff --git a/website/src/theme/DocSidebar/Desktop/Content/index.js b/website/src/theme/DocSidebar/Desktop/Content/index.js new file mode 100644 index 0000000000..1096f37716 --- /dev/null +++ b/website/src/theme/DocSidebar/Desktop/Content/index.js @@ -0,0 +1,30 @@ +/** + * 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 from 'react'; +import Content from '@theme-original/DocSidebar/Desktop/Content'; +import {useLocation} from '@docusaurus/router'; + +function SidebarAd() { + return ( +
+ Sidebar Ad +
+ ); +} + +export default function ContentWrapper(props) { + const {pathname} = useLocation(); + const shouldShowSidebarAd = pathname.includes('/tests/'); + return ( + <> + {shouldShowSidebarAd && } + + {shouldShowSidebarAd && } + + ); +}