saagie-ui
Version:
Saagie UI from Saagie Design System
82 lines (65 loc) • 2.31 kB
JavaScript
import React, { useRef, useEffect, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Container } from '../container/Container';
import { usePageContext } from './Page';
const propTypes = {
children: PropTypes.node,
tag: PropTypes.elementType,
};
const defaultProps = {
children: '',
tag: 'div',
};
export const PageContent = ({ children, tag: Tag }) => {
const {
size,
gutterHorizontal,
isContentScrolled,
setIsContentScrolled,
rangeAnimationShouldNotStart,
shouldNotAnimateTopBar,
setShouldNotAnimateTopBar,
} = usePageContext();
const scrollRef = useRef();
const isContentScrolledRef = useRef();
isContentScrolledRef.current = isContentScrolled;
const handleScroll = useCallback((e) => {
const { scrollTop } = e.srcElement || {};
const isScrolled = (scrollTop && scrollTop > 0) || false;
// Do not trigger shriking of the page top bar if the scrollTop
// is too little, otherwise we get stuck in a loop
if (shouldNotAnimateTopBar && isScrolled) {
return;
}
if (isScrolled !== isContentScrolledRef.current) {
setIsContentScrolled(isScrolled);
}
}, [rangeAnimationShouldNotStart, setIsContentScrolled, shouldNotAnimateTopBar]);
useEffect(() => {
if (!scrollRef.current || !rangeAnimationShouldNotStart) {
return () => {};
}
const { scrollHeight, clientHeight } = scrollRef.current;
const noScroll = scrollHeight - clientHeight > 0;
const notEnoughScroll = scrollHeight - clientHeight <= rangeAnimationShouldNotStart;
const isContentNotScrollableEnough = noScroll && notEnoughScroll;
if (isContentNotScrollableEnough) {
setShouldNotAnimateTopBar(true);
}
scrollRef.current.addEventListener('scroll', handleScroll);
return () => {
scrollRef.current.removeEventListener('scroll', handleScroll);
};
}, [rangeAnimationShouldNotStart, shouldNotAnimateTopBar, children]);
return (
<Tag className="sui-l-app-layout__page">
<div className="sui-l-app-layout__page-scroll" ref={scrollRef}>
<Container size={size} gutterHorizontal={gutterHorizontal}>
{children}
</Container>
</div>
</Tag>
);
};
PageContent.propTypes = propTypes;
PageContent.defaultProps = defaultProps;