UNPKG

@tamagui/react-native-web-lite

Version:
144 lines 5.31 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var VirtualizeUtils_exports = {}; __export(VirtualizeUtils_exports, { computeWindowedRenderLimits: () => computeWindowedRenderLimits, elementsThatOverlapOffsets: () => elementsThatOverlapOffsets, keyExtractor: () => keyExtractor, newRangeCount: () => newRangeCount }); module.exports = __toCommonJS(VirtualizeUtils_exports); function elementsThatOverlapOffsets(offsets, props, getFrameMetrics, zoomScale = 1) { const itemCount = props.getItemCount(props.data); const result = []; for (let offsetIndex = 0; offsetIndex < offsets.length; offsetIndex++) { const currentOffset = offsets[offsetIndex]; let left = 0; let right = itemCount - 1; while (left <= right) { const mid = left + (right - left >>> 1); const frame = getFrameMetrics(mid, props); const scaledOffsetStart = frame.offset * zoomScale; const scaledOffsetEnd = (frame.offset + frame.length) * zoomScale; if (mid === 0 && currentOffset < scaledOffsetStart || mid !== 0 && currentOffset <= scaledOffsetStart) { right = mid - 1; } else if (currentOffset > scaledOffsetEnd) { left = mid + 1; } else { result[offsetIndex] = mid; break; } } } return result; } function newRangeCount(prev, next) { return next.last - next.first + 1 - Math.max(0, 1 + Math.min(next.last, prev.last) - Math.max(next.first, prev.first)); } function computeWindowedRenderLimits(props, maxToRenderPerBatch, windowSize, prev, getFrameMetricsApprox, scrollMetrics) { const itemCount = props.getItemCount(props.data); if (itemCount === 0) { return { first: 0, last: -1 }; } const { offset, velocity, visibleLength, zoomScale = 1 } = scrollMetrics; const visibleBegin = Math.max(0, offset); const visibleEnd = visibleBegin + visibleLength; const overscanLength = (windowSize - 1) * visibleLength; const leadFactor = 0.5; const fillPreference = velocity > 1 ? "after" : velocity < -1 ? "before" : "none"; const overscanBegin = Math.max(0, visibleBegin - (1 - leadFactor) * overscanLength); const overscanEnd = Math.max(0, visibleEnd + leadFactor * overscanLength); const lastItemOffset = getFrameMetricsApprox(itemCount - 1, props).offset * zoomScale; if (lastItemOffset < overscanBegin) { return { first: Math.max(0, itemCount - 1 - maxToRenderPerBatch), last: itemCount - 1 }; } let [overscanFirst, first, last, overscanLast] = elementsThatOverlapOffsets([overscanBegin, visibleBegin, visibleEnd, overscanEnd], props, getFrameMetricsApprox, zoomScale); overscanFirst = overscanFirst == null ? 0 : overscanFirst; first = first == null ? Math.max(0, overscanFirst) : first; overscanLast = overscanLast == null ? itemCount - 1 : overscanLast; last = last == null ? Math.min(overscanLast, first + maxToRenderPerBatch - 1) : last; const visible = { first, last }; let newCellCount = newRangeCount(prev, visible); while (true) { if (first <= overscanFirst && last >= overscanLast) { break; } const maxNewCells = newCellCount >= maxToRenderPerBatch; const firstWillAddMore = first <= prev.first || first > prev.last; const firstShouldIncrement = first > overscanFirst && (!maxNewCells || !firstWillAddMore); const lastWillAddMore = last >= prev.last || last < prev.first; const lastShouldIncrement = last < overscanLast && (!maxNewCells || !lastWillAddMore); if (maxNewCells && !firstShouldIncrement && !lastShouldIncrement) { break; } if (firstShouldIncrement && !(fillPreference === "after" && lastShouldIncrement && lastWillAddMore)) { if (firstWillAddMore) { newCellCount++; } first--; } if (lastShouldIncrement && !(fillPreference === "before" && firstShouldIncrement && firstWillAddMore)) { if (lastWillAddMore) { newCellCount++; } last++; } } if (!(last >= first && first >= 0 && last < itemCount && first >= overscanFirst && last <= overscanLast && first <= visible.first && last >= visible.last)) { throw new Error("Bad window calculation " + JSON.stringify({ first, last, itemCount, overscanFirst, overscanLast, visible })); } return { first, last }; } function keyExtractor(item, index) { if (typeof item === "object" && item?.key != null) { return item.key; } if (typeof item === "object" && item?.id != null) { return item.id; } return String(index); }