diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js index b14ccf2a3ba2..c5aaf709ef3c 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/index.js +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/index.js @@ -101,110 +101,105 @@ function DocItem(props) { {permalink && } {permalink && } -
-
-
-
-
- {version && ( -
- - Version: {version} - -
- )} - {!hideTitle && ( -
-

{title}

-
- )} -
- + +
+
+
+
+ {version && ( +
+ + Version: {version} +
-
- {(editUrl || lastUpdatedAt || lastUpdatedBy) && ( -
-
-
- {editUrl && ( - - - - - - - Edit this page - - )} -
- {(lastUpdatedAt || lastUpdatedBy) && ( -
- - - Last updated{' '} - {lastUpdatedAt && ( - <> - on{' '} - - {lastUpdatedBy && ' '} - - )} - {lastUpdatedBy && ( - <> - by {lastUpdatedBy} - - )} - {process.env.NODE_ENV === 'development' && ( -
- - {' '} - (Simulated during dev for better perf) - -
- )} -
-
-
+ )} + {!hideTitle && ( +
+

{title}

+
+ )} +
+ +
+
+ {(editUrl || lastUpdatedAt || lastUpdatedBy) && ( +
+
+
+ {editUrl && ( + + + + + + + Edit this page + )}
+ {(lastUpdatedAt || lastUpdatedBy) && ( +
+ + + Last updated{' '} + {lastUpdatedAt && ( + <> + on{' '} + + {lastUpdatedBy && ' '} + + )} + {lastUpdatedBy && ( + <> + by {lastUpdatedBy} + + )} + {process.env.NODE_ENV === 'development' && ( +
+ + {' '} + (Simulated during dev for better perf) + +
+ )} +
+
+
+ )}
- )} -
-
+ )} +
+
- {!hideTableOfContents && DocContent.rightToc && ( - - )}
+ {!hideTableOfContents && DocContent.rightToc && ( + + )}
); diff --git a/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css index cf9e52051164..b5fc2b3fc931 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocItem/styles.module.css @@ -21,14 +21,6 @@ } } -@media (min-width: 997px) and (max-width: 1320px) { - .docItemWrapper { - max-width: calc( - var(--ifm-container-width) - 300px - var(--ifm-spacing-horizontal) * 2 - ); - } -} - .tableOfContents { display: inherit; max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem)); diff --git a/packages/docusaurus-theme-classic/src/theme/DocPage/index.js b/packages/docusaurus-theme-classic/src/theme/DocPage/index.js index 397fecd22784..554423b6a9db 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPage/index.js +++ b/packages/docusaurus-theme-classic/src/theme/DocPage/index.js @@ -5,8 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {useState, useCallback} from 'react'; import {MDXProvider} from '@mdx-js/react'; +import classnames from 'classnames'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import renderRoutes from '@docusaurus/renderRoutes'; @@ -44,6 +45,23 @@ function DocPage(props) { isClient, } = useDocusaurusContext(); + const [hiddenSidebar, setHiddenSidebar] = useState(false); + // This state (and timeout above) is necessary to prevent background blinking + // (since click triggers hover effect) when collapsing sidebar. + const [enabledSidebarEffects, setEnabledSidebarEffects] = useState(false); + + const toggleSidebar = useCallback(() => { + if (!hiddenSidebar) { + setTimeout(() => { + setEnabledSidebarEffects(true); + }, 500); + } else { + setEnabledSidebarEffects(false); + } + + setHiddenSidebar(!hiddenSidebar); + }); + if (!isHomePage && Object.keys(currentRoute).length === 0) { return ; } @@ -52,23 +70,50 @@ function DocPage(props) {
{sidebar && ( -
+
+ + {hiddenSidebar && ( +
+ )}
)}
- - {isHomePage ? ( - - ) : ( - renderRoutes(baseRoute.routes) - )} - +
+ + {isHomePage ? ( + + ) : ( + renderRoutes(baseRoute.routes) + )} + +
diff --git a/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css index 9e3427363d81..55cd3a30d8f5 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocPage/styles.module.css @@ -5,20 +5,21 @@ * LICENSE file in the root directory of this source tree. */ +:root { + --doc-sidebar-width: 300px; +} + .docPage { display: flex; } .docSidebarContainer { border-right: 1px solid var(--ifm-toc-border-color); - box-sizing: border-box; - width: 300px; - position: relative; + width: var(--doc-sidebar-width); margin-top: calc(-1 * var(--ifm-navbar-height)); -} - -.docMainContainer { - flex-grow: 1; + will-change: width; + transition: width 0.2s ease-in-out; + clip-path: inset(0); } @media (max-width: 996px) { @@ -27,6 +28,61 @@ } .docSidebarContainer { - margin-top: 0; + display: none; + } +} + +.docSidebarContainerHidden { + width: 30px; + cursor: e-resize; + pointer-events: none; +} + +.docSidebarContainerHidden:hover, +.docSidebarContainerHidden:focus { + background-color: var(--ifm-color-emphasis-100); +} + +.docSidebarContainerEnabledEffects { + pointer-events: initial; +} + +.collapsedDocSidebar { + height: 100%; + position: relative; + z-index: 1; +} + +.collapsedDocSidebar:before { + content: ''; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='20px' height='20px' viewBox='0 0 20 20'%3E%3Cg%3E%3Cpath style='stroke:none;fill-rule:nonzero;fill:rgb(122,122,122);fill-opacity:1;' d='M 9.992188 10.023438 C 9.992188 10.222656 9.929688 10.421875 9.820312 10.570312 L 4.824219 18.0625 C 4.644531 18.335938 4.347656 18.515625 3.996094 18.515625 L 1 18.515625 C 0.449219 18.515625 0 18.0625 0 17.515625 C 0 17.316406 0.0585938 17.113281 0.167969 16.964844 L 4.796875 10.023438 L 0.167969 3.078125 C 0.0585938 2.929688 0 2.730469 0 2.527344 C 0 1.980469 0.449219 1.53125 1 1.53125 L 3.996094 1.53125 C 4.347656 1.53125 4.644531 1.710938 4.824219 1.980469 L 9.820312 9.472656 C 9.929688 9.621094 9.992188 9.820312 9.992188 10.023438 Z M 9.992188 10.023438 '/%3E%3Cpath style='stroke:none;fill-rule:nonzero;fill:rgb(122,122,122);fill-opacity:1;' d='M 19.980469 10.023438 C 19.980469 10.222656 19.921875 10.421875 19.8125 10.570312 L 14.816406 18.0625 C 14.636719 18.335938 14.335938 18.515625 13.988281 18.515625 L 10.988281 18.515625 C 10.441406 18.515625 9.992188 18.0625 9.992188 17.515625 C 9.992188 17.316406 10.050781 17.113281 10.160156 16.964844 L 14.785156 10.023438 L 10.160156 3.078125 C 10.050781 2.929688 9.992188 2.730469 9.992188 2.527344 C 9.992188 1.980469 10.441406 1.53125 10.988281 1.53125 L 13.988281 1.53125 C 14.335938 1.53125 14.636719 1.710938 14.816406 1.980469 L 19.8125 9.472656 C 19.921875 9.621094 19.980469 9.820312 19.980469 10.023438 Z M 19.980469 10.023438'/%3E%3C/g%3E%3C/svg%3E"); + top: calc(100vh - 21px); + display: block; + width: 20px; + height: 20px; + position: sticky; + left: 4px; +} + +.docMainContainer { + flex-grow: 1; +} + +.docItemWrapperEnhanced { + max-width: calc(var(--ifm-container-width) + var(--doc-sidebar-width)); +} + +@media (min-width: 997px) and (max-width: 1320px) { + .docItemWrapper { + max-width: calc( + var(--ifm-container-width) - var(--doc-sidebar-width) - + var(--ifm-spacing-horizontal) * 2 + ); + } + + .docItemWrapperEnhanced { + max-width: calc( + var(--ifm-container-width) - var(--ifm-spacing-horizontal) * 2 + ); } } diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.js b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.js index ebe1d4c9776c..8a8f2f280a31 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.js +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/index.js @@ -160,7 +160,10 @@ function DocSidebar(props) { const [showResponsiveSidebar, setShowResponsiveSidebar] = useState(false); const { siteConfig: { - themeConfig: {navbar: {title, hideOnScroll = false} = {}}, + themeConfig: { + navbar: {title, hideOnScroll = false} = {}, + hideableSidebar = false, + }, } = {}, isClient, } = useDocusaurusContext(); @@ -173,6 +176,8 @@ function DocSidebar(props) { path, sidebar: currentSidebar, sidebarCollapsible, + onToggle, + isHiddenSidebar, } = props; useLockBodyScroll(showResponsiveSidebar); @@ -193,6 +198,7 @@ function DocSidebar(props) {
{hideOnScroll && (
+ + {hideableSidebar && ( + + )}
); } diff --git a/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css b/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css index af715c0b9266..5b5d388b5651 100644 --- a/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/DocSidebar/styles.module.css @@ -5,12 +5,15 @@ * LICENSE file in the root directory of this source tree. */ +:root { + --toggle-sidebar-button-height: 35px; +} + @media (min-width: 997px) { .sidebar { display: flex; flex-direction: column; height: 100vh; - overflow-y: auto; position: sticky; top: 0; padding-top: var(--ifm-navbar-height); @@ -20,6 +23,11 @@ padding-top: 0; } + .sidebarHidden { + opacity: 0; + display: none; + } + .sidebar::-webkit-scrollbar { width: 7px; } @@ -81,3 +89,27 @@ line-height: 0.9; width: 24px; } + +.toggleSidebarButton { + position: sticky; + bottom: 0; + display: flex; + justify-content: center; + border-radius: 0; +} + +html[data-theme='dark'] .toggleSidebarButton { + background: var(--ifm-color-emphasis-200); + color: var(--ifm-color-content); + border: none; +} + +html[data-theme='dark'] .toggleSidebarButton:hover, +html[data-theme='dark'] .toggleSidebarButton:focus { + background: var(--ifm-color-emphasis-300); +} + +.toggleSidebarButton:focus { + --ifm-button-background-color: var(--ifm-color-secondary-dark) !important; + --ifm-button-border-color: var(--ifm-color-secondary-dark); +} diff --git a/website/docs/docs.md b/website/docs/docs.md index fbebab73f6ec..35a744d7f1a8 100644 --- a/website/docs/docs.md +++ b/website/docs/docs.md @@ -97,6 +97,20 @@ module.exports = { }; ``` +### Hideable sidebar + +Using the enabled `themeConfig.hideableSidebar` option, you can make the entire sidebar hided, allowing you to better focus your users on the content. This is especially useful when content consumption on medium screens (e.g. on tablets). + +```js {4} title="docusaurus.config.js" +module.exports = { + // ... + themeConfig: { + hideableSidebar: true, + // ... + }, +}; +``` + ### Sidebar object A sidebar object is defined like this: diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index faa58f1cbba4..56d5ebf89a90 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -62,6 +62,7 @@ module.exports = { ], ], themeConfig: { + hideableSidebar: true, announcementBar: { id: 'supportus', content: