@legendapp/list 2.0.0-next.0 → 2.0.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/.cursor/rules/changelog.mdc +60 -0
  3. package/.github/FUNDING.yml +15 -0
  4. package/.gitignore +5 -0
  5. package/.prettierrc.json +5 -0
  6. package/.vscode/settings.json +14 -0
  7. package/CLAUDE.md +126 -0
  8. package/biome.json +46 -0
  9. package/bun.lock +1289 -0
  10. package/bunfig.toml +2 -0
  11. package/dist/CHANGELOG.md +119 -0
  12. package/dist/LICENSE +21 -0
  13. package/dist/README.md +139 -0
  14. package/{animated.d.mts → dist/animated.d.mts} +1 -1
  15. package/{animated.d.ts → dist/animated.d.ts} +1 -1
  16. package/{index.d.mts → dist/index.d.mts} +63 -15
  17. package/{index.d.ts → dist/index.d.ts} +63 -15
  18. package/dist/index.js +2525 -0
  19. package/dist/index.mjs +2497 -0
  20. package/{keyboard-controller.d.mts → dist/keyboard-controller.d.mts} +4 -4
  21. package/{keyboard-controller.d.ts → dist/keyboard-controller.d.ts} +4 -4
  22. package/dist/package.json +35 -0
  23. package/example/README.md +40 -0
  24. package/example/api/data/genres.json +23 -0
  25. package/example/api/data/playlist/10402-10749.json +1 -0
  26. package/example/api/data/playlist/10402-10770.json +1 -0
  27. package/example/api/data/playlist/10402-37.json +1 -0
  28. package/example/api/data/playlist/10749-10752.json +1 -0
  29. package/example/api/data/playlist/10749-10770.json +1 -0
  30. package/example/api/data/playlist/10749-37.json +1 -0
  31. package/example/api/data/playlist/10749-878.json +1 -0
  32. package/example/api/data/playlist/10751-10402.json +1 -0
  33. package/example/api/data/playlist/10751-10752.json +1 -0
  34. package/example/api/data/playlist/10751-37.json +1 -0
  35. package/example/api/data/playlist/10751-53.json +1 -0
  36. package/example/api/data/playlist/10751-878.json +1 -0
  37. package/example/api/data/playlist/10751-9648.json +1 -0
  38. package/example/api/data/playlist/10752-37.json +1 -0
  39. package/example/api/data/playlist/12-10402.json +1 -0
  40. package/example/api/data/playlist/12-10749.json +1 -0
  41. package/example/api/data/playlist/12-18.json +1 -0
  42. package/example/api/data/playlist/12-27.json +1 -0
  43. package/example/api/data/playlist/12-35.json +1 -0
  44. package/example/api/data/playlist/14-36.json +1 -0
  45. package/example/api/data/playlist/14-878.json +1 -0
  46. package/example/api/data/playlist/16-10751.json +1 -0
  47. package/example/api/data/playlist/16-10770.json +1 -0
  48. package/example/api/data/playlist/16-35.json +1 -0
  49. package/example/api/data/playlist/16-36.json +1 -0
  50. package/example/api/data/playlist/16-53.json +1 -0
  51. package/example/api/data/playlist/18-10751.json +1 -0
  52. package/example/api/data/playlist/18-10752.json +1 -0
  53. package/example/api/data/playlist/18-37.json +1 -0
  54. package/example/api/data/playlist/18-53.json +1 -0
  55. package/example/api/data/playlist/18-878.json +1 -0
  56. package/example/api/data/playlist/27-10749.json +1 -0
  57. package/example/api/data/playlist/27-10770.json +1 -0
  58. package/example/api/data/playlist/28-10749.json +1 -0
  59. package/example/api/data/playlist/28-10751.json +1 -0
  60. package/example/api/data/playlist/28-10770.json +1 -0
  61. package/example/api/data/playlist/28-16.json +1 -0
  62. package/example/api/data/playlist/28-18.json +1 -0
  63. package/example/api/data/playlist/28-36.json +1 -0
  64. package/example/api/data/playlist/28-37.json +1 -0
  65. package/example/api/data/playlist/28-53.json +1 -0
  66. package/example/api/data/playlist/28-80.json +1 -0
  67. package/example/api/data/playlist/28-99.json +1 -0
  68. package/example/api/data/playlist/35-10749.json +1 -0
  69. package/example/api/data/playlist/35-10751.json +1 -0
  70. package/example/api/data/playlist/35-10752.json +1 -0
  71. package/example/api/data/playlist/35-27.json +1 -0
  72. package/example/api/data/playlist/35-36.json +1 -0
  73. package/example/api/data/playlist/35-53.json +1 -0
  74. package/example/api/data/playlist/35-80.json +1 -0
  75. package/example/api/data/playlist/36-37.json +1 -0
  76. package/example/api/data/playlist/36-878.json +1 -0
  77. package/example/api/data/playlist/36-9648.json +1 -0
  78. package/example/api/data/playlist/53-10752.json +1 -0
  79. package/example/api/data/playlist/80-10770.json +1 -0
  80. package/example/api/data/playlist/80-14.json +1 -0
  81. package/example/api/data/playlist/80-18.json +1 -0
  82. package/example/api/data/playlist/80-37.json +1 -0
  83. package/example/api/data/playlist/878-37.json +1 -0
  84. package/example/api/data/playlist/9648-10770.json +1 -0
  85. package/example/api/data/playlist/9648-37.json +1 -0
  86. package/example/api/data/playlist/9648-53.json +1 -0
  87. package/example/api/data/playlist/9648-878.json +1 -0
  88. package/example/api/data/playlist/99-10749.json +1 -0
  89. package/example/api/data/playlist/99-14.json +1 -0
  90. package/example/api/data/playlist/99-18.json +1 -0
  91. package/example/api/data/playlist/99-27.json +1 -0
  92. package/example/api/data/playlist/99-53.json +1 -0
  93. package/example/api/data/playlist/99-9648.json +1 -0
  94. package/example/api/data/playlist/index.ts +73 -0
  95. package/example/api/data/rows.json +1 -0
  96. package/example/api/index.ts +36 -0
  97. package/example/app/(tabs)/_layout.tsx +60 -0
  98. package/example/app/(tabs)/cards.tsx +81 -0
  99. package/example/app/(tabs)/index.tsx +205 -0
  100. package/example/app/(tabs)/moviesL.tsx +7 -0
  101. package/example/app/(tabs)/moviesLR.tsx +7 -0
  102. package/example/app/+not-found.tsx +32 -0
  103. package/example/app/_layout.tsx +34 -0
  104. package/example/app/accurate-scrollto/index.tsx +125 -0
  105. package/example/app/accurate-scrollto-2/index.tsx +52 -0
  106. package/example/app/accurate-scrollto-huge/index.tsx +128 -0
  107. package/example/app/add-to-end/index.tsx +82 -0
  108. package/example/app/ai-chat/index.tsx +236 -0
  109. package/example/app/bidirectional-infinite-list/index.tsx +133 -0
  110. package/example/app/cards-columns/index.tsx +37 -0
  111. package/example/app/cards-flashlist/index.tsx +122 -0
  112. package/example/app/cards-flatlist/index.tsx +94 -0
  113. package/example/app/cards-no-recycle/index.tsx +110 -0
  114. package/example/app/cards-renderItem.tsx +354 -0
  115. package/example/app/chat-example/index.tsx +167 -0
  116. package/example/app/chat-infinite/index.tsx +239 -0
  117. package/example/app/chat-keyboard/index.tsx +248 -0
  118. package/example/app/chat-resize-outer/index.tsx +247 -0
  119. package/example/app/columns/index.tsx +78 -0
  120. package/example/app/countries/index.tsx +182 -0
  121. package/example/app/countries-flashlist/index.tsx +163 -0
  122. package/example/app/countries-reorder/index.tsx +187 -0
  123. package/example/app/extra-data/index.tsx +86 -0
  124. package/example/app/filter-elements/filter-data-provider.tsx +55 -0
  125. package/example/app/filter-elements/index.tsx +118 -0
  126. package/example/app/initial-scroll-index/index.tsx +106 -0
  127. package/example/app/initial-scroll-index/renderFixedItem.tsx +215 -0
  128. package/example/app/initial-scroll-index-free-height/index.tsx +70 -0
  129. package/example/app/initial-scroll-index-keyed/index.tsx +62 -0
  130. package/example/app/lazy-list/index.tsx +123 -0
  131. package/example/app/movies-flashlist/index.tsx +7 -0
  132. package/example/app/mutable-cells/index.tsx +104 -0
  133. package/example/app/video-feed/index.tsx +119 -0
  134. package/example/app.config.js +22 -0
  135. package/example/app.json +45 -0
  136. package/example/assets/fonts/SpaceMono-Regular.ttf +0 -0
  137. package/example/assets/images/adaptive-icon.png +0 -0
  138. package/example/assets/images/favicon.png +0 -0
  139. package/example/assets/images/icon.png +0 -0
  140. package/example/assets/images/partial-react-logo.png +0 -0
  141. package/example/assets/images/react-logo.png +0 -0
  142. package/example/assets/images/react-logo@2x.png +0 -0
  143. package/example/assets/images/react-logo@3x.png +0 -0
  144. package/example/assets/images/splash-icon.png +0 -0
  145. package/example/autoscroll.sh +101 -0
  146. package/example/bun.lock +2266 -0
  147. package/example/bunfig.toml +2 -0
  148. package/example/components/Breathe.tsx +54 -0
  149. package/example/components/Circle.tsx +69 -0
  150. package/example/components/Collapsible.tsx +44 -0
  151. package/example/components/ExternalLink.tsx +24 -0
  152. package/example/components/HapticTab.tsx +18 -0
  153. package/example/components/HelloWave.tsx +37 -0
  154. package/example/components/Movies.tsx +179 -0
  155. package/example/components/ParallaxScrollView.tsx +81 -0
  156. package/example/components/ThemedText.tsx +60 -0
  157. package/example/components/ThemedView.tsx +14 -0
  158. package/example/components/__tests__/ThemedText-test.tsx +10 -0
  159. package/example/components/__tests__/__snapshots__/ThemedText-test.tsx.snap +24 -0
  160. package/example/components/ui/IconSymbol.ios.tsx +32 -0
  161. package/example/components/ui/IconSymbol.tsx +43 -0
  162. package/example/components/ui/TabBarBackground.ios.tsx +22 -0
  163. package/example/components/ui/TabBarBackground.tsx +6 -0
  164. package/example/constants/Colors.ts +26 -0
  165. package/example/constants/constants.ts +5 -0
  166. package/example/constants/useScrollTest.ts +19 -0
  167. package/example/hooks/useColorScheme.ts +1 -0
  168. package/example/hooks/useColorScheme.web.ts +8 -0
  169. package/example/hooks/useThemeColor.ts +22 -0
  170. package/example/ios/.xcode.env +11 -0
  171. package/example/ios/Podfile +64 -0
  172. package/example/ios/Podfile.lock +2767 -0
  173. package/example/ios/Podfile.properties.json +5 -0
  174. package/example/ios/listtest/AppDelegate.swift +70 -0
  175. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  176. package/example/ios/listtest/Images.xcassets/AppIcon.appiconset/Contents.json +14 -0
  177. package/example/ios/listtest/Images.xcassets/Contents.json +6 -0
  178. package/example/ios/listtest/Images.xcassets/SplashScreenBackground.colorset/Contents.json +20 -0
  179. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/Contents.json +23 -0
  180. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image.png +0 -0
  181. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@2x.png +0 -0
  182. package/example/ios/listtest/Images.xcassets/SplashScreenLogo.imageset/image@3x.png +0 -0
  183. package/example/ios/listtest/Info.plist +85 -0
  184. package/example/ios/listtest/PrivacyInfo.xcprivacy +48 -0
  185. package/example/ios/listtest/SplashScreen.storyboard +42 -0
  186. package/example/ios/listtest/Supporting/Expo.plist +12 -0
  187. package/example/ios/listtest/listtest-Bridging-Header.h +3 -0
  188. package/example/ios/listtest/listtest.entitlements +5 -0
  189. package/example/ios/listtest.xcodeproj/project.pbxproj +547 -0
  190. package/example/ios/listtest.xcodeproj/xcshareddata/xcschemes/listtest.xcscheme +88 -0
  191. package/example/ios/listtest.xcworkspace/contents.xcworkspacedata +10 -0
  192. package/example/metro.config.js +16 -0
  193. package/example/package.json +73 -0
  194. package/example/scripts/reset-project.js +84 -0
  195. package/example/tsconfig.json +26 -0
  196. package/package.json +88 -34
  197. package/posttsup.ts +24 -0
  198. package/src/Container.tsx +176 -0
  199. package/src/Containers.tsx +85 -0
  200. package/src/ContextContainer.ts +145 -0
  201. package/src/DebugView.tsx +83 -0
  202. package/src/LazyLegendList.tsx +41 -0
  203. package/src/LeanView.tsx +18 -0
  204. package/src/LegendList.tsx +558 -0
  205. package/src/ListComponent.tsx +191 -0
  206. package/src/ScrollAdjust.tsx +24 -0
  207. package/src/ScrollAdjustHandler.ts +26 -0
  208. package/src/Separator.tsx +14 -0
  209. package/src/animated.tsx +6 -0
  210. package/src/calculateItemsInView.ts +363 -0
  211. package/src/calculateOffsetForIndex.ts +23 -0
  212. package/src/calculateOffsetWithOffsetPosition.ts +26 -0
  213. package/src/checkAllSizesKnown.ts +17 -0
  214. package/src/checkAtBottom.ts +36 -0
  215. package/src/checkAtTop.ts +27 -0
  216. package/src/checkThreshold.ts +30 -0
  217. package/src/constants.ts +11 -0
  218. package/src/createColumnWrapperStyle.ts +16 -0
  219. package/src/doInitialAllocateContainers.ts +40 -0
  220. package/src/doMaintainScrollAtEnd.ts +34 -0
  221. package/src/findAvailableContainers.ts +98 -0
  222. package/src/finishScrollTo.ts +8 -0
  223. package/src/getId.ts +21 -0
  224. package/src/getItemSize.ts +52 -0
  225. package/src/getRenderedItem.ts +34 -0
  226. package/src/getScrollVelocity.ts +47 -0
  227. package/src/handleLayout.ts +70 -0
  228. package/src/helpers.ts +39 -0
  229. package/src/index.ts +11 -0
  230. package/src/keyboard-controller.tsx +63 -0
  231. package/src/onScroll.ts +66 -0
  232. package/src/prepareMVCP.ts +50 -0
  233. package/src/reanimated.tsx +63 -0
  234. package/src/requestAdjust.ts +41 -0
  235. package/src/scrollTo.ts +40 -0
  236. package/src/scrollToIndex.ts +34 -0
  237. package/src/setDidLayout.ts +25 -0
  238. package/src/setPaddingTop.ts +28 -0
  239. package/src/state.tsx +304 -0
  240. package/src/types.ts +610 -0
  241. package/src/updateAlignItemsPaddingTop.ts +18 -0
  242. package/src/updateAllPositions.ts +130 -0
  243. package/src/updateItemSize.ts +203 -0
  244. package/src/updateTotalSize.ts +44 -0
  245. package/src/useAnimatedValue.ts +6 -0
  246. package/src/useCombinedRef.ts +22 -0
  247. package/src/useInit.ts +17 -0
  248. package/src/useSyncLayout.tsx +68 -0
  249. package/src/useValue$.ts +53 -0
  250. package/src/viewability.ts +279 -0
  251. package/tsconfig.json +59 -0
  252. package/tsup.config.ts +21 -0
  253. package/index.js +0 -2348
  254. package/index.mjs +0 -2320
  255. /package/{animated.js → dist/animated.js} +0 -0
  256. /package/{animated.mjs → dist/animated.mjs} +0 -0
  257. /package/{keyboard-controller.js → dist/keyboard-controller.js} +0 -0
  258. /package/{keyboard-controller.mjs → dist/keyboard-controller.mjs} +0 -0
  259. /package/{reanimated.d.mts → dist/reanimated.d.mts} +0 -0
  260. /package/{reanimated.d.ts → dist/reanimated.d.ts} +0 -0
  261. /package/{reanimated.js → dist/reanimated.js} +0 -0
  262. /package/{reanimated.mjs → dist/reanimated.mjs} +0 -0
package/dist/index.js ADDED
@@ -0,0 +1,2525 @@
1
+ 'use strict';
2
+
3
+ var React3 = require('react');
4
+ var reactNative = require('react-native');
5
+ var shim = require('use-sync-external-store/shim');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
26
+
27
+ // src/LegendList.tsx
28
+ var ContextState = React3__namespace.createContext(null);
29
+ function StateProvider({ children }) {
30
+ const [value] = React3__namespace.useState(() => ({
31
+ listeners: /* @__PURE__ */ new Map(),
32
+ values: /* @__PURE__ */ new Map([
33
+ ["alignItemsPaddingTop", 0],
34
+ ["stylePaddingTop", 0],
35
+ ["headerSize", 0]
36
+ ]),
37
+ mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
38
+ mapViewabilityValues: /* @__PURE__ */ new Map(),
39
+ mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
40
+ mapViewabilityAmountValues: /* @__PURE__ */ new Map(),
41
+ columnWrapperStyle: void 0,
42
+ viewRefs: /* @__PURE__ */ new Map()
43
+ }));
44
+ return /* @__PURE__ */ React3__namespace.createElement(ContextState.Provider, { value }, children);
45
+ }
46
+ function useStateContext() {
47
+ return React3__namespace.useContext(ContextState);
48
+ }
49
+ function createSelectorFunctionsArr(ctx, signalNames) {
50
+ let lastValues = [];
51
+ let lastSignalValues = [];
52
+ return {
53
+ subscribe: (cb) => {
54
+ const listeners = [];
55
+ for (const signalName of signalNames) {
56
+ listeners.push(listen$(ctx, signalName, cb));
57
+ }
58
+ return () => {
59
+ for (const listener of listeners) {
60
+ listener();
61
+ }
62
+ };
63
+ },
64
+ get: () => {
65
+ const currentValues = [];
66
+ let hasChanged = false;
67
+ for (let i = 0; i < signalNames.length; i++) {
68
+ const value = peek$(ctx, signalNames[i]);
69
+ currentValues.push(value);
70
+ if (value !== lastSignalValues[i]) {
71
+ hasChanged = true;
72
+ }
73
+ }
74
+ lastSignalValues = currentValues;
75
+ if (hasChanged) {
76
+ lastValues = currentValues;
77
+ }
78
+ return lastValues;
79
+ }
80
+ };
81
+ }
82
+ function listen$(ctx, signalName, cb) {
83
+ const { listeners } = ctx;
84
+ let setListeners = listeners.get(signalName);
85
+ if (!setListeners) {
86
+ setListeners = /* @__PURE__ */ new Set();
87
+ listeners.set(signalName, setListeners);
88
+ }
89
+ setListeners.add(cb);
90
+ return () => setListeners.delete(cb);
91
+ }
92
+ function peek$(ctx, signalName) {
93
+ const { values } = ctx;
94
+ return values.get(signalName);
95
+ }
96
+ function set$(ctx, signalName, value) {
97
+ const { listeners, values } = ctx;
98
+ if (values.get(signalName) !== value) {
99
+ values.set(signalName, value);
100
+ const setListeners = listeners.get(signalName);
101
+ if (setListeners) {
102
+ for (const listener of setListeners) {
103
+ listener(value);
104
+ }
105
+ }
106
+ }
107
+ }
108
+ function getContentSize(ctx) {
109
+ const { values } = ctx;
110
+ const stylePaddingTop = values.get("stylePaddingTop") || 0;
111
+ const headerSize = values.get("headerSize") || 0;
112
+ const footerSize = values.get("footerSize") || 0;
113
+ const totalSize = values.get("totalSize") || 0;
114
+ return headerSize + footerSize + totalSize + stylePaddingTop;
115
+ }
116
+ function useArr$(signalNames) {
117
+ const ctx = React3__namespace.useContext(ContextState);
118
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
119
+ const value = shim.useSyncExternalStore(subscribe, get);
120
+ return value;
121
+ }
122
+ function useSelector$(signalName, selector) {
123
+ const ctx = React3__namespace.useContext(ContextState);
124
+ const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, [signalName]), [ctx, signalName]);
125
+ const value = shim.useSyncExternalStore(subscribe, () => selector(get()[0]));
126
+ return value;
127
+ }
128
+
129
+ // src/DebugView.tsx
130
+ var DebugRow = ({ children }) => {
131
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
132
+ };
133
+ var DebugView = React3__namespace.memo(function DebugView2({ state }) {
134
+ const ctx = useStateContext();
135
+ const [totalSize = 0, scrollAdjust = 0, rawScroll = 0, scroll = 0, numContainers = 0, numContainersPooled = 0] = useArr$([
136
+ "totalSize",
137
+ "scrollAdjust",
138
+ "debugRawScroll",
139
+ "debugComputedScroll",
140
+ "numContainers",
141
+ "numContainersPooled"
142
+ ]);
143
+ const contentSize = getContentSize(ctx);
144
+ const [, forceUpdate] = React3.useReducer((x) => x + 1, 0);
145
+ useInterval(() => {
146
+ forceUpdate();
147
+ }, 100);
148
+ return /* @__PURE__ */ React3__namespace.createElement(
149
+ reactNative.View,
150
+ {
151
+ style: {
152
+ position: "absolute",
153
+ top: 0,
154
+ right: 0,
155
+ paddingLeft: 4,
156
+ paddingBottom: 4,
157
+ // height: 100,
158
+ backgroundColor: "#FFFFFFCC",
159
+ padding: 4,
160
+ borderRadius: 4
161
+ },
162
+ pointerEvents: "none"
163
+ },
164
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "TotalSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, totalSize.toFixed(2))),
165
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ContentSize:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, contentSize.toFixed(2))),
166
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "At end:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, String(state.isAtEnd))),
167
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
168
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ScrollAdjust:"), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scrollAdjust.toFixed(2))),
169
+ /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null),
170
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "RawScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, rawScroll.toFixed(2))),
171
+ /* @__PURE__ */ React3__namespace.createElement(DebugRow, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, "ComputedScroll: "), /* @__PURE__ */ React3__namespace.createElement(reactNative.Text, null, scroll.toFixed(2)))
172
+ );
173
+ });
174
+ function useInterval(callback, delay) {
175
+ React3.useEffect(() => {
176
+ const interval = setInterval(callback, delay);
177
+ return () => clearInterval(interval);
178
+ }, [delay]);
179
+ }
180
+
181
+ // src/helpers.ts
182
+ function isFunction(obj) {
183
+ return typeof obj === "function";
184
+ }
185
+ function isArray(obj) {
186
+ return Array.isArray(obj);
187
+ }
188
+ var warned = /* @__PURE__ */ new Set();
189
+ function warnDevOnce(id, text) {
190
+ if (__DEV__ && !warned.has(id)) {
191
+ warned.add(id);
192
+ console.warn(`[legend-list] ${text}`);
193
+ }
194
+ }
195
+ function roundSize(size) {
196
+ return Math.floor(size * 8) / 8;
197
+ }
198
+ function isNullOrUndefined(value) {
199
+ return value === null || value === void 0;
200
+ }
201
+ function comparatorDefault(a, b) {
202
+ return a - b;
203
+ }
204
+ function getPadding(s, type) {
205
+ var _a, _b, _c;
206
+ return (_c = (_b = (_a = s[`padding${type}`]) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
207
+ }
208
+ function extractPadding(style, contentContainerStyle, type) {
209
+ return getPadding(style, type) + getPadding(contentContainerStyle, type);
210
+ }
211
+ var symbolFirst = Symbol();
212
+ function useInit(cb) {
213
+ const refValue = React3.useRef(symbolFirst);
214
+ if (refValue.current === symbolFirst) {
215
+ refValue.current = cb();
216
+ }
217
+ return refValue.current;
218
+ }
219
+
220
+ // src/ContextContainer.ts
221
+ var ContextContainer = React3.createContext(null);
222
+ function useViewability(callback, configId) {
223
+ const ctx = useStateContext();
224
+ const { containerId } = React3.useContext(ContextContainer);
225
+ const key = containerId + (configId != null ? configId : "");
226
+ useInit(() => {
227
+ const value = ctx.mapViewabilityValues.get(key);
228
+ if (value) {
229
+ callback(value);
230
+ }
231
+ });
232
+ ctx.mapViewabilityCallbacks.set(key, callback);
233
+ React3.useEffect(
234
+ () => () => {
235
+ ctx.mapViewabilityCallbacks.delete(key);
236
+ },
237
+ []
238
+ );
239
+ }
240
+ function useViewabilityAmount(callback) {
241
+ const ctx = useStateContext();
242
+ const { containerId } = React3.useContext(ContextContainer);
243
+ useInit(() => {
244
+ const value = ctx.mapViewabilityAmountValues.get(containerId);
245
+ if (value) {
246
+ callback(value);
247
+ }
248
+ });
249
+ ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
250
+ React3.useEffect(
251
+ () => () => {
252
+ ctx.mapViewabilityAmountCallbacks.delete(containerId);
253
+ },
254
+ []
255
+ );
256
+ }
257
+ function useRecyclingEffect(effect) {
258
+ const { index, value } = React3.useContext(ContextContainer);
259
+ const prevValues = React3.useRef({
260
+ prevIndex: void 0,
261
+ prevItem: void 0
262
+ });
263
+ React3.useEffect(() => {
264
+ let ret = void 0;
265
+ if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
266
+ ret = effect({
267
+ index,
268
+ item: value,
269
+ prevIndex: prevValues.current.prevIndex,
270
+ prevItem: prevValues.current.prevItem
271
+ });
272
+ }
273
+ prevValues.current = {
274
+ prevIndex: index,
275
+ prevItem: value
276
+ };
277
+ return ret;
278
+ }, [index, value]);
279
+ }
280
+ function useRecyclingState(valueOrFun) {
281
+ const { index, value, itemKey, triggerLayout } = React3.useContext(ContextContainer);
282
+ const refState = React3.useRef({
283
+ itemKey: null,
284
+ value: null
285
+ });
286
+ const [_, setRenderNum] = React3.useState(0);
287
+ const state = refState.current;
288
+ if (state.itemKey !== itemKey) {
289
+ state.itemKey = itemKey;
290
+ state.value = isFunction(valueOrFun) ? valueOrFun({
291
+ index,
292
+ item: value,
293
+ prevIndex: void 0,
294
+ prevItem: void 0
295
+ }) : valueOrFun;
296
+ }
297
+ const setState = React3.useCallback(
298
+ (newState) => {
299
+ state.value = isFunction(newState) ? newState(state.value) : newState;
300
+ setRenderNum((v) => v + 1);
301
+ triggerLayout();
302
+ },
303
+ [triggerLayout, state]
304
+ );
305
+ return [state.value, setState];
306
+ }
307
+ function useIsLastItem() {
308
+ const { itemKey } = React3.useContext(ContextContainer);
309
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
310
+ return isLast;
311
+ }
312
+ function useListScrollSize() {
313
+ const [scrollSize] = useArr$(["scrollSize"]);
314
+ return scrollSize;
315
+ }
316
+ var LeanViewComponent = React3__namespace.forwardRef((props, ref) => {
317
+ return React3__namespace.createElement("RCTView", { ...props, ref });
318
+ });
319
+ LeanViewComponent.displayName = "RCTView";
320
+ var LeanView = reactNative.Platform.OS === "android" || reactNative.Platform.OS === "ios" ? LeanViewComponent : reactNative.View;
321
+
322
+ // src/Separator.tsx
323
+ function Separator({ ItemSeparatorComponent, itemKey, leadingItem }) {
324
+ const [lastItemKeys] = useArr$(["lastItemKeys"]);
325
+ const isALastItem = lastItemKeys.includes(itemKey);
326
+ return isALastItem ? null : /* @__PURE__ */ React.createElement(ItemSeparatorComponent, { leadingItem });
327
+ }
328
+
329
+ // src/constants.ts
330
+ var POSITION_OUT_OF_VIEW = -1e7;
331
+ var ENABLE_DEVMODE = __DEV__ && false;
332
+ var ENABLE_DEBUG_VIEW = __DEV__ && false;
333
+ var IsNewArchitecture = global.nativeFabricUIManager != null;
334
+
335
+ // src/Container.tsx
336
+ var Container = ({
337
+ id,
338
+ recycleItems,
339
+ horizontal,
340
+ getRenderedItem: getRenderedItem2,
341
+ updateItemSize: updateItemSize2,
342
+ ItemSeparatorComponent
343
+ }) => {
344
+ const ctx = useStateContext();
345
+ const columnWrapperStyle = ctx.columnWrapperStyle;
346
+ const [column = 0, data, itemKey, position = POSITION_OUT_OF_VIEW, numColumns, extraData] = useArr$([
347
+ `containerColumn${id}`,
348
+ `containerItemData${id}`,
349
+ `containerItemKey${id}`,
350
+ `containerPosition${id}`,
351
+ "numColumns",
352
+ "extraData"
353
+ ]);
354
+ const refLastSize = React3.useRef();
355
+ const ref = React3.useRef(null);
356
+ const [layoutRenderCount, forceLayoutRender] = React3.useState(0);
357
+ const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
358
+ const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
359
+ let didLayout = false;
360
+ let paddingStyles;
361
+ if (columnWrapperStyle) {
362
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
363
+ if (horizontal) {
364
+ paddingStyles = {
365
+ paddingRight: columnGap || gap || void 0,
366
+ paddingVertical: numColumns > 1 ? (rowGap || gap || 0) / 2 : void 0
367
+ };
368
+ } else {
369
+ paddingStyles = {
370
+ paddingBottom: rowGap || gap || void 0,
371
+ paddingHorizontal: numColumns > 1 ? (columnGap || gap || 0) / 2 : void 0
372
+ };
373
+ }
374
+ }
375
+ const style = horizontal ? {
376
+ flexDirection: ItemSeparatorComponent ? "row" : void 0,
377
+ position: "absolute",
378
+ top: otherAxisPos,
379
+ height: otherAxisSize,
380
+ left: position,
381
+ ...paddingStyles || {}
382
+ } : {
383
+ position: "absolute",
384
+ left: otherAxisPos,
385
+ right: numColumns > 1 ? null : 0,
386
+ width: otherAxisSize,
387
+ top: position,
388
+ ...paddingStyles || {}
389
+ };
390
+ const renderedItemInfo = React3.useMemo(
391
+ () => itemKey !== void 0 ? getRenderedItem2(itemKey) : null,
392
+ [itemKey, data, extraData]
393
+ );
394
+ const { index, renderedItem } = renderedItemInfo || {};
395
+ const triggerLayout = React3.useCallback(() => {
396
+ forceLayoutRender((v) => v + 1);
397
+ }, []);
398
+ const contextValue = React3.useMemo(() => {
399
+ ctx.viewRefs.set(id, ref);
400
+ return { containerId: id, itemKey, index, value: data, triggerLayout };
401
+ }, [id, itemKey, index, data]);
402
+ const onLayout = (event) => {
403
+ var _a, _b;
404
+ if (!isNullOrUndefined(itemKey)) {
405
+ didLayout = true;
406
+ let layout = event.nativeEvent.layout;
407
+ const size = layout[horizontal ? "width" : "height"];
408
+ const doUpdate = () => {
409
+ refLastSize.current = { width: layout.width, height: layout.height };
410
+ updateItemSize2(itemKey, layout);
411
+ };
412
+ if (IsNewArchitecture || size > 0) {
413
+ doUpdate();
414
+ } else {
415
+ (_b = (_a = ref.current) == null ? void 0 : _a.measure) == null ? void 0 : _b.call(_a, (x, y, width, height) => {
416
+ layout = { width, height };
417
+ doUpdate();
418
+ });
419
+ }
420
+ }
421
+ };
422
+ if (IsNewArchitecture) {
423
+ React3.useLayoutEffect(() => {
424
+ var _a, _b;
425
+ if (!isNullOrUndefined(itemKey)) {
426
+ const measured = (_b = (_a = ref.current) == null ? void 0 : _a.unstable_getBoundingClientRect) == null ? void 0 : _b.call(_a);
427
+ if (measured) {
428
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
429
+ if (size) {
430
+ updateItemSize2(itemKey, measured);
431
+ }
432
+ }
433
+ }
434
+ }, [itemKey, layoutRenderCount]);
435
+ } else {
436
+ React3.useEffect(() => {
437
+ if (!isNullOrUndefined(itemKey)) {
438
+ const timeout = setTimeout(() => {
439
+ if (!didLayout && refLastSize.current) {
440
+ updateItemSize2(itemKey, refLastSize.current);
441
+ }
442
+ }, 16);
443
+ return () => {
444
+ clearTimeout(timeout);
445
+ };
446
+ }
447
+ }, [itemKey]);
448
+ }
449
+ return /* @__PURE__ */ React3__namespace.createElement(LeanView, { style, onLayout, ref, key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React3__namespace.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && /* @__PURE__ */ React3__namespace.createElement(
450
+ Separator,
451
+ {
452
+ itemKey,
453
+ ItemSeparatorComponent,
454
+ leadingItem: renderedItemInfo.item
455
+ }
456
+ )));
457
+ };
458
+ var typedForwardRef = React3.forwardRef;
459
+ var typedMemo = React3.memo;
460
+ var useAnimatedValue = (initialValue) => {
461
+ return React3.useRef(new reactNative.Animated.Value(initialValue)).current;
462
+ };
463
+
464
+ // src/useValue$.ts
465
+ function useValue$(key, params) {
466
+ var _a;
467
+ const { getValue, delay } = params || {};
468
+ const ctx = useStateContext();
469
+ const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
470
+ React3.useMemo(() => {
471
+ let newValue = void 0;
472
+ let prevValue = void 0;
473
+ let didQueueTask = false;
474
+ listen$(ctx, key, (v) => {
475
+ newValue = getValue ? getValue(v) : v;
476
+ if (delay !== void 0) {
477
+ const fn = () => {
478
+ didQueueTask = false;
479
+ if (newValue !== void 0) {
480
+ animValue.setValue(newValue);
481
+ }
482
+ };
483
+ const delayValue = typeof delay === "function" ? delay(newValue, prevValue) : delay;
484
+ prevValue = newValue;
485
+ if (!didQueueTask) {
486
+ didQueueTask = true;
487
+ if (delayValue === 0) {
488
+ queueMicrotask(fn);
489
+ } else {
490
+ setTimeout(fn, delayValue);
491
+ }
492
+ }
493
+ } else {
494
+ animValue.setValue(newValue);
495
+ }
496
+ });
497
+ }, []);
498
+ return animValue;
499
+ }
500
+
501
+ // src/Containers.tsx
502
+ var Containers = typedMemo(function Containers2({
503
+ horizontal,
504
+ recycleItems,
505
+ ItemSeparatorComponent,
506
+ waitForInitialLayout,
507
+ updateItemSize: updateItemSize2,
508
+ getRenderedItem: getRenderedItem2
509
+ }) {
510
+ const ctx = useStateContext();
511
+ const columnWrapperStyle = ctx.columnWrapperStyle;
512
+ const [numContainers, numColumns] = useArr$(["numContainersPooled", "numColumns"]);
513
+ const animSize = useValue$("totalSize", {
514
+ // Use a microtask if increasing the size significantly, otherwise use a timeout
515
+ delay: (value, prevValue) => !prevValue || value - prevValue > 20 ? 0 : 200
516
+ });
517
+ const animOpacity = waitForInitialLayout && !IsNewArchitecture ? useValue$("containersDidLayout", { getValue: (value) => value ? 1 : 0 }) : void 0;
518
+ const otherAxisSize = useValue$("otherAxisSize", { delay: 0 });
519
+ const containers = [];
520
+ for (let i = 0; i < numContainers; i++) {
521
+ containers.push(
522
+ /* @__PURE__ */ React3__namespace.createElement(
523
+ Container,
524
+ {
525
+ id: i,
526
+ key: i,
527
+ recycleItems,
528
+ horizontal,
529
+ getRenderedItem: getRenderedItem2,
530
+ updateItemSize: updateItemSize2,
531
+ ItemSeparatorComponent
532
+ }
533
+ )
534
+ );
535
+ }
536
+ const style = horizontal ? { width: animSize, opacity: animOpacity, minHeight: otherAxisSize } : { height: animSize, opacity: animOpacity, minWidth: otherAxisSize };
537
+ if (columnWrapperStyle && numColumns > 1) {
538
+ const { columnGap, rowGap, gap } = columnWrapperStyle;
539
+ const gapX = columnGap || gap || 0;
540
+ const gapY = rowGap || gap || 0;
541
+ if (horizontal) {
542
+ if (gapY) {
543
+ style.marginVertical = -gapY / 2;
544
+ }
545
+ if (gapX) {
546
+ style.marginRight = -gapX;
547
+ }
548
+ } else {
549
+ if (gapX) {
550
+ style.marginHorizontal = -gapX;
551
+ }
552
+ if (gapY) {
553
+ style.marginBottom = -gapY;
554
+ }
555
+ }
556
+ }
557
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style }, containers);
558
+ });
559
+ function ScrollAdjust() {
560
+ const bias = 1e7;
561
+ const [scrollAdjust, scrollAdjustUserOffset] = useArr$(["scrollAdjust", "scrollAdjustUserOffset"]);
562
+ const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0) + bias;
563
+ return /* @__PURE__ */ React3__namespace.createElement(
564
+ reactNative.View,
565
+ {
566
+ style: {
567
+ position: "absolute",
568
+ height: 0,
569
+ width: 0,
570
+ top: scrollOffset,
571
+ left: 0
572
+ }
573
+ }
574
+ );
575
+ }
576
+ function useSyncLayout({
577
+ onChange
578
+ }) {
579
+ const ref = React3.useRef(null);
580
+ const onLayout = React3.useCallback(
581
+ (event) => {
582
+ onChange(event.nativeEvent.layout, false);
583
+ },
584
+ [onChange]
585
+ );
586
+ React3.useLayoutEffect(() => {
587
+ if (ref.current) {
588
+ ref.current.measure((x, y, width, height) => {
589
+ onChange({ x, y, width, height }, true);
590
+ });
591
+ }
592
+ }, []);
593
+ return { onLayout, ref };
594
+ }
595
+
596
+ // src/ListComponent.tsx
597
+ var getComponent = (Component) => {
598
+ if (React3__namespace.isValidElement(Component)) {
599
+ return Component;
600
+ }
601
+ if (Component) {
602
+ return /* @__PURE__ */ React3__namespace.createElement(Component, null);
603
+ }
604
+ return null;
605
+ };
606
+ var Padding = () => {
607
+ const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
608
+ return /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } });
609
+ };
610
+ var PaddingDevMode = () => {
611
+ const animPaddingTop = useValue$("alignItemsPaddingTop", { delay: 0 });
612
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(reactNative.Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React3__namespace.createElement(
613
+ reactNative.Animated.View,
614
+ {
615
+ style: {
616
+ position: "absolute",
617
+ top: 0,
618
+ height: animPaddingTop,
619
+ left: 0,
620
+ right: 0,
621
+ backgroundColor: "green"
622
+ }
623
+ }
624
+ ));
625
+ };
626
+ var ListComponent = typedMemo(function ListComponent2({
627
+ canRender,
628
+ style,
629
+ contentContainerStyle,
630
+ horizontal,
631
+ initialContentOffset,
632
+ recycleItems,
633
+ ItemSeparatorComponent,
634
+ alignItemsAtEnd,
635
+ waitForInitialLayout,
636
+ onScroll: onScroll2,
637
+ onLayout,
638
+ ListHeaderComponent,
639
+ ListHeaderComponentStyle,
640
+ ListFooterComponent,
641
+ ListFooterComponentStyle,
642
+ ListEmptyComponent,
643
+ getRenderedItem: getRenderedItem2,
644
+ updateItemSize: updateItemSize2,
645
+ refScrollView,
646
+ maintainVisibleContentPosition,
647
+ renderScrollComponent,
648
+ scrollAdjustHandler,
649
+ onLayoutHeader,
650
+ ...rest
651
+ }) {
652
+ const ctx = useStateContext();
653
+ const { onLayout: onLayoutHeaderSync, ref: refHeader } = useSyncLayout({
654
+ onChange: onLayoutHeader
655
+ });
656
+ const ScrollComponent = renderScrollComponent ? React3.useMemo(
657
+ () => React3__namespace.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
658
+ [renderScrollComponent]
659
+ ) : reactNative.ScrollView;
660
+ React3__namespace.useEffect(() => {
661
+ if (canRender) {
662
+ setTimeout(() => {
663
+ scrollAdjustHandler.setMounted();
664
+ }, 0);
665
+ }
666
+ }, [canRender]);
667
+ return /* @__PURE__ */ React3__namespace.createElement(
668
+ ScrollComponent,
669
+ {
670
+ ...rest,
671
+ style,
672
+ maintainVisibleContentPosition: maintainVisibleContentPosition && !ListEmptyComponent ? { minIndexForVisible: 0 } : void 0,
673
+ contentContainerStyle: [
674
+ contentContainerStyle,
675
+ horizontal ? {
676
+ height: "100%"
677
+ } : {}
678
+ ],
679
+ onScroll: onScroll2,
680
+ onLayout,
681
+ horizontal,
682
+ contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
683
+ ref: refScrollView
684
+ },
685
+ maintainVisibleContentPosition && /* @__PURE__ */ React3__namespace.createElement(ScrollAdjust, null),
686
+ ENABLE_DEVMODE ? /* @__PURE__ */ React3__namespace.createElement(PaddingDevMode, null) : /* @__PURE__ */ React3__namespace.createElement(Padding, null),
687
+ ListHeaderComponent && /* @__PURE__ */ React3__namespace.createElement(reactNative.View, { style: ListHeaderComponentStyle, onLayout: onLayoutHeaderSync, ref: refHeader }, getComponent(ListHeaderComponent)),
688
+ ListEmptyComponent && getComponent(ListEmptyComponent),
689
+ canRender && /* @__PURE__ */ React3__namespace.createElement(
690
+ Containers,
691
+ {
692
+ horizontal,
693
+ recycleItems,
694
+ waitForInitialLayout,
695
+ getRenderedItem: getRenderedItem2,
696
+ ItemSeparatorComponent,
697
+ updateItemSize: updateItemSize2
698
+ }
699
+ ),
700
+ ListFooterComponent && /* @__PURE__ */ React3__namespace.createElement(
701
+ reactNative.View,
702
+ {
703
+ style: ListFooterComponentStyle,
704
+ onLayout: (event) => {
705
+ const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
706
+ set$(ctx, "footerSize", size);
707
+ }
708
+ },
709
+ getComponent(ListFooterComponent)
710
+ )
711
+ );
712
+ });
713
+
714
+ // src/ScrollAdjustHandler.ts
715
+ var ScrollAdjustHandler = class {
716
+ constructor(ctx) {
717
+ this.appliedAdjust = 0;
718
+ this.mounted = false;
719
+ this.context = ctx;
720
+ }
721
+ requestAdjust(add) {
722
+ const oldAdjustTop = peek$(this.context, "scrollAdjust") || 0;
723
+ this.appliedAdjust = add + oldAdjustTop;
724
+ const set = () => set$(this.context, "scrollAdjust", this.appliedAdjust);
725
+ if (this.mounted) {
726
+ set();
727
+ } else {
728
+ requestAnimationFrame(set);
729
+ }
730
+ }
731
+ setMounted() {
732
+ this.mounted = true;
733
+ }
734
+ };
735
+
736
+ // src/getId.ts
737
+ function getId(state, index) {
738
+ const { data, keyExtractor } = state.props;
739
+ if (!data) {
740
+ return "";
741
+ }
742
+ const ret = index < data.length ? keyExtractor ? keyExtractor(data[index], index) : index : null;
743
+ const id = ret;
744
+ state.idCache.set(index, id);
745
+ return id;
746
+ }
747
+
748
+ // src/calculateOffsetForIndex.ts
749
+ function calculateOffsetForIndex(ctx, state, index) {
750
+ let position = 0;
751
+ if (index !== void 0) {
752
+ position = (state == null ? void 0 : state.positions.get(getId(state, index))) || 0;
753
+ }
754
+ const paddingTop = peek$(ctx, "stylePaddingTop");
755
+ if (paddingTop) {
756
+ position += paddingTop;
757
+ }
758
+ const headerSize = peek$(ctx, "headerSize");
759
+ if (headerSize) {
760
+ position += headerSize;
761
+ }
762
+ return position;
763
+ }
764
+
765
+ // src/getItemSize.ts
766
+ function getItemSize(state, key, index, data, useAverageSize) {
767
+ const {
768
+ sizesKnown,
769
+ sizes,
770
+ scrollingTo,
771
+ props: { estimatedItemSize, getEstimatedItemSize }
772
+ } = state;
773
+ const sizeKnown = sizesKnown.get(key);
774
+ if (sizeKnown !== void 0) {
775
+ return sizeKnown;
776
+ }
777
+ let size;
778
+ if (IsNewArchitecture && useAverageSize !== void 0 && sizeKnown === void 0 && !getEstimatedItemSize && !scrollingTo) {
779
+ size = useAverageSize;
780
+ }
781
+ if (size === void 0) {
782
+ size = sizes.get(key);
783
+ if (size !== void 0) {
784
+ return size;
785
+ }
786
+ }
787
+ if (size === void 0) {
788
+ size = getEstimatedItemSize ? getEstimatedItemSize(index, data) : estimatedItemSize;
789
+ }
790
+ sizes.set(key, size);
791
+ return size;
792
+ }
793
+
794
+ // src/calculateOffsetWithOffsetPosition.ts
795
+ function calculateOffsetWithOffsetPosition(state, offsetParam, params) {
796
+ const { index, viewOffset, viewPosition } = params;
797
+ let offset = offsetParam;
798
+ if (viewOffset) {
799
+ offset -= viewOffset;
800
+ }
801
+ if (viewPosition !== void 0 && index !== void 0) {
802
+ offset -= viewPosition * (state.scrollLength - getItemSize(state, getId(state, index), index, state.props.data[index]));
803
+ }
804
+ return offset;
805
+ }
806
+
807
+ // src/checkAllSizesKnown.ts
808
+ function checkAllSizesKnown(state) {
809
+ const { startBuffered, endBuffered, sizesKnown } = state;
810
+ if (endBuffered !== null) {
811
+ let areAllKnown = true;
812
+ for (let i = startBuffered; areAllKnown && i <= endBuffered; i++) {
813
+ const key = getId(state, i);
814
+ areAllKnown && (areAllKnown = sizesKnown.has(key));
815
+ }
816
+ return areAllKnown;
817
+ }
818
+ return false;
819
+ }
820
+
821
+ // src/findAvailableContainers.ts
822
+ function findAvailableContainers(ctx, state, numNeeded, startBuffered, endBuffered, pendingRemoval) {
823
+ const numContainers = peek$(ctx, "numContainers");
824
+ const result = [];
825
+ const availableContainers = [];
826
+ for (let u = 0; u < numContainers; u++) {
827
+ const key = peek$(ctx, `containerItemKey${u}`);
828
+ let isOk = key === void 0;
829
+ if (!isOk) {
830
+ const index = pendingRemoval.indexOf(u);
831
+ if (index !== -1) {
832
+ pendingRemoval.splice(index, 1);
833
+ isOk = true;
834
+ }
835
+ }
836
+ if (isOk) {
837
+ result.push(u);
838
+ if (result.length >= numNeeded) {
839
+ return result;
840
+ }
841
+ }
842
+ }
843
+ for (let u = 0; u < numContainers; u++) {
844
+ const key = peek$(ctx, `containerItemKey${u}`);
845
+ if (key === void 0) continue;
846
+ const index = state.indexByKey.get(key);
847
+ if (index < startBuffered) {
848
+ availableContainers.push({ index: u, distance: startBuffered - index });
849
+ } else if (index > endBuffered) {
850
+ availableContainers.push({ index: u, distance: index - endBuffered });
851
+ }
852
+ }
853
+ const remaining = numNeeded - result.length;
854
+ if (remaining > 0) {
855
+ if (availableContainers.length > 0) {
856
+ if (availableContainers.length > remaining) {
857
+ availableContainers.sort(comparatorByDistance);
858
+ availableContainers.length = remaining;
859
+ }
860
+ for (const container of availableContainers) {
861
+ result.push(container.index);
862
+ }
863
+ }
864
+ const stillNeeded = numNeeded - result.length;
865
+ if (stillNeeded > 0) {
866
+ for (let i = 0; i < stillNeeded; i++) {
867
+ result.push(numContainers + i);
868
+ }
869
+ if (__DEV__ && numContainers + stillNeeded > peek$(ctx, "numContainersPooled")) {
870
+ console.warn(
871
+ "[legend-list] No unused container available, so creating one on demand. This can be a minor performance issue and is likely caused by the estimatedItemSize being too large. Consider decreasing estimatedItemSize or increasing initialContainerPoolRatio.",
872
+ {
873
+ debugInfo: {
874
+ numContainers,
875
+ numNeeded,
876
+ stillNeeded,
877
+ numContainersPooled: peek$(ctx, "numContainersPooled")
878
+ }
879
+ }
880
+ );
881
+ }
882
+ }
883
+ }
884
+ return result.sort(comparatorDefault);
885
+ }
886
+ function comparatorByDistance(a, b) {
887
+ return b.distance - a.distance;
888
+ }
889
+
890
+ // src/getScrollVelocity.ts
891
+ var getScrollVelocity = (state) => {
892
+ const { scrollHistory } = state;
893
+ let velocity = 0;
894
+ if (scrollHistory.length >= 1) {
895
+ const newest = scrollHistory[scrollHistory.length - 1];
896
+ let oldest;
897
+ let start = 0;
898
+ for (let i = 0; i < scrollHistory.length - 1; i++) {
899
+ const entry = scrollHistory[i];
900
+ const nextEntry = scrollHistory[i + 1];
901
+ if (i > 0) {
902
+ const prevEntry = scrollHistory[i - 1];
903
+ const prevDirection = entry.scroll - prevEntry.scroll;
904
+ const currentDirection = nextEntry.scroll - entry.scroll;
905
+ if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
906
+ start = i;
907
+ break;
908
+ }
909
+ }
910
+ }
911
+ for (let i = start; i < scrollHistory.length - 1; i++) {
912
+ const entry = scrollHistory[i];
913
+ if (newest.time - entry.time <= 1e3) {
914
+ oldest = entry;
915
+ break;
916
+ }
917
+ }
918
+ if (oldest) {
919
+ const scrollDiff = newest.scroll - oldest.scroll;
920
+ const timeDiff = newest.time - oldest.time;
921
+ velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
922
+ }
923
+ }
924
+ return velocity;
925
+ };
926
+
927
+ // src/requestAdjust.ts
928
+ function requestAdjust(ctx, state, positionDiff) {
929
+ if (Math.abs(positionDiff) > 0.1) {
930
+ const doit = () => {
931
+ state.scrollAdjustHandler.requestAdjust(positionDiff);
932
+ };
933
+ state.scroll += positionDiff;
934
+ state.scrollForNextCalculateItemsInView = void 0;
935
+ const didLayout = peek$(ctx, "containersDidLayout");
936
+ if (didLayout) {
937
+ doit();
938
+ const threshold = state.scroll - positionDiff / 2;
939
+ if (!state.ignoreScrollFromMVCP) {
940
+ state.ignoreScrollFromMVCP = {};
941
+ }
942
+ if (positionDiff > 0) {
943
+ state.ignoreScrollFromMVCP.lt = threshold;
944
+ } else {
945
+ state.ignoreScrollFromMVCP.gt = threshold;
946
+ }
947
+ if (state.ignoreScrollFromMVCPTimeout) {
948
+ clearTimeout(state.ignoreScrollFromMVCPTimeout);
949
+ }
950
+ state.ignoreScrollFromMVCPTimeout = setTimeout(() => {
951
+ state.ignoreScrollFromMVCP = void 0;
952
+ }, 100);
953
+ } else {
954
+ requestAnimationFrame(doit);
955
+ }
956
+ }
957
+ }
958
+
959
+ // src/prepareMVCP.ts
960
+ function prepareMVCP(ctx, state) {
961
+ const {
962
+ positions,
963
+ scrollingTo,
964
+ props: { maintainVisibleContentPosition }
965
+ } = state;
966
+ let prevPosition;
967
+ let targetId;
968
+ let targetIndex;
969
+ const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
970
+ if (maintainVisibleContentPosition) {
971
+ const indexByKey = state.indexByKey;
972
+ if (scrollTarget !== void 0) {
973
+ targetId = getId(state, scrollTarget);
974
+ targetIndex = scrollTarget;
975
+ } else if (state.idsInView.length > 0 && peek$(ctx, "containersDidLayout")) {
976
+ targetId = state.idsInView.find((id) => indexByKey.get(id) !== void 0);
977
+ targetIndex = indexByKey.get(targetId);
978
+ }
979
+ if (targetId !== void 0 && targetIndex !== void 0) {
980
+ prevPosition = positions.get(targetId);
981
+ }
982
+ }
983
+ return () => {
984
+ if (targetId !== void 0 && prevPosition !== void 0) {
985
+ const newPosition = positions.get(targetId);
986
+ if (newPosition !== void 0) {
987
+ const positionDiff = newPosition - prevPosition;
988
+ if (Math.abs(positionDiff) > 0.1) {
989
+ requestAdjust(ctx, state, positionDiff);
990
+ }
991
+ }
992
+ }
993
+ };
994
+ }
995
+
996
+ // src/checkThreshold.ts
997
+ var checkThreshold = (distance, atThreshold, threshold, isReached, isBlockedByTimer, onReached, blockTimer) => {
998
+ const distanceAbs = Math.abs(distance);
999
+ const isAtThreshold = atThreshold || distanceAbs < threshold;
1000
+ if (!isReached && !isBlockedByTimer) {
1001
+ if (isAtThreshold) {
1002
+ onReached == null ? void 0 : onReached(distance);
1003
+ blockTimer == null ? void 0 : blockTimer(true);
1004
+ setTimeout(() => {
1005
+ blockTimer == null ? void 0 : blockTimer(false);
1006
+ }, 700);
1007
+ return true;
1008
+ }
1009
+ } else {
1010
+ if (distance >= 1.3 * threshold) {
1011
+ return false;
1012
+ }
1013
+ }
1014
+ return isReached;
1015
+ };
1016
+
1017
+ // src/checkAtBottom.ts
1018
+ function checkAtBottom(ctx, state) {
1019
+ if (!state) {
1020
+ return;
1021
+ }
1022
+ const {
1023
+ queuedInitialLayout,
1024
+ scrollLength,
1025
+ scroll,
1026
+ maintainingScrollAtEnd,
1027
+ props: { maintainScrollAtEndThreshold, onEndReachedThreshold }
1028
+ } = state;
1029
+ const contentSize = getContentSize(ctx);
1030
+ if (contentSize > 0 && queuedInitialLayout && !maintainingScrollAtEnd) {
1031
+ const distanceFromEnd = contentSize - scroll - scrollLength;
1032
+ const isContentLess = contentSize < scrollLength;
1033
+ state.isAtEnd = isContentLess || distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
1034
+ state.isEndReached = checkThreshold(
1035
+ distanceFromEnd,
1036
+ isContentLess,
1037
+ onEndReachedThreshold * scrollLength,
1038
+ state.isEndReached,
1039
+ state.endReachedBlockedByTimer,
1040
+ (distance) => {
1041
+ var _a, _b;
1042
+ return (_b = (_a = state.props).onEndReached) == null ? void 0 : _b.call(_a, { distanceFromEnd: distance });
1043
+ },
1044
+ (block) => {
1045
+ state.endReachedBlockedByTimer = block;
1046
+ }
1047
+ );
1048
+ }
1049
+ }
1050
+
1051
+ // src/finishScrollTo.ts
1052
+ var finishScrollTo = (state) => {
1053
+ if (state) {
1054
+ state.scrollingTo = void 0;
1055
+ state.scrollHistory.length = 0;
1056
+ }
1057
+ };
1058
+
1059
+ // src/scrollTo.ts
1060
+ function scrollTo(state, params = {}) {
1061
+ var _a;
1062
+ const { animated } = params;
1063
+ const {
1064
+ refScroller,
1065
+ props: { horizontal }
1066
+ } = state;
1067
+ const offset = calculateOffsetWithOffsetPosition(state, params.offset, params);
1068
+ state.scrollHistory.length = 0;
1069
+ state.scrollingTo = params;
1070
+ state.scrollPending = offset;
1071
+ (_a = refScroller.current) == null ? void 0 : _a.scrollTo({
1072
+ x: horizontal ? offset : 0,
1073
+ y: horizontal ? 0 : offset,
1074
+ animated: !!animated
1075
+ });
1076
+ if (!animated) {
1077
+ state.scroll = offset;
1078
+ setTimeout(() => finishScrollTo(state), 100);
1079
+ }
1080
+ }
1081
+
1082
+ // src/scrollToIndex.ts
1083
+ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, viewPosition }) {
1084
+ if (index >= state.props.data.length) {
1085
+ index = state.props.data.length - 1;
1086
+ } else if (index < 0) {
1087
+ index = 0;
1088
+ }
1089
+ const firstIndexOffset = calculateOffsetForIndex(ctx, state, index);
1090
+ const isLast = index === state.props.data.length - 1;
1091
+ if (isLast && viewPosition === void 0) {
1092
+ viewPosition = 1;
1093
+ }
1094
+ const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1095
+ state.scrollForNextCalculateItemsInView = void 0;
1096
+ scrollTo(state, {
1097
+ offset: firstIndexScrollPostion,
1098
+ animated,
1099
+ index,
1100
+ viewPosition: viewPosition != null ? viewPosition : 0,
1101
+ viewOffset
1102
+ });
1103
+ }
1104
+
1105
+ // src/setDidLayout.ts
1106
+ function setDidLayout(ctx, state) {
1107
+ const {
1108
+ loadStartTime,
1109
+ initialScroll,
1110
+ props: { onLoad }
1111
+ } = state;
1112
+ state.queuedInitialLayout = true;
1113
+ checkAtBottom(ctx, state);
1114
+ if (!IsNewArchitecture && initialScroll) {
1115
+ scrollToIndex(ctx, state, { ...initialScroll, animated: false });
1116
+ }
1117
+ set$(ctx, "containersDidLayout", true);
1118
+ if (onLoad) {
1119
+ onLoad({ elapsedTimeInMs: Date.now() - loadStartTime });
1120
+ }
1121
+ }
1122
+
1123
+ // src/setPaddingTop.ts
1124
+ function setPaddingTop(ctx, { stylePaddingTop, alignItemsPaddingTop }) {
1125
+ if (stylePaddingTop !== void 0) {
1126
+ const prevStylePaddingTop = peek$(ctx, "stylePaddingTop") || 0;
1127
+ if (stylePaddingTop < prevStylePaddingTop) {
1128
+ const prevTotalSize = peek$(ctx, "totalSize") || 0;
1129
+ set$(ctx, "totalSize", prevTotalSize + prevStylePaddingTop);
1130
+ setTimeout(() => {
1131
+ set$(ctx, "totalSize", prevTotalSize);
1132
+ }, 16);
1133
+ }
1134
+ set$(ctx, "stylePaddingTop", stylePaddingTop);
1135
+ }
1136
+ if (alignItemsPaddingTop !== void 0) {
1137
+ set$(ctx, "alignItemsPaddingTop", alignItemsPaddingTop);
1138
+ }
1139
+ }
1140
+
1141
+ // src/updateAlignItemsPaddingTop.ts
1142
+ function updateAlignItemsPaddingTop(ctx, state) {
1143
+ const {
1144
+ scrollLength,
1145
+ props: { alignItemsAtEnd, data }
1146
+ } = state;
1147
+ if (alignItemsAtEnd) {
1148
+ let alignItemsPaddingTop = 0;
1149
+ if ((data == null ? void 0 : data.length) > 0) {
1150
+ const contentSize = getContentSize(ctx);
1151
+ alignItemsPaddingTop = Math.max(0, Math.floor(scrollLength - contentSize));
1152
+ }
1153
+ setPaddingTop(ctx, { alignItemsPaddingTop });
1154
+ }
1155
+ }
1156
+
1157
+ // src/updateTotalSize.ts
1158
+ function updateTotalSize(ctx, state) {
1159
+ const {
1160
+ positions,
1161
+ props: { data }
1162
+ } = state;
1163
+ if (data.length === 0) {
1164
+ addTotalSize(ctx, state, null, 0);
1165
+ } else {
1166
+ const lastId = getId(state, data.length - 1);
1167
+ if (lastId !== void 0) {
1168
+ const lastPosition = positions.get(lastId);
1169
+ if (lastPosition !== void 0) {
1170
+ const lastSize = getItemSize(state, lastId, data.length - 1, data[data.length - 1]);
1171
+ if (lastSize !== void 0) {
1172
+ const totalSize = lastPosition + lastSize;
1173
+ addTotalSize(ctx, state, null, totalSize);
1174
+ }
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+ function addTotalSize(ctx, state, key, add) {
1180
+ const { alignItemsAtEnd } = state.props;
1181
+ {
1182
+ state.totalSize = add;
1183
+ }
1184
+ set$(ctx, "totalSize", state.totalSize);
1185
+ if (alignItemsAtEnd) {
1186
+ updateAlignItemsPaddingTop(ctx, state);
1187
+ }
1188
+ }
1189
+
1190
+ // src/updateAllPositions.ts
1191
+ function updateAllPositions(ctx, state, dataChanged) {
1192
+ var _a, _b, _c, _d, _e;
1193
+ const { averageSizes, columns, indexByKey, positions, firstFullyOnScreenIndex, idCache, sizesKnown } = state;
1194
+ const data = state.props.data;
1195
+ const numColumns = peek$(ctx, "numColumns");
1196
+ const indexByKeyForChecking = __DEV__ ? /* @__PURE__ */ new Map() : void 0;
1197
+ const scrollVelocity = getScrollVelocity(state);
1198
+ if (dataChanged) {
1199
+ indexByKey.clear();
1200
+ idCache.clear();
1201
+ }
1202
+ const itemType = "";
1203
+ let averageSize = (_a = averageSizes[itemType]) == null ? void 0 : _a.avg;
1204
+ if (averageSize !== void 0) {
1205
+ averageSize = roundSize(averageSize);
1206
+ }
1207
+ const shouldUseBackwards = !dataChanged && scrollVelocity < 0 && firstFullyOnScreenIndex > 5 && firstFullyOnScreenIndex < data.length;
1208
+ if (shouldUseBackwards && firstFullyOnScreenIndex !== void 0) {
1209
+ const anchorId = getId(state, firstFullyOnScreenIndex);
1210
+ const anchorPosition = positions.get(anchorId);
1211
+ if (anchorPosition !== void 0) {
1212
+ let currentRowTop2 = anchorPosition;
1213
+ let maxSizeInRow2 = 0;
1214
+ let bailout = false;
1215
+ for (let i = firstFullyOnScreenIndex - 1; i >= 0; i--) {
1216
+ const id = (_b = idCache.get(i)) != null ? _b : getId(state, i);
1217
+ const size = (_c = sizesKnown.get(id)) != null ? _c : getItemSize(state, id, i, data[i], averageSize);
1218
+ const itemColumn = columns.get(id);
1219
+ maxSizeInRow2 = Math.max(maxSizeInRow2, size);
1220
+ if (itemColumn === 1) {
1221
+ currentRowTop2 -= maxSizeInRow2;
1222
+ maxSizeInRow2 = 0;
1223
+ }
1224
+ if (currentRowTop2 < -2e3) {
1225
+ bailout = true;
1226
+ break;
1227
+ }
1228
+ positions.set(id, currentRowTop2);
1229
+ }
1230
+ if (!bailout) {
1231
+ updateTotalSize(ctx, state);
1232
+ return;
1233
+ }
1234
+ }
1235
+ }
1236
+ let currentRowTop = 0;
1237
+ let column = 1;
1238
+ let maxSizeInRow = 0;
1239
+ const hasColumns = numColumns > 1;
1240
+ const needsIndexByKey = dataChanged || indexByKey.size === 0;
1241
+ const dataLength = data.length;
1242
+ for (let i = 0; i < dataLength; i++) {
1243
+ const id = (_d = idCache.get(i)) != null ? _d : getId(state, i);
1244
+ const size = (_e = sizesKnown.get(id)) != null ? _e : getItemSize(state, id, i, data[i], averageSize);
1245
+ if (__DEV__ && needsIndexByKey) {
1246
+ if (indexByKeyForChecking.has(id)) {
1247
+ console.error(
1248
+ `[legend-list] Error: Detected overlapping key (${id}) which causes missing items and gaps and other terrrible things. Check that keyExtractor returns unique values.`
1249
+ );
1250
+ }
1251
+ indexByKeyForChecking.set(id, i);
1252
+ }
1253
+ positions.set(id, currentRowTop);
1254
+ if (needsIndexByKey) {
1255
+ indexByKey.set(id, i);
1256
+ }
1257
+ columns.set(id, column);
1258
+ if (hasColumns) {
1259
+ if (size > maxSizeInRow) {
1260
+ maxSizeInRow = size;
1261
+ }
1262
+ column++;
1263
+ if (column > numColumns) {
1264
+ currentRowTop += maxSizeInRow;
1265
+ column = 1;
1266
+ maxSizeInRow = 0;
1267
+ }
1268
+ } else {
1269
+ currentRowTop += size;
1270
+ }
1271
+ }
1272
+ updateTotalSize(ctx, state);
1273
+ }
1274
+
1275
+ // src/viewability.ts
1276
+ var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
1277
+ function setupViewability(props) {
1278
+ let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
1279
+ if (viewabilityConfig || onViewableItemsChanged) {
1280
+ viewabilityConfigCallbackPairs = [
1281
+ ...viewabilityConfigCallbackPairs || [],
1282
+ {
1283
+ viewabilityConfig: viewabilityConfig || {
1284
+ viewAreaCoveragePercentThreshold: 0
1285
+ },
1286
+ onViewableItemsChanged
1287
+ }
1288
+ ];
1289
+ }
1290
+ if (viewabilityConfigCallbackPairs) {
1291
+ for (const pair of viewabilityConfigCallbackPairs) {
1292
+ mapViewabilityConfigCallbackPairs.set(pair.viewabilityConfig.id, {
1293
+ viewableItems: [],
1294
+ start: -1,
1295
+ end: -1,
1296
+ previousStart: -1,
1297
+ previousEnd: -1
1298
+ });
1299
+ }
1300
+ }
1301
+ return viewabilityConfigCallbackPairs;
1302
+ }
1303
+ function updateViewableItems(state, ctx, viewabilityConfigCallbackPairs, scrollSize, start, end) {
1304
+ for (const viewabilityConfigCallbackPair of viewabilityConfigCallbackPairs) {
1305
+ const viewabilityState = mapViewabilityConfigCallbackPairs.get(
1306
+ viewabilityConfigCallbackPair.viewabilityConfig.id
1307
+ );
1308
+ viewabilityState.start = start;
1309
+ viewabilityState.end = end;
1310
+ if (viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime) {
1311
+ const timer = setTimeout(() => {
1312
+ state.timeouts.delete(timer);
1313
+ updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1314
+ }, viewabilityConfigCallbackPair.viewabilityConfig.minimumViewTime);
1315
+ state.timeouts.add(timer);
1316
+ } else {
1317
+ updateViewableItemsWithConfig(state.data, viewabilityConfigCallbackPair, state, ctx, scrollSize);
1318
+ }
1319
+ }
1320
+ }
1321
+ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, state, ctx, scrollSize) {
1322
+ const { viewabilityConfig, onViewableItemsChanged } = viewabilityConfigCallbackPair;
1323
+ const configId = viewabilityConfig.id;
1324
+ const viewabilityState = mapViewabilityConfigCallbackPairs.get(configId);
1325
+ const { viewableItems: previousViewableItems, start, end } = viewabilityState;
1326
+ const viewabilityTokens = /* @__PURE__ */ new Map();
1327
+ for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
1328
+ viewabilityTokens.set(
1329
+ containerId,
1330
+ computeViewability(
1331
+ state,
1332
+ ctx,
1333
+ viewabilityConfig,
1334
+ containerId,
1335
+ value.key,
1336
+ scrollSize,
1337
+ value.item,
1338
+ value.index
1339
+ )
1340
+ );
1341
+ }
1342
+ const changed = [];
1343
+ if (previousViewableItems) {
1344
+ for (const viewToken of previousViewableItems) {
1345
+ const containerId = findContainerId(ctx, viewToken.key);
1346
+ if (!isViewable(
1347
+ state,
1348
+ ctx,
1349
+ viewabilityConfig,
1350
+ containerId,
1351
+ viewToken.key,
1352
+ scrollSize,
1353
+ viewToken.item,
1354
+ viewToken.index
1355
+ )) {
1356
+ viewToken.isViewable = false;
1357
+ changed.push(viewToken);
1358
+ }
1359
+ }
1360
+ }
1361
+ const viewableItems = [];
1362
+ for (let i = start; i <= end; i++) {
1363
+ const item = data[i];
1364
+ if (item) {
1365
+ const key = getId(state, i);
1366
+ const containerId = findContainerId(ctx, key);
1367
+ if (isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, i)) {
1368
+ const viewToken = {
1369
+ item,
1370
+ key,
1371
+ index: i,
1372
+ isViewable: true,
1373
+ containerId
1374
+ };
1375
+ viewableItems.push(viewToken);
1376
+ if (!(previousViewableItems == null ? void 0 : previousViewableItems.find((v) => v.key === viewToken.key))) {
1377
+ changed.push(viewToken);
1378
+ }
1379
+ }
1380
+ }
1381
+ }
1382
+ Object.assign(viewabilityState, {
1383
+ viewableItems,
1384
+ previousStart: start,
1385
+ previousEnd: end
1386
+ });
1387
+ if (changed.length > 0) {
1388
+ viewabilityState.viewableItems = viewableItems;
1389
+ for (let i = 0; i < changed.length; i++) {
1390
+ const change = changed[i];
1391
+ maybeUpdateViewabilityCallback(ctx, configId, change.containerId, change);
1392
+ }
1393
+ if (onViewableItemsChanged) {
1394
+ onViewableItemsChanged({ viewableItems, changed });
1395
+ }
1396
+ }
1397
+ for (const [containerId, value] of ctx.mapViewabilityAmountValues) {
1398
+ if (value.sizeVisible < 0) {
1399
+ ctx.mapViewabilityAmountValues.delete(containerId);
1400
+ }
1401
+ }
1402
+ }
1403
+ function computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1404
+ const { sizes, positions, scroll: scrollState } = state;
1405
+ const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
1406
+ const { itemVisiblePercentThreshold, viewAreaCoveragePercentThreshold } = viewabilityConfig;
1407
+ const viewAreaMode = viewAreaCoveragePercentThreshold != null;
1408
+ const viewablePercentThreshold = viewAreaMode ? viewAreaCoveragePercentThreshold : itemVisiblePercentThreshold;
1409
+ const scroll = scrollState - topPad;
1410
+ const top = positions.get(key) - scroll;
1411
+ const size = sizes.get(key) || 0;
1412
+ const bottom = top + size;
1413
+ const isEntirelyVisible = top >= 0 && bottom <= scrollSize && bottom > top;
1414
+ const sizeVisible = isEntirelyVisible ? size : Math.min(bottom, scrollSize) - Math.max(top, 0);
1415
+ const percentVisible = size ? isEntirelyVisible ? 100 : 100 * (sizeVisible / size) : 0;
1416
+ const percentOfScroller = size ? 100 * (sizeVisible / scrollSize) : 0;
1417
+ const percent = isEntirelyVisible ? 100 : viewAreaMode ? percentOfScroller : percentVisible;
1418
+ const isViewable2 = percent >= viewablePercentThreshold;
1419
+ const value = {
1420
+ index,
1421
+ isViewable: isViewable2,
1422
+ item,
1423
+ key,
1424
+ percentVisible,
1425
+ percentOfScroller,
1426
+ sizeVisible,
1427
+ size,
1428
+ scrollSize,
1429
+ containerId
1430
+ };
1431
+ if (JSON.stringify(value) !== JSON.stringify(ctx.mapViewabilityAmountValues.get(containerId))) {
1432
+ ctx.mapViewabilityAmountValues.set(containerId, value);
1433
+ const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
1434
+ if (cb) {
1435
+ cb(value);
1436
+ }
1437
+ }
1438
+ return value;
1439
+ }
1440
+ function isViewable(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index) {
1441
+ const value = ctx.mapViewabilityAmountValues.get(containerId) || computeViewability(state, ctx, viewabilityConfig, containerId, key, scrollSize, item, index);
1442
+ return value.isViewable;
1443
+ }
1444
+ function findContainerId(ctx, key) {
1445
+ const numContainers = peek$(ctx, "numContainers");
1446
+ for (let i = 0; i < numContainers; i++) {
1447
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1448
+ if (itemKey === key) {
1449
+ return i;
1450
+ }
1451
+ }
1452
+ return -1;
1453
+ }
1454
+ function maybeUpdateViewabilityCallback(ctx, configId, containerId, viewToken) {
1455
+ const key = containerId + configId;
1456
+ ctx.mapViewabilityValues.set(key, viewToken);
1457
+ const cb = ctx.mapViewabilityCallbacks.get(key);
1458
+ cb == null ? void 0 : cb(viewToken);
1459
+ }
1460
+
1461
+ // src/calculateItemsInView.ts
1462
+ function calculateItemsInView(ctx, state, params = {}) {
1463
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1464
+ const {
1465
+ scrollLength,
1466
+ startBufferedId: startBufferedIdOrig,
1467
+ positions,
1468
+ columns,
1469
+ containerItemKeys,
1470
+ idCache,
1471
+ sizes,
1472
+ indexByKey,
1473
+ scrollForNextCalculateItemsInView,
1474
+ enableScrollForNextCalculateItemsInView,
1475
+ minIndexSizeChanged
1476
+ } = state;
1477
+ const data = state.props.data;
1478
+ if (!data || scrollLength === 0) {
1479
+ return;
1480
+ }
1481
+ const totalSize = peek$(ctx, "totalSize");
1482
+ const topPad = peek$(ctx, "stylePaddingTop") + peek$(ctx, "headerSize");
1483
+ const numColumns = peek$(ctx, "numColumns");
1484
+ const previousScrollAdjust = 0;
1485
+ const { dataChanged, doMVCP } = params;
1486
+ const speed = getScrollVelocity(state);
1487
+ if (doMVCP || dataChanged) {
1488
+ const checkMVCP = doMVCP ? prepareMVCP(ctx, state) : void 0;
1489
+ updateAllPositions(ctx, state, dataChanged);
1490
+ checkMVCP == null ? void 0 : checkMVCP();
1491
+ }
1492
+ const scrollExtra = 0;
1493
+ const { queuedInitialLayout } = state;
1494
+ let { scroll: scrollState } = state;
1495
+ const initialScroll = state.props.initialScroll;
1496
+ if (!queuedInitialLayout && initialScroll) {
1497
+ const updatedOffset = calculateOffsetWithOffsetPosition(
1498
+ state,
1499
+ calculateOffsetForIndex(ctx, state, initialScroll.index),
1500
+ initialScroll
1501
+ );
1502
+ scrollState = updatedOffset;
1503
+ }
1504
+ const scrollAdjustPad = -previousScrollAdjust - topPad;
1505
+ let scroll = scrollState + scrollExtra + scrollAdjustPad;
1506
+ if (scroll + scrollLength > totalSize) {
1507
+ scroll = totalSize - scrollLength;
1508
+ }
1509
+ if (ENABLE_DEBUG_VIEW) {
1510
+ set$(ctx, "debugRawScroll", scrollState);
1511
+ set$(ctx, "debugComputedScroll", scroll);
1512
+ }
1513
+ const scrollBuffer = state.props.scrollBuffer;
1514
+ let scrollBufferTop = scrollBuffer;
1515
+ let scrollBufferBottom = scrollBuffer;
1516
+ if (speed > 0) {
1517
+ scrollBufferTop = scrollBuffer * 0.5;
1518
+ scrollBufferBottom = scrollBuffer * 1.5;
1519
+ } else {
1520
+ scrollBufferTop = scrollBuffer * 1.5;
1521
+ scrollBufferBottom = scrollBuffer * 0.5;
1522
+ }
1523
+ const scrollTopBuffered = scroll - scrollBufferTop;
1524
+ const scrollBottom = scroll + scrollLength;
1525
+ const scrollBottomBuffered = scrollBottom + scrollBufferBottom;
1526
+ if (scrollForNextCalculateItemsInView) {
1527
+ const { top, bottom } = scrollForNextCalculateItemsInView;
1528
+ if (scrollTopBuffered > top && scrollBottomBuffered < bottom) {
1529
+ return;
1530
+ }
1531
+ }
1532
+ let startNoBuffer = null;
1533
+ let startBuffered = null;
1534
+ let startBufferedId = null;
1535
+ let endNoBuffer = null;
1536
+ let endBuffered = null;
1537
+ let loopStart = startBufferedIdOrig ? indexByKey.get(startBufferedIdOrig) || 0 : 0;
1538
+ if (minIndexSizeChanged !== void 0) {
1539
+ loopStart = Math.min(minIndexSizeChanged, loopStart);
1540
+ state.minIndexSizeChanged = void 0;
1541
+ }
1542
+ for (let i = loopStart; i >= 0; i--) {
1543
+ const id = (_a = idCache.get(i)) != null ? _a : getId(state, i);
1544
+ const top = positions.get(id);
1545
+ const size = (_b = sizes.get(id)) != null ? _b : getItemSize(state, id, i, data[i]);
1546
+ const bottom = top + size;
1547
+ if (bottom > scroll - scrollBuffer) {
1548
+ loopStart = i;
1549
+ } else {
1550
+ break;
1551
+ }
1552
+ }
1553
+ const loopStartMod = loopStart % numColumns;
1554
+ if (loopStartMod > 0) {
1555
+ loopStart -= loopStartMod;
1556
+ }
1557
+ let foundEnd = false;
1558
+ let nextTop;
1559
+ let nextBottom;
1560
+ const prevNumContainers = ctx.values.get("numContainers");
1561
+ let maxIndexRendered = 0;
1562
+ for (let i = 0; i < prevNumContainers; i++) {
1563
+ const key = peek$(ctx, `containerItemKey${i}`);
1564
+ if (key !== void 0) {
1565
+ const index = indexByKey.get(key);
1566
+ maxIndexRendered = Math.max(maxIndexRendered, index);
1567
+ }
1568
+ }
1569
+ let firstFullyOnScreenIndex;
1570
+ const dataLength = data.length;
1571
+ for (let i = Math.max(0, loopStart); i < dataLength && (!foundEnd || i <= maxIndexRendered); i++) {
1572
+ const id = (_c = idCache.get(i)) != null ? _c : getId(state, i);
1573
+ const size = (_d = sizes.get(id)) != null ? _d : getItemSize(state, id, i, data[i]);
1574
+ const top = positions.get(id);
1575
+ if (!foundEnd) {
1576
+ if (startNoBuffer === null && top + size > scroll) {
1577
+ startNoBuffer = i;
1578
+ }
1579
+ if (firstFullyOnScreenIndex === void 0 && top >= scroll - 10) {
1580
+ firstFullyOnScreenIndex = i;
1581
+ }
1582
+ if (startBuffered === null && top + size > scrollTopBuffered) {
1583
+ startBuffered = i;
1584
+ startBufferedId = id;
1585
+ nextTop = top;
1586
+ }
1587
+ if (startNoBuffer !== null) {
1588
+ if (top <= scrollBottom) {
1589
+ endNoBuffer = i;
1590
+ }
1591
+ if (top <= scrollBottomBuffered) {
1592
+ endBuffered = i;
1593
+ nextBottom = top + size;
1594
+ } else {
1595
+ foundEnd = true;
1596
+ }
1597
+ }
1598
+ }
1599
+ }
1600
+ const idsInView = [];
1601
+ for (let i = firstFullyOnScreenIndex; i <= endNoBuffer; i++) {
1602
+ const id = (_e = idCache.get(i)) != null ? _e : getId(state, i);
1603
+ idsInView.push(id);
1604
+ }
1605
+ Object.assign(state, {
1606
+ startBuffered,
1607
+ startBufferedId,
1608
+ startNoBuffer,
1609
+ endBuffered,
1610
+ endNoBuffer,
1611
+ idsInView,
1612
+ firstFullyOnScreenIndex
1613
+ });
1614
+ if (enableScrollForNextCalculateItemsInView && nextTop !== void 0 && nextBottom !== void 0) {
1615
+ state.scrollForNextCalculateItemsInView = nextTop !== void 0 && nextBottom !== void 0 ? {
1616
+ top: nextTop,
1617
+ bottom: nextBottom
1618
+ } : void 0;
1619
+ }
1620
+ const numContainers = peek$(ctx, "numContainers");
1621
+ const pendingRemoval = [];
1622
+ if (dataChanged) {
1623
+ for (let i = 0; i < numContainers; i++) {
1624
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1625
+ if (!state.props.keyExtractor || itemKey && indexByKey.get(itemKey) === void 0) {
1626
+ pendingRemoval.push(i);
1627
+ }
1628
+ }
1629
+ }
1630
+ if (startBuffered !== null && endBuffered !== null) {
1631
+ let numContainers2 = prevNumContainers;
1632
+ const needNewContainers = [];
1633
+ for (let i = startBuffered; i <= endBuffered; i++) {
1634
+ const id = (_f = idCache.get(i)) != null ? _f : getId(state, i);
1635
+ if (!containerItemKeys.has(id)) {
1636
+ needNewContainers.push(i);
1637
+ }
1638
+ }
1639
+ if (needNewContainers.length > 0) {
1640
+ const availableContainers = findAvailableContainers(
1641
+ ctx,
1642
+ state,
1643
+ needNewContainers.length,
1644
+ startBuffered,
1645
+ endBuffered,
1646
+ pendingRemoval
1647
+ );
1648
+ for (let idx = 0; idx < needNewContainers.length; idx++) {
1649
+ const i = needNewContainers[idx];
1650
+ const containerIndex = availableContainers[idx];
1651
+ const id = (_g = idCache.get(i)) != null ? _g : getId(state, i);
1652
+ const oldKey = peek$(ctx, `containerItemKey${containerIndex}`);
1653
+ if (oldKey && oldKey !== id) {
1654
+ containerItemKeys.delete(oldKey);
1655
+ }
1656
+ set$(ctx, `containerItemKey${containerIndex}`, id);
1657
+ set$(ctx, `containerItemData${containerIndex}`, data[i]);
1658
+ containerItemKeys.add(id);
1659
+ if (containerIndex >= numContainers2) {
1660
+ numContainers2 = containerIndex + 1;
1661
+ }
1662
+ }
1663
+ if (numContainers2 !== prevNumContainers) {
1664
+ set$(ctx, "numContainers", numContainers2);
1665
+ if (numContainers2 > peek$(ctx, "numContainersPooled")) {
1666
+ set$(ctx, "numContainersPooled", Math.ceil(numContainers2 * 1.5));
1667
+ }
1668
+ }
1669
+ }
1670
+ }
1671
+ for (let i = 0; i < numContainers; i++) {
1672
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
1673
+ if (pendingRemoval.includes(i)) {
1674
+ if (itemKey) {
1675
+ containerItemKeys.delete(itemKey);
1676
+ }
1677
+ set$(ctx, `containerItemKey${i}`, void 0);
1678
+ set$(ctx, `containerItemData${i}`, void 0);
1679
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1680
+ set$(ctx, `containerColumn${i}`, -1);
1681
+ } else {
1682
+ const itemIndex = indexByKey.get(itemKey);
1683
+ const item = data[itemIndex];
1684
+ if (item !== void 0) {
1685
+ const id = (_h = idCache.get(itemIndex)) != null ? _h : getId(state, itemIndex);
1686
+ const position = positions.get(id);
1687
+ if (position === void 0) {
1688
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1689
+ } else {
1690
+ const pos = positions.get(id);
1691
+ const column = columns.get(id) || 1;
1692
+ const prevPos = peek$(ctx, `containerPosition${i}`);
1693
+ const prevColumn = peek$(ctx, `containerColumn${i}`);
1694
+ const prevData = peek$(ctx, `containerItemData${i}`);
1695
+ if (!prevPos || pos > POSITION_OUT_OF_VIEW && pos !== prevPos) {
1696
+ set$(ctx, `containerPosition${i}`, pos);
1697
+ }
1698
+ if (column >= 0 && column !== prevColumn) {
1699
+ set$(ctx, `containerColumn${i}`, column);
1700
+ }
1701
+ if (prevData !== item) {
1702
+ set$(ctx, `containerItemData${i}`, data[itemIndex]);
1703
+ }
1704
+ }
1705
+ }
1706
+ }
1707
+ }
1708
+ if (!queuedInitialLayout && endBuffered !== null) {
1709
+ if (checkAllSizesKnown(state)) {
1710
+ setDidLayout(ctx, state);
1711
+ }
1712
+ }
1713
+ if (state.props.viewabilityConfigCallbackPairs) {
1714
+ updateViewableItems(
1715
+ state,
1716
+ ctx,
1717
+ state.props.viewabilityConfigCallbackPairs,
1718
+ scrollLength,
1719
+ startNoBuffer,
1720
+ endNoBuffer
1721
+ );
1722
+ }
1723
+ }
1724
+
1725
+ // src/checkAtTop.ts
1726
+ function checkAtTop(state) {
1727
+ if (!state) {
1728
+ return;
1729
+ }
1730
+ const {
1731
+ scrollLength,
1732
+ scroll,
1733
+ props: { onStartReachedThreshold }
1734
+ } = state;
1735
+ const distanceFromTop = scroll;
1736
+ state.isAtStart = distanceFromTop <= 0;
1737
+ state.isStartReached = checkThreshold(
1738
+ distanceFromTop,
1739
+ false,
1740
+ onStartReachedThreshold * scrollLength,
1741
+ state.isStartReached,
1742
+ state.startReachedBlockedByTimer,
1743
+ (distance) => {
1744
+ var _a, _b;
1745
+ return (_b = (_a = state.props).onStartReached) == null ? void 0 : _b.call(_a, { distanceFromStart: distance });
1746
+ },
1747
+ (block) => {
1748
+ state.startReachedBlockedByTimer = block;
1749
+ }
1750
+ );
1751
+ }
1752
+
1753
+ // src/createColumnWrapperStyle.ts
1754
+ function createColumnWrapperStyle(contentContainerStyle) {
1755
+ const { gap, columnGap, rowGap } = contentContainerStyle;
1756
+ if (gap || columnGap || rowGap) {
1757
+ contentContainerStyle.gap = void 0;
1758
+ contentContainerStyle.columnGap = void 0;
1759
+ contentContainerStyle.rowGap = void 0;
1760
+ return {
1761
+ gap,
1762
+ columnGap,
1763
+ rowGap
1764
+ };
1765
+ }
1766
+ }
1767
+
1768
+ // src/doInitialAllocateContainers.ts
1769
+ function doInitialAllocateContainers(ctx, state) {
1770
+ const { scrollLength } = state;
1771
+ const data = state.props.data;
1772
+ if (scrollLength > 0 && data.length > 0 && !peek$(ctx, "numContainers")) {
1773
+ const averageItemSize = state.props.getEstimatedItemSize ? state.props.getEstimatedItemSize(0, data[0]) : state.props.estimatedItemSize;
1774
+ const Extra = 1.5;
1775
+ const numContainers = Math.ceil(
1776
+ (scrollLength + state.props.scrollBuffer * 2) / averageItemSize * state.props.numColumns * Extra
1777
+ );
1778
+ for (let i = 0; i < numContainers; i++) {
1779
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
1780
+ set$(ctx, `containerColumn${i}`, -1);
1781
+ }
1782
+ set$(ctx, "numContainers", numContainers);
1783
+ set$(ctx, "numContainersPooled", numContainers * state.props.initialContainerPoolRatio);
1784
+ if (!IsNewArchitecture) {
1785
+ if (state.props.initialScroll) {
1786
+ requestAnimationFrame(() => {
1787
+ calculateItemsInView(ctx, state);
1788
+ });
1789
+ } else {
1790
+ calculateItemsInView(ctx, state);
1791
+ }
1792
+ }
1793
+ return true;
1794
+ }
1795
+ }
1796
+
1797
+ // src/doMaintainScrollAtEnd.ts
1798
+ function doMaintainScrollAtEnd(ctx, state, animated) {
1799
+ const {
1800
+ refScroller,
1801
+ props: { maintainScrollAtEnd }
1802
+ } = state;
1803
+ if ((state == null ? void 0 : state.isAtEnd) && maintainScrollAtEnd && peek$(ctx, "containersDidLayout")) {
1804
+ const paddingTop = peek$(ctx, "alignItemsPaddingTop");
1805
+ if (paddingTop > 0) {
1806
+ state.scroll = 0;
1807
+ }
1808
+ requestAnimationFrame(() => {
1809
+ var _a;
1810
+ state.maintainingScrollAtEnd = true;
1811
+ (_a = refScroller.current) == null ? void 0 : _a.scrollToEnd({
1812
+ animated
1813
+ });
1814
+ setTimeout(
1815
+ () => {
1816
+ state.maintainingScrollAtEnd = false;
1817
+ },
1818
+ 0
1819
+ );
1820
+ });
1821
+ return true;
1822
+ }
1823
+ }
1824
+ function getRenderedItem(ctx, state, key) {
1825
+ if (!state) {
1826
+ return null;
1827
+ }
1828
+ const {
1829
+ indexByKey,
1830
+ props: { data, renderItem: renderItem2 }
1831
+ } = state;
1832
+ const index = indexByKey.get(key);
1833
+ if (index === void 0) {
1834
+ return null;
1835
+ }
1836
+ let renderedItem = null;
1837
+ if (renderItem2) {
1838
+ const itemProps = {
1839
+ item: data[index],
1840
+ index,
1841
+ extraData: peek$(ctx, "extraData")
1842
+ };
1843
+ renderedItem = React3__namespace.default.createElement(renderItem2, itemProps);
1844
+ }
1845
+ return { index, item: data[index], renderedItem };
1846
+ }
1847
+
1848
+ // src/handleLayout.ts
1849
+ function handleLayout(ctx, state, layout, setCanRender) {
1850
+ const { maintainScrollAtEnd } = state.props;
1851
+ const scrollLength = layout[state.props.horizontal ? "width" : "height"];
1852
+ const otherAxisSize = layout[state.props.horizontal ? "height" : "width"];
1853
+ const needsCalculate = !state.lastLayout || scrollLength > state.scrollLength || state.lastLayout.x !== layout.x || state.lastLayout.y !== layout.y;
1854
+ state.lastLayout = layout;
1855
+ const didChange = scrollLength !== state.scrollLength;
1856
+ const prevOtherAxisSize = state.otherAxisSize;
1857
+ state.scrollLength = scrollLength;
1858
+ state.otherAxisSize = otherAxisSize;
1859
+ state.lastBatchingAction = Date.now();
1860
+ state.scrollForNextCalculateItemsInView = void 0;
1861
+ doInitialAllocateContainers(ctx, state);
1862
+ if (needsCalculate) {
1863
+ calculateItemsInView(ctx, state, { doMVCP: true });
1864
+ }
1865
+ if (didChange || otherAxisSize !== prevOtherAxisSize) {
1866
+ set$(ctx, "scrollSize", { width: layout.width, height: layout.height });
1867
+ }
1868
+ if (maintainScrollAtEnd === true || maintainScrollAtEnd.onLayout) {
1869
+ doMaintainScrollAtEnd(ctx, state, false);
1870
+ }
1871
+ updateAlignItemsPaddingTop(ctx, state);
1872
+ checkAtBottom(ctx, state);
1873
+ checkAtTop(state);
1874
+ if (state) {
1875
+ state.needsOtherAxisSize = otherAxisSize - (state.props.stylePaddingTop || 0) < 10;
1876
+ }
1877
+ if (__DEV__ && scrollLength === 0) {
1878
+ warnDevOnce(
1879
+ "height0",
1880
+ `List ${state.props.horizontal ? "width" : "height"} is 0. You may need to set a style or \`flex: \` for the list, because children are absolutely positioned.`
1881
+ );
1882
+ }
1883
+ setCanRender(true);
1884
+ }
1885
+
1886
+ // src/onScroll.ts
1887
+ function onScroll(ctx, state, event) {
1888
+ var _a, _b, _c, _d, _e;
1889
+ if (((_b = (_a = event.nativeEvent) == null ? void 0 : _a.contentSize) == null ? void 0 : _b.height) === 0 && ((_c = event.nativeEvent.contentSize) == null ? void 0 : _c.width) === 0) {
1890
+ return;
1891
+ }
1892
+ const newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
1893
+ const ignoreScrollFromMVCP = state.ignoreScrollFromMVCP;
1894
+ if (ignoreScrollFromMVCP && !state.scrollingTo) {
1895
+ const { lt, gt } = ignoreScrollFromMVCP;
1896
+ if (lt && newScroll < lt || gt && newScroll > gt) {
1897
+ return;
1898
+ }
1899
+ }
1900
+ state.scrollPending = newScroll;
1901
+ updateScroll(ctx, state, newScroll);
1902
+ (_e = (_d = state.props).onScroll) == null ? void 0 : _e.call(_d, event);
1903
+ }
1904
+ function updateScroll(ctx, state, newScroll) {
1905
+ const scrollingTo = state.scrollingTo;
1906
+ state.hasScrolled = true;
1907
+ state.lastBatchingAction = Date.now();
1908
+ const currentTime = performance.now();
1909
+ if (scrollingTo === void 0 && !(state.scrollHistory.length === 0 && newScroll === state.scroll)) {
1910
+ state.scrollHistory.push({ scroll: newScroll, time: currentTime });
1911
+ }
1912
+ if (state.scrollHistory.length > 5) {
1913
+ state.scrollHistory.shift();
1914
+ }
1915
+ state.scrollPrev = state.scroll;
1916
+ state.scrollPrevTime = state.scrollTime;
1917
+ state.scroll = newScroll;
1918
+ state.scrollTime = currentTime;
1919
+ calculateItemsInView(ctx, state);
1920
+ checkAtBottom(ctx, state);
1921
+ checkAtTop(state);
1922
+ }
1923
+
1924
+ // src/updateItemSize.ts
1925
+ function updateItemSizes(ctx, state, itemUpdates) {
1926
+ var _a;
1927
+ const {
1928
+ props: {
1929
+ horizontal,
1930
+ maintainVisibleContentPosition,
1931
+ suggestEstimatedItemSize,
1932
+ onItemSizeChanged,
1933
+ data,
1934
+ maintainScrollAtEnd
1935
+ }
1936
+ } = state;
1937
+ if (!data) return;
1938
+ let needsRecalculate = false;
1939
+ let shouldMaintainScrollAtEnd = false;
1940
+ let minIndexSizeChanged;
1941
+ let maxOtherAxisSize = peek$(ctx, "otherAxisSize") || 0;
1942
+ for (const { itemKey, sizeObj } of itemUpdates) {
1943
+ const index = state.indexByKey.get(itemKey);
1944
+ const prevSizeKnown = state.sizesKnown.get(itemKey);
1945
+ const diff = updateOneItemSize(state, itemKey, sizeObj);
1946
+ const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
1947
+ if (diff !== 0) {
1948
+ minIndexSizeChanged = minIndexSizeChanged !== void 0 ? Math.min(minIndexSizeChanged, index) : index;
1949
+ if (((_a = state.scrollingTo) == null ? void 0 : _a.viewPosition) && maintainVisibleContentPosition && index === state.scrollingTo.index) {
1950
+ requestAdjust(ctx, state, diff * state.scrollingTo.viewPosition);
1951
+ }
1952
+ const { startBuffered, endBuffered } = state;
1953
+ needsRecalculate || (needsRecalculate = index >= startBuffered && index <= endBuffered);
1954
+ if (!needsRecalculate) {
1955
+ const numContainers = ctx.values.get("numContainers");
1956
+ for (let i = 0; i < numContainers; i++) {
1957
+ if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
1958
+ needsRecalculate = true;
1959
+ break;
1960
+ }
1961
+ }
1962
+ }
1963
+ if (state.needsOtherAxisSize) {
1964
+ const otherAxisSize = horizontal ? sizeObj.height : sizeObj.width;
1965
+ maxOtherAxisSize = Math.max(maxOtherAxisSize, otherAxisSize);
1966
+ }
1967
+ if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
1968
+ shouldMaintainScrollAtEnd = true;
1969
+ }
1970
+ onItemSizeChanged == null ? void 0 : onItemSizeChanged({
1971
+ size,
1972
+ previous: size - diff,
1973
+ index,
1974
+ itemKey,
1975
+ itemData: state.props.data[index]
1976
+ });
1977
+ }
1978
+ }
1979
+ if (minIndexSizeChanged !== void 0) {
1980
+ state.minIndexSizeChanged = state.minIndexSizeChanged !== void 0 ? Math.min(state.minIndexSizeChanged, minIndexSizeChanged) : minIndexSizeChanged;
1981
+ }
1982
+ if (__DEV__ && suggestEstimatedItemSize && minIndexSizeChanged !== void 0) {
1983
+ if (state.timeoutSizeMessage) clearTimeout(state.timeoutSizeMessage);
1984
+ state.timeoutSizeMessage = setTimeout(() => {
1985
+ var _a2;
1986
+ state.timeoutSizeMessage = void 0;
1987
+ const num = state.sizesKnown.size;
1988
+ const avg = (_a2 = state.averageSizes[""]) == null ? void 0 : _a2.avg;
1989
+ console.warn(
1990
+ `[legend-list] Based on the ${num} items rendered so far, the optimal estimated size is ${avg}.`
1991
+ );
1992
+ }, 1e3);
1993
+ }
1994
+ const cur = peek$(ctx, "otherAxisSize");
1995
+ if (!cur || maxOtherAxisSize > cur) {
1996
+ set$(ctx, "otherAxisSize", maxOtherAxisSize);
1997
+ }
1998
+ const containersDidLayout = peek$(ctx, "containersDidLayout");
1999
+ if (containersDidLayout || checkAllSizesKnown(state)) {
2000
+ if (needsRecalculate) {
2001
+ state.scrollForNextCalculateItemsInView = void 0;
2002
+ calculateItemsInView(ctx, state, { doMVCP: true });
2003
+ }
2004
+ if (shouldMaintainScrollAtEnd) {
2005
+ if (maintainScrollAtEnd === true || maintainScrollAtEnd.onItemLayout) {
2006
+ doMaintainScrollAtEnd(ctx, state, false);
2007
+ }
2008
+ }
2009
+ }
2010
+ }
2011
+ function updateItemSize(ctx, state, itemKey, sizeObj) {
2012
+ if (IsNewArchitecture) {
2013
+ const { sizesKnown } = state;
2014
+ const numContainers = ctx.values.get("numContainers");
2015
+ const changes = [];
2016
+ for (let i = 0; i < numContainers; i++) {
2017
+ const containerItemKey = peek$(ctx, `containerItemKey${i}`);
2018
+ if (itemKey === containerItemKey) {
2019
+ changes.push({ itemKey, sizeObj });
2020
+ } else if (!sizesKnown.has(containerItemKey) && containerItemKey !== void 0) {
2021
+ const containerRef = ctx.viewRefs.get(i);
2022
+ if (containerRef == null ? void 0 : containerRef.current) {
2023
+ let measured;
2024
+ containerRef.current.measure((x, y, width, height) => {
2025
+ measured = { x, y, width, height };
2026
+ });
2027
+ if (measured) {
2028
+ changes.push({ itemKey: containerItemKey, sizeObj: measured });
2029
+ }
2030
+ }
2031
+ }
2032
+ }
2033
+ if (changes.length > 0) {
2034
+ updateItemSizes(ctx, state, changes);
2035
+ }
2036
+ } else {
2037
+ updateItemSizes(ctx, state, [{ itemKey, sizeObj }]);
2038
+ }
2039
+ }
2040
+ function updateOneItemSize(state, itemKey, sizeObj) {
2041
+ const {
2042
+ sizes,
2043
+ indexByKey,
2044
+ sizesKnown,
2045
+ averageSizes,
2046
+ props: { data, horizontal }
2047
+ } = state;
2048
+ if (!data) return 0;
2049
+ const index = indexByKey.get(itemKey);
2050
+ const prevSize = getItemSize(state, itemKey, index, data);
2051
+ const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2052
+ sizesKnown.set(itemKey, size);
2053
+ const itemType = "";
2054
+ let averages = averageSizes[itemType];
2055
+ if (!averages) {
2056
+ averages = averageSizes[itemType] = { num: 0, avg: 0 };
2057
+ }
2058
+ averages.avg = (averages.avg * averages.num + size) / (averages.num + 1);
2059
+ averages.num++;
2060
+ if (!prevSize || Math.abs(prevSize - size) > 0.1) {
2061
+ sizes.set(itemKey, size);
2062
+ return size - prevSize;
2063
+ }
2064
+ return 0;
2065
+ }
2066
+ var useCombinedRef = (...refs) => {
2067
+ const callback = React3.useCallback((element) => {
2068
+ for (const ref of refs) {
2069
+ if (!ref) {
2070
+ continue;
2071
+ }
2072
+ if (isFunction(ref)) {
2073
+ ref(element);
2074
+ } else {
2075
+ ref.current = element;
2076
+ }
2077
+ }
2078
+ }, refs);
2079
+ return callback;
2080
+ };
2081
+
2082
+ // src/LegendList.tsx
2083
+ var DEFAULT_DRAW_DISTANCE = 250;
2084
+ var DEFAULT_ITEM_SIZE = 100;
2085
+ var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
2086
+ return /* @__PURE__ */ React3__namespace.createElement(StateProvider, null, /* @__PURE__ */ React3__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
2087
+ });
2088
+ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
2089
+ var _a;
2090
+ const {
2091
+ data: dataProp = [],
2092
+ initialScrollIndex: initialScrollIndexProp,
2093
+ initialScrollOffset,
2094
+ horizontal,
2095
+ drawDistance = 250,
2096
+ recycleItems = false,
2097
+ onEndReachedThreshold = 0.5,
2098
+ onStartReachedThreshold = 0.5,
2099
+ maintainScrollAtEnd = false,
2100
+ maintainScrollAtEndThreshold = 0.1,
2101
+ alignItemsAtEnd = false,
2102
+ maintainVisibleContentPosition = false,
2103
+ onScroll: onScrollProp,
2104
+ onMomentumScrollEnd,
2105
+ numColumns: numColumnsProp = 1,
2106
+ columnWrapperStyle,
2107
+ keyExtractor: keyExtractorProp,
2108
+ renderItem: renderItem2,
2109
+ estimatedListSize,
2110
+ estimatedItemSize: estimatedItemSizeProp,
2111
+ getEstimatedItemSize,
2112
+ suggestEstimatedItemSize,
2113
+ ListHeaderComponent,
2114
+ ListEmptyComponent,
2115
+ onItemSizeChanged,
2116
+ refScrollView,
2117
+ waitForInitialLayout = true,
2118
+ extraData,
2119
+ contentContainerStyle: contentContainerStyleProp,
2120
+ style: styleProp,
2121
+ onLayout: onLayoutProp,
2122
+ onRefresh,
2123
+ refreshing,
2124
+ progressViewOffset,
2125
+ refreshControl,
2126
+ initialContainerPoolRatio = 2,
2127
+ viewabilityConfig,
2128
+ viewabilityConfigCallbackPairs,
2129
+ onViewableItemsChanged,
2130
+ onStartReached,
2131
+ onEndReached,
2132
+ onLoad,
2133
+ ...rest
2134
+ } = props;
2135
+ const [renderNum, setRenderNum] = React3.useState(0);
2136
+ const initialScroll = typeof initialScrollIndexProp === "number" ? { index: initialScrollIndexProp } : initialScrollIndexProp;
2137
+ const initialScrollIndex = initialScroll == null ? void 0 : initialScroll.index;
2138
+ const [canRender, setCanRender] = React3__namespace.useState(!IsNewArchitecture);
2139
+ const contentContainerStyle = { ...reactNative.StyleSheet.flatten(contentContainerStyleProp) };
2140
+ const style = { ...reactNative.StyleSheet.flatten(styleProp) };
2141
+ const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
2142
+ const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
2143
+ const ctx = useStateContext();
2144
+ ctx.columnWrapperStyle = columnWrapperStyle || (contentContainerStyle ? createColumnWrapperStyle(contentContainerStyle) : void 0);
2145
+ const refScroller = React3.useRef(null);
2146
+ const combinedRef = useCombinedRef(refScroller, refScrollView);
2147
+ const estimatedItemSize = estimatedItemSizeProp != null ? estimatedItemSizeProp : DEFAULT_ITEM_SIZE;
2148
+ const scrollBuffer = (drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE) || 1;
2149
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
2150
+ const refState = React3.useRef();
2151
+ if (!refState.current) {
2152
+ const initialScrollLength = (estimatedListSize != null ? estimatedListSize : IsNewArchitecture ? { width: 0, height: 0 } : reactNative.Dimensions.get("window"))[horizontal ? "width" : "height"];
2153
+ refState.current = {
2154
+ sizes: /* @__PURE__ */ new Map(),
2155
+ positions: /* @__PURE__ */ new Map(),
2156
+ columns: /* @__PURE__ */ new Map(),
2157
+ pendingAdjust: 0,
2158
+ isStartReached: false,
2159
+ isEndReached: false,
2160
+ isAtEnd: false,
2161
+ isAtStart: false,
2162
+ scrollLength: initialScrollLength,
2163
+ startBuffered: -1,
2164
+ startNoBuffer: -1,
2165
+ endBuffered: -1,
2166
+ endNoBuffer: -1,
2167
+ firstFullyOnScreenIndex: -1,
2168
+ scroll: 0,
2169
+ totalSize: 0,
2170
+ timeouts: /* @__PURE__ */ new Set(),
2171
+ viewabilityConfigCallbackPairs: void 0,
2172
+ scrollAdjustHandler: new ScrollAdjustHandler(ctx),
2173
+ nativeMarginTop: 0,
2174
+ scrollPrev: 0,
2175
+ scrollPrevTime: 0,
2176
+ scrollTime: 0,
2177
+ scrollPending: 0,
2178
+ indexByKey: /* @__PURE__ */ new Map(),
2179
+ scrollHistory: [],
2180
+ sizesKnown: /* @__PURE__ */ new Map(),
2181
+ timeoutSizeMessage: 0,
2182
+ startReachedBlockedByTimer: false,
2183
+ endReachedBlockedByTimer: false,
2184
+ scrollForNextCalculateItemsInView: void 0,
2185
+ enableScrollForNextCalculateItemsInView: true,
2186
+ minIndexSizeChanged: 0,
2187
+ queuedCalculateItemsInView: 0,
2188
+ lastBatchingAction: Date.now(),
2189
+ averageSizes: {},
2190
+ idsInView: [],
2191
+ containerItemKeys: /* @__PURE__ */ new Set(),
2192
+ idCache: /* @__PURE__ */ new Map(),
2193
+ props: {},
2194
+ refScroller: void 0,
2195
+ loadStartTime: Date.now(),
2196
+ initialScroll,
2197
+ lastLayout: void 0
2198
+ };
2199
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
2200
+ set$(ctx, "extraData", extraData);
2201
+ }
2202
+ const state = refState.current;
2203
+ const isFirst = !state.props.renderItem;
2204
+ const didDataChange = state.props.data !== dataProp;
2205
+ state.props = {
2206
+ alignItemsAtEnd,
2207
+ data: dataProp,
2208
+ estimatedItemSize,
2209
+ maintainScrollAtEnd,
2210
+ maintainScrollAtEndThreshold,
2211
+ onEndReachedThreshold,
2212
+ onStartReachedThreshold,
2213
+ stylePaddingBottom: stylePaddingBottomState,
2214
+ horizontal: !!horizontal,
2215
+ maintainVisibleContentPosition,
2216
+ onItemSizeChanged,
2217
+ suggestEstimatedItemSize: !!suggestEstimatedItemSize,
2218
+ keyExtractor,
2219
+ onScroll: onScrollProp,
2220
+ getEstimatedItemSize,
2221
+ onStartReached,
2222
+ onEndReached,
2223
+ onLoad,
2224
+ renderItem: renderItem2,
2225
+ initialScroll,
2226
+ scrollBuffer,
2227
+ viewabilityConfigCallbackPairs: void 0,
2228
+ numColumns: numColumnsProp,
2229
+ initialContainerPoolRatio,
2230
+ stylePaddingTop: stylePaddingTopState
2231
+ };
2232
+ state.refScroller = refScroller;
2233
+ const checkResetContainers = (isFirst2) => {
2234
+ const state2 = refState.current;
2235
+ if (state2) {
2236
+ state2.props.data = dataProp;
2237
+ if (!isFirst2) {
2238
+ calculateItemsInView(ctx, state2, { dataChanged: true, doMVCP: true });
2239
+ const shouldMaintainScrollAtEnd = maintainScrollAtEnd === true || maintainScrollAtEnd.onDataChange;
2240
+ const didMaintainScrollAtEnd = shouldMaintainScrollAtEnd && doMaintainScrollAtEnd(ctx, state2, false);
2241
+ if (!didMaintainScrollAtEnd && dataProp.length > state2.props.data.length) {
2242
+ state2.isEndReached = false;
2243
+ }
2244
+ if (!didMaintainScrollAtEnd) {
2245
+ checkAtTop(state2);
2246
+ checkAtBottom(ctx, state2);
2247
+ }
2248
+ }
2249
+ }
2250
+ };
2251
+ const memoizedLastItemKeys = React3.useMemo(() => {
2252
+ if (!dataProp.length) return [];
2253
+ return Array.from(
2254
+ { length: Math.min(numColumnsProp, dataProp.length) },
2255
+ (_, i) => getId(state, dataProp.length - 1 - i)
2256
+ );
2257
+ }, [dataProp, numColumnsProp]);
2258
+ const initalizeStateVars = () => {
2259
+ set$(ctx, "lastItemKeys", memoizedLastItemKeys);
2260
+ set$(ctx, "numColumns", numColumnsProp);
2261
+ const prevPaddingTop = peek$(ctx, "stylePaddingTop");
2262
+ setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
2263
+ refState.current.props.stylePaddingBottom = stylePaddingBottomState;
2264
+ const paddingDiff = stylePaddingTopState - prevPaddingTop;
2265
+ if (paddingDiff && prevPaddingTop !== void 0 && reactNative.Platform.OS === "ios") {
2266
+ calculateItemsInView(ctx, state, { doMVCP: true });
2267
+ requestAdjust(ctx, state, paddingDiff);
2268
+ }
2269
+ };
2270
+ if (isFirst) {
2271
+ initalizeStateVars();
2272
+ updateAllPositions(ctx, state);
2273
+ }
2274
+ const initialContentOffset = React3.useMemo(() => {
2275
+ const initialContentOffset2 = initialScrollOffset || calculateOffsetForIndex(ctx, state, initialScrollIndex);
2276
+ refState.current.isStartReached = initialContentOffset2 < refState.current.scrollLength * onStartReachedThreshold;
2277
+ if (initialContentOffset2 > 0) {
2278
+ scrollTo(state, { offset: initialContentOffset2, animated: false, index: initialScrollIndex });
2279
+ }
2280
+ return initialContentOffset2;
2281
+ }, [renderNum]);
2282
+ if (isFirst || didDataChange || numColumnsProp !== peek$(ctx, "numColumns")) {
2283
+ refState.current.lastBatchingAction = Date.now();
2284
+ if (!keyExtractorProp && !isFirst && didDataChange) {
2285
+ __DEV__ && warnDevOnce(
2286
+ "keyExtractor",
2287
+ "Changing data without a keyExtractor can cause slow performance and resetting scroll. If your list data can change you should use a keyExtractor with a unique id for best performance and behavior."
2288
+ );
2289
+ refState.current.sizes.clear();
2290
+ refState.current.positions.clear();
2291
+ }
2292
+ }
2293
+ React3.useLayoutEffect(() => {
2294
+ if (IsNewArchitecture) {
2295
+ let measured;
2296
+ refScroller.current.measure((x, y, width, height) => {
2297
+ measured = { x, y, width, height };
2298
+ });
2299
+ if (measured) {
2300
+ const size = Math.floor(measured[horizontal ? "width" : "height"] * 8) / 8;
2301
+ if (size) {
2302
+ handleLayout(ctx, state, measured, setCanRender);
2303
+ }
2304
+ }
2305
+ }
2306
+ if (!isFirst) {
2307
+ calculateItemsInView(ctx, state, { doMVCP: true });
2308
+ }
2309
+ }, [dataProp]);
2310
+ const onLayoutHeader = React3.useCallback((rect, fromLayoutEffect) => {
2311
+ const size = rect[horizontal ? "width" : "height"];
2312
+ set$(ctx, "headerSize", size);
2313
+ if (initialScroll) {
2314
+ if (IsNewArchitecture && reactNative.Platform.OS !== "android") {
2315
+ if (fromLayoutEffect) {
2316
+ setRenderNum((v) => v + 1);
2317
+ }
2318
+ } else {
2319
+ setTimeout(() => {
2320
+ scrollToIndex(ctx, state, { ...initialScroll, animated: false });
2321
+ }, 17);
2322
+ }
2323
+ }
2324
+ }, []);
2325
+ React3.useLayoutEffect(() => {
2326
+ const didAllocateContainers = doInitialAllocateContainersCallback();
2327
+ if (!didAllocateContainers) {
2328
+ checkResetContainers(
2329
+ /*isFirst*/
2330
+ isFirst
2331
+ );
2332
+ }
2333
+ }, [dataProp, numColumnsProp]);
2334
+ React3.useLayoutEffect(() => {
2335
+ set$(ctx, "extraData", extraData);
2336
+ }, [extraData]);
2337
+ React3.useLayoutEffect(initalizeStateVars, [
2338
+ memoizedLastItemKeys.join(","),
2339
+ numColumnsProp,
2340
+ stylePaddingTopState,
2341
+ stylePaddingBottomState
2342
+ ]);
2343
+ const doInitialAllocateContainersCallback = () => {
2344
+ return doInitialAllocateContainers(ctx, state);
2345
+ };
2346
+ React3.useEffect(() => {
2347
+ const viewability = setupViewability({
2348
+ viewabilityConfig,
2349
+ viewabilityConfigCallbackPairs,
2350
+ onViewableItemsChanged
2351
+ });
2352
+ state.viewabilityConfigCallbackPairs = viewability;
2353
+ state.props.viewabilityConfigCallbackPairs = viewability;
2354
+ state.enableScrollForNextCalculateItemsInView = !viewability;
2355
+ }, [viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged]);
2356
+ if (!IsNewArchitecture) {
2357
+ useInit(() => {
2358
+ doInitialAllocateContainersCallback();
2359
+ });
2360
+ }
2361
+ const onLayout = React3.useCallback((event) => {
2362
+ const layout = event.nativeEvent.layout;
2363
+ handleLayout(ctx, state, layout, setCanRender);
2364
+ if (onLayoutProp) {
2365
+ onLayoutProp(event);
2366
+ }
2367
+ }, []);
2368
+ React3.useImperativeHandle(
2369
+ forwardedRef,
2370
+ () => {
2371
+ const scrollIndexIntoView = (options) => {
2372
+ const state2 = refState.current;
2373
+ if (state2) {
2374
+ const { index, ...rest2 } = options;
2375
+ const { startNoBuffer, endNoBuffer } = state2;
2376
+ if (index < startNoBuffer || index > endNoBuffer) {
2377
+ const viewPosition = index < startNoBuffer ? 0 : 1;
2378
+ scrollToIndex(ctx, state2, {
2379
+ ...rest2,
2380
+ viewPosition,
2381
+ index
2382
+ });
2383
+ }
2384
+ }
2385
+ };
2386
+ return {
2387
+ flashScrollIndicators: () => refScroller.current.flashScrollIndicators(),
2388
+ getNativeScrollRef: () => refScroller.current,
2389
+ getScrollableNode: () => refScroller.current.getScrollableNode(),
2390
+ getScrollResponder: () => refScroller.current.getScrollResponder(),
2391
+ getState: () => {
2392
+ const state2 = refState.current;
2393
+ return state2 ? {
2394
+ contentLength: state2.totalSize,
2395
+ end: state2.endNoBuffer,
2396
+ endBuffered: state2.endBuffered,
2397
+ isAtEnd: state2.isAtEnd,
2398
+ isAtStart: state2.isAtStart,
2399
+ scroll: state2.scroll,
2400
+ scrollLength: state2.scrollLength,
2401
+ start: state2.startNoBuffer,
2402
+ startBuffered: state2.startBuffered,
2403
+ sizes: state2.sizesKnown,
2404
+ sizeAtIndex: (index) => state2.sizesKnown.get(getId(state2, index))
2405
+ } : {};
2406
+ },
2407
+ scrollIndexIntoView,
2408
+ scrollItemIntoView: ({ item, ...props2 }) => {
2409
+ const data = refState.current.props.data;
2410
+ const index = data.indexOf(item);
2411
+ if (index !== -1) {
2412
+ scrollIndexIntoView({ index, ...props2 });
2413
+ }
2414
+ },
2415
+ scrollToIndex: (params) => scrollToIndex(ctx, state, params),
2416
+ scrollToItem: ({ item, ...props2 }) => {
2417
+ const data = refState.current.props.data;
2418
+ const index = data.indexOf(item);
2419
+ if (index !== -1) {
2420
+ scrollToIndex(ctx, state, { index, ...props2 });
2421
+ }
2422
+ },
2423
+ scrollToOffset: (params) => scrollTo(state, params),
2424
+ scrollToEnd: (options) => {
2425
+ const data = refState.current.props.data;
2426
+ const stylePaddingBottom = refState.current.props.stylePaddingBottom;
2427
+ const index = data.length - 1;
2428
+ if (index !== -1) {
2429
+ const paddingBottom = stylePaddingBottom || 0;
2430
+ const footerSize = peek$(ctx, "footerSize") || 0;
2431
+ scrollToIndex(ctx, state, {
2432
+ index,
2433
+ viewPosition: 1,
2434
+ viewOffset: -paddingBottom - footerSize,
2435
+ ...options
2436
+ });
2437
+ }
2438
+ },
2439
+ setVisibleContentAnchorOffset: (value) => {
2440
+ const val = typeof value === "function" ? value(peek$(ctx, "scrollAdjustUserOffset") || 0) : value;
2441
+ set$(ctx, "scrollAdjustUserOffset", val);
2442
+ }
2443
+ };
2444
+ },
2445
+ []
2446
+ );
2447
+ if (reactNative.Platform.OS === "web") {
2448
+ React3.useEffect(() => {
2449
+ if (initialContentOffset) {
2450
+ scrollTo(state, { offset: initialContentOffset, animated: false });
2451
+ }
2452
+ }, []);
2453
+ }
2454
+ const fns = React3.useMemo(
2455
+ () => ({
2456
+ updateItemSize: (itemKey, sizeObj) => updateItemSize(ctx, state, itemKey, sizeObj),
2457
+ getRenderedItem: (key) => getRenderedItem(ctx, state, key),
2458
+ onScroll: (event) => onScroll(ctx, state, event)
2459
+ }),
2460
+ []
2461
+ );
2462
+ return /* @__PURE__ */ React3__namespace.createElement(React3__namespace.Fragment, null, /* @__PURE__ */ React3__namespace.createElement(
2463
+ ListComponent,
2464
+ {
2465
+ ...rest,
2466
+ canRender,
2467
+ horizontal,
2468
+ refScrollView: combinedRef,
2469
+ initialContentOffset,
2470
+ getRenderedItem: fns.getRenderedItem,
2471
+ updateItemSize: fns.updateItemSize,
2472
+ onScroll: fns.onScroll,
2473
+ onMomentumScrollEnd: (event) => {
2474
+ requestAnimationFrame(() => {
2475
+ finishScrollTo(refState.current);
2476
+ });
2477
+ if (onMomentumScrollEnd) {
2478
+ onMomentumScrollEnd(event);
2479
+ }
2480
+ },
2481
+ onLayout,
2482
+ recycleItems,
2483
+ alignItemsAtEnd,
2484
+ ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
2485
+ ListHeaderComponent,
2486
+ maintainVisibleContentPosition,
2487
+ scrollEventThrottle: reactNative.Platform.OS === "web" ? 16 : void 0,
2488
+ waitForInitialLayout,
2489
+ refreshControl: refreshControl ? stylePaddingTopState > 0 ? React3__namespace.cloneElement(refreshControl, {
2490
+ progressViewOffset: (refreshControl.props.progressViewOffset || 0) + stylePaddingTopState
2491
+ }) : refreshControl : onRefresh && /* @__PURE__ */ React3__namespace.createElement(
2492
+ reactNative.RefreshControl,
2493
+ {
2494
+ refreshing: !!refreshing,
2495
+ onRefresh,
2496
+ progressViewOffset: (progressViewOffset || 0) + stylePaddingTopState
2497
+ }
2498
+ ),
2499
+ style,
2500
+ contentContainerStyle,
2501
+ scrollAdjustHandler: (_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler,
2502
+ onLayoutHeader
2503
+ }
2504
+ ), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React3__namespace.createElement(DebugView, { state: refState.current }));
2505
+ });
2506
+ var typedForwardRef2 = React3.forwardRef;
2507
+ var renderItem = ({ item }) => item;
2508
+ var LazyLegendList = typedForwardRef2(function LazyLegendList2(props, forwardedRef) {
2509
+ const { LegendList: LegendListProp, children, ...rest } = props;
2510
+ const LegendListComponent = LegendListProp != null ? LegendListProp : LegendList;
2511
+ const data = (isArray(children) ? children : React3__namespace.Children.toArray(children)).flat(1);
2512
+ return (
2513
+ // @ts-expect-error TODO: Fix this type
2514
+ /* @__PURE__ */ React3__namespace.createElement(LegendListComponent, { ...rest, data, renderItem, ref: forwardedRef })
2515
+ );
2516
+ });
2517
+
2518
+ exports.LazyLegendList = LazyLegendList;
2519
+ exports.LegendList = LegendList;
2520
+ exports.useIsLastItem = useIsLastItem;
2521
+ exports.useListScrollSize = useListScrollSize;
2522
+ exports.useRecyclingEffect = useRecyclingEffect;
2523
+ exports.useRecyclingState = useRecyclingState;
2524
+ exports.useViewability = useViewability;
2525
+ exports.useViewabilityAmount = useViewabilityAmount;