diff --git a/README.md b/README.md index f11bc74..d373090 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # react-overflow -A React component that detects when it's overflowed by its content. +A React component that detects when it's overflowed by its content. It can also tell you if you are at the edge of the scroll area. ## Installation @@ -12,6 +12,8 @@ npm install --save react-overflow ## Usage +Using the `onOverFlowChange` callback: + ```jsx import { OverflowDetector } from 'react-overflow'; @@ -27,6 +29,30 @@ function handleOverflowChange(isOverflowed) { ``` +Using the `onScrolled` callback: + +```jsx +import { OverflowDetector } from 'react-overflow'; + +class TextWithArrows extends React.Component { + state = { atTop: true, atBottom: true, atLeft: true, atRight: true }; + handleScrolled = pos => this.setState(pos); + render() { + const { text } = this.props; + const { atTop, atBottom, atLeft, atRight } = this.state; + return ( + + + {!atTop && } + {text} + {!atBottom && } + + + ); + } +} +``` + ## License [MIT](https://github.com/nickuraltsev/react-overflow/blob/master/LICENSE) diff --git a/src/OverflowDetector.jsx b/src/OverflowDetector.jsx index c18ed33..82148f5 100644 --- a/src/OverflowDetector.jsx +++ b/src/OverflowDetector.jsx @@ -17,8 +17,15 @@ export default class OverflowDetector extends Component { super(props); this.isOverflowed = false; this.domElement = null; + this.scrollState = { + atTop: true, + atBottom: true, + atLeft: true, + atRight: true, + }; this.setDOMElement = this.setDOMElement.bind(this); this.checkOverflow = this.checkOverflow.bind(this); + this.handleScroll = this.handleScroll.bind(this); } componentDidMount() { @@ -43,16 +50,48 @@ export default class OverflowDetector extends Component { if (this.props.onOverflowChange) { this.props.onOverflowChange(isOverflowed); } + if (!isOverflowed) { + this.handleScroll(); + } + } + } + + handleScroll() { + const { + clientHeight, + clientWidth, + scrollTop, + scrollLeft, + scrollHeight, + scrollWidth, + } = this.domElement; + const atTop = scrollTop === 0; + const atBottom = scrollTop + clientHeight === scrollHeight; + const atLeft = scrollLeft === 0; + const atRight = scrollLeft + clientWidth === scrollWidth; + const s = this.scrollState; + if ( + s.atTop !== atTop || + s.atBottom !== atBottom || + s.atLeft !== atLeft || + s.atRight !== atRight + ) { + const scrollState = { atTop, atBottom, atLeft, atRight }; + this.scrollState = scrollState; + this.props.onScrolled(scrollState); } } render() { - const { style, className, children } = this.props; + const { style, className, children, onScrolled } = this.props; + const onScroll = + this.isOverflowed && onScrolled ? this.handleScroll : undefined; return (
{children}