From c5fda066b1bc1654c2854c97b5c22734a6e34344 Mon Sep 17 00:00:00 2001 From: Erik Larsson Date: Mon, 21 Feb 2022 23:15:15 +0100 Subject: [PATCH] Collapse techdocs sidebar on small devices Signed-off-by: Erik Larsson --- .changeset/lovely-goats-press.md | 5 ++ .../techdocs/src/reader/components/Reader.tsx | 49 ++++++++++++++----- .../reader/transformers/addSidebarToggle.ts | 44 +++++++++++++++++ .../techdocs/src/reader/transformers/index.ts | 1 + 4 files changed, 87 insertions(+), 12 deletions(-) create mode 100644 .changeset/lovely-goats-press.md create mode 100644 plugins/techdocs/src/reader/transformers/addSidebarToggle.ts diff --git a/.changeset/lovely-goats-press.md b/.changeset/lovely-goats-press.md new file mode 100644 index 0000000000..fc3c0b4763 --- /dev/null +++ b/.changeset/lovely-goats-press.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Collapse techdocs sidebar on small devices diff --git a/plugins/techdocs/src/reader/components/Reader.tsx b/plugins/techdocs/src/reader/components/Reader.tsx index d930eaf4e8..5f103fe535 100644 --- a/plugins/techdocs/src/reader/components/Reader.tsx +++ b/plugins/techdocs/src/reader/components/Reader.tsx @@ -46,6 +46,7 @@ import { addBaseUrl, addGitFeedbackLink, addLinkClickListener, + addSidebarToggle, injectCss, onCssReady, removeMkdocsHeader, @@ -74,8 +75,8 @@ const useStyles = makeStyles(theme => ({ marginBottom: theme.spacing(1), marginLeft: 'calc(16rem + 1.2rem)', '@media screen and (max-width: 76.1875em)': { - marginLeft: 'calc(10rem + 0.8rem)', - maxWidth: 'calc(100% - 10rem - 1.6rem)', + marginLeft: '0', + maxWidth: '100%', }, }, })); @@ -171,11 +172,20 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => { if (!dom || !sidebars) return; // set sidebar height so they don't initially render in wrong position const mdTabs = dom.querySelector('.md-container > .md-tabs'); + const sidebarsCollapsed = window.matchMedia( + 'screen and (max-width: 76.1875em)', + ).matches; + const newTop = Math.max(dom.getBoundingClientRect().top, 0); sidebars.forEach(sidebar => { - const newTop = Math.max(dom.getBoundingClientRect().top, 0); - sidebar.style.top = mdTabs - ? `${newTop + mdTabs.getBoundingClientRect().height}px` - : `${newTop}px`; + if (sidebarsCollapsed) { + sidebar.style.top = '0px'; + } else if (mdTabs) { + sidebar.style.top = `${ + newTop + mdTabs.getBoundingClientRect().height + }px`; + } else { + sidebar.style.top = `${newTop}px`; + } }); }, [dom, sidebars]); @@ -222,6 +232,7 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => { path: contentPath, }), rewriteDocLinks(), + addSidebarToggle(), removeMkdocsHeader(), simplifyMkdocsFooter(), addGitFeedbackLink(scmIntegrationsApi), @@ -489,21 +500,34 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => { } .md-sidebar--primary { - width: 10rem !important; - left: ${isPinned ? '242px' : '72px'} !important; + width: 12.1rem !important; + z-index: 200; + left: ${ + isPinned ? 'calc(224px - 12.1rem)' : 'calc(72px - 12.1rem)' + } !important; } .md-sidebar--secondary:not([hidden]) { display: none; } .md-content { - max-width: calc(100% - 10rem); - margin-left: 10rem; + max-width: 100%; + margin-left: 0; + } + + .md-header__button { + margin: 0.4rem 0; + margin-left: 0.4rem; + padding: 0; + } + + .md-overlay { + left: 0; } .md-footer { position: static; - padding-left: 10rem; + padding-left: 0; } .md-footer-nav__link { /* footer links begin to overlap at small sizes without setting width */ @@ -513,7 +537,8 @@ export const useTechDocsReaderDom = (entityRef: EntityName): Element | null => { @media screen and (max-width: 600px) { .md-sidebar--primary { - left: 1rem !important; + left: -12.1rem !important; + width: 12.1rem; } } `, diff --git a/plugins/techdocs/src/reader/transformers/addSidebarToggle.ts b/plugins/techdocs/src/reader/transformers/addSidebarToggle.ts new file mode 100644 index 0000000000..9d9db15e45 --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/addSidebarToggle.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Transformer } from './index'; +import MenuIcon from '@material-ui/icons/Menu'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +export const addSidebarToggle = (): Transformer => { + return dom => { + // attempting to use selectors that are more likely to be static as MkDocs updates over time + const mkdocsToggleSidebar = dom.querySelector( + '.md-header label[for="__drawer"]', + ) as HTMLLabelElement; + const article = dom.querySelector('article') as HTMLElement; + + // Fail gracefully + if (!mkdocsToggleSidebar || !article) { + return dom; + } + + const toggleSidebar = mkdocsToggleSidebar.cloneNode() as HTMLLabelElement; + ReactDOM.render(React.createElement(MenuIcon), toggleSidebar); + toggleSidebar.style.paddingLeft = '5px'; + toggleSidebar.classList.add('md-content__button'); + toggleSidebar.title = 'Toggle Sidebar'; + toggleSidebar.id = 'toggle-sidebar'; + article?.prepend(toggleSidebar); + return dom; + }; +}; diff --git a/plugins/techdocs/src/reader/transformers/index.ts b/plugins/techdocs/src/reader/transformers/index.ts index aa0fba2a18..dcd79180a7 100644 --- a/plugins/techdocs/src/reader/transformers/index.ts +++ b/plugins/techdocs/src/reader/transformers/index.ts @@ -16,6 +16,7 @@ export * from './addBaseUrl'; export * from './addGitFeedbackLink'; +export * from './addSidebarToggle'; export * from './rewriteDocLinks'; export * from './addLinkClickListener'; export * from './copyToClipboard';