react-native-scroll-into-view
Version:
React-Native port of DOMElement.scrollIntoView() web function, for ScrollView
60 lines • 3.19 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import { throttle } from './utils';
import { normalizeOptions } from './config';
export const scrollIntoView = (scrollView, view, scrollY, options) => __awaiter(void 0, void 0, void 0, function* () {
const { align, animated, computeScrollY, measureElement, insets, } = normalizeOptions(options);
const [scrollViewLayout, viewLayout] = yield Promise.all([
measureElement(scrollView),
measureElement(view),
]);
const newScrollY = computeScrollY(scrollViewLayout, viewLayout, scrollY, insets, align);
const scrollResponder = scrollView.getScrollResponder();
if (scrollResponder.scrollResponderScrollTo != null) {
scrollResponder.scrollResponderScrollTo({ x: 0, y: newScrollY, animated });
}
else {
scrollView.scrollTo({ x: 0, y: newScrollY, animated });
}
});
export class ScrollIntoViewAPI {
constructor(dependencies) {
this.getNormalizedOptions = (options = {}) => normalizeOptions(options, this.dependencies.getDefaultOptions());
this.scrollIntoView = (view, options) => {
const normalizedOptions = this.getNormalizedOptions(options);
if (normalizedOptions.immediate) {
return this.scrollIntoViewImmediate(view, normalizedOptions);
}
else {
return this.scrollIntoViewThrottled(view, normalizedOptions);
}
};
// We throttle the calls, so that if 2 views where to scroll into view at almost the same time, only the first one will do
// ie if we want to scroll into view form errors, the first error will scroll into view
// this behavior is probably subjective and should be configurable?
this.scrollIntoViewThrottled = throttle((view, options) => {
return scrollIntoView(this.dependencies.getScrollView(), view, this.dependencies.getScrollY(), options);
}, 16);
this.scrollIntoViewImmediate = (view, options) => {
return scrollIntoView(this.dependencies.getScrollView(), view, this.dependencies.getScrollY(), options);
};
if (!dependencies.getScrollView) {
throw new Error('getScrollView is required');
}
if (!dependencies.getScrollY) {
throw new Error('getScrollY is required');
}
if (!dependencies.getDefaultOptions) {
throw new Error('getDefaultOptions is required');
}
this.dependencies = dependencies;
}
}
//# sourceMappingURL=api.js.map