diff --git a/packages/docusaurus-playground/docs/test/1.md b/packages/docusaurus-playground/docs/test/1.md new file mode 100644 index 0000000..ffb0a30 --- /dev/null +++ b/packages/docusaurus-playground/docs/test/1.md @@ -0,0 +1,6 @@ +--- +title: 1 +sidebar_position: 1 +--- + +# 111 diff --git a/packages/docusaurus-playground/docs/test/2.md b/packages/docusaurus-playground/docs/test/2.md new file mode 100644 index 0000000..c066eac --- /dev/null +++ b/packages/docusaurus-playground/docs/test/2.md @@ -0,0 +1,6 @@ +--- +title: 2 +sidebar_position: 1 +--- + +# 222 diff --git a/packages/docusaurus-playground/docs/test/3/33.md b/packages/docusaurus-playground/docs/test/3/33.md new file mode 100644 index 0000000..9fc7246 --- /dev/null +++ b/packages/docusaurus-playground/docs/test/3/33.md @@ -0,0 +1,6 @@ +--- +title: 333 +sidebar_position: 1 +--- + +# 333 diff --git a/packages/logos-docusaurus-theme/src/client/css/custom.scss b/packages/logos-docusaurus-theme/src/client/css/custom.scss index f7a02fb..e4dca32 100644 --- a/packages/logos-docusaurus-theme/src/client/css/custom.scss +++ b/packages/logos-docusaurus-theme/src/client/css/custom.scss @@ -12,7 +12,6 @@ --ifm-navbar-link-color: rgb(var(--lsd-text-primary)); --ifm-dropdown-link-color: rgb(var(--lsd-text-secondary)); --ifm-dropdown-hover-background-color: rgb(var(--lsd-surface-secondary)); - --ifm-menu-color-active: rgb(var(--lsd-text-secondary)); /* Colors. */ /*--ifm-dark-value: 10%;*/ @@ -159,7 +158,8 @@ --ifm-menu-link-padding-horizontal: var(--ifm-spacing-horizontal); --ifm-menu-link-padding-vertical: 0.375rem; - --ifm-menu-color-background-active: var(--ifm-color-gray-300); + --ifm-menu-color: rgb(var(--lsd-text-primary), 0.6); + --ifm-menu-color-background-active: transparent; --ifm-menu-link-sublist-icon: url('data:image/svg+xml;utf8,'); --ifm-menu-link-sublist-icon-filter: none; @@ -317,6 +317,12 @@ small { border: none !important; } +.menu__link { + display: flex; + justify-content: space-between; + align-items: center; +} + @media (max-width: 576px) { :root { --ifm-global-spacing: 0.5rem; diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/index.tsx new file mode 100644 index 0000000..87e18c0 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/index.tsx @@ -0,0 +1,74 @@ +import React, { 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 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 }) { + const sidebar = useDocsSidebar() + return ( + + {children} + + ) +} +export default function DocPageLayoutSidebar({ + sidebar, + hiddenSidebarContainer, + setHiddenSidebarContainer, +}) { + 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 ( + + ) +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/styles.module.css b/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/styles.module.css new file mode 100644 index 0000000..ded4577 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocPage/Layout/Sidebar/styles.module.css @@ -0,0 +1,31 @@ +: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; + } + + .sidebarViewport { + top: 0; + position: sticky; + height: 100%; + max-height: 100vh; + } +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/index.tsx new file mode 100644 index 0000000..5198702 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/index.tsx @@ -0,0 +1,30 @@ +import React from 'react' +import clsx from 'clsx' +import { translate } from '@docusaurus/Translate' +import IconArrow from '@theme/Icon/Arrow' +import styles from './styles.module.css' + +export default function CollapseButton({ onClick }) { + return ( + + ) +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/styles.module.css b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/styles.module.css new file mode 100644 index 0000000..df46519 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/CollapseButton/styles.module.css @@ -0,0 +1,40 @@ +:root { + --docusaurus-collapse-button-bg: transparent; + --docusaurus-collapse-button-bg-hover: rgb(0 0 0 / 10%); +} + +[data-theme='dark']:root { + --docusaurus-collapse-button-bg: rgb(255 255 255 / 5%); + --docusaurus-collapse-button-bg-hover: rgb(255 255 255 / 10%); +} + +@media (min-width: 997px) { + .collapseSidebarButton { + display: block !important; + background-color: var(--docusaurus-collapse-button-bg); + 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); + } + + .collapseSidebarButton:hover, + .collapseSidebarButton:focus { + background-color: var(--docusaurus-collapse-button-bg-hover); + } +} + +.collapseSidebarButton { + display: none; + margin: 0; +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/index.js b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/index.js new file mode 100644 index 0000000..81f7c3f --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/index.js @@ -0,0 +1,45 @@ +import React, { useState } from 'react' +import clsx from 'clsx' +import { ThemeClassNames } from '@docusaurus/theme-common' +import { + useAnnouncementBar, + useScrollPosition, +} from '@docusaurus/theme-common/internal' +import { translate } from '@docusaurus/Translate' +import DocSidebarItems from '@theme/DocSidebarItems' +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 }) { + const showAnnouncementBar = useShowAnnouncementBar() + return ( + + ) +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/styles.module.css b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/styles.module.css new file mode 100644 index 0000000..0c43a4e --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/Content/styles.module.css @@ -0,0 +1,16 @@ +@media (min-width: 997px) { + .menu { + flex-grow: 1; + padding: 0.5rem; + } + @supports (scrollbar-gutter: stable) { + .menu { + padding: 0.5rem 0 0.5rem 0.5rem; + scrollbar-gutter: stable; + } + } + + .menuWithAnnouncementBar { + margin-bottom: var(--docusaurus-announcement-bar-height); + } +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/index.tsx new file mode 100644 index 0000000..7242ecf --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/index.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import clsx from 'clsx' +import { useThemeConfig } from '@docusaurus/theme-common' +import Logo from '@theme/Logo' +import Content from '@theme/DocSidebar/Desktop/Content' +import styles from './styles.module.css' +function DocSidebarDesktop({ path, sidebar, onCollapse, isHidden }) { + const { + navbar: { hideOnScroll }, + docs: { + sidebar: { hideable }, + }, + } = useThemeConfig() + return ( +
+ {hideOnScroll && } + +
+ ) +} +export default React.memo(DocSidebarDesktop) diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/styles.module.css b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/styles.module.css new file mode 100644 index 0000000..c5d5e50 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/Desktop/styles.module.css @@ -0,0 +1,37 @@ +@media (min-width: 997px) { + .sidebar { + display: flex; + flex-direction: column; + height: 100%; + padding-top: var(--ifm-navbar-height); + width: var(--doc-sidebar-width); + } + + .sidebarWithHideableNavbar { + padding-top: 0; + } + + .sidebarHidden { + opacity: 0; + 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/logos-docusaurus-theme/src/client/theme/DocSidebar/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/index.tsx new file mode 100644 index 0000000..fd80d91 --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebar/index.tsx @@ -0,0 +1,18 @@ +import React from 'react' +import { useWindowSize } from '@docusaurus/theme-common' +import DocSidebarDesktop from '@theme/DocSidebar/Desktop' +import DocSidebarMobile from '@theme/DocSidebar/Mobile' +export default function DocSidebar(props) { + const windowSize = useWindowSize() + // Desktop sidebar visible on hydration: need SSR rendering + const shouldRenderSidebarDesktop = + windowSize === 'desktop' || windowSize === 'ssr' + // Mobile sidebar not visible on hydration: can avoid SSR rendering + const shouldRenderSidebarMobile = windowSize === 'mobile' + return ( + <> + {shouldRenderSidebarDesktop && } + {shouldRenderSidebarMobile && } + + ) +} diff --git a/packages/logos-docusaurus-theme/src/client/theme/DocSidebarItem/Category/index.tsx b/packages/logos-docusaurus-theme/src/client/theme/DocSidebarItem/Category/index.tsx new file mode 100644 index 0000000..bba0b2d --- /dev/null +++ b/packages/logos-docusaurus-theme/src/client/theme/DocSidebarItem/Category/index.tsx @@ -0,0 +1,193 @@ +import React, { useEffect, useMemo } from 'react' +import clsx from 'clsx' +import { + ThemeClassNames, + useThemeConfig, + usePrevious, + Collapsible, + useCollapsible, +} from '@docusaurus/theme-common' +import { + isActiveSidebarItem, + findFirstCategoryLink, + useDocSidebarItemsExpandedState, + isSamePath, +} from '@docusaurus/theme-common/internal' +import Link from '@docusaurus/Link' +import { translate } from '@docusaurus/Translate' +import useIsBrowser from '@docusaurus/useIsBrowser' +import DocSidebarItems from '@theme/DocSidebarItems' +import { ArrowDownIcon, ArrowUpIcon } from '@acid-info/lsd-react' + +// If we navigate to a category and it becomes active, it should automatically +// expand itself +function useAutoExpandActiveCategory({ isActive, collapsed, updateCollapsed }) { + const wasActive = usePrevious(isActive) + useEffect(() => { + const justBecameActive = isActive && !wasActive + if (justBecameActive && collapsed) { + updateCollapsed(false) + } + }, [isActive, wasActive, collapsed, updateCollapsed]) +} +/** + * When a collapsible category has no link, we still link it to its first child + * during SSR as a temporary fallback. This allows to be able to navigate inside + * the category even when JS fails to load, is delayed or simply disabled + * React hydration becomes an optional progressive enhancement + * see https://github.com/facebookincubator/infima/issues/36#issuecomment-772543188 + * see https://github.com/facebook/docusaurus/issues/3030 + */ + +function useCategoryHrefWithSSRFallback(item) { + const isBrowser = useIsBrowser() + return useMemo(() => { + if (item.href) { + return item.href + } + // In these cases, it's not necessary to render a fallback + // We skip the "findFirstCategoryLink" computation + if (isBrowser || !item.collapsible) { + return undefined + } + return findFirstCategoryLink(item) + }, [item, isBrowser]) +} + +function CollapseButton({ categoryLabel, onClick }) { + return ( +