UNPKG

react-select-module

Version:
64 lines (54 loc) 1.87 kB
/** @jsx jsx */ import { PureComponent } from 'react'; import * as emotionCore from '@emotion/core'; import NodeResolver from './NodeResolver'; import ScrollLock from './ScrollLock/index'; const { jsx } = emotionCore; // NOTE: // We shouldn't need this after updating to React v16.3.0, which introduces: // - createRef() https://reactjs.org/docs/react-api.html#reactcreateref // - forwardRef() https://reactjs.org/docs/react-api.html#reactforwardref export default class ScrollBlock extends PureComponent { state = { touchScrollTarget: null }; // must be in state to trigger a re-render, only runs once per instance getScrollTarget = ref => { if (ref === this.state.touchScrollTarget) return; this.setState({ touchScrollTarget: ref }); }; // this will close the menu when a user clicks outside blurSelectInput = () => { if (document.activeElement) { document.activeElement.blur(); } }; render() { const { children, isEnabled } = this.props; const { touchScrollTarget } = this.state; // bail early if not enabled if (!isEnabled) return children; /* * Div * ------------------------------ * blocks scrolling on non-body elements behind the menu * NodeResolver * ------------------------------ * we need a reference to the scrollable element to "unlock" scroll on * mobile devices * ScrollLock * ------------------------------ * actually does the scroll locking */ return ( <div> <div onClick={this.blurSelectInput} css={{ position: 'fixed', left: 0, bottom: 0, right: 0, top: 0 }} /> <NodeResolver innerRef={this.getScrollTarget}>{children}</NodeResolver> {touchScrollTarget ? ( <ScrollLock touchScrollTarget={touchScrollTarget} /> ) : null} </div> ); } }