@shopify/flash-list 1.0.1
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/CHANGELOG.md +159 -0
- package/LICENSE.md +7 -0
- package/README.md +65 -0
- package/RNFlashList.podspec +26 -0
- package/android/build.gradle +59 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +94 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +79 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +69 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainer.java +16 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerImpl.kt +16 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +27 -0
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/FlashListPackage.kt +19 -0
- package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +146 -0
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/Rect.kt +59 -0
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestCollection.kt +6 -0
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestDataModel.kt +8 -0
- package/android/src/test/resources/LayoutTestData.json +708 -0
- package/dist/AnimatedFlashList.d.ts +6 -0
- package/dist/AnimatedFlashList.d.ts.map +1 -0
- package/dist/AnimatedFlashList.js +8 -0
- package/dist/AnimatedFlashList.js.map +1 -0
- package/dist/FlashList.d.ts +121 -0
- package/dist/FlashList.d.ts.map +1 -0
- package/dist/FlashList.js +502 -0
- package/dist/FlashList.js.map +1 -0
- package/dist/FlashListProps.d.ts +251 -0
- package/dist/FlashListProps.d.ts.map +1 -0
- package/dist/FlashListProps.js +3 -0
- package/dist/FlashListProps.js.map +1 -0
- package/dist/GridLayoutProviderWithProps.d.ts +30 -0
- package/dist/GridLayoutProviderWithProps.d.ts.map +1 -0
- package/dist/GridLayoutProviderWithProps.js +80 -0
- package/dist/GridLayoutProviderWithProps.js.map +1 -0
- package/dist/PureComponentWrapper.d.ts +22 -0
- package/dist/PureComponentWrapper.d.ts.map +1 -0
- package/dist/PureComponentWrapper.js +37 -0
- package/dist/PureComponentWrapper.js.map +1 -0
- package/dist/__tests__/AverageWindow.test.d.ts +2 -0
- package/dist/__tests__/AverageWindow.test.d.ts.map +1 -0
- package/dist/__tests__/AverageWindow.test.js +69 -0
- package/dist/__tests__/AverageWindow.test.js.map +1 -0
- package/dist/__tests__/FlashList.test.d.ts +2 -0
- package/dist/__tests__/FlashList.test.d.ts.map +1 -0
- package/dist/__tests__/FlashList.test.js +656 -0
- package/dist/__tests__/FlashList.test.js.map +1 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts +2 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts.map +1 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.js +133 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +1 -0
- package/dist/__tests__/PlatformHelper.web.test.d.ts +2 -0
- package/dist/__tests__/PlatformHelper.web.test.d.ts.map +1 -0
- package/dist/__tests__/PlatformHelper.web.test.js +25 -0
- package/dist/__tests__/PlatformHelper.web.test.js.map +1 -0
- package/dist/__tests__/ViewabilityHelper.test.d.ts +2 -0
- package/dist/__tests__/ViewabilityHelper.test.d.ts.map +1 -0
- package/dist/__tests__/ViewabilityHelper.test.js +187 -0
- package/dist/__tests__/ViewabilityHelper.test.js.map +1 -0
- package/dist/__tests__/helpers/mountFlashList.d.ts +20 -0
- package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -0
- package/dist/__tests__/helpers/mountFlashList.js +44 -0
- package/dist/__tests__/helpers/mountFlashList.js.map +1 -0
- package/dist/__tests__/useBlankAreaTracker.test.d.ts +2 -0
- package/dist/__tests__/useBlankAreaTracker.test.d.ts.map +1 -0
- package/dist/__tests__/useBlankAreaTracker.test.js +179 -0
- package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -0
- package/dist/benchmark/AutoScrollHelper.d.ts +18 -0
- package/dist/benchmark/AutoScrollHelper.d.ts.map +1 -0
- package/dist/benchmark/AutoScrollHelper.js +68 -0
- package/dist/benchmark/AutoScrollHelper.js.map +1 -0
- package/dist/benchmark/JSFPSMonitor.d.ts +23 -0
- package/dist/benchmark/JSFPSMonitor.d.ts.map +1 -0
- package/dist/benchmark/JSFPSMonitor.js +65 -0
- package/dist/benchmark/JSFPSMonitor.js.map +1 -0
- package/dist/benchmark/roundToDecimalPlaces.d.ts +2 -0
- package/dist/benchmark/roundToDecimalPlaces.d.ts.map +1 -0
- package/dist/benchmark/roundToDecimalPlaces.js +9 -0
- package/dist/benchmark/roundToDecimalPlaces.js.map +1 -0
- package/dist/benchmark/useBenchmark.d.ts +35 -0
- package/dist/benchmark/useBenchmark.d.ts.map +1 -0
- package/dist/benchmark/useBenchmark.js +167 -0
- package/dist/benchmark/useBenchmark.js.map +1 -0
- package/dist/benchmark/useBlankAreaTracker.d.ts +34 -0
- package/dist/benchmark/useBlankAreaTracker.d.ts.map +1 -0
- package/dist/benchmark/useBlankAreaTracker.js +67 -0
- package/dist/benchmark/useBlankAreaTracker.js.map +1 -0
- package/dist/benchmark/useDataMultiplier.d.ts +9 -0
- package/dist/benchmark/useDataMultiplier.d.ts.map +1 -0
- package/dist/benchmark/useDataMultiplier.js +25 -0
- package/dist/benchmark/useDataMultiplier.js.map +1 -0
- package/dist/benchmark/useFlatListBenchmark.d.ts +13 -0
- package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -0
- package/dist/benchmark/useFlatListBenchmark.js +100 -0
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -0
- package/dist/errors/CustomError.d.ts +8 -0
- package/dist/errors/CustomError.d.ts.map +1 -0
- package/dist/errors/CustomError.js +14 -0
- package/dist/errors/CustomError.js.map +1 -0
- package/dist/errors/ExceptionList.d.ts +20 -0
- package/dist/errors/ExceptionList.d.ts.map +1 -0
- package/dist/errors/ExceptionList.js +22 -0
- package/dist/errors/ExceptionList.js.map +1 -0
- package/dist/errors/Warnings.d.ts +10 -0
- package/dist/errors/Warnings.d.ts.map +1 -0
- package/dist/errors/Warnings.js +15 -0
- package/dist/errors/Warnings.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/native/auto-layout/AutoLayoutView.d.ts +21 -0
- package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -0
- package/dist/native/auto-layout/AutoLayoutView.js +48 -0
- package/dist/native/auto-layout/AutoLayoutView.js.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts +4 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js +6 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.web.d.ts +5 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.web.d.ts.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.web.js +6 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.web.js.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +14 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js +3 -0
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js.map +1 -0
- package/dist/native/cell-container/CellContainer.d.ts +6 -0
- package/dist/native/cell-container/CellContainer.d.ts.map +1 -0
- package/dist/native/cell-container/CellContainer.js +9 -0
- package/dist/native/cell-container/CellContainer.js.map +1 -0
- package/dist/native/cell-container/CellContainer.web.d.ts +7 -0
- package/dist/native/cell-container/CellContainer.web.d.ts.map +1 -0
- package/dist/native/cell-container/CellContainer.web.js +13 -0
- package/dist/native/cell-container/CellContainer.web.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/AverageWindow.d.ts +21 -0
- package/dist/utils/AverageWindow.d.ts.map +1 -0
- package/dist/utils/AverageWindow.js +49 -0
- package/dist/utils/AverageWindow.js.map +1 -0
- package/dist/utils/PlatformHelper.d.ts +14 -0
- package/dist/utils/PlatformHelper.d.ts.map +1 -0
- package/dist/utils/PlatformHelper.js +16 -0
- package/dist/utils/PlatformHelper.js.map +1 -0
- package/dist/utils/PlatformHelper.web.d.ts +14 -0
- package/dist/utils/PlatformHelper.web.d.ts.map +1 -0
- package/dist/utils/PlatformHelper.web.js +18 -0
- package/dist/utils/PlatformHelper.web.js.map +1 -0
- package/dist/viewability/ViewToken.d.ts +8 -0
- package/dist/viewability/ViewToken.d.ts.map +1 -0
- package/dist/viewability/ViewToken.js +3 -0
- package/dist/viewability/ViewToken.js.map +1 -0
- package/dist/viewability/ViewabilityHelper.d.ts +25 -0
- package/dist/viewability/ViewabilityHelper.d.ts.map +1 -0
- package/dist/viewability/ViewabilityHelper.js +104 -0
- package/dist/viewability/ViewabilityHelper.js.map +1 -0
- package/dist/viewability/ViewabilityManager.d.ts +24 -0
- package/dist/viewability/ViewabilityManager.d.ts.map +1 -0
- package/dist/viewability/ViewabilityManager.js +94 -0
- package/dist/viewability/ViewabilityManager.js.map +1 -0
- package/ios/RNFlashList.xcodeproj/project.pbxproj +3 -0
- package/ios/RNFlashList.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
- package/ios/Sources/AutoLayoutView.swift +218 -0
- package/ios/Sources/AutoLayoutViewManager.m +14 -0
- package/ios/Sources/AutoLayoutViewManager.swift +12 -0
- package/ios/Sources/CellContainer.swift +9 -0
- package/ios/Sources/CellContainerManager.m +8 -0
- package/ios/Sources/CellContainerManager.swift +12 -0
- package/ios/Sources/FlatListPro-Bridging-Header.h +8 -0
- package/ios/Tests/AutoLayoutViewTests.swift +113 -0
- package/jestSetup.js +15 -0
- package/package.json +75 -0
- package/src/AnimatedFlashList.ts +11 -0
- package/src/FlashList.tsx +801 -0
- package/src/FlashListProps.ts +312 -0
- package/src/GridLayoutProviderWithProps.ts +137 -0
- package/src/PureComponentWrapper.tsx +42 -0
- package/src/__tests__/AverageWindow.test.ts +80 -0
- package/src/__tests__/FlashList.test.tsx +738 -0
- package/src/__tests__/GridLayoutProviderWithProps.test.ts +150 -0
- package/src/__tests__/PlatformHelper.web.test.ts +29 -0
- package/src/__tests__/ViewabilityHelper.test.ts +283 -0
- package/src/__tests__/helpers/mountFlashList.tsx +62 -0
- package/src/__tests__/useBlankAreaTracker.test.tsx +206 -0
- package/src/benchmark/AutoScrollHelper.ts +70 -0
- package/src/benchmark/JSFPSMonitor.ts +74 -0
- package/src/benchmark/roundToDecimalPlaces.ts +4 -0
- package/src/benchmark/useBenchmark.ts +240 -0
- package/src/benchmark/useBlankAreaTracker.ts +117 -0
- package/src/benchmark/useDataMultiplier.ts +19 -0
- package/src/benchmark/useFlatListBenchmark.ts +107 -0
- package/src/errors/CustomError.ts +10 -0
- package/src/errors/ExceptionList.ts +23 -0
- package/src/errors/Warnings.ts +18 -0
- package/src/index.ts +32 -0
- package/src/native/auto-layout/AutoLayoutView.tsx +72 -0
- package/src/native/auto-layout/AutoLayoutViewNativeComponent.ts +7 -0
- package/src/native/auto-layout/AutoLayoutViewNativeComponent.web.ts +8 -0
- package/src/native/auto-layout/AutoLayoutViewNativeComponentProps.ts +14 -0
- package/src/native/cell-container/CellContainer.ts +7 -0
- package/src/native/cell-container/CellContainer.web.tsx +9 -0
- package/src/utils/AverageWindow.ts +49 -0
- package/src/utils/PlatformHelper.ts +16 -0
- package/src/utils/PlatformHelper.web.ts +20 -0
- package/src/viewability/ViewToken.ts +7 -0
- package/src/viewability/ViewabilityHelper.ts +162 -0
- package/src/viewability/ViewabilityManager.ts +133 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
|
+
and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
- `data` prop change will force update items only if `renderItem` is also updated
|
|
11
|
+
- https://github.com/Shopify/flash-list/pull/453
|
|
12
|
+
|
|
13
|
+
## [1.0.0] - 2022-06-17
|
|
14
|
+
|
|
15
|
+
- Upgrade recyclerlistview to v3.3.0-beta.2
|
|
16
|
+
- https://github.com/Shopify/flash-list/pull/445
|
|
17
|
+
- Added web support
|
|
18
|
+
- https://github.com/Shopify/flash-list/pull/444
|
|
19
|
+
- Added `disableAutoLayout` prop to prevent conflicts with custom `CellRendererComponent`
|
|
20
|
+
- https://github.com/Shopify/flash-list/pull/452
|
|
21
|
+
|
|
22
|
+
## [0.6.1] - 2022-05-26
|
|
23
|
+
|
|
24
|
+
- Fix amending layout on iOS
|
|
25
|
+
- https://github.com/Shopify/flash-list/pull/412
|
|
26
|
+
- Define `FlashList` props previously inherited from `VirtualizedList` and `FlatList` explicitly
|
|
27
|
+
- https://github.com/Shopify/flash-list/pull/386
|
|
28
|
+
- Make `estimatedItemSize` optional
|
|
29
|
+
- https://github.com/Shopify/flash-list/pull/378
|
|
30
|
+
- Change `overrideItemType` prop name to `getItemType`
|
|
31
|
+
- https://github.com/Shopify/flash-list/pull/369
|
|
32
|
+
- Added `useBlankAreaTracker` hook for tracking blank area in production
|
|
33
|
+
- https://github.com/Shopify/flash-list/pull/411
|
|
34
|
+
- Added `CellRendererComponent` prop
|
|
35
|
+
- https://github.com/Shopify/flash-list/pull/362
|
|
36
|
+
- Added automatic height measurement for horizontal lists even when parent isn't deterministic
|
|
37
|
+
- https://github.com/Shopify/flash-list/pull/409
|
|
38
|
+
|
|
39
|
+
## [0.5.0] - 2022-04-29
|
|
40
|
+
|
|
41
|
+
- Fix finding props with testId
|
|
42
|
+
- https://github.com/Shopify/flash-list/pull/357
|
|
43
|
+
- Reuse cached layouts on orientation change
|
|
44
|
+
- https://github.com/Shopify/flash-list/pull/319
|
|
45
|
+
|
|
46
|
+
## [0.4.6] - 2022-04-13
|
|
47
|
+
|
|
48
|
+
- Match FlashList's empty list behavior with FlatList
|
|
49
|
+
- https://github.com/Shopify/flash-list/pull/312
|
|
50
|
+
|
|
51
|
+
## [0.4.5] - 2022-04-13
|
|
52
|
+
|
|
53
|
+
- Upgrade recyclerlistview to v3.2.0-beta.4
|
|
54
|
+
|
|
55
|
+
- https://github.com/Shopify/flash-list/pull/315
|
|
56
|
+
|
|
57
|
+
- Add viewability callbacks
|
|
58
|
+
|
|
59
|
+
- https://github.com/Shopify/flash-list/pull/301
|
|
60
|
+
|
|
61
|
+
- Calculate average item sizes automatically
|
|
62
|
+
- https://github.com/Shopify/flash-list/pull/296
|
|
63
|
+
|
|
64
|
+
## [0.4.4] - 2022-04-06
|
|
65
|
+
|
|
66
|
+
- Fix `FlashList` mock when no data is provided
|
|
67
|
+
- https://github.com/Shopify/flash-list/pull/295
|
|
68
|
+
|
|
69
|
+
## [0.4.3] - 2022-04-04
|
|
70
|
+
|
|
71
|
+
- Reduce number of render item calls
|
|
72
|
+
|
|
73
|
+
- https://github.com/Shopify/flash-list/pull/253
|
|
74
|
+
|
|
75
|
+
- Upgrade recyclerlistview to v3.2.0-beta.2
|
|
76
|
+
- https://github.com/Shopify/flash-list/pull/284
|
|
77
|
+
|
|
78
|
+
## [0.4.2] - 2022-04-04
|
|
79
|
+
|
|
80
|
+
- Minor changes
|
|
81
|
+
|
|
82
|
+
## [0.4.1] - 2022-03-29
|
|
83
|
+
|
|
84
|
+
- Crash fix for android activity switching (#256)
|
|
85
|
+
|
|
86
|
+
- https://github.com/Shopify/flash-list/pull/257
|
|
87
|
+
|
|
88
|
+
- initialScrollIndex, scrollTo methods will now account for size of header
|
|
89
|
+
|
|
90
|
+
- https://github.com/Shopify/flash-list/pull/194
|
|
91
|
+
|
|
92
|
+
- Added a new mock for easier testing of components with `FlashList`
|
|
93
|
+
- https://github.com/Shopify/flash-list/pull/236
|
|
94
|
+
|
|
95
|
+
## [0.4.0] - 2022-03-23
|
|
96
|
+
|
|
97
|
+
- Add support for layout animations
|
|
98
|
+
|
|
99
|
+
- https://github.com/Shopify/flash-list/pull/183
|
|
100
|
+
|
|
101
|
+
- Suppress recyclerlistview's bounded size exception for some missing cases.
|
|
102
|
+
|
|
103
|
+
- https://github.com/Shopify/flash-list/pull/192
|
|
104
|
+
|
|
105
|
+
- Expose reference to recyclerlistview and firstItemOffset
|
|
106
|
+
|
|
107
|
+
- https://github.com/Shopify/flash-list/pull/217
|
|
108
|
+
|
|
109
|
+
- recyclerlistview upgraded to v3.1.0-alpha.9
|
|
110
|
+
- https://github.com/Shopify/flash-list/pull/227
|
|
111
|
+
|
|
112
|
+
## [0.3.3] - 2022-03-16
|
|
113
|
+
|
|
114
|
+
- Prevent implicit scroll to top on device orientation change
|
|
115
|
+
- Change recyclerlistview's bounded size exception to a warning
|
|
116
|
+
- https://github.com/Shopify/flash-list/pull/187
|
|
117
|
+
|
|
118
|
+
## [0.3.2] - 2022-03-15
|
|
119
|
+
|
|
120
|
+
- Minor changes
|
|
121
|
+
|
|
122
|
+
## [0.3.1] - 2022-03-15
|
|
123
|
+
|
|
124
|
+
- Revert react-native-safe-area upgrade and minSdkVersion bump
|
|
125
|
+
- https://github.com/Shopify/flash-list/pull/184
|
|
126
|
+
|
|
127
|
+
## [0.3.0] - 2022-03-15
|
|
128
|
+
|
|
129
|
+
- Fixed untranspiled library code by enforcing stricter TS rules.
|
|
130
|
+
- https://github.com/Shopify/flash-list/pull/181
|
|
131
|
+
|
|
132
|
+
## [0.2.4] - 2022-03-14
|
|
133
|
+
|
|
134
|
+
- Added `onLoad` event that is called once the list has rendered items. This is required because FlashList doesn't render items in the first cycle.
|
|
135
|
+
- https://github.com/Shopify/flash-list/pull/180
|
|
136
|
+
|
|
137
|
+
## [0.2.3] - 2022-03-10
|
|
138
|
+
|
|
139
|
+
- Fixing publish steps for transpiled code
|
|
140
|
+
- https://github.com/Shopify/flash-list/pull/150
|
|
141
|
+
|
|
142
|
+
## [0.2.2] - 2022-03-10
|
|
143
|
+
|
|
144
|
+
- Fixing publish steps for transpiled code
|
|
145
|
+
- https://github.com/Shopify/flash-list/pull/149
|
|
146
|
+
|
|
147
|
+
## [0.2.1] - 2022-03-09
|
|
148
|
+
|
|
149
|
+
- Bug fix for style and last separator
|
|
150
|
+
- https://github.com/Shopify/flash-list/pull/141
|
|
151
|
+
|
|
152
|
+
## [0.2.0] - 2022-03-08
|
|
153
|
+
|
|
154
|
+
- Rename the component from `RecyclerFlatList` to `FlashList`
|
|
155
|
+
- https://github.com/Shopify/flash-list/pull/140
|
|
156
|
+
|
|
157
|
+
## [0.1.0] - 2022-03-02
|
|
158
|
+
|
|
159
|
+
- Initial release
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright 2022-present, Shopify Inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
[](https://buildkite.com/shopify/flash-list)
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<a href="https://shopify.github.io/flash-list/">Website</a> •
|
|
5
|
+
<a href="https://discord.gg/k2gzABTfav">Discord</a> •
|
|
6
|
+
<a href="https://shopify.github.io/flash-list/docs/">Getting started</a> •
|
|
7
|
+
<a href="https://shopify.github.io/flash-list/docs/usage">Usage</a> •
|
|
8
|
+
<a href="https://shopify.github.io/flash-list/docs/performance-troubleshooting">Performance</a> •
|
|
9
|
+
<a href="https://shopify.github.io/flash-list/performant-components">Writing performant components</a> •
|
|
10
|
+
<a href="https://shopify.github.io/flash-list/docs/known-issues">Known Issues</a>
|
|
11
|
+
<br><br>
|
|
12
|
+
|
|
13
|
+
**Fast & performant React Native list. No more blank cells.**
|
|
14
|
+
|
|
15
|
+
Swap from FlatList in seconds. Get instant performance.
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
Add the package to your project via `yarn add @shopify/flash-list` and run `pod install` in the `ios` directory.
|
|
22
|
+
|
|
23
|
+
If you get the error `Plugin with id 'kotlin-android' not found` while building on Android, go to `android/build.gradle` and add `classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.0")` inside your `dependencies` block. Please change the plugin version as per your needs.
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
We recommend reading the detailed documentation for using `FlashList` [here](https://shopify.github.io/flash-list/docs/usage).
|
|
28
|
+
|
|
29
|
+
But if you are familiar with [FlatList](https://reactnative.dev/docs/flatlist), you already know how to use `FlashList`. You can try out `FlashList` by changing the component name and adding the `estimatedItemSize` prop or refer to the example below:
|
|
30
|
+
|
|
31
|
+
```jsx
|
|
32
|
+
import React from "react";
|
|
33
|
+
import { View, Text } from "react-native";
|
|
34
|
+
import { FlashList } from "@shopify/flash-list";
|
|
35
|
+
|
|
36
|
+
const DATA = [
|
|
37
|
+
{
|
|
38
|
+
title: "First Item",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
title: "Second Item",
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const MyList = () => {
|
|
46
|
+
return (
|
|
47
|
+
<FlashList
|
|
48
|
+
data={DATA}
|
|
49
|
+
renderItem={({ item }) => <Text>{item.title}</Text>}
|
|
50
|
+
estimatedItemSize={200}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
To avoid common pitfalls, you can also follow these steps for migrating from `FlatList`, based on our own experiences:
|
|
57
|
+
|
|
58
|
+
1. Switch from `FlatList` to `FlashList` and render the list once. You should see a warning about missing `estimatedItemSize` and a suggestion. Set this value as the prop directly.
|
|
59
|
+
2. **Important**: Scan your [`renderItem`](https://shopify.github.io/flash-list/docs/usage/#renderitem) hierarchy for explicit `key` prop definitions and remove them. If you’re doing a `.map()` use indices as keys.
|
|
60
|
+
3. If your list has heterogenous views, pass their types to `FlashList` using [`getItemType`](https://shopify.github.io/flash-list/docs/usage/#getitemtype) prop to improve performance.
|
|
61
|
+
4. Do not test performance with JS dev mode on. Make sure you’re in release mode. `FlashList` can appear slower while in dev mode due to a small render buffer.
|
|
62
|
+
|
|
63
|
+
## App / Playground
|
|
64
|
+
|
|
65
|
+
The [fixture](https://github.com/Shopify/flash-list/tree/main/fixture) is an example app showing how to use the library.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'RNFlashList'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.homepage = package['homepage']
|
|
10
|
+
s.license = package['license']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.platform = :ios, '11.0'
|
|
13
|
+
s.source = { git: 'https://github.com/shopify/flash-list.git', tag: 'v#{s.version}' }
|
|
14
|
+
s.source_files = 'ios/Sources/**/*'
|
|
15
|
+
s.requires_arc = true
|
|
16
|
+
s.swift_version = '5.0'
|
|
17
|
+
|
|
18
|
+
# Dependencies
|
|
19
|
+
s.dependency 'React-Core'
|
|
20
|
+
|
|
21
|
+
# Tests spec
|
|
22
|
+
s.test_spec 'Tests' do |test_spec|
|
|
23
|
+
test_spec.source_files = 'ios/Tests/**/*'
|
|
24
|
+
test_spec.framework = 'XCTest'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
apply plugin: 'com.android.library'
|
|
2
|
+
|
|
3
|
+
apply plugin: 'kotlin-android'
|
|
4
|
+
|
|
5
|
+
def _ext = rootProject.ext
|
|
6
|
+
|
|
7
|
+
def _reactNativeVersion = _ext.has('reactNative') ? _ext.reactNative : '+'
|
|
8
|
+
def _compileSdkVersion = _ext.has('compileSdkVersion') ? _ext.compileSdkVersion : 30
|
|
9
|
+
def _buildToolsVersion = _ext.has('buildToolsVersion') ? _ext.buildToolsVersion : '30.0.2'
|
|
10
|
+
def _minSdkVersion = _ext.has('minSdkVersion') ? _ext.minSdkVersion : 21
|
|
11
|
+
def _targetSdkVersion = _ext.has('targetSdkVersion') ? _ext.targetSdkVersion : 30
|
|
12
|
+
def _kotlinVersion = _ext.has('kotlinVersion') ? _ext.kotlinVersion : '1.5.30'
|
|
13
|
+
def _junitVersion = _ext.has('junitVersion') ? _ext.junitVersion : '4.13.2'
|
|
14
|
+
def _mockitoVersion = _ext.has('mockitoVersion') ? _ext.mockitoVersion : '3.2.0'
|
|
15
|
+
def _androidTestRunnerVersion = _ext.has('androidTestRunnerVersion') ? _ext.androidTestRunnerVersion : '1.1.0'
|
|
16
|
+
|
|
17
|
+
android {
|
|
18
|
+
compileSdkVersion _compileSdkVersion
|
|
19
|
+
buildToolsVersion _buildToolsVersion
|
|
20
|
+
|
|
21
|
+
compileOptions {
|
|
22
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
23
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
sourceSets {
|
|
27
|
+
main.java.srcDirs += 'src/main/kotlin'
|
|
28
|
+
debug.java.srcDirs += 'src/debug/kotlin'
|
|
29
|
+
test.java.srcDirs += 'src/test/kotlin'
|
|
30
|
+
androidTest.java.srcDirs += 'src/androidTest/kotlin'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
defaultConfig {
|
|
34
|
+
minSdkVersion _minSdkVersion
|
|
35
|
+
targetSdkVersion _targetSdkVersion
|
|
36
|
+
versionCode 1
|
|
37
|
+
versionName "1.0"
|
|
38
|
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
lintOptions {
|
|
42
|
+
abortOnError false
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
testOptions {
|
|
46
|
+
unitTests.returnDefaultValues = true
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dependencies {
|
|
51
|
+
compileOnly "com.facebook.react:react-native:${_reactNativeVersion}"
|
|
52
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${_kotlinVersion}"
|
|
53
|
+
testImplementation "junit:junit:${_junitVersion}"
|
|
54
|
+
testImplementation "org.mockito.kotlin:mockito-kotlin:${_mockitoVersion}"
|
|
55
|
+
testImplementation "org.mockito:mockito-inline:${_mockitoVersion}"
|
|
56
|
+
testImplementation 'com.google.code.gson:gson:2.8.9'
|
|
57
|
+
androidTestImplementation("androidx.test:runner:${_androidTestRunnerVersion}")
|
|
58
|
+
androidTestImplementation("androidx.test:rules:${_androidTestRunnerVersion}")
|
|
59
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
class AutoLayoutShadow {
|
|
4
|
+
var horizontal: Boolean = false
|
|
5
|
+
var scrollOffset: Int = 0
|
|
6
|
+
var offsetFromStart: Int = 0
|
|
7
|
+
var windowSize: Int = 0
|
|
8
|
+
var renderOffset = 0
|
|
9
|
+
|
|
10
|
+
var blankOffsetAtStart = 0 // Tracks blank area from the top
|
|
11
|
+
var blankOffsetAtEnd = 0 // Tracks blank area from the bottom
|
|
12
|
+
|
|
13
|
+
private var lastMaxBound = 0 // Tracks where the last pixel is drawn in the visible window
|
|
14
|
+
private var lastMinBound = 0 // Tracks where first pixel is drawn in the visible window
|
|
15
|
+
|
|
16
|
+
/** Checks for overlaps or gaps between adjacent items and then applies a correction (Only Grid layouts with varying spans)
|
|
17
|
+
* Performance: RecyclerListView renders very small number of views and this is not going to trigger multiple layouts on Android side. Not expecting any major perf issue. */
|
|
18
|
+
fun clearGapsAndOverlaps(sortedItems: Array<CellContainer>) {
|
|
19
|
+
var maxBound = 0
|
|
20
|
+
var minBound = Int.MAX_VALUE
|
|
21
|
+
var maxBoundNeighbour = 0
|
|
22
|
+
for (i in 0 until sortedItems.size - 1) {
|
|
23
|
+
val cell = sortedItems[i]
|
|
24
|
+
val neighbour = sortedItems[i + 1]
|
|
25
|
+
if (isWithinBounds(cell)) {
|
|
26
|
+
if (!horizontal) {
|
|
27
|
+
maxBound = kotlin.math.max(maxBound, cell.bottom);
|
|
28
|
+
minBound = kotlin.math.min(minBound, cell.top);
|
|
29
|
+
maxBoundNeighbour = maxBound
|
|
30
|
+
if (cell.left < neighbour.left) {
|
|
31
|
+
if (cell.right != neighbour.left) {
|
|
32
|
+
neighbour.right = cell.right + neighbour.width
|
|
33
|
+
neighbour.left = cell.right
|
|
34
|
+
}
|
|
35
|
+
if (cell.top != neighbour.top) {
|
|
36
|
+
neighbour.bottom = cell.top + neighbour.height
|
|
37
|
+
neighbour.top = cell.top
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
neighbour.bottom = maxBound + neighbour.height
|
|
41
|
+
neighbour.top = maxBound
|
|
42
|
+
}
|
|
43
|
+
if (isWithinBounds(neighbour)) {
|
|
44
|
+
maxBoundNeighbour = kotlin.math.max(maxBound, neighbour.bottom)
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
maxBound = kotlin.math.max(maxBound, cell.right);
|
|
48
|
+
minBound = kotlin.math.min(minBound, cell.left);
|
|
49
|
+
maxBoundNeighbour = maxBound
|
|
50
|
+
if (cell.top < neighbour.top) {
|
|
51
|
+
if (cell.bottom != neighbour.top) {
|
|
52
|
+
neighbour.bottom = cell.bottom + neighbour.height
|
|
53
|
+
neighbour.top = cell.bottom
|
|
54
|
+
}
|
|
55
|
+
if (cell.left != neighbour.left) {
|
|
56
|
+
neighbour.right = cell.left + neighbour.width
|
|
57
|
+
neighbour.left = cell.left
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
neighbour.right = maxBound + neighbour.width
|
|
61
|
+
neighbour.left = maxBound
|
|
62
|
+
}
|
|
63
|
+
if (isWithinBounds(neighbour)) {
|
|
64
|
+
maxBoundNeighbour = kotlin.math.max(maxBound, neighbour.right)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
lastMaxBound = maxBoundNeighbour
|
|
70
|
+
lastMinBound = minBound
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Offset provided by react can be one frame behind the real one, it's important that this method is called with offset taken directly from
|
|
74
|
+
* scrollview object */
|
|
75
|
+
fun computeBlankFromGivenOffset(actualScrollOffset: Int, distanceFromWindowStart: Int, distanceFromWindowEnd: Int): Int {
|
|
76
|
+
val actualScrollOffset = actualScrollOffset - offsetFromStart;
|
|
77
|
+
blankOffsetAtStart = lastMinBound - actualScrollOffset - distanceFromWindowStart
|
|
78
|
+
blankOffsetAtEnd = actualScrollOffset + windowSize - renderOffset - lastMaxBound - distanceFromWindowEnd
|
|
79
|
+
return kotlin.math.max(blankOffsetAtStart, blankOffsetAtEnd)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** 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
|
|
83
|
+
* unused items will cause algorithm to fail.*/
|
|
84
|
+
private fun isWithinBounds(cell: CellContainer): Boolean {
|
|
85
|
+
val scrollOffset = scrollOffset - offsetFromStart;
|
|
86
|
+
return if (!horizontal) {
|
|
87
|
+
(cell.top >= (scrollOffset - renderOffset) || cell.bottom >= (scrollOffset - renderOffset)) &&
|
|
88
|
+
(cell.top <= scrollOffset + windowSize || cell.bottom <= scrollOffset + windowSize)
|
|
89
|
+
} else {
|
|
90
|
+
(cell.left >= (scrollOffset - renderOffset) || cell.right >= (scrollOffset - renderOffset)) &&
|
|
91
|
+
(cell.left <= scrollOffset + windowSize || cell.right <= scrollOffset + windowSize)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.util.DisplayMetrics
|
|
6
|
+
import android.view.View
|
|
7
|
+
import com.facebook.react.bridge.Arguments
|
|
8
|
+
import com.facebook.react.bridge.ReactContext
|
|
9
|
+
import com.facebook.react.bridge.WritableMap
|
|
10
|
+
import com.facebook.react.uimanager.events.RCTEventEmitter
|
|
11
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/** Container for all RecyclerListView children. This will automatically remove all gaps and overlaps for GridLayouts with flexible spans.
|
|
15
|
+
* Note: This cannot work for masonry layouts i.e, pinterest like layout */
|
|
16
|
+
class AutoLayoutView(context: Context) : ReactViewGroup(context) {
|
|
17
|
+
val alShadow = AutoLayoutShadow()
|
|
18
|
+
var enableInstrumentation = false
|
|
19
|
+
var disableAutoLayout = false
|
|
20
|
+
|
|
21
|
+
var pixelDensity = 1.0;
|
|
22
|
+
|
|
23
|
+
/** Overriding draw instead of onLayout. RecyclerListView uses absolute positions for each and every item which means that changes in child layouts may not trigger onLayout on this container. The same layout
|
|
24
|
+
* can still cause views to overlap. Therefore, it makes sense to override draw to do correction. */
|
|
25
|
+
override fun dispatchDraw(canvas: Canvas?) {
|
|
26
|
+
fixLayout()
|
|
27
|
+
super.dispatchDraw(canvas)
|
|
28
|
+
|
|
29
|
+
if (enableInstrumentation && parent?.parent != null) {
|
|
30
|
+
/** Since we need to call this method with scrollOffset on the UI thread and not with the one react has we're querying parent's parent
|
|
31
|
+
directly which will be a ScrollView. If it isn't reported values will be incorrect but the component will not break.
|
|
32
|
+
RecyclerListView is expected not to change the hierarchy of children. */
|
|
33
|
+
|
|
34
|
+
val scrollContainerSize = (parent.parent as View).let {
|
|
35
|
+
if (alShadow.horizontal) it.width else it.height
|
|
36
|
+
}
|
|
37
|
+
val scrollOffset = (parent.parent as View).let {
|
|
38
|
+
if (alShadow.horizontal) it.scrollX else it.scrollY
|
|
39
|
+
}
|
|
40
|
+
val startOffset = if (alShadow.horizontal) left else top
|
|
41
|
+
val endOffset = if (alShadow.horizontal) right else bottom
|
|
42
|
+
|
|
43
|
+
val distanceFromWindowStart = kotlin.math.max(startOffset - scrollOffset, 0)
|
|
44
|
+
val distanceFromWindowEnd = kotlin.math.max(scrollOffset + scrollContainerSize - endOffset, 0)
|
|
45
|
+
|
|
46
|
+
alShadow.computeBlankFromGivenOffset(scrollOffset, distanceFromWindowStart, distanceFromWindowEnd)
|
|
47
|
+
emitBlankAreaEvent()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Sorts views by index and then invokes clearGaps which does the correction.
|
|
52
|
+
* Performance: Sort is needed. Given relatively low number of views in RecyclerListView render tree this should be a non issue.*/
|
|
53
|
+
private fun fixLayout() {
|
|
54
|
+
if (childCount > 1 && !disableAutoLayout) {
|
|
55
|
+
val positionSortedViews: Array<CellContainer> = Array(childCount) {
|
|
56
|
+
val child = getChildAt(it)
|
|
57
|
+
if (child is CellContainer) {
|
|
58
|
+
child
|
|
59
|
+
} else {
|
|
60
|
+
throw IllegalStateException("CellRendererComponent outer view should always be CellContainer. Learn more here: https://shopify.github.io/flash-list/docs/usage#cellrenderercomponent.")
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
positionSortedViews.sortBy { it.index }
|
|
64
|
+
alShadow.offsetFromStart = if (alShadow.horizontal) left else top
|
|
65
|
+
alShadow.clearGapsAndOverlaps(positionSortedViews)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** TODO: Check migration to Fabric */
|
|
70
|
+
private fun emitBlankAreaEvent() {
|
|
71
|
+
val event: WritableMap = Arguments.createMap()
|
|
72
|
+
event.putDouble("offsetStart", alShadow.blankOffsetAtStart / pixelDensity)
|
|
73
|
+
event.putDouble("offsetEnd", alShadow.blankOffsetAtEnd / pixelDensity)
|
|
74
|
+
val reactContext = context as ReactContext
|
|
75
|
+
reactContext
|
|
76
|
+
.getJSModule(RCTEventEmitter::class.java)
|
|
77
|
+
.receiveEvent(id, "onBlankAreaEvent", event)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
6
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
7
|
+
import com.facebook.react.views.view.ReactViewManager
|
|
8
|
+
import com.facebook.react.common.MapBuilder
|
|
9
|
+
import kotlin.math.roundToInt
|
|
10
|
+
|
|
11
|
+
/** ViewManager for AutoLayoutView - Container for all RecyclerListView children. Automatically removes all gaps and overlaps for GridLayouts with flexible spans.
|
|
12
|
+
* Note: This cannot work for masonry layouts i.e, pinterest like layout */
|
|
13
|
+
@ReactModule(name = AutoLayoutViewManager.REACT_CLASS)
|
|
14
|
+
class AutoLayoutViewManager: ReactViewManager() {
|
|
15
|
+
|
|
16
|
+
companion object {
|
|
17
|
+
const val REACT_CLASS = "AutoLayoutView"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
override fun getName(): String {
|
|
21
|
+
return REACT_CLASS
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
|
|
25
|
+
return AutoLayoutView(context).also { it.pixelDensity = context.resources.displayMetrics.density.toDouble() }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> {
|
|
29
|
+
return MapBuilder.builder<String, Any>().put(
|
|
30
|
+
"onBlankAreaEvent",
|
|
31
|
+
MapBuilder.of(
|
|
32
|
+
"registrationName", "onBlankAreaEvent")
|
|
33
|
+
).build();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@ReactProp(name = "horizontal")
|
|
37
|
+
fun setHorizontal(view: AutoLayoutView, isHorizontal: Boolean) {
|
|
38
|
+
view.alShadow.horizontal = isHorizontal
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@ReactProp(name = "disableAutoLayout")
|
|
42
|
+
fun setDisableAutoLayout(view: AutoLayoutView, disableAutoLayout: Boolean) {
|
|
43
|
+
view.disableAutoLayout = disableAutoLayout
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@ReactProp(name = "scrollOffset")
|
|
47
|
+
fun setScrollOffset(view: AutoLayoutView, scrollOffset: Double) {
|
|
48
|
+
view.alShadow.scrollOffset = convertToPixelLayout(scrollOffset, view.pixelDensity)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@ReactProp(name = "windowSize")
|
|
52
|
+
fun setWindowSize(view: AutoLayoutView, windowSize: Double) {
|
|
53
|
+
view.alShadow.windowSize = convertToPixelLayout(windowSize, view.pixelDensity)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@ReactProp(name = "renderAheadOffset")
|
|
57
|
+
fun setRenderAheadOffset(view: AutoLayoutView, renderOffset: Double) {
|
|
58
|
+
view.alShadow.renderOffset = convertToPixelLayout(renderOffset, view.pixelDensity)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactProp(name = "enableInstrumentation")
|
|
62
|
+
fun setEnableInstrumentation(view: AutoLayoutView, enableInstrumentation: Boolean) {
|
|
63
|
+
view.enableInstrumentation = enableInstrumentation
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private fun convertToPixelLayout(dp: Double, density: Double): Int {
|
|
67
|
+
return (dp * density).roundToInt()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list;
|
|
2
|
+
|
|
3
|
+
public interface CellContainer {
|
|
4
|
+
void setIndex(int value);
|
|
5
|
+
int getIndex();
|
|
6
|
+
void setLeft(int value);
|
|
7
|
+
int getLeft();
|
|
8
|
+
void setTop(int value);
|
|
9
|
+
int getTop();
|
|
10
|
+
void setRight(int value);
|
|
11
|
+
int getRight();
|
|
12
|
+
void setBottom(int value);
|
|
13
|
+
int getBottom();
|
|
14
|
+
int getHeight();
|
|
15
|
+
int getWidth();
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
5
|
+
|
|
6
|
+
class CellContainerImpl(context: Context) : ReactViewGroup(context), CellContainer {
|
|
7
|
+
private var index = -1
|
|
8
|
+
override fun setIndex(value: Int) {
|
|
9
|
+
index = value
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
override fun getIndex(): Int {
|
|
13
|
+
return index
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
4
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
5
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
6
|
+
import com.facebook.react.views.view.ReactViewGroup
|
|
7
|
+
import com.facebook.react.views.view.ReactViewManager
|
|
8
|
+
|
|
9
|
+
@ReactModule(name = AutoLayoutViewManager.REACT_CLASS)
|
|
10
|
+
class CellContainerManager: ReactViewManager() {
|
|
11
|
+
companion object {
|
|
12
|
+
const val REACT_CLASS = "CellContainer"
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
override fun getName(): String {
|
|
16
|
+
return REACT_CLASS
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun createViewInstance(context: ThemedReactContext): ReactViewGroup {
|
|
20
|
+
return CellContainerImpl(context)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@ReactProp(name = "index")
|
|
24
|
+
fun setIndex(view: CellContainerImpl, index: Int) {
|
|
25
|
+
view.index = index
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.shopify.reactnative.flash_list
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class ReactNativeFlashListPackage : ReactPackage {
|
|
9
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
10
|
+
return listOf()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
14
|
+
return listOf(
|
|
15
|
+
AutoLayoutViewManager(),
|
|
16
|
+
CellContainerManager()
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
}
|