UNPKG

react-native-scroll-into-view

Version:

React-Native port of DOMElement.scrollIntoView() web function, for ScrollView

98 lines 3.96 kB
import React from 'react'; import PropTypes from 'prop-types'; import { View } from 'react-native'; import { throttle } from './utils'; import { OptionKeys } from './config'; import { APIConsumer } from './context'; const showNotInContextWarning = throttle(() => { console.warn('ScrollIntoView API is not provided in React context. Make sure you wrapped your ScrollView component with wrapScrollView(ScrollView)'); }, 5000); export class ContainerBase extends React.Component { constructor() { super(...arguments); this.container = React.createRef(); this.unmounted = false; this.ensureApiProvided = () => { if (this.props.scrollIntoViewAPI) { return true; } else { showNotInContextWarning(); return false; } }; this.getPropsOptions = () => { const options = Object.assign({}, this.props.scrollIntoViewOptions); // Allow option shortcuts like animated={true} OptionKeys.forEach((optionKey) => { const optionValue = this.props[optionKey]; if (typeof optionValue !== 'undefined') { // @ts-ignore options[optionKey] = optionValue; } }); return options; }; this.scrollIntoView = (providedOptions = {}) => { if (this.unmounted) { return; } if (this.ensureApiProvided()) { const options = Object.assign(Object.assign({}, this.getPropsOptions()), providedOptions); this.props.scrollIntoViewAPI.scrollIntoView(this.container.current, options); } }; } componentDidMount() { // see https://github.com/APSL/react-native-keyboard-aware-scroll-view/issues/259#issuecomment-392863157 setTimeout(() => { this.props.onMount && this.props.enabled && this.scrollIntoView(); }, 0); } componentDidUpdate(prevProps) { const hasBeenEnabled = this.props.enabled && !prevProps.enabled; if (this.props.onUpdate && hasBeenEnabled) { this.scrollIntoView(); return; } // Allow to pass a "scrollIntoViewKey" so that const keyHasChanged = this.props.scrollIntoViewKey !== prevProps.scrollIntoViewKey; if (this.props.onUpdate && this.props.enabled && keyHasChanged) { this.scrollIntoView(); return; } } componentWillUnmount() { this.unmounted = true; } render() { return (React.createElement(View, Object.assign({}, this.props, { ref: this.container, collapsable: false }), this.props.children)); } } ContainerBase.propTypes = { // if enabled, will scrollIntoView on mount + on update (if it was previously disabled) enabled: PropTypes.bool.isRequired, // if enabled, will scrollIntoView on key change scrollIntoViewKey: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.bool, ]), // weither to use animation to scroll into view the element animated: PropTypes.bool.isRequired, // by default, calls are throttled because you can only scroll into view one element at a time immediate: PropTypes.bool.isRequired, // scroll into view on mount (if enabled) onMount: PropTypes.bool.isRequired, // scroll into view on update (if enabled) onUpdate: PropTypes.bool.isRequired, }; ContainerBase.defaultProps = { enabled: true, animated: true, immediate: false, onMount: true, onUpdate: true, }; export const Container = React.forwardRef((props, ref) => (React.createElement(APIConsumer, null, (scrollIntoViewAPI) => (React.createElement(ContainerBase, Object.assign({ ref: ref }, props, { scrollIntoViewAPI: scrollIntoViewAPI })))))); //# sourceMappingURL=container.js.map