@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.
- package/RNFlashList.podspec +13 -2
- package/android/build.gradle +18 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +1 -1
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +16 -8
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +19 -18
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +29 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +12 -5
- package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerDelegate.java +46 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerInterface.java +21 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerDelegate.java +31 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerInterface.java +16 -0
- package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +3 -3
- package/dist/FlashList.d.ts +1 -1
- package/dist/MasonryFlashList.d.ts.map +1 -1
- package/dist/MasonryFlashList.js +6 -4
- package/dist/MasonryFlashList.js.map +1 -1
- package/dist/__tests__/helpers/mountFlashList.d.ts +1 -1
- package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountFlashList.js +1 -1
- package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.js +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
- package/dist/__tests__/useBlankAreaTracker.test.js +1 -1
- package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
- package/dist/native/cell-container/CellContainer.web.d.ts +1 -1
- package/dist/native/cell-container/CellContainer.web.d.ts.map +1 -1
- package/dist/specs/AutoLayoutNativeComponent.d.ts +19 -0
- package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -0
- package/dist/specs/AutoLayoutNativeComponent.js +6 -0
- package/dist/specs/AutoLayoutNativeComponent.js.map +1 -0
- package/dist/specs/CellContainerNativeComponent.d.ts +9 -0
- package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -0
- package/dist/specs/CellContainerNativeComponent.js +6 -0
- package/dist/specs/CellContainerNativeComponent.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/ios/Sources/AutoLayoutView.swift +47 -29
- package/ios/Sources/AutoLayoutViewComponentView.h +16 -0
- package/ios/Sources/AutoLayoutViewComponentView.mm +90 -0
- package/ios/Sources/CellContainerComponentView.h +18 -0
- package/ios/Sources/CellContainerComponentView.mm +62 -0
- package/ios/Sources/CellContainerManager.swift +1 -1
- package/ios/Sources/FlatListPro-Bridging-Header.h +3 -0
- package/package.json +26 -21
- package/src/MasonryFlashList.tsx +5 -2
- package/src/__tests__/helpers/mountFlashList.tsx +2 -2
- package/src/__tests__/helpers/mountMasonryFlashList.tsx +2 -2
- package/src/__tests__/useBlankAreaTracker.test.tsx +2 -2
- package/src/specs/AutoLayoutNativeComponent.ts +24 -0
- package/src/specs/CellContainerNativeComponent.ts +9 -0
- package/CHANGELOG.md +0 -284
- package/ios/Sources/CellContainer.swift +0 -9
- /package/ios/Sources/{AutoLayoutViewManager.m → AutoLayoutViewManager.mm} +0 -0
- /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 ->
|
|
95
|
-
if let cellContainer = subview as?
|
|
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: [
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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 */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopify/flash-list",
|
|
3
|
-
"version": "1.
|
|
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
|
|
32
|
-
"
|
|
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
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"ra": "yarn
|
|
46
|
-
"
|
|
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
|
-
"
|
|
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": "
|
|
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
|
|
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": "
|
|
76
|
-
"react-native": "0.
|
|
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.
|
|
89
|
-
"tslib": "2.
|
|
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
|
}
|
package/src/MasonryFlashList.tsx
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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 {
|
|
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 =
|
|
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 {
|
|
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 =
|
|
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 {
|
|
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 =
|
|
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");
|