react-native-scroll-into-view
Version:
React-Native port of DOMElement.scrollIntoView() web function, for ScrollView
98 lines • 3.96 kB
JavaScript
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