Adjust scrollbar / toc height to available space

This commit is contained in:
Piotr Janosz
2019-08-29 23:58:18 +02:00
parent 775a41a789
commit 47f4321611

View File

@@ -1,3 +1,4 @@
import * as _ from 'lodash';
import * as React from 'react';
import MediaQuery from 'react-responsive';
import styled from 'styled-components';
@@ -11,10 +12,43 @@ interface ISidebarWrapperProps {
children: React.ReactNode;
}
const THROTTLE_RATE = 200;
export const SidebarWrapper: React.FC<ISidebarWrapperProps> = ({ children }) => {
const [maxHeight, setMaxHeight] = React.useState<number>(0);
const el = React.useRef(null);
function visibleHeight(el: any) {
const elementHeight = el.offsetHeight;
const windowHeight = window.innerHeight;
const { bottom, top } = el.getBoundingClientRect();
return Math.max(0, top > 0 ? Math.min(elementHeight, windowHeight - top) : Math.min(bottom, windowHeight));
}
const listener = (e: any) => {
const newMaxHeight = visibleHeight(el.current);
setMaxHeight(newMaxHeight);
};
const throttledListener = _.throttle(listener, THROTTLE_RATE);
React.useEffect(() => {
const { top } = el.current.getBoundingClientRect();
const newHeight = window.innerHeight - top;
setMaxHeight(newHeight);
window.addEventListener('scroll', throttledListener);
window.addEventListener('resize', throttledListener);
return () => {
window.removeEventListener('scroll', throttledListener);
window.removeEventListener('resize', throttledListener);
};
}, []);
return (
<SidebarAside>
<SidebarContent>
<SidebarAside ref={el}>
<SidebarContent maxHeight={maxHeight}>
<MediaQuery maxWidth={900}>
<Collapse>{children}</Collapse>
</MediaQuery>
@@ -29,10 +63,10 @@ const SidebarAside = styled.aside`
position: relative;
`;
const SidebarContent = styled.div`
const SidebarContent = styled.div<{ maxHeight: number }>`
position: sticky;
top: ${docs.headerOffset}px; /* To make space for the header (react-headroom) when clicking on links */
max-height: 85vh;
max-height: ${props => props.maxHeight - 20}px;
overflow-y: auto;
overflow-x: hidden;