Add sticky sidebars and footer nav in Techdocs Reader

Signed-off-by: Chongyang Adrian, Ke <ftt.adrian.ke@grabtaxi.com>
This commit is contained in:
Chongyang Adrian, Ke
2021-03-19 15:43:34 +08:00
parent 8012eafa28
commit 8c32fbb8c4
2 changed files with 43 additions and 3 deletions
@@ -17,7 +17,7 @@ import { EntityName } from '@backstage/catalog-model';
import { useApi } from '@backstage/core';
import { BackstageTheme } from '@backstage/theme';
import { useTheme } from '@material-ui/core';
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useAsync } from 'react-use';
import { techdocsStorageApiRef } from '../../api';
@@ -47,12 +47,32 @@ export const Reader = ({ entityId, onReady }: Props) => {
const techdocsStorageApi = useApi(techdocsStorageApiRef);
const [shadowDomRef, shadowRoot] = useShadowDom();
const [sidebars, setSidebars] = useState<HTMLElement[]>();
const navigate = useNavigate();
const { value, loading, error } = useAsync(async () => {
return techdocsStorageApi.getEntityDocs({ kind, namespace, name }, path);
}, [techdocsStorageApi, kind, namespace, name, path]);
useEffect(() => {
const updateSidebarPosition = () => {
if (!!shadowRoot && !!shadowDomRef.current && !!sidebars) {
sidebars!.forEach(sidebar => {
const newTop = Math.max(
shadowDomRef.current!.getBoundingClientRect().top,
0,
);
sidebar.style.top = `${newTop}px`;
});
}
};
updateSidebarPosition();
document.addEventListener('scroll', updateSidebarPosition);
return () => {
document.removeEventListener('scroll', updateSidebarPosition);
};
}, [shadowDomRef, shadowRoot, sidebars]);
React.useEffect(() => {
if (!shadowRoot || loading || error) {
return; // Shadow DOM isn't ready / It's not ready / Docs was not found
@@ -82,10 +102,15 @@ export const Reader = ({ entityId, onReady }: Props) => {
--md-code-bg-color: ${theme.palette.background.paper};
}
.md-main__inner { margin-top: 0; }
.md-sidebar { top: 0; width: 20rem; }
.md-sidebar { position: fixed; bottom: 100px; width: 20rem; }
.md-sidebar--secondary { right: 2rem; }
.md-content { margin-bottom: 50px }
.md-footer { position: fixed; bottom: 0px; width: 100vw; }
.md-footer-nav__link { width: 20rem;}
.md-content { margin-left: 20rem; max-width: calc(100% - 20rem * 2 - 3rem); }
.md-typeset { font-size: 1rem; }
.md-nav { font-size: 1rem; }
.md-grid { max-width: 80vw; }
.md-grid { max-width: 90vw; margin: 0 }
`,
}),
]);
@@ -135,6 +160,16 @@ export const Reader = ({ entityId, onReady }: Props) => {
},
onLoaded: (dom: Element) => {
(dom as HTMLElement).style.removeProperty('opacity');
const sideDivs: HTMLElement[] = Array.from(
shadowRoot!.querySelectorAll('.md-sidebar'),
);
setSidebars(sideDivs);
// set sidebar height so they don't initially render in wrong position
const docTopPosition = (dom as HTMLElement).getBoundingClientRect()
.top;
sideDivs!.forEach(sidebar => {
sidebar.style.top = `${docTopPosition}px`;
});
},
}),
]);