Skip to content

Instantly share code, notes, and snippets.

@chrisregner
Created August 29, 2018 05:08
Show Gist options
  • Save chrisregner/7b48d2f97f3d5042aaf7f0baea8f942a to your computer and use it in GitHub Desktop.
Save chrisregner/7b48d2f97f3d5042aaf7f0baea8f942a to your computer and use it in GitHub Desktop.
import React from "react";
import PropTypes from "prop-types";
import styled from "styled-components";
import debounce from "lodash/debounce";
class OverflowShadow extends React.Component {
state = { scrollPos: null }
componentDidMount = () => {
const el = this.containerRef.current
this.setState({ scrollPos: calcScrollPos(el) })
el.addEventListener("scroll", this.handleScroll);
}
containerRef = React.createRef()
handleScroll = debounce(ev => {
this.setState({ scrollPos: calcScrollPos(ev.target) })
}, 100);
render = () => (
<Container innerRef={this.containerRef} {...this.props}>
{["BOT", "MID"].includes(this.state.scrollPos) && <UpperShadow />}
{this.props.children}
{["TOP", "MID"].includes(this.state.scrollPos) && <LowerShadow />}
</Container>
)
}
OverflowShadow.propTypes = {
children: PropTypes.node.isRequired,
}
const calcScrollPos = el => {
const isTop = el.scrollTop <= 0;
const isBot = el.scrollTop === el.scrollHeight - el.offsetHeight;
const isOverflowed = el.scrollHeight > el.clientHeight;
const scrollPos = (
(!isOverflowed && "NO_OVERFLOW")
|| (isTop && "TOP")
|| (isBot && "BOT")
|| "MID"
);
return console.log(scrollPos) || scrollPos;
};
const Container = styled.div`
overflow: auto;
position: relative;
min-height: 50px;
`;
const UpperShadow = styled.div`
position: absolute;
top: 0;
width: 100%;
min-height: 50px;
background: -moz-linear-gradient(top, rgba(0,0,0,0.75) 0%, rgba(255,255,255,0) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(0,0,0,0.75) 0%,rgba(255,255,255,0) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(0,0,0,0.75) 0%,rgba(255,255,255,0) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bf000000', endColorstr='#00ffffff',GradientType=0 ); /* IE6-9 */
`;
const LowerShadow = styled.div`
position: absolute;
bottom: 0;
width: 100%;
min-height: 50px;
background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(0,0,0,0.75) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(0,0,0,0.75) 100%); /* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(0,0,0,0.75) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#bf000000',GradientType=0 ); /* IE6-9 */
`;
export default OverflowShadow;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment