UNPKG

@tamagui/react-native-web-lite

Version:
1,006 lines (1,004 loc) 54.3 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { invariant, StyleSheet } from "@tamagui/react-native-web-internals"; import ViewabilityHelper from "../ViewabilityHelper.native.js"; import { CellRenderMask } from "./CellRenderMask.native.js"; import StateSafePureComponent from "./StateSafePureComponent.native.js"; import { VirtualizedListCellContextProvider, VirtualizedListContext, VirtualizedListContextProvider } from "./VirtualizedListContext.native.js"; import ScrollView from "../../../ScrollView/ScrollViewBase.native.js"; import View from "../../../View"; import CellRenderer from "./VirtualizedListCellRenderer.native.js"; import FillRateHelper from "../FillRateHelper"; import ChildListCollection from "./ChildListCollection.native.js"; import React from "react"; import clamp from "../Utilities/clamp.native.js"; import { keyExtractor as defaultKeyExtractor } from "../VirtualizeUtils"; import Batchinator from "../../../Batchinator"; import RefreshControl from "../../../RefreshControl"; function _assert_this_initialized(self) { if (self === void 0) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return self; } function _call_super(_this, derived, args) { return derived = _get_prototype_of(derived), _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args)); } function _class_call_check(instance, Constructor) { if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0, "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor); } } function _create_class(Constructor, protoProps, staticProps) { return protoProps && _defineProperties(Constructor.prototype, protoProps), staticProps && _defineProperties(Constructor, staticProps), Constructor; } function _define_property(obj, key, value) { return key in obj ? Object.defineProperty(obj, key, { value, enumerable: !0, configurable: !0, writable: !0 }) : obj[key] = value, obj; } function _get_prototype_of(o) { return _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function (o2) { return o2.__proto__ || Object.getPrototypeOf(o2); }, _get_prototype_of(o); } function _inherits(subClass, superClass) { if (typeof superClass != "function" && superClass !== null) throw new TypeError("Super expression must either be null or a function"); subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: !0, configurable: !0 } }), superClass && _set_prototype_of(subClass, superClass); } function _possible_constructor_return(self, call) { return call && (_type_of(call) === "object" || typeof call == "function") ? call : _assert_this_initialized(self); } function _set_prototype_of(o, p) { return _set_prototype_of = Object.setPrototypeOf || function (o2, p2) { return o2.__proto__ = p2, o2; }, _set_prototype_of(o, p); } function _type_of(obj) { "@swc/helpers - typeof"; return obj && typeof Symbol < "u" && obj.constructor === Symbol ? "symbol" : typeof obj; } function _is_native_reflect_construct() { try { var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch {} return (_is_native_reflect_construct = function () { return !!result; })(); } var __DEV__ = process.env.NODE_ENV !== "production", ON_EDGE_REACHED_EPSILON = 1e-3, _usedIndexForKey = !1, _keylessItemComponentName = ""; function horizontalOrDefault(horizontal) { return horizontal ?? !1; } function initialNumToRenderOrDefault(initialNumToRender) { return initialNumToRender ?? 10; } function maxToRenderPerBatchOrDefault(maxToRenderPerBatch) { return maxToRenderPerBatch ?? 10; } function onStartReachedThresholdOrDefault(onStartReachedThreshold) { return onStartReachedThreshold ?? 2; } function onEndReachedThresholdOrDefault(onEndReachedThreshold) { return onEndReachedThreshold ?? 2; } function getScrollingThreshold(threshold, visibleLength) { return threshold * visibleLength / 2; } function scrollEventThrottleOrDefault(scrollEventThrottle) { return scrollEventThrottle ?? 50; } function windowSizeOrDefault(windowSize) { return windowSize ?? 21; } function findLastWhere(arr, predicate) { for (var i = arr.length - 1; i >= 0; i--) if (predicate(arr[i])) return arr[i]; return null; } var VirtualizedList = /* @__PURE__ */function (StateSafePureComponent2) { "use strict"; _inherits(VirtualizedList2, StateSafePureComponent2); function VirtualizedList2(props) { _class_call_check(this, VirtualizedList2); var _this; _this = _call_super(this, VirtualizedList2, [props]), _define_property(_this, "_getScrollMetrics", function () { return _this._scrollMetrics; }), _define_property(_this, "_getOutermostParentListRef", function () { return _this._isNestedWithSameOrientation() ? _this.context.getOutermostParentListRef() : _this; }), _define_property(_this, "_registerAsNestedChild", function (childList) { _this._nestedChildLists.add(childList.ref, childList.cellKey), _this._hasInteracted && childList.ref.recordInteraction(); }), _define_property(_this, "_unregisterAsNestedChild", function (childList) { _this._nestedChildLists.remove(childList.ref); }), _define_property(_this, "invertedWheelEventHandler", void 0), _define_property(_this, "_onUpdateSeparators", function (keys, newProps) { keys.forEach(function (key) { var ref = key != null && _this._cellRefs[key]; ref && ref.updateSeparatorProps(newProps); }); }), _define_property(_this, "_getSpacerKey", function (isVertical) { return isVertical ? "height" : "width"; }), _define_property(_this, "_averageCellLength", 0), _define_property(_this, "_cellRefs", {}), _define_property(_this, "_fillRateHelper", void 0), _define_property(_this, "_frames", {}), _define_property(_this, "_footerLength", 0), _define_property(_this, "_hasTriggeredInitialScrollToIndex", !1), _define_property(_this, "_hasInteracted", !1), _define_property(_this, "_hasMore", !1), _define_property(_this, "_hasWarned", {}), _define_property(_this, "_headerLength", 0), _define_property(_this, "_hiPriInProgress", !1), _define_property(_this, "_highestMeasuredFrameIndex", 0), _define_property(_this, "_indicesToKeys", /* @__PURE__ */new Map()), _define_property(_this, "_lastFocusedCellKey", null), _define_property(_this, "_nestedChildLists", new ChildListCollection()), _define_property(_this, "_offsetFromParentVirtualizedList", 0), _define_property(_this, "_prevParentOffset", 0), _define_property(_this, "_scrollMetrics", { contentLength: 0, dOffset: 0, dt: 10, offset: 0, timestamp: 0, velocity: 0, visibleLength: 0, zoomScale: 1 }), _define_property(_this, "_scrollRef", null), _define_property(_this, "_sentStartForContentLength", 0), _define_property(_this, "_sentEndForContentLength", 0), _define_property(_this, "_totalCellLength", 0), _define_property(_this, "_totalCellsMeasured", 0), _define_property(_this, "_updateCellsToRenderBatcher", void 0), _define_property(_this, "_viewabilityTuples", []), _define_property(_this, "_captureScrollRef", function (ref) { _this._scrollRef = ref; }), _define_property(_this, "_defaultRenderScrollComponent", function (props2) { var onRefresh = props2.onRefresh; if (_this._isNestedWithSameOrientation()) return /* @__PURE__ */_jsx(View, { ...props2 }); if (onRefresh) { var _props_refreshing; return invariant(typeof props2.refreshing == "boolean", "`refreshing` prop must be set as a boolean in order to use `onRefresh`, but got `" + JSON.stringify((_props_refreshing = props2.refreshing) !== null && _props_refreshing !== void 0 ? _props_refreshing : "undefined") + "`"), /* @__PURE__ */_jsx(ScrollView, { ...props2, refreshControl: props2.refreshControl == null ? /* @__PURE__ */_jsx(RefreshControl, { refreshing: props2.refreshing, onRefresh, progressViewOffset: props2.progressViewOffset }) : props2.refreshControl }); } else return /* @__PURE__ */_jsx(ScrollView, { ...props2 }); }), _define_property(_this, "_onCellLayout", function (e, cellKey, index) { var layout = e.nativeEvent.layout, next = { offset: _this._selectOffset(layout), length: _this._selectLength(layout), index, inLayout: !0 }, curr = _this._frames[cellKey]; !curr || next.offset !== curr.offset || next.length !== curr.length || index !== curr.index ? (_this._totalCellLength += next.length - (curr ? curr.length : 0), _this._totalCellsMeasured += curr ? 0 : 1, _this._averageCellLength = _this._totalCellLength / _this._totalCellsMeasured, _this._frames[cellKey] = next, _this._highestMeasuredFrameIndex = Math.max(_this._highestMeasuredFrameIndex, index), _this._scheduleCellsToRenderUpdate()) : _this._frames[cellKey].inLayout = !0, _this._triggerRemeasureForChildListsInCell(cellKey), _this._computeBlankness(), _this._updateViewableItems( // @ts-ignore _this.props, _this.state.cellsAroundViewport); }), _define_property(_this, "_onCellUnmount", function (cellKey) { delete _this._cellRefs[cellKey]; var curr = _this._frames[cellKey]; curr && (_this._frames[cellKey] = { ...curr, inLayout: !1 }); }), _define_property(_this, "_onLayout", function (e) { _this._isNestedWithSameOrientation() ? _this.measureLayoutRelativeToContainingList() : _this._scrollMetrics.visibleLength = _this._selectLength(e.nativeEvent.layout), _this.props.onLayout && _this.props.onLayout(e), _this._scheduleCellsToRenderUpdate(), _this._maybeCallOnEdgeReached(); }), _define_property(_this, "_onLayoutEmpty", function (e) { _this.props.onLayout && _this.props.onLayout(e); }), _define_property(_this, "_onLayoutFooter", function (e) { _this._triggerRemeasureForChildListsInCell(_this._getFooterCellKey()), _this._footerLength = _this._selectLength(e.nativeEvent.layout); }), _define_property(_this, "_onLayoutHeader", function (e) { _this._headerLength = _this._selectLength(e.nativeEvent.layout); }), _define_property(_this, "_onContentSizeChange", function (width, height) { width > 0 && height > 0 && _this.props.initialScrollIndex != null && _this.props.initialScrollIndex > 0 && !_this._hasTriggeredInitialScrollToIndex && (_this.props.contentOffset == null && (_this.props.initialScrollIndex < _this.props.getItemCount(_this.props.data) ? _this.scrollToIndex({ animated: !1, index: nullthrows(_this.props.initialScrollIndex) }) : _this.scrollToEnd({ animated: !1 })), _this._hasTriggeredInitialScrollToIndex = !0), _this.props.onContentSizeChange && _this.props.onContentSizeChange(width, height), _this._scrollMetrics.contentLength = _this._selectLength({ height, width }), _this._scheduleCellsToRenderUpdate(), _this._maybeCallOnEdgeReached(); }), _define_property(_this, "_convertParentScrollMetrics", function (metrics) { var offset = metrics.offset - _this._offsetFromParentVirtualizedList, visibleLength = metrics.visibleLength, dOffset = offset - _this._scrollMetrics.offset, contentLength = _this._scrollMetrics.contentLength; return { visibleLength, contentLength, offset, dOffset }; }), _define_property(_this, "_onScroll", function (e) { _this._nestedChildLists.forEach(function (childList) { childList._onScroll(e); }), _this.props.onScroll && _this.props.onScroll(e); var timestamp = e.timeStamp, visibleLength = _this._selectLength(e.nativeEvent.layoutMeasurement), contentLength = _this._selectLength(e.nativeEvent.contentSize), offset = _this._selectOffset(e.nativeEvent.contentOffset), dOffset = offset - _this._scrollMetrics.offset; if (_this._isNestedWithSameOrientation()) { if (_this._scrollMetrics.contentLength === 0) return; ({ visibleLength, contentLength, offset, dOffset } = _this._convertParentScrollMetrics({ visibleLength, offset })); } var dt = _this._scrollMetrics.timestamp ? Math.max(1, timestamp - _this._scrollMetrics.timestamp) : 1, velocity = dOffset / dt; dt > 500 && _this._scrollMetrics.dt > 500 && contentLength > 5 * visibleLength && !_this._hasWarned.perf && (infoLog("VirtualizedList: You have a large list that is slow to update - make sure your renderItem function renders components that follow React performance best practices like PureComponent, shouldComponentUpdate, etc.", { dt, prevDt: _this._scrollMetrics.dt, contentLength }), _this._hasWarned.perf = !0); var zoomScale = e.nativeEvent.zoomScale < 0 ? 1 : e.nativeEvent.zoomScale; _this._scrollMetrics = { contentLength, dt, dOffset, offset, timestamp, velocity, visibleLength, zoomScale }, _this._updateViewableItems(_this.props, _this.state.cellsAroundViewport), _this.props && (_this._maybeCallOnEdgeReached(), velocity !== 0 && _this._fillRateHelper.activate(), _this._computeBlankness(), _this._scheduleCellsToRenderUpdate()); }), _define_property(_this, "_onScrollBeginDrag", function (e) { _this._nestedChildLists.forEach(function (childList) { childList._onScrollBeginDrag(e); }), _this._viewabilityTuples.forEach(function (tuple) { tuple.viewabilityHelper.recordInteraction(); }), _this._hasInteracted = !0, _this.props.onScrollBeginDrag && _this.props.onScrollBeginDrag(e); }), _define_property(_this, "_onScrollEndDrag", function (e) { _this._nestedChildLists.forEach(function (childList) { childList._onScrollEndDrag(e); }); var { velocity } = e.nativeEvent; velocity && (_this._scrollMetrics.velocity = _this._selectOffset(velocity)), _this._computeBlankness(), _this.props.onScrollEndDrag && _this.props.onScrollEndDrag(e); }), _define_property(_this, "_onMomentumScrollBegin", function (e) { _this._nestedChildLists.forEach(function (childList) { childList._onMomentumScrollBegin(e); }), _this.props.onMomentumScrollBegin && _this.props.onMomentumScrollBegin(e); }), _define_property(_this, "_onMomentumScrollEnd", function (e) { _this._nestedChildLists.forEach(function (childList) { childList._onMomentumScrollEnd(e); }), _this._scrollMetrics.velocity = 0, _this._computeBlankness(), _this.props.onMomentumScrollEnd && _this.props.onMomentumScrollEnd(e); }), _define_property(_this, "_updateCellsToRender", function () { _this._updateViewableItems(_this.props, _this.state.cellsAroundViewport), _this.setState(function (state, props2) { var cellsAroundViewport = _this._adjustCellsAroundViewport(props2, state.cellsAroundViewport), renderMask = VirtualizedList2._createRenderMask(props2, cellsAroundViewport, _this._getNonViewportRenderRegions(props2)); return cellsAroundViewport.first === state.cellsAroundViewport.first && cellsAroundViewport.last === state.cellsAroundViewport.last && renderMask.equals(state.renderMask) ? null : { cellsAroundViewport, renderMask }; }); }), _define_property(_this, "_createViewToken", function (index, isViewable, props2) { var { data, getItem } = props2, item = getItem(data, index); return { index, item, key: _this._keyExtractor(item, index, props2), isViewable }; }), _define_property(_this, "_getOffsetApprox", function (index, props2) { if (Number.isInteger(index)) return _this.__getFrameMetricsApprox(index, props2).offset; var frameMetrics = _this.__getFrameMetricsApprox(Math.floor(index), props2), remainder = index - Math.floor(index); return frameMetrics.offset + remainder * frameMetrics.length; }), _define_property(_this, "__getFrameMetricsApprox", function (index, props2) { var frame = _this._getFrameMetrics(index, props2); if (frame && frame.index === index) return frame; var { data, getItemCount, getItemLayout } = props2; return invariant(index >= 0 && index < getItemCount(data), "Tried to get frame for out of range index " + index), invariant(!getItemLayout, "Should not have to estimate frames when a measurement metrics function is provided"), { length: _this._averageCellLength, offset: _this._averageCellLength * index }; }), _define_property(_this, "_getFrameMetrics", function (index, props2) { var { data, getItem, getItemCount, getItemLayout } = props2; invariant(index >= 0 && index < getItemCount(data), "Tried to get frame for out of range index " + index); var item = getItem(data, index), frame = _this._frames[_this._keyExtractor(item, index, props2)]; return (!frame || frame.index !== index) && getItemLayout ? getItemLayout(data, index) : frame; }), _define_property(_this, "_getNonViewportRenderRegions", function (props2) { if (!(_this._lastFocusedCellKey && _this._cellRefs[_this._lastFocusedCellKey])) return []; var lastFocusedCellRenderer = _this._cellRefs[_this._lastFocusedCellKey], focusedCellIndex = lastFocusedCellRenderer.props.index, itemCount = props2.getItemCount(props2.data); if (focusedCellIndex >= itemCount || _this._keyExtractor(props2.getItem(props2.data, focusedCellIndex), focusedCellIndex, props2) !== _this._lastFocusedCellKey) return []; for (var first = focusedCellIndex, heightOfCellsBeforeFocused = 0, i = first - 1; i >= 0 && heightOfCellsBeforeFocused < _this._scrollMetrics.visibleLength; i--) first--, heightOfCellsBeforeFocused += _this.__getFrameMetricsApprox(i, props2).length; for (var last = focusedCellIndex, heightOfCellsAfterFocused = 0, i1 = last + 1; i1 < itemCount && heightOfCellsAfterFocused < _this._scrollMetrics.visibleLength; i1++) last++, heightOfCellsAfterFocused += _this.__getFrameMetricsApprox(i1, props2).length; return [{ first, last }]; }), _this._checkProps(props), _this._fillRateHelper = new FillRateHelper(_this._getFrameMetrics); var _this_props_updateCellsBatchingPeriod; if (_this._updateCellsToRenderBatcher = new Batchinator(_this._updateCellsToRender, (_this_props_updateCellsBatchingPeriod = _this.props.updateCellsBatchingPeriod) !== null && _this_props_updateCellsBatchingPeriod !== void 0 ? _this_props_updateCellsBatchingPeriod : 50), _this.props.viewabilityConfigCallbackPairs) _this._viewabilityTuples = _this.props.viewabilityConfigCallbackPairs.map(function (pair) { return { viewabilityHelper: new ViewabilityHelper(pair.viewabilityConfig), onViewableItemsChanged: pair.onViewableItemsChanged }; });else { var { onViewableItemsChanged, viewabilityConfig } = _this.props; onViewableItemsChanged && _this._viewabilityTuples.push({ viewabilityHelper: new ViewabilityHelper(viewabilityConfig), onViewableItemsChanged }); } var initialRenderRegion = VirtualizedList2._initialRenderRegion(props); return _this.state = { cellsAroundViewport: initialRenderRegion, renderMask: VirtualizedList2._createRenderMask(props, initialRenderRegion) }, _this.invertedWheelEventHandler = function (ev) { var scrollOffset = _this.props.horizontal ? ev.target.scrollLeft : ev.target.scrollTop, scrollLength = _this.props.horizontal ? ev.target.scrollWidth : ev.target.scrollHeight, clientLength = _this.props.horizontal ? ev.target.clientWidth : ev.target.clientHeight, isEventTargetScrollable = scrollLength > clientLength, delta = _this.props.horizontal ? ev.deltaX || ev.wheelDeltaX : ev.deltaY || ev.wheelDeltaY, leftoverDelta = delta; isEventTargetScrollable && (leftoverDelta = delta < 0 ? Math.min(delta + scrollOffset, 0) : Math.max(delta - (scrollLength - clientLength - scrollOffset), 0)); var targetDelta = delta - leftoverDelta; if (_this.props.inverted && _this._scrollRef && _this._scrollRef.getScrollableNode) { var node = _this._scrollRef.getScrollableNode(); if (_this.props.horizontal) { ev.target.scrollLeft += targetDelta; var nextScrollLeft = node.scrollLeft - leftoverDelta; node.scrollLeft = _this.props.getItemLayout ? nextScrollLeft : Math.min(nextScrollLeft, _this._totalCellLength); } else { ev.target.scrollTop += targetDelta; var nextScrollTop = node.scrollTop - leftoverDelta; node.scrollTop = _this.props.getItemLayout ? nextScrollTop : Math.min(nextScrollTop, _this._totalCellLength); } ev.preventDefault(); } }, _this; } return _create_class(VirtualizedList2, [{ // scrollToEnd may be janky without getItemLayout prop key: "scrollToEnd", value: function (params) { var animated = params ? params.animated : !0, veryLast = this.props.getItemCount(this.props.data) - 1; if (!(veryLast < 0)) { var frame = this.__getFrameMetricsApprox(veryLast, this.props), offset = Math.max(0, frame.offset + frame.length + this._footerLength - this._scrollMetrics.visibleLength); if (this._scrollRef != null) { if (this._scrollRef.scrollTo == null) { console.warn("No scrollTo method provided. This may be because you have two nested VirtualizedLists with the same orientation, or because you are using a custom component that does not implement scrollTo."); return; } this._scrollRef.scrollTo(horizontalOrDefault(this.props.horizontal) ? { x: offset, animated } : { y: offset, animated }); } } } }, { // scrollToIndex may be janky without getItemLayout prop key: "scrollToIndex", value: function (params) { var { data, horizontal, getItemCount, getItemLayout, onScrollToIndexFailed } = this.props, { animated, index, viewOffset, viewPosition } = params; if (invariant(index >= 0, `scrollToIndex out of range: requested index ${index} but minimum is 0`), invariant(getItemCount(data) >= 1, `scrollToIndex out of range: item length ${getItemCount(data)} but minimum is 1`), invariant(index < getItemCount(data), `scrollToIndex out of range: requested index ${index} is out of 0 to ${getItemCount(data) - 1}`), !getItemLayout && index > this._highestMeasuredFrameIndex) { invariant(!!onScrollToIndexFailed, "scrollToIndex should be used in conjunction with getItemLayout or onScrollToIndexFailed, otherwise there is no way to know the location of offscreen indices or handle failures."), onScrollToIndexFailed({ averageItemLength: this._averageCellLength, highestMeasuredFrameIndex: this._highestMeasuredFrameIndex, index }); return; } var frame = this.__getFrameMetricsApprox(Math.floor(index), this.props), offset = Math.max(0, // @ts-ignore this._getOffsetApprox(index, this.props) - (viewPosition || 0) * (this._scrollMetrics.visibleLength - frame.length)) - (viewOffset || 0); if (this._scrollRef != null) { if (this._scrollRef.scrollTo == null) { console.warn("No scrollTo method provided. This may be because you have two nested VirtualizedLists with the same orientation, or because you are using a custom component that does not implement scrollTo."); return; } this._scrollRef.scrollTo(horizontal ? { x: offset, animated } : { y: offset, animated }); } } }, { // scrollToItem may be janky without getItemLayout prop. Required linear scan through items - // use scrollToIndex instead if possible. key: "scrollToItem", value: function (params) { for (var { item } = params, { data, getItem, getItemCount } = this.props, itemCount = getItemCount(data), index = 0; index < itemCount; index++) if (getItem(data, index) === item) { this.scrollToIndex({ ...params, index }); break; } } }, { /** * Scroll to a specific content pixel offset in the list. * * Param `offset` expects the offset to scroll to. * In case of `horizontal` is true, the offset is the x-value, * in any other case the offset is the y-value. * * Param `animated` (`true` by default) defines whether the list * should do an animation while scrolling. */ key: "scrollToOffset", value: function (params) { var { animated, offset } = params; if (this._scrollRef != null) { if (this._scrollRef.scrollTo == null) { console.warn("No scrollTo method provided. This may be because you have two nested VirtualizedLists with the same orientation, or because you are using a custom component that does not implement scrollTo."); return; } this._scrollRef.scrollTo(horizontalOrDefault(this.props.horizontal) ? { x: offset, animated } : { y: offset, animated }); } } }, { key: "recordInteraction", value: function () { this._nestedChildLists.forEach(function (childList) { childList.recordInteraction(); }), this._viewabilityTuples.forEach(function (t) { t.viewabilityHelper.recordInteraction(); }), this._updateViewableItems(this.props, this.state.cellsAroundViewport); } }, { key: "flashScrollIndicators", value: function () { this._scrollRef != null && this._scrollRef.flashScrollIndicators(); } }, { /** * Provides a handle to the underlying scroll responder. * Note that `this._scrollRef` might not be a `ScrollView`, so we * need to check that it responds to `getScrollResponder` before calling it. */ key: "getScrollResponder", value: function () { return this._scrollRef && this._scrollRef.getScrollResponder ? this._scrollRef.getScrollResponder() : null; } }, { key: "getScrollableNode", value: function () { return this._scrollRef && this._scrollRef.getScrollableNode ? this._scrollRef.getScrollableNode() : this._scrollRef; } }, { key: "getScrollRef", value: function () { return this._scrollRef && this._scrollRef.getScrollRef ? this._scrollRef.getScrollRef() : this._scrollRef; } }, { key: "_getCellKey", value: function () { var _this_context; return ((_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.cellKey) || "rootList"; } }, { key: "hasMore", value: function () { return this._hasMore; } }, { key: "_checkProps", value: function (props) { var { onScroll, windowSize, getItemCount, data, initialScrollIndex } = props; invariant(!(onScroll && onScroll.__isNative), "Components based on VirtualizedList must be wrapped with Animated.createAnimatedComponent to support native onScroll events with useNativeDriver"), invariant(windowSizeOrDefault(windowSize) > 0, "VirtualizedList: The windowSize prop must be present and set to a value greater than 0."), invariant(getItemCount, 'VirtualizedList: The "getItemCount" prop must be provided'); var itemCount = getItemCount(data); if (initialScrollIndex != null && !this._hasTriggeredInitialScrollToIndex && (initialScrollIndex < 0 || itemCount > 0 && initialScrollIndex >= itemCount) && !this._hasWarned.initialScrollIndex && (console.warn(`initialScrollIndex "${initialScrollIndex}" is not valid (list has ${itemCount} items)`), this._hasWarned.initialScrollIndex = !0), __DEV__ && !this._hasWarned.flexWrap) { var flatStyles = StyleSheet.flatten(this.props.contentContainerStyle); flatStyles != null && flatStyles.flexWrap === "wrap" && (console.warn("`flexWrap: `wrap`` is not supported with the `VirtualizedList` components.Consider using `numColumns` with `FlatList` instead."), this._hasWarned.flexWrap = !0); } } }, { key: "_adjustCellsAroundViewport", value: function (props, cellsAroundViewport) { var { data, getItemCount } = props, onEndReachedThreshold = onEndReachedThresholdOrDefault(props.onEndReachedThreshold), { contentLength, offset, visibleLength } = this._scrollMetrics, distanceFromEnd = contentLength - visibleLength - offset; if (visibleLength <= 0 || contentLength <= 0) return cellsAroundViewport.last >= getItemCount(data) ? VirtualizedList2._constrainToItemCount(cellsAroundViewport, props) : cellsAroundViewport; var newCellsAroundViewport; if (props.disableVirtualization) { var renderAhead = distanceFromEnd < onEndReachedThreshold * visibleLength ? maxToRenderPerBatchOrDefault(props.maxToRenderPerBatch) : 0; newCellsAroundViewport = { first: 0, last: Math.min(cellsAroundViewport.last + renderAhead, getItemCount(data) - 1) }; } else { if (props.initialScrollIndex && !this._scrollMetrics.offset && Math.abs(distanceFromEnd) >= Number.EPSILON) return cellsAroundViewport.last >= getItemCount(data) ? VirtualizedList2._constrainToItemCount(cellsAroundViewport, props) : cellsAroundViewport; newCellsAroundViewport = computeWindowedRenderLimits(props, maxToRenderPerBatchOrDefault(props.maxToRenderPerBatch), windowSizeOrDefault(props.windowSize), cellsAroundViewport, this.__getFrameMetricsApprox, this._scrollMetrics), invariant(newCellsAroundViewport.last < getItemCount(data), "computeWindowedRenderLimits() should return range in-bounds"); } if (this._nestedChildLists.size() > 0) { var childIdx = this._findFirstChildWithMore(newCellsAroundViewport.first, newCellsAroundViewport.last); newCellsAroundViewport.last = childIdx ?? newCellsAroundViewport.last; } return newCellsAroundViewport; } }, { key: "_findFirstChildWithMore", value: function (first, last) { for (var ii = first; ii <= last; ii++) { var cellKeyForIndex = this._indicesToKeys.get(ii); if (cellKeyForIndex != null && this._nestedChildLists.anyInCell(cellKeyForIndex, function (childList) { return childList.hasMore(); })) return ii; } return null; } }, { key: "componentDidMount", value: function () { this._isNestedWithSameOrientation() && this.context.registerAsNestedChild({ ref: this, cellKey: this.context.cellKey }), this.setupWebWheelHandler(); } }, { key: "componentWillUnmount", value: function () { this._isNestedWithSameOrientation() && this.context.unregisterAsNestedChild({ ref: this }), this._updateCellsToRenderBatcher.dispose({ abort: !0 }), this._viewabilityTuples.forEach(function (tuple) { tuple.viewabilityHelper.dispose(); }), this._fillRateHelper.deactivateAndFlush(), this.teardownWebWheelHandler(); } }, { key: "setupWebWheelHandler", value: function () { var _this = this; if (this._scrollRef && this._scrollRef.getScrollableNode) this._scrollRef.getScrollableNode().addEventListener("wheel", this.invertedWheelEventHandler);else { setTimeout(function () { return _this.setupWebWheelHandler(); }, 50); return; } } }, { key: "teardownWebWheelHandler", value: function () { this._scrollRef && this._scrollRef.getScrollableNode && this._scrollRef.getScrollableNode().removeEventListener("wheel", this.invertedWheelEventHandler); } }, { key: "_pushCells", value: function (cells, stickyHeaderIndices, stickyIndicesFromProps, first, last, inversionStyle) { var _this, _loop = function (ii2) { var item = getItem(data, ii2), key = _this._keyExtractor(item, ii2, _this.props); _this._indicesToKeys.set(ii2, key), stickyIndicesFromProps.has(ii2 + stickyOffset) && stickyHeaderIndices.push(cells.length); var shouldListenForLayout = getItemLayout == null || debug || _this._fillRateHelper.enabled(); cells.push(/* @__PURE__ */_jsx(CellRenderer, { CellRendererComponent, ItemSeparatorComponent: ii2 < end ? ItemSeparatorComponent : void 0, ListItemComponent, cellKey: key, horizontal, index: ii2, inversionStyle, item, prevCellKey, onUpdateSeparators: _this._onUpdateSeparators, onCellFocusCapture: function (e) { return _this1._onCellFocusCapture(key); }, onUnmount: _this._onCellUnmount, ref: function (ref) { _this1._cellRefs[key] = ref; }, renderItem, ...(shouldListenForLayout && { onCellLayout: _this._onCellLayout }) }, key)), prevCellKey = key; }, _this1 = this, { CellRendererComponent, ItemSeparatorComponent, ListHeaderComponent, ListItemComponent, data, debug, getItem, getItemCount, getItemLayout, horizontal, renderItem } = this.props, stickyOffset = ListHeaderComponent ? 1 : 0, end = getItemCount(data) - 1, prevCellKey; last = Math.min(end, last); for (var ii = first; ii <= last; ii++) _this = this, _loop(ii); } }, { key: "_isNestedWithSameOrientation", value: function () { var nestedContext = this.context; return !!(nestedContext && !!nestedContext.horizontal === horizontalOrDefault(this.props.horizontal)); } }, { key: "_keyExtractor", value: function (item, index, props) { if (props.keyExtractor != null) return props.keyExtractor(item, index); var key = defaultKeyExtractor(item, index); return key === String(index) && (_usedIndexForKey = !0, item.type && item.type.displayName && (_keylessItemComponentName = item.type.displayName)), key; } }, { key: "render", value: function () { var _this = this; this._checkProps(this.props); var { ListEmptyComponent, ListFooterComponent, ListHeaderComponent } = this.props, { data, horizontal } = this.props, inversionStyle = this.props.inverted ? horizontalOrDefault(this.props.horizontal) ? styles.horizontallyInverted : styles.verticallyInverted : null, cells = [], stickyIndicesFromProps = new Set(this.props.stickyHeaderIndices), stickyHeaderIndices = []; if (ListHeaderComponent) { stickyIndicesFromProps.has(0) && stickyHeaderIndices.push(0); var element = /* @__PURE__ */React.isValidElement(ListHeaderComponent) ? ListHeaderComponent : /* @__PURE__ */_jsx(ListHeaderComponent, {}); cells.push(/* @__PURE__ */_jsx(VirtualizedListCellContextProvider, { cellKey: this._getCellKey() + "-header", children: /* @__PURE__ */_jsx(View, { onLayout: this._onLayoutHeader, style: [inversionStyle, this.props.ListHeaderComponentStyle], children: element }) }, "$header")); } var itemCount = this.props.getItemCount(data); if (itemCount === 0 && ListEmptyComponent) { var element1 = /* @__PURE__ */React.isValidElement(ListEmptyComponent) ? ListEmptyComponent : /* @__PURE__ */_jsx(ListEmptyComponent, {}); cells.push(/* @__PURE__ */_jsx(VirtualizedListCellContextProvider, { cellKey: this._getCellKey() + "-empty", children: /* @__PURE__ */React.cloneElement(element1, { onLayout: function (event) { _this._onLayoutEmpty(event), element1.props.onLayout && element1.props.onLayout(event); }, style: [inversionStyle, element1.props.style] }) }, "$empty")); } if (itemCount > 0) { _usedIndexForKey = !1, _keylessItemComponentName = ""; var spacerKey = this._getSpacerKey(!horizontal), renderRegions = this.state.renderMask.enumerateRegions(), lastSpacer = findLastWhere(renderRegions, function (r) { return r.isSpacer; }), _iteratorNormalCompletion = !0, _didIteratorError = !1, _iteratorError = void 0; try { for (var _iterator = renderRegions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = !0) { var section = _step.value; if (section.isSpacer) { if (this.props.disableVirtualization) continue; var isLastSpacer = section === lastSpacer, constrainToMeasured = isLastSpacer && !this.props.getItemLayout, last = constrainToMeasured ? clamp(section.first - 1, section.last, this._highestMeasuredFrameIndex) : section.last, firstMetrics = this.__getFrameMetricsApprox(section.first, this.props), lastMetrics = this.__getFrameMetricsApprox(last, this.props), spacerSize = lastMetrics.offset + lastMetrics.length - firstMetrics.offset; cells.push(/* @__PURE__ */_jsx(View, { style: { [spacerKey]: spacerSize } }, `$spacer-${section.first}`)); } else this._pushCells(cells, stickyHeaderIndices, stickyIndicesFromProps, section.first, section.last, inversionStyle); } } catch (err) { _didIteratorError = !0, _iteratorError = err; } finally { try { !_iteratorNormalCompletion && _iterator.return != null && _iterator.return(); } finally { if (_didIteratorError) throw _iteratorError; } } !this._hasWarned.keys && _usedIndexForKey && (console.warn("VirtualizedList: missing keys for items, make sure to specify a key or id property on each item or provide a custom keyExtractor.", _keylessItemComponentName), this._hasWarned.keys = !0); } if (ListFooterComponent) { var element2 = /* @__PURE__ */React.isValidElement(ListFooterComponent) ? ListFooterComponent : /* @__PURE__ */_jsx(ListFooterComponent, {}); cells.push(/* @__PURE__ */_jsx(VirtualizedListCellContextProvider, { cellKey: this._getFooterCellKey(), children: /* @__PURE__ */_jsx(View, { onLayout: this._onLayoutFooter, style: [inversionStyle, this.props.ListFooterComponentStyle], children: element2 }) }, "$footer")); } var scrollProps = { ...this.props, onContentSizeChange: this._onContentSizeChange, onLayout: this._onLayout, onScroll: this._onScroll, onScrollBeginDrag: this._onScrollBeginDrag, onScrollEndDrag: this._onScrollEndDrag, onMomentumScrollBegin: this._onMomentumScrollBegin, onMomentumScrollEnd: this._onMomentumScrollEnd, scrollEventThrottle: scrollEventThrottleOrDefault(this.props.scrollEventThrottle), invertStickyHeaders: this.props.invertStickyHeaders !== void 0 ? this.props.invertStickyHeaders : this.props.inverted, stickyHeaderIndices, style: inversionStyle ? [inversionStyle, this.props.style] : this.props.style }; this._hasMore = this.state.cellsAroundViewport.last < itemCount - 1; var innerRet = /* @__PURE__ */_jsx(VirtualizedListContextProvider, { value: { cellKey: null, getScrollMetrics: this._getScrollMetrics, horizontal: horizontalOrDefault(this.props.horizontal), getOutermostParentListRef: this._getOutermostParentListRef, registerAsNestedChild: this._registerAsNestedChild, unregisterAsNestedChild: this._unregisterAsNestedChild }, children: /* @__PURE__ */React.cloneElement((this.props.renderScrollComponent || this._defaultRenderScrollComponent)(scrollProps), { ref: this._captureScrollRef }, cells) }), ret = innerRet; return ret; } }, { key: "componentDidUpdate", value: function (prevProps) { var { data, extraData } = this.props; (data !== prevProps.data || extraData !== prevProps.extraData) && this._viewabilityTuples.forEach(function (tuple) { tuple.viewabilityHelper.resetViewableIndices(); }); var hiPriInProgress = this._hiPriInProgress; this._scheduleCellsToRenderUpdate(), hiPriInProgress && (this._hiPriInProgress = !1); } }, { key: "_computeBlankness", value: function () { this._fillRateHelper.computeBlankness( // @ts-ignore this.props, this.state.cellsAroundViewport, this._scrollMetrics); } }, { key: "_onCellFocusCapture", value: function (cellKey) { this._lastFocusedCellKey = cellKey, this._updateCellsToRender(); } }, { key: "_triggerRemeasureForChildListsInCell", value: function (cellKey) { this._nestedChildLists.forEachInCell(cellKey, function (childList) { childList.measureLayoutRelativeToContainingList(); }); } }, { key: "measureLayoutRelativeToContainingList", value: function () { var _this = this; try { if (!this._scrollRef) return; this._scrollRef.measureLayout(this.context.getOutermostParentListRef().getScrollRef(), function (x, y, width, height) { _this._offsetFromParentVirtualizedList = _this._selectOffset({ x, y }), _this._scrollMetrics.contentLength = _this._selectLength({ width, height }); var scrollMetrics = _this._convertParentScrollMetrics(_this.context.getScrollMetrics()), metricsChanged = _this._scrollMetrics.visibleLength !== scrollMetrics.visibleLength || _this._scrollMetrics.offset !== scrollMetrics.offset; metricsChanged && (_this._scrollMetrics.visibleLength = scrollMetrics.visibleLength, _this._scrollMetrics.offset = scrollMetrics.offset, _this._nestedChildLists.forEach(function (childList) { childList.measureLayoutRelativeToContainingList(); })); }, function (error) { console.warn("VirtualizedList: Encountered an error while measuring a list's offset from its containing VirtualizedList."); }); } catch (error) { console.warn("measureLayoutRelativeToContainingList threw an error", error.stack); } } }, { key: "_getFooterCellKey", value: function () { return this._getCellKey() + "-footer"; } }, { key: "_renderDebugOverlay", value: function () { for (var normalize = this._scrollMetrics.visibleLength / (this._scrollMetrics.contentLength || 1), framesInLayout = [], itemCount = this.props.getItemCount(this.props.data), ii = 0; ii < itemCount; ii++) { var frame = this.__getFrameMetricsApprox(ii, this.props); frame.inLayout && framesInLayout.push(frame); } var windowTop = this.__getFrameMetricsApprox(this.state.cellsAroundViewport.first, this.props).offset, frameLast = this.__getFrameMetricsApprox(this.state.cellsAroundViewport.last, this.props), windowLen = frameLast.offset + frameLast.length - windowTop, visTop = this._scrollMetrics.offset, visLen = this._scrollMetrics.visibleLength; return /* @__PURE__ */_jsxs(View, { style: [styles.debugOverlayBase, styles.debugOverlay], children: [framesInLayout.map(function (f, ii2) { return /* @__PURE__ */_jsx(View, { style: [styles.debugOverlayBase, styles.debugOverlayFrame, { top: f.offset * normalize, height: f.length * normalize }] }, "f" + ii2); }), /* @__PURE__ */_jsx(View, { style: [styles.debugOverlayBase, styles.debugOverlayFrameLast, { top: windowTop * normalize, height: windowLen * normalize }] }), /* @__PURE__ */_jsx(View, { style: [styles.debugOverlayBase, styles.debugOverlayFrameVis, { top: visTop * normalize, height: visLen * normalize }] })] }); } }, { key: "_selectLength", value: function (metrics) { return horizontalOrDefault(this.props.horizontal) ? metrics.width : metrics.height; } }, { key: "_selectOffset", value: function (metrics) { return horizontalOrDefault(this.props.horizontal) ? metrics.x : metrics.y; } }, { key: "_maybeCallOnEdgeReached", value: function () { var { data, getItemCount, onStartReached, onStartReachedThreshold, onEndReached, onEndReachedThreshold, initialScrollIndex } = this.props, { contentLength, visibleLength, offset } = this._scrollMetrics, distanceFromStart = offset, distanceFromEnd = contentLength - visibleLength - offset; distanceFromStart < ON_EDGE_REACHED_EPSILON && (distanceFromStart = 0), distanceFromEnd < ON_EDGE_REACHED_EPSILON && (distanceFromEnd = 0); var DEFAULT_THRESHOLD_PX = 2, startThreshold = onStartReachedThreshold != null ? onStartReachedThreshold * visibleLength : DEFAULT_THRESHOLD_PX, endThreshold = onEndReachedThreshold != null ? onEndReachedThreshold * visibleLength : DEFAULT_THRESHOLD_PX, isWithinStartThreshold = distanceFromStart <= startThreshold, isWithinEndThreshold = distanceFromEnd <= endThreshold; onEndReached && this.state.cellsAroundViewport.last === getItemCount(data) - 1 && isWithinEndThreshold && this._scrollMetrics.contentLength !== this._sentEndForContentLength ? (this._sentEndForContentLength = this._scrollMetrics.contentLength, onEndReached({ distanceFromEnd })) : onStartReached != null && this.state.cellsAroundViewport.first === 0 && isWithinStartThreshold && this._scrollMetrics.contentLength !== this._sentStartForContentLength ? (!initialScrollIndex || this._scrollMetrics.timestamp !== 0) && (this._sentStartForContentLength = this._scrollMetrics.contentLength, onStartReached({ distanceFromStart })) : (this._sentStartForContentLength = isWithinStartThreshold ? this._sentStartForContentLength : 0, this._sentEndForContentLength = isWithinEndThreshold ? this._sentEndForContentLength : 0); } }, { key: "_scheduleCellsToRenderUpdate", value: function () { var { first, last } = this.state.cellsAroundViewport, { offset, visibleLength, velocity } = this._scrollMetrics, itemCount = this.props.getItemCount(this.props.data), hiPri = !1, onStartReachedThreshold = onStartReachedThresholdOrDefault(this.props.onStartReachedThreshold), onEndReachedThreshold = onEndReachedThresholdOrDefault(this.props.onEndReachedThreshold); if (first > 0) { var distTop = offset - this.__getFrameMetricsApprox(first, this.props).offset; hiPri = distTop < 0 || velocity < -2 && distTop < getScrollingThreshold(onStartReachedThreshold, visibleLength); } if (!hiPri && last >= 0 && last < itemCount - 1) { var distBottom = this.__getFrameMetricsApprox(last, this.props).offset - (offset + visibleLength); hiPri = distBottom < 0 || velocity > 2 && distBottom < getScrollingThreshold(onEndReachedThreshold, visibleLength); } if (hiPri && (this._averageCellLength || this.props.getItemLayout) && !this._hiPriInProgress) { this._hiPriInProgress = !0, this._updateCellsToRenderBatcher.dispose({ abort: !0 }), this._updateCellsToRender(); return; } else this._updateCellsToRenderBatcher.schedule(); } }, { key: "_updateViewableItems", value: function (props, cellsAroundViewport) { var _this = this; this._viewabilityTuples.forEach(function (tuple) { tuple.viewabilityHelper.onUpdate(props, _this._scrollMetrics.offset, _this._scrollMetrics.visibleLength, _this._getFrameMetrics, _this._createViewToken, tuple.onViewableItemsChanged, cellsAroundViewport); }); } }], [{ key: "_createRenderMask", value: function (props, cellsAroundViewport, additionalRegions) { var itemCount = props.getItemCount(props.data); invariant(cellsAroundViewport.first >= 0 && cellsAroundViewport.last >= cellsAr