@shopify/flash-list 1.6.4 → 1.7.0

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 (56) hide show
  1. package/RNFlashList.podspec +13 -2
  2. package/android/build.gradle +18 -0
  3. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +1 -1
  4. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +16 -8
  5. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +19 -18
  6. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +29 -0
  7. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +12 -5
  8. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerDelegate.java +46 -0
  9. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerInterface.java +21 -0
  10. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerDelegate.java +31 -0
  11. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerInterface.java +16 -0
  12. package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +3 -3
  13. package/dist/FlashList.d.ts +1 -1
  14. package/dist/MasonryFlashList.d.ts.map +1 -1
  15. package/dist/MasonryFlashList.js +6 -4
  16. package/dist/MasonryFlashList.js.map +1 -1
  17. package/dist/__tests__/helpers/mountFlashList.d.ts +1 -1
  18. package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
  19. package/dist/__tests__/helpers/mountFlashList.js +1 -1
  20. package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
  21. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +1 -1
  22. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
  23. package/dist/__tests__/helpers/mountMasonryFlashList.js +1 -1
  24. package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
  25. package/dist/__tests__/useBlankAreaTracker.test.js +1 -1
  26. package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
  27. package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
  28. package/dist/native/cell-container/CellContainer.web.d.ts +1 -1
  29. package/dist/native/cell-container/CellContainer.web.d.ts.map +1 -1
  30. package/dist/specs/AutoLayoutNativeComponent.d.ts +19 -0
  31. package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -0
  32. package/dist/specs/AutoLayoutNativeComponent.js +6 -0
  33. package/dist/specs/AutoLayoutNativeComponent.js.map +1 -0
  34. package/dist/specs/CellContainerNativeComponent.d.ts +9 -0
  35. package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -0
  36. package/dist/specs/CellContainerNativeComponent.js +6 -0
  37. package/dist/specs/CellContainerNativeComponent.js.map +1 -0
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/ios/Sources/AutoLayoutView.swift +47 -29
  40. package/ios/Sources/AutoLayoutViewComponentView.h +16 -0
  41. package/ios/Sources/AutoLayoutViewComponentView.mm +90 -0
  42. package/ios/Sources/CellContainerComponentView.h +18 -0
  43. package/ios/Sources/CellContainerComponentView.mm +62 -0
  44. package/ios/Sources/CellContainerManager.swift +1 -1
  45. package/ios/Sources/FlatListPro-Bridging-Header.h +3 -0
  46. package/package.json +26 -21
  47. package/src/MasonryFlashList.tsx +5 -2
  48. package/src/__tests__/helpers/mountFlashList.tsx +2 -2
  49. package/src/__tests__/helpers/mountMasonryFlashList.tsx +2 -2
  50. package/src/__tests__/useBlankAreaTracker.test.tsx +2 -2
  51. package/src/specs/AutoLayoutNativeComponent.ts +24 -0
  52. package/src/specs/CellContainerNativeComponent.ts +9 -0
  53. package/CHANGELOG.md +0 -284
  54. package/ios/Sources/CellContainer.swift +0 -9
  55. /package/ios/Sources/{AutoLayoutViewManager.m → AutoLayoutViewManager.mm} +0 -0
  56. /package/ios/Sources/{CellContainerManager.m → CellContainerManager.mm} +0 -0
@@ -4,31 +4,35 @@ import UIKit
4
4
 
5
5
  /// Container for all RecyclerListView children. This will automatically remove all gaps and overlaps for GridLayouts with flexible spans.
6
6
  /// Note: This cannot work for masonry layouts i.e, pinterest like layout
7
- @objc class AutoLayoutView: UIView {
7
+ @objc public class AutoLayoutView: UIView {
8
+ #if RCT_NEW_ARCH_ENABLED
9
+ @objc public var onBlankAreaEventHandler: ((CGFloat, CGFloat) -> Void)?
10
+ #endif
11
+
8
12
  @objc(onBlankAreaEvent)
9
13
  var onBlankAreaEvent: RCTDirectEventBlock?
10
14
 
11
- @objc func setHorizontal(_ horizontal: Bool) {
15
+ @objc public func setHorizontal(_ horizontal: Bool) {
12
16
  self.horizontal = horizontal
13
17
  }
14
18
 
15
- @objc func setScrollOffset(_ scrollOffset: Int) {
19
+ @objc public func setScrollOffset(_ scrollOffset: Int) {
16
20
  self.scrollOffset = CGFloat(scrollOffset)
17
21
  }
18
22
 
19
- @objc func setWindowSize(_ windowSize: Int) {
23
+ @objc public func setWindowSize(_ windowSize: Int) {
20
24
  self.windowSize = CGFloat(windowSize)
21
25
  }
22
26
 
23
- @objc func setRenderAheadOffset(_ renderAheadOffset: Int) {
27
+ @objc public func setRenderAheadOffset(_ renderAheadOffset: Int) {
24
28
  self.renderAheadOffset = CGFloat(renderAheadOffset)
25
29
  }
26
30
 
27
- @objc func setEnableInstrumentation(_ enableInstrumentation: Bool) {
31
+ @objc public func setEnableInstrumentation(_ enableInstrumentation: Bool) {
28
32
  self.enableInstrumentation = enableInstrumentation
29
33
  }
30
34
 
31
- @objc func setDisableAutoLayout(_ disableAutoLayout: Bool) {
35
+ @objc public func setDisableAutoLayout(_ disableAutoLayout: Bool) {
32
36
  self.disableAutoLayout = disableAutoLayout
33
37
  }
34
38
 
@@ -46,7 +50,7 @@ import UIKit
46
50
  /// Tracks where first pixel is drawn in the visible window
47
51
  private var lastMinBound: CGFloat = 0
48
52
 
49
- override func layoutSubviews() {
53
+ override public func layoutSubviews() {
50
54
  fixLayout()
51
55
  super.layoutSubviews()
52
56
 
@@ -68,13 +72,17 @@ import UIKit
68
72
  distanceFromWindowStart: distanceFromWindowStart,
69
73
  distanceFromWindowEnd: distanceFromWindowEnd
70
74
  )
71
-
75
+
76
+ #if RCT_NEW_ARCH_ENABLED
77
+ onBlankAreaEventHandler?(blankOffsetStart, blankOffsetEnd)
78
+ #else
72
79
  onBlankAreaEvent?(
73
80
  [
74
81
  "offsetStart": blankOffsetStart,
75
82
  "offsetEnd": blankOffsetEnd,
76
83
  ]
77
84
  )
85
+ #endif
78
86
  }
79
87
 
80
88
  func getScrollView() -> UIScrollView? {
@@ -91,8 +99,8 @@ import UIKit
91
99
  !disableAutoLayout
92
100
  else { return }
93
101
  let cellContainers = subviews
94
- .compactMap { subview -> CellContainer? in
95
- if let cellContainer = subview as? CellContainer {
102
+ .compactMap { subview -> CellContainerComponentView? in
103
+ if let cellContainer = subview as? CellContainerComponentView {
96
104
  return cellContainer
97
105
  } else {
98
106
  assertionFailure("CellRendererComponent outer view should always be CellContainer. Learn more here: https://shopify.github.io/flash-list/docs/usage#cellrenderercomponent.")
@@ -106,7 +114,7 @@ import UIKit
106
114
 
107
115
  /// Checks for overlaps or gaps between adjacent items and then applies a correction.
108
116
  /// Performance: RecyclerListView renders very small number of views and this is not going to trigger multiple layouts on the iOS side.
109
- private func clearGaps(for cellContainers: [CellContainer]) {
117
+ private func clearGaps(for cellContainers: [CellContainerComponentView]) {
110
118
  var maxBound: CGFloat = 0
111
119
  var minBound: CGFloat = CGFloat(Int.max)
112
120
  var maxBoundNextCell: CGFloat = 0
@@ -125,26 +133,29 @@ import UIKit
125
133
 
126
134
  // Only apply correction if the next cell is consecutive.
127
135
  let isNextCellConsecutive = nextCell.index == cellContainer.index + 1
136
+
137
+ let isCellVisible = isWithinBounds(
138
+ cellContainer,
139
+ scrollOffset: correctedScrollOffset,
140
+ renderAheadOffset: renderAheadOffset,
141
+ windowSize: windowSize,
142
+ isHorizontal: horizontal
143
+ )
144
+ let isNextCellVisible = isWithinBounds(
145
+ nextCell,
146
+ scrollOffset: correctedScrollOffset,
147
+ renderAheadOffset: renderAheadOffset,
148
+ windowSize: windowSize,
149
+ isHorizontal: horizontal
150
+ )
128
151
 
129
152
  guard
130
- isWithinBounds(
131
- cellContainer,
132
- scrollOffset: correctedScrollOffset,
133
- renderAheadOffset: renderAheadOffset,
134
- windowSize: windowSize,
135
- isHorizontal: horizontal
136
- )
153
+ isCellVisible || isNextCellVisible
137
154
  else {
138
155
  updateLastMaxBoundOverall(currentCell: cellContainer, nextCell: nextCell)
139
156
  return
140
157
  }
141
- let isNextCellVisible = isWithinBounds(
142
- nextCell,
143
- scrollOffset: correctedScrollOffset,
144
- renderAheadOffset: renderAheadOffset,
145
- windowSize: windowSize,
146
- isHorizontal: horizontal
147
- )
158
+
148
159
 
149
160
  if horizontal {
150
161
  maxBound = max(maxBound, cellRight)
@@ -192,7 +203,7 @@ import UIKit
192
203
  lastMinBound = minBound
193
204
  }
194
205
 
195
- private func updateLastMaxBoundOverall(currentCell: CellContainer, nextCell: CellContainer) {
206
+ private func updateLastMaxBoundOverall(currentCell: CellContainerComponentView, nextCell: CellContainerComponentView) {
196
207
  lastMaxBoundOverall = max(lastMaxBoundOverall, horizontal ? currentCell.frame.maxX : currentCell.frame.maxY, horizontal ? nextCell.frame.maxX : nextCell.frame.maxY)
197
208
  }
198
209
 
@@ -217,7 +228,7 @@ import UIKit
217
228
 
218
229
  /// It's important to avoid correcting views outside the render window. An item that isn't being recycled might still remain in the view tree. If views outside get considered then gaps between unused items will cause algorithm to fail.
219
230
  func isWithinBounds(
220
- _ cellContainer: CellContainer,
231
+ _ cellContainer: CellContainerComponentView,
221
232
  scrollOffset: CGFloat,
222
233
  renderAheadOffset: CGFloat,
223
234
  windowSize: CGFloat,
@@ -271,6 +282,13 @@ import UIKit
271
282
  }
272
283
 
273
284
  private func footer() -> UIView? {
274
- return superview?.subviews.first(where:{($0 as? CellContainer)?.index == -1})
285
+ // On the new arch, AutoLayoutView is wrapped with AutoLayoutViewComponentView, so we need to go up one more level
286
+ #if RCT_NEW_ARCH_ENABLED
287
+ let parentSubviews = superview?.superview?.subviews
288
+ #else
289
+ let parentSubviews = superview?.subviews
290
+ #endif
291
+
292
+ return parentSubviews?.first(where:{($0 as? CellContainerComponentView)?.index == -1})
275
293
  }
276
294
  }
@@ -0,0 +1,16 @@
1
+ #ifndef AutoLayoutViewComponentView_h
2
+ #define AutoLayoutViewComponentView_h
3
+
4
+ #ifdef RCT_NEW_ARCH_ENABLED
5
+
6
+ #import <UIKit/UIKit.h>
7
+ #import <React/RCTViewComponentView.h>
8
+
9
+ @interface AutoLayoutViewComponentView : RCTViewComponentView
10
+
11
+ @end
12
+
13
+
14
+ #endif /* RCT_NEW_ARCH_ENABLED */
15
+
16
+ #endif /* AutoLayoutViewComponentView_h */
@@ -0,0 +1,90 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import "AutoLayoutViewComponentView.h"
3
+ #import <React/RCTConversions.h>
4
+ #import <React/RCTViewManager.h>
5
+
6
+ #import <react/renderer/components/rnflashlist/ComponentDescriptors.h>
7
+ #import <react/renderer/components/rnflashlist/EventEmitters.h>
8
+ #import <react/renderer/components/rnflashlist/Props.h>
9
+ #import <react/renderer/components/rnflashlist/RCTComponentViewHelpers.h>
10
+
11
+ #import "RCTFabricComponentsPlugins.h"
12
+
13
+ #if __has_include(<RNFlashList/RNFlashList-Swift.h>)
14
+ #import <RNFlashList/RNFlashList-Swift.h>
15
+ #else
16
+ #import "RNFlashList-Swift.h"
17
+ #endif
18
+
19
+ using namespace facebook::react;
20
+
21
+ @interface AutoLayoutViewComponentView () <RCTAutoLayoutViewViewProtocol>
22
+ @end
23
+
24
+ @implementation AutoLayoutViewComponentView
25
+ {
26
+ AutoLayoutView *_autoLayoutView;
27
+ }
28
+
29
+ - (instancetype)initWithFrame:(CGRect)frame
30
+ {
31
+ if (self = [super initWithFrame:frame]) {
32
+ static const auto defaultProps = std::make_shared<const AutoLayoutViewProps>();
33
+ _props = defaultProps;
34
+ _autoLayoutView = [[AutoLayoutView alloc] initWithFrame:self.bounds];
35
+ self.contentView = _autoLayoutView;
36
+
37
+ __weak AutoLayoutViewComponentView* weakSelf = self;
38
+ _autoLayoutView.onBlankAreaEventHandler = ^(CGFloat start, CGFloat end) {
39
+ AutoLayoutViewComponentView *strongSelf = weakSelf;
40
+ if (strongSelf != nullptr && strongSelf->_eventEmitter != nullptr) {
41
+ std::dynamic_pointer_cast<const facebook::react::AutoLayoutViewEventEmitter>(strongSelf->_eventEmitter)
42
+ ->onBlankAreaEvent(facebook::react::AutoLayoutViewEventEmitter::OnBlankAreaEvent{
43
+ .offsetStart = (int) floor(start),
44
+ .offsetEnd = (int) floor(end),
45
+ });
46
+ }
47
+ };
48
+ }
49
+
50
+ return self;
51
+ }
52
+
53
+ - (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
54
+ {
55
+ [_autoLayoutView mountChildComponentView:childComponentView index:index];
56
+ }
57
+
58
+ - (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
59
+ {
60
+ [_autoLayoutView unmountChildComponentView:childComponentView index:index];
61
+ }
62
+
63
+ #pragma mark - RCTComponentViewProtocol
64
+
65
+ + (ComponentDescriptorProvider)componentDescriptorProvider
66
+ {
67
+ return concreteComponentDescriptorProvider<AutoLayoutViewComponentDescriptor>();
68
+ }
69
+
70
+ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
71
+ {
72
+ const auto &newProps = *std::static_pointer_cast<const AutoLayoutViewProps>(props);
73
+
74
+ [_autoLayoutView setHorizontal:newProps.horizontal];
75
+ [_autoLayoutView setScrollOffset:newProps.scrollOffset];
76
+ [_autoLayoutView setWindowSize:newProps.windowSize];
77
+ [_autoLayoutView setRenderAheadOffset:newProps.renderAheadOffset];
78
+ [_autoLayoutView setEnableInstrumentation:newProps.enableInstrumentation];
79
+ [_autoLayoutView setDisableAutoLayout:newProps.disableAutoLayout];
80
+
81
+ [super updateProps:props oldProps:oldProps];
82
+ }
83
+ @end
84
+
85
+ Class<RCTComponentViewProtocol> AutoLayoutViewCls(void)
86
+ {
87
+ return AutoLayoutViewComponentView.class;
88
+ }
89
+
90
+ #endif /* RCT_NEW_ARCH_ENABLED */
@@ -0,0 +1,18 @@
1
+ #ifndef CellContainer_h
2
+ #define CellContainer_h
3
+
4
+ #import <UIKit/UIKit.h>
5
+
6
+ #ifdef RCT_NEW_ARCH_ENABLED
7
+ #import <React/RCTViewComponentView.h>
8
+
9
+ @interface CellContainerComponentView : RCTViewComponentView
10
+ #else
11
+ @interface CellContainerComponentView : UIView
12
+ #endif // RCT_NEW_ARCH_ENABLED
13
+
14
+ @property int64_t index;
15
+
16
+ @end
17
+
18
+ #endif /* CellContainer_h */
@@ -0,0 +1,62 @@
1
+ #import "CellContainerComponentView.h"
2
+
3
+ #ifdef RCT_NEW_ARCH_ENABLED
4
+ #import <React/RCTConversions.h>
5
+
6
+ #import <react/renderer/components/rnflashlist/ComponentDescriptors.h>
7
+ #import <react/renderer/components/rnflashlist/EventEmitters.h>
8
+ #import <react/renderer/components/rnflashlist/Props.h>
9
+ #import <react/renderer/components/rnflashlist/RCTComponentViewHelpers.h>
10
+
11
+ #import "RCTFabricComponentsPlugins.h"
12
+
13
+ #if __has_include(<RNFlashList/RNFlashList-Swift.h>)
14
+ #import <RNFlashList/RNFlashList-Swift.h>
15
+ #else
16
+ #import "RNFlashList-Swift.h"
17
+ #endif
18
+
19
+ using namespace facebook::react;
20
+
21
+ @interface CellContainerComponentView () <RCTCellContainerViewProtocol>
22
+ @end
23
+
24
+ @implementation CellContainerComponentView
25
+
26
+ - (instancetype)initWithFrame:(CGRect)frame
27
+ {
28
+ if (self = [super initWithFrame:frame]) {
29
+ static const auto defaultProps = std::make_shared<const CellContainerProps>();
30
+ _props = defaultProps;
31
+
32
+ self.userInteractionEnabled = true;
33
+ }
34
+
35
+ return self;
36
+ }
37
+
38
+ #pragma mark - RCTComponentViewProtocol
39
+
40
+ + (ComponentDescriptorProvider)componentDescriptorProvider
41
+ {
42
+ return concreteComponentDescriptorProvider<CellContainerComponentDescriptor>();
43
+ }
44
+
45
+ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
46
+ {
47
+ const auto &newProps = *std::static_pointer_cast<const CellContainerProps>(props);
48
+
49
+ self.index = newProps.index;
50
+
51
+ [super updateProps:props oldProps:oldProps];
52
+ }
53
+ @end
54
+
55
+ Class<RCTComponentViewProtocol> CellContainerCls(void)
56
+ {
57
+ return CellContainerComponentView.class;
58
+ }
59
+ #else
60
+ @implementation CellContainerComponentView
61
+ @end
62
+ #endif /* RCT_NEW_ARCH_ENABLED */
@@ -3,7 +3,7 @@ import Foundation
3
3
  @objc(CellContainerManager)
4
4
  class CellContainerManager: RCTViewManager {
5
5
  override func view() -> UIView! {
6
- return CellContainer()
6
+ return CellContainerComponentView()
7
7
  }
8
8
 
9
9
  override static func requiresMainQueueSetup() -> Bool {
@@ -4,5 +4,8 @@
4
4
  #import <React/RCTBridgeModule.h>
5
5
  #import <React/RCTEventEmitter.h>
6
6
  #import <React/RCTViewManager.h>
7
+ #import <React/RCTComponent.h>
8
+
9
+ #import "CellContainerComponentView.h"
7
10
 
8
11
  #endif /* FlatListPro_Bridging_Header_h */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopify/flash-list",
3
- "version": "1.6.4",
3
+ "version": "1.7.0",
4
4
  "keywords": [
5
5
  "react-native",
6
6
  "recyclerview",
@@ -28,27 +28,26 @@
28
28
  "main": "dist/index.js",
29
29
  "types": "dist/index.d.ts",
30
30
  "scripts": {
31
- "up": "bundle install && yarn fixture-up && yarn e2e-up && yarn build",
32
- "fixture-web-up": "cd fixture/web-app && yarn && cd ../../",
33
- "fixture-up": "cd fixture && yarn && cd ios && bundle exec pod install && cd ../../",
34
- "e2e-up": "cd fixture/ios && brew tap wix/brew && brew install applesimutils && cd ../../",
35
- "start": "cd fixture && react-native start",
31
+ "up": "bundle install && yarn fixture:rn:up && yarn e2e:up && yarn build",
32
+ "start": "cd fixture/react-native && react-native start",
36
33
  "test": "jest",
37
34
  "lint": "yarn eslint . --ext .ts,.tsx",
38
35
  "lint:fix": "yarn eslint . --ext .ts,.tsx --fix",
39
36
  "type-check": "yarn tsc --pretty --noEmit",
40
37
  "build": "tsc -b",
41
- "e2e:build:android": "detox build -c android.emu.release",
42
- "run-ios": "cd fixture && yarn react-native run-ios && yarn build --watch",
43
- "ri": "yarn run-ios",
44
- "run-android": "cd fixture && yarn react-native run-android && yarn build --watch",
45
- "ra": "yarn run-android",
46
- "run-e2e-ios": "cd fixture && yarn e2e:build:ios && yarn e2e:test:ios",
38
+ "fixture:rn:up": "cd fixture/react-native && yarn && cd ios && bundle exec pod install && cd ../../../",
39
+ "fixture:expo:up": "cd fixture/expo && yarn && cd ../../",
40
+ "fixture:rn:android": "cd fixture/react-native && yarn react-native run-android && yarn build --watch",
41
+ "fixture:rn:ios": "cd fixture/react-native && yarn react-native run-ios && yarn build --watch",
42
+ "ra": "yarn fixture:rn:android",
43
+ "ri": "yarn fixture:rn:ios",
44
+ "fixture:expo:start": "cd fixture/expo && yarn start",
45
+ "rw": "yarn fixture:expo:start",
46
+ "e2e:up": "cd fixture/react-native/ios && brew tap wix/brew && brew install applesimutils && cd ../../../",
47
+ "e2e:ios": "cd fixture/react-native && yarn e2e:build:ios && yarn e2e:test:ios",
47
48
  "rei": "yarn run-e2e-ios",
48
- "run-e2e-android": "cd fixture && yarn e2e:build:android && yarn e2e:test:android",
49
+ "e2e:android": "cd fixture/react-native && yarn e2e:build:android && yarn e2e:test:android",
49
50
  "rea": "yarn run-e2e-android",
50
- "run-web": "cd fixture/web-app && yarn web",
51
- "rw": "yarn run-web",
52
51
  "predeploy:website": "sh ./build_website.sh",
53
52
  "deploy:website": "gh-pages -d website/_site"
54
53
  },
@@ -60,11 +59,11 @@
60
59
  "devDependencies": {
61
60
  "@babel/core": "^7.18.5",
62
61
  "@babel/runtime": "^7.18.3",
63
- "@quilted/react-testing": "^0.5.14",
62
+ "@quilted/react-testing": "0.5.27",
64
63
  "@react-native-community/eslint-config": "^3.0.3",
65
64
  "@shopify/eslint-plugin": "^41.3.1",
66
65
  "@types/jest": "^29.5.10",
67
- "@types/react-native": "0.72.2",
66
+ "@types/react": "^18.0.24",
68
67
  "babel-jest": "^28.1.1",
69
68
  "enhanced-resolve": "^5.9.3",
70
69
  "eslint": "8.18.0",
@@ -72,8 +71,9 @@
72
71
  "jest": "^29.7.0",
73
72
  "metro-react-native-babel-preset": "^0.71.1",
74
73
  "prettier": "^2.7.1",
75
- "react": "17.0.2",
76
- "react-native": "0.68.5",
74
+ "react": "18.2.0",
75
+ "react-native": "0.72.10",
76
+ "react-test-renderer": "18.2.0",
77
77
  "typescript": "^4.7.4"
78
78
  },
79
79
  "files": [
@@ -85,7 +85,12 @@
85
85
  "jestSetup.js"
86
86
  ],
87
87
  "dependencies": {
88
- "recyclerlistview": "4.2.0",
89
- "tslib": "2.4.0"
88
+ "recyclerlistview": "4.2.1",
89
+ "tslib": "2.6.3"
90
+ },
91
+ "codegenConfig": {
92
+ "name": "rnflashlist",
93
+ "type": "components",
94
+ "jsSrcsDir": "./src/specs"
90
95
  }
91
96
  }
@@ -114,6 +114,9 @@ const MasonryFlashListComponent = React.forwardRef(
114
114
 
115
115
  const totalColumnFlex = useTotalColumnFlex(dataSet, props);
116
116
 
117
+ const propsRef = useRef(props);
118
+ propsRef.current = props;
119
+
117
120
  const onScrollRef = useRef<OnScrollCallback[]>([]);
118
121
  const emptyScrollEvent = useRef(getEmptyScrollEvent())
119
122
  .current as NativeSyntheticEvent<MasonryFlashListScrollEvent>;
@@ -135,7 +138,7 @@ const MasonryFlashListComponent = React.forwardRef(
135
138
  onScrollCallback?.(emptyScrollEvent);
136
139
  });
137
140
  if (!scrollEvent.nativeEvent.doNotPropagate) {
138
- props.onScroll?.(scrollEvent);
141
+ propsRef.current.onScroll?.(scrollEvent);
139
142
  }
140
143
  }
141
144
  ).current;
@@ -151,7 +154,7 @@ const MasonryFlashListComponent = React.forwardRef(
151
154
  onScrollProxy?.(emptyScrollEvent);
152
155
  emptyScrollEvent.nativeEvent.doNotPropagate = false;
153
156
  }, 32);
154
- props.onLoad?.(args);
157
+ propsRef.current.onLoad?.(args);
155
158
  }).current;
156
159
 
157
160
  const [parentFlashList, getFlashList] =
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Text } from "react-native";
3
3
  import "@quilted/react-testing/matchers";
4
- import { mount, Root } from "@quilted/react-testing";
4
+ import { render, Root } from "@quilted/react-testing";
5
5
 
6
6
  import FlashList from "../../FlashList";
7
7
  import { FlashListProps, ListRenderItem } from "../../FlashListProps";
@@ -34,7 +34,7 @@ export const mountFlashList = (
34
34
  props?: MockFlashListProps,
35
35
  ref?: React.RefObject<FlashList<string>>
36
36
  ) => {
37
- const flashList = mount(renderFlashList(props, ref)) as Omit<
37
+ const flashList = render(renderFlashList(props, ref)) as Omit<
38
38
  Root<FlashListProps<string>>,
39
39
  "instance"
40
40
  > & {
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Text } from "react-native";
3
3
  import "@quilted/react-testing/matchers";
4
- import { mount, Root } from "@quilted/react-testing";
4
+ import { render, Root } from "@quilted/react-testing";
5
5
 
6
6
  import { ListRenderItem } from "../../FlashListProps";
7
7
  import {
@@ -44,7 +44,7 @@ export const mountMasonryFlashList = (
44
44
  props?: MockMasonryFlashListProps,
45
45
  ref?: React.RefObject<MasonryFlashListRef<string>>
46
46
  ) => {
47
- const flashList = mount(renderMasonryFlashList(props, ref)) as Omit<
47
+ const flashList = render(renderMasonryFlashList(props, ref)) as Omit<
48
48
  Root<MasonryFlashListProps<string>>,
49
49
  "instance"
50
50
  > & {
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from "react";
2
- import { mount } from "@quilted/react-testing";
2
+ import { render } from "@quilted/react-testing";
3
3
 
4
4
  import {
5
5
  BlankAreaTrackerConfig,
@@ -44,7 +44,7 @@ const mountBlankTrackingFlashList = (props?: BlankTrackingFlashListProps) => {
44
44
  const flashListRef: React.RefObject<FlashList<any>> = {
45
45
  current: null,
46
46
  };
47
- const blankTrackingFlashList = mount(
47
+ const blankTrackingFlashList = render(
48
48
  <BlankTrackingFlashList {...props} instance={flashListRef} />
49
49
  );
50
50
  return {
@@ -0,0 +1,24 @@
1
+ import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2
+ import type { ViewProps } from "react-native";
3
+ import type {
4
+ Int32,
5
+ Double,
6
+ DirectEventHandler,
7
+ } from "react-native/Libraries/Types/CodegenTypes";
8
+
9
+ type BlankAreaEvent = Readonly<{
10
+ offsetStart: Int32;
11
+ offsetEnd: Int32;
12
+ }>;
13
+
14
+ interface NativeProps extends ViewProps {
15
+ horizontal?: boolean;
16
+ scrollOffset?: Double;
17
+ windowSize?: Double;
18
+ renderAheadOffset?: Double;
19
+ enableInstrumentation?: boolean;
20
+ disableAutoLayout?: boolean;
21
+ onBlankAreaEvent?: DirectEventHandler<BlankAreaEvent>;
22
+ }
23
+
24
+ export default codegenNativeComponent<NativeProps>("AutoLayoutView");
@@ -0,0 +1,9 @@
1
+ import codegenNativeComponent from "react-native/Libraries/Utilities/codegenNativeComponent";
2
+ import type { Int32 } from "react-native/Libraries/Types/CodegenTypes";
3
+ import type { ViewProps } from "react-native";
4
+
5
+ interface NativeProps extends ViewProps {
6
+ index?: Int32;
7
+ }
8
+
9
+ export default codegenNativeComponent<NativeProps>("CellContainer");