@react-native-macos/virtualized-lists 0.79.0 → 0.81.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/Lists/ListMetricsAggregator.js +1 -1
- package/Lists/VirtualizeUtils.js +2 -3
- package/Lists/VirtualizedList.d.ts +2 -2
- package/Lists/VirtualizedList.js +47 -22
- package/Lists/VirtualizedListCellRenderer.js +7 -7
- package/Lists/VirtualizedListContext.js +6 -6
- package/Lists/VirtualizedListProps.js +15 -14
- package/Lists/VirtualizedSectionList.js +87 -48
- package/Utilities/clamp.js +1 -1
- package/Utilities/infoLog.js +1 -1
- package/index.js +13 -11
- package/package.json +28 -4
- package/CHANGELOG.json +0 -20
- package/CHANGELOG.md +0 -13
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type {VirtualizedListProps} from './VirtualizedListProps';
|
|
12
|
-
import type {LayoutRectangle} from 'react-native
|
|
12
|
+
import type {LayoutRectangle} from 'react-native';
|
|
13
13
|
|
|
14
14
|
import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
|
|
15
15
|
import invariant from 'invariant';
|
package/Lists/VirtualizeUtils.js
CHANGED
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
import type ListMetricsAggregator
|
|
14
|
-
|
|
15
|
-
} from './ListMetricsAggregator';
|
|
13
|
+
import type ListMetricsAggregator from './ListMetricsAggregator';
|
|
14
|
+
import type {CellMetricProps} from './ListMetricsAggregator';
|
|
16
15
|
|
|
17
16
|
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
|
|
18
17
|
|
|
@@ -131,8 +131,8 @@ export class VirtualizedList<ItemT> extends React.Component<
|
|
|
131
131
|
recordInteraction: () => void;
|
|
132
132
|
|
|
133
133
|
getScrollRef: () =>
|
|
134
|
-
| React.
|
|
135
|
-
| React.
|
|
134
|
+
| React.ComponentRef<typeof ScrollView>
|
|
135
|
+
| React.ComponentRef<typeof View>
|
|
136
136
|
| null;
|
|
137
137
|
|
|
138
138
|
getScrollResponder: () => ScrollResponderMixin | null;
|
package/Lists/VirtualizedList.js
CHANGED
|
@@ -17,12 +17,13 @@ import type {
|
|
|
17
17
|
Separators,
|
|
18
18
|
VirtualizedListProps,
|
|
19
19
|
} from './VirtualizedListProps';
|
|
20
|
-
import type {ScrollResponderType} from 'react-native/Libraries/Components/ScrollView/ScrollView';
|
|
21
|
-
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
|
22
20
|
import type {
|
|
23
21
|
LayoutChangeEvent,
|
|
24
22
|
ScrollEvent,
|
|
25
|
-
|
|
23
|
+
ScrollResponderType,
|
|
24
|
+
StyleProp,
|
|
25
|
+
ViewStyle,
|
|
26
|
+
} from 'react-native';
|
|
26
27
|
import type {KeyEvent} from 'react-native/Libraries/Types/CoreEventTypes'; // [macOS]
|
|
27
28
|
|
|
28
29
|
import clamp from '../Utilities/clamp';
|
|
@@ -54,6 +55,7 @@ import {
|
|
|
54
55
|
import invariant from 'invariant';
|
|
55
56
|
import nullthrows from 'nullthrows';
|
|
56
57
|
import * as React from 'react';
|
|
58
|
+
import {cloneElement, isValidElement} from 'react';
|
|
57
59
|
import {
|
|
58
60
|
I18nManager,
|
|
59
61
|
Platform,
|
|
@@ -63,6 +65,7 @@ import {
|
|
|
63
65
|
View,
|
|
64
66
|
findNodeHandle,
|
|
65
67
|
} from 'react-native';
|
|
68
|
+
import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags';
|
|
66
69
|
|
|
67
70
|
export type {ListRenderItemInfo, ListRenderItem, Separators};
|
|
68
71
|
|
|
@@ -340,7 +343,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
340
343
|
if (this._scrollRef && this._scrollRef.getScrollableNode) {
|
|
341
344
|
return this._scrollRef.getScrollableNode();
|
|
342
345
|
} else {
|
|
343
|
-
return findNodeHandle(this._scrollRef);
|
|
346
|
+
return findNodeHandle<$FlowFixMe>(this._scrollRef);
|
|
344
347
|
}
|
|
345
348
|
}
|
|
346
349
|
|
|
@@ -800,7 +803,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
800
803
|
stickyIndicesFromProps: Set<number>,
|
|
801
804
|
first: number,
|
|
802
805
|
last: number,
|
|
803
|
-
inversionStyle:
|
|
806
|
+
inversionStyle: StyleProp<ViewStyle>,
|
|
804
807
|
) {
|
|
805
808
|
const {
|
|
806
809
|
CellRendererComponent,
|
|
@@ -928,6 +931,30 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
928
931
|
return key;
|
|
929
932
|
}
|
|
930
933
|
|
|
934
|
+
_renderEmptyComponent(
|
|
935
|
+
element: ExactReactElement_DEPRECATED<any>,
|
|
936
|
+
inversionStyle: StyleProp<ViewStyle>,
|
|
937
|
+
): React.Node {
|
|
938
|
+
// $FlowFixMe[prop-missing] React.Element internal inspection
|
|
939
|
+
const isFragment = element.type === React.Fragment;
|
|
940
|
+
|
|
941
|
+
if (isFragment) {
|
|
942
|
+
return element;
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return cloneElement(element, {
|
|
946
|
+
onLayout: (event: LayoutChangeEvent) => {
|
|
947
|
+
this._onLayoutEmpty(event);
|
|
948
|
+
// $FlowFixMe[prop-missing] React.Element internal inspection
|
|
949
|
+
if (element.props.onLayout) {
|
|
950
|
+
element.props.onLayout(event);
|
|
951
|
+
}
|
|
952
|
+
},
|
|
953
|
+
// $FlowFixMe[prop-missing] React.Element internal inspection
|
|
954
|
+
style: StyleSheet.compose(inversionStyle, element.props.style),
|
|
955
|
+
});
|
|
956
|
+
}
|
|
957
|
+
|
|
931
958
|
render(): React.Node {
|
|
932
959
|
this._checkProps(this.props);
|
|
933
960
|
const {ListEmptyComponent, ListFooterComponent, ListHeaderComponent} =
|
|
@@ -949,7 +976,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
949
976
|
if (stickyIndicesFromProps.has(0)) {
|
|
950
977
|
stickyHeaderIndices.push(0);
|
|
951
978
|
}
|
|
952
|
-
const element =
|
|
979
|
+
const element = isValidElement(ListHeaderComponent) ? (
|
|
953
980
|
ListHeaderComponent
|
|
954
981
|
) : (
|
|
955
982
|
// $FlowFixMe[not-a-component]
|
|
@@ -982,7 +1009,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
982
1009
|
// 2a. Add a cell for ListEmptyComponent if applicable
|
|
983
1010
|
const itemCount = this.props.getItemCount(data);
|
|
984
1011
|
if (itemCount === 0 && ListEmptyComponent) {
|
|
985
|
-
const element: ExactReactElement_DEPRECATED<any> = ((
|
|
1012
|
+
const element: ExactReactElement_DEPRECATED<any> = ((isValidElement(
|
|
986
1013
|
ListEmptyComponent,
|
|
987
1014
|
) ? (
|
|
988
1015
|
ListEmptyComponent
|
|
@@ -997,17 +1024,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
997
1024
|
cellKey={this._getCellKey() + '-empty'}
|
|
998
1025
|
collapsable={Platform.OS !== 'macos'} // [macOS]
|
|
999
1026
|
key="$empty">
|
|
1000
|
-
{
|
|
1001
|
-
onLayout: (event: LayoutChangeEvent) => {
|
|
1002
|
-
this._onLayoutEmpty(event);
|
|
1003
|
-
// $FlowFixMe[prop-missing] React.Element internal inspection
|
|
1004
|
-
if (element.props.onLayout) {
|
|
1005
|
-
element.props.onLayout(event);
|
|
1006
|
-
}
|
|
1007
|
-
},
|
|
1008
|
-
// $FlowFixMe[prop-missing] React.Element internal inspection
|
|
1009
|
-
style: StyleSheet.compose(inversionStyle, element.props.style),
|
|
1010
|
-
})}
|
|
1027
|
+
{this._renderEmptyComponent(element, inversionStyle)}
|
|
1011
1028
|
</VirtualizedListCellContextProvider>,
|
|
1012
1029
|
);
|
|
1013
1030
|
}
|
|
@@ -1085,7 +1102,7 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
1085
1102
|
|
|
1086
1103
|
// 3. Add cell for ListFooterComponent
|
|
1087
1104
|
if (ListFooterComponent) {
|
|
1088
|
-
const element =
|
|
1105
|
+
const element = isValidElement(ListFooterComponent) ? (
|
|
1089
1106
|
ListFooterComponent
|
|
1090
1107
|
) : (
|
|
1091
1108
|
// $FlowFixMe[not-a-component]
|
|
@@ -1158,11 +1175,14 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
1158
1175
|
registerAsNestedChild: this._registerAsNestedChild,
|
|
1159
1176
|
unregisterAsNestedChild: this._unregisterAsNestedChild,
|
|
1160
1177
|
}}>
|
|
1161
|
-
{
|
|
1178
|
+
{cloneElement(
|
|
1162
1179
|
(
|
|
1163
1180
|
this.props.renderScrollComponent ||
|
|
1164
1181
|
this._defaultRenderScrollComponent
|
|
1165
|
-
)(
|
|
1182
|
+
)(
|
|
1183
|
+
// $FlowExpectedError[prop-missing] scrollProps is a superset of ScrollViewProps
|
|
1184
|
+
scrollProps,
|
|
1185
|
+
) as ExactReactElement_DEPRECATED<any>,
|
|
1166
1186
|
{
|
|
1167
1187
|
ref: this._captureScrollRef,
|
|
1168
1188
|
},
|
|
@@ -1393,7 +1413,12 @@ class VirtualizedList extends StateSafePureComponent<
|
|
|
1393
1413
|
|
|
1394
1414
|
_onCellFocusCapture = (cellKey: string) => {
|
|
1395
1415
|
this._lastFocusedCellKey = cellKey;
|
|
1396
|
-
|
|
1416
|
+
if (ReactNativeFeatureFlags.deferFlatListFocusChangeRenderUpdate()) {
|
|
1417
|
+
// Schedule the cells to render update the same way we handle scroll or layout events.
|
|
1418
|
+
this._scheduleCellsToRenderUpdate();
|
|
1419
|
+
} else {
|
|
1420
|
+
this._updateCellsToRender();
|
|
1421
|
+
}
|
|
1397
1422
|
};
|
|
1398
1423
|
|
|
1399
1424
|
_onCellUnmount = (cellKey: string) => {
|
|
@@ -9,16 +9,18 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type {CellRendererProps, ListRenderItem} from './VirtualizedListProps';
|
|
12
|
-
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
|
13
12
|
import type {
|
|
14
13
|
FocusEvent,
|
|
15
14
|
LayoutChangeEvent,
|
|
16
|
-
|
|
15
|
+
StyleProp,
|
|
16
|
+
ViewStyle,
|
|
17
|
+
} from 'react-native';
|
|
17
18
|
|
|
18
19
|
import {VirtualizedListCellContextProvider} from './VirtualizedListContext.js';
|
|
19
20
|
import invariant from 'invariant';
|
|
20
21
|
import * as React from 'react';
|
|
21
|
-
import {
|
|
22
|
+
import {isValidElement} from 'react';
|
|
23
|
+
import {Platform, StyleSheet, View} from 'react-native';
|
|
22
24
|
|
|
23
25
|
export type Props<ItemT> = {
|
|
24
26
|
CellRendererComponent?: ?React.ComponentType<CellRendererProps<ItemT>>,
|
|
@@ -29,7 +31,7 @@ export type Props<ItemT> = {
|
|
|
29
31
|
cellKey: string,
|
|
30
32
|
horizontal: ?boolean,
|
|
31
33
|
index: number,
|
|
32
|
-
inversionStyle:
|
|
34
|
+
inversionStyle: StyleProp<ViewStyle>,
|
|
33
35
|
isSelected: ?boolean, // [macOS]
|
|
34
36
|
item: ItemT,
|
|
35
37
|
onCellLayout?: (
|
|
@@ -197,9 +199,7 @@ export default class CellRenderer<ItemT> extends React.PureComponent<
|
|
|
197
199
|
|
|
198
200
|
// NOTE: that when this is a sticky header, `onLayout` will get automatically extracted and
|
|
199
201
|
// called explicitly by `ScrollViewStickyHeader`.
|
|
200
|
-
const itemSeparator: React.Node =
|
|
201
|
-
ItemSeparatorComponent,
|
|
202
|
-
)
|
|
202
|
+
const itemSeparator: React.Node = isValidElement(ItemSeparatorComponent)
|
|
203
203
|
? // $FlowFixMe[incompatible-type]
|
|
204
204
|
ItemSeparatorComponent
|
|
205
205
|
: // $FlowFixMe[incompatible-type]
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import typeof
|
|
11
|
+
import typeof VirtualizedListT from './VirtualizedList';
|
|
12
12
|
|
|
13
13
|
import * as React from 'react';
|
|
14
|
-
import {useContext, useMemo} from 'react';
|
|
14
|
+
import {createContext, useContext, useMemo} from 'react';
|
|
15
15
|
|
|
16
16
|
type Context = $ReadOnly<{
|
|
17
17
|
cellKey: ?string,
|
|
@@ -26,16 +26,16 @@ type Context = $ReadOnly<{
|
|
|
26
26
|
zoomScale: number,
|
|
27
27
|
},
|
|
28
28
|
horizontal: ?boolean,
|
|
29
|
-
getOutermostParentListRef: () => React.ElementRef<
|
|
29
|
+
getOutermostParentListRef: () => React.ElementRef<VirtualizedListT>,
|
|
30
30
|
registerAsNestedChild: ({
|
|
31
31
|
cellKey: string,
|
|
32
|
-
ref: React.ElementRef<
|
|
32
|
+
ref: React.ElementRef<VirtualizedListT>,
|
|
33
33
|
}) => void,
|
|
34
|
-
unregisterAsNestedChild: ({ref: React.ElementRef<
|
|
34
|
+
unregisterAsNestedChild: ({ref: React.ElementRef<VirtualizedListT>}) => void,
|
|
35
35
|
}>;
|
|
36
36
|
|
|
37
37
|
export const VirtualizedListContext: React.Context<?Context> =
|
|
38
|
-
|
|
38
|
+
createContext(null);
|
|
39
39
|
if (__DEV__) {
|
|
40
40
|
VirtualizedListContext.displayName = 'VirtualizedListContext';
|
|
41
41
|
}
|
|
@@ -13,14 +13,15 @@ import type {
|
|
|
13
13
|
ViewabilityConfigCallbackPair,
|
|
14
14
|
ViewToken,
|
|
15
15
|
} from './ViewabilityHelper';
|
|
16
|
-
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
|
17
16
|
import type {
|
|
18
17
|
FocusEvent,
|
|
19
18
|
LayoutChangeEvent,
|
|
20
|
-
|
|
19
|
+
ScrollViewProps,
|
|
20
|
+
StyleProp,
|
|
21
|
+
ViewStyle,
|
|
22
|
+
} from 'react-native';
|
|
21
23
|
|
|
22
24
|
import * as React from 'react';
|
|
23
|
-
import {typeof ScrollView} from 'react-native';
|
|
24
25
|
|
|
25
26
|
export type Item = any;
|
|
26
27
|
|
|
@@ -46,7 +47,7 @@ export type CellRendererProps<ItemT> = $ReadOnly<{
|
|
|
46
47
|
item: ItemT,
|
|
47
48
|
onFocusCapture?: (event: FocusEvent) => void,
|
|
48
49
|
onLayout?: (event: LayoutChangeEvent) => void,
|
|
49
|
-
style:
|
|
50
|
+
style: StyleProp<ViewStyle>,
|
|
50
51
|
}>;
|
|
51
52
|
|
|
52
53
|
export type ListRenderItem<ItemT> = (
|
|
@@ -59,7 +60,7 @@ export type SelectedRowIndexPathType = {
|
|
|
59
60
|
rowIndex: number,
|
|
60
61
|
}; // macOS]
|
|
61
62
|
|
|
62
|
-
type
|
|
63
|
+
type RequiredVirtualizedListProps = {
|
|
63
64
|
/**
|
|
64
65
|
* The default accessor functions assume this is an Array<{key: string} | {id: string}> but you can override
|
|
65
66
|
* getItem, getItemCount, and keyExtractor to handle any type of index-based data.
|
|
@@ -74,7 +75,7 @@ type RequiredProps = {
|
|
|
74
75
|
*/
|
|
75
76
|
getItemCount: (data: any) => number,
|
|
76
77
|
};
|
|
77
|
-
type
|
|
78
|
+
type OptionalVirtualizedListProps = {
|
|
78
79
|
renderItem?: ?ListRenderItem<Item>,
|
|
79
80
|
/**
|
|
80
81
|
* `debug` will turn on extra logging and visual overlays to aid with debugging both usage and
|
|
@@ -176,7 +177,7 @@ type OptionalProps = {
|
|
|
176
177
|
/**
|
|
177
178
|
* Styling for internal View for ListFooterComponent
|
|
178
179
|
*/
|
|
179
|
-
ListFooterComponentStyle?:
|
|
180
|
+
ListFooterComponentStyle?: StyleProp<ViewStyle>,
|
|
180
181
|
/**
|
|
181
182
|
* Rendered at the top of all the items. Can be a React Component Class, a render function, or
|
|
182
183
|
* a rendered element.
|
|
@@ -185,7 +186,7 @@ type OptionalProps = {
|
|
|
185
186
|
/**
|
|
186
187
|
* Styling for internal View for ListHeaderComponent
|
|
187
188
|
*/
|
|
188
|
-
ListHeaderComponentStyle?:
|
|
189
|
+
ListHeaderComponentStyle?: StyleProp<ViewStyle>,
|
|
189
190
|
/**
|
|
190
191
|
* The maximum number of items to render in each incremental render batch. The more rendered at
|
|
191
192
|
* once, the better the fill rate, but responsiveness may suffer because rendering content may
|
|
@@ -265,7 +266,7 @@ type OptionalProps = {
|
|
|
265
266
|
/**
|
|
266
267
|
* Render a custom scroll component, e.g. with a differently styled `RefreshControl`.
|
|
267
268
|
*/
|
|
268
|
-
renderScrollComponent?: (props:
|
|
269
|
+
renderScrollComponent?: (props: ScrollViewProps) => React.MixedElement,
|
|
269
270
|
/**
|
|
270
271
|
* Amount of time between low-pri item render batches, e.g. for rendering items quite a ways off
|
|
271
272
|
* screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`.
|
|
@@ -290,7 +291,7 @@ type OptionalProps = {
|
|
|
290
291
|
windowSize?: ?number,
|
|
291
292
|
};
|
|
292
293
|
// [macOS
|
|
293
|
-
type
|
|
294
|
+
type VirtualizedListMacOSProps = {
|
|
294
295
|
/**
|
|
295
296
|
* Allows you to 'select' a row using arrow keys. The selected row will have the prop `isSelected`
|
|
296
297
|
* passed in as true to it's renderItem / ListItemComponent. You can also imperatively select a row
|
|
@@ -335,10 +336,10 @@ type MacOSProps = {
|
|
|
335
336
|
// macOS]
|
|
336
337
|
|
|
337
338
|
export type VirtualizedListProps = {
|
|
338
|
-
...
|
|
339
|
-
...
|
|
340
|
-
...
|
|
341
|
-
...
|
|
339
|
+
...ScrollViewProps,
|
|
340
|
+
...RequiredVirtualizedListProps,
|
|
341
|
+
...OptionalVirtualizedListProps,
|
|
342
|
+
...VirtualizedListMacOSProps, // [macOS]
|
|
342
343
|
};
|
|
343
344
|
|
|
344
345
|
/**
|
|
@@ -9,14 +9,25 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type {ViewToken} from './ViewabilityHelper';
|
|
12
|
+
import type {VirtualizedListProps} from './VirtualizedListProps';
|
|
12
13
|
|
|
13
14
|
import VirtualizedList from './VirtualizedList';
|
|
14
15
|
import {keyExtractor as defaultKeyExtractor} from './VirtualizeUtils';
|
|
15
16
|
import invariant from 'invariant';
|
|
16
17
|
import * as React from 'react';
|
|
17
|
-
|
|
18
|
+
import {useEffect, useState} from 'react';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
type DefaultVirtualizedSectionT = {
|
|
21
|
+
data: any,
|
|
22
|
+
[key: string]: any,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type SectionData<SectionItemT, SectionT = DefaultVirtualizedSectionT> =
|
|
26
|
+
| ($ReadOnly<SectionBase<SectionItemT, SectionT>> & SectionT)
|
|
27
|
+
| (SectionBase<SectionItemT, SectionT> & SectionT)
|
|
28
|
+
| SectionT;
|
|
29
|
+
|
|
30
|
+
export type SectionBase<SectionItemT, SectionT = DefaultVirtualizedSectionT> = {
|
|
20
31
|
/**
|
|
21
32
|
* The data for rendering items in this section.
|
|
22
33
|
*/
|
|
@@ -30,7 +41,7 @@ export type SectionBase<SectionItemT> = {
|
|
|
30
41
|
renderItem?: ?(info: {
|
|
31
42
|
item: SectionItemT,
|
|
32
43
|
index: number,
|
|
33
|
-
section:
|
|
44
|
+
section: SectionData<SectionItemT, SectionT>,
|
|
34
45
|
separators: {
|
|
35
46
|
highlight: () => void,
|
|
36
47
|
unhighlight: () => void,
|
|
@@ -40,21 +51,28 @@ export type SectionBase<SectionItemT> = {
|
|
|
40
51
|
...
|
|
41
52
|
}) => null | React.MixedElement,
|
|
42
53
|
ItemSeparatorComponent?: ?React.ComponentType<any>,
|
|
43
|
-
keyExtractor?: (item: SectionItemT, index?: ?number) => string,
|
|
54
|
+
keyExtractor?: (item: ?SectionItemT, index?: ?number) => string,
|
|
44
55
|
...
|
|
45
56
|
};
|
|
46
57
|
|
|
47
|
-
type
|
|
48
|
-
|
|
58
|
+
type RequiredVirtualizedSectionListProps<
|
|
59
|
+
ItemT,
|
|
60
|
+
SectionT = DefaultVirtualizedSectionT,
|
|
61
|
+
> = {
|
|
62
|
+
sections: $ReadOnlyArray<SectionData<ItemT, SectionT>>,
|
|
49
63
|
};
|
|
50
64
|
|
|
51
|
-
type
|
|
65
|
+
type OptionalVirtualizedSectionListProps<
|
|
66
|
+
ItemT,
|
|
67
|
+
SectionT = DefaultVirtualizedSectionT,
|
|
68
|
+
> = {
|
|
52
69
|
/**
|
|
53
70
|
* Default renderer for every item in every section.
|
|
54
71
|
*/
|
|
55
72
|
renderItem?: (info: {
|
|
56
|
-
item:
|
|
73
|
+
item: ItemT,
|
|
57
74
|
index: number,
|
|
75
|
+
isSelected: ?boolean, // [macOS]
|
|
58
76
|
section: SectionT,
|
|
59
77
|
separators: {
|
|
60
78
|
highlight: () => void,
|
|
@@ -89,19 +107,13 @@ type OptionalProps<SectionT: SectionBase<any>> = {
|
|
|
89
107
|
onEndReached?: ?({distanceFromEnd: number, ...}) => void,
|
|
90
108
|
};
|
|
91
109
|
|
|
92
|
-
type
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
...
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
{
|
|
100
|
-
renderItem: $PropertyType<VirtualizedListProps, 'renderItem'>,
|
|
101
|
-
data: $PropertyType<VirtualizedListProps, 'data'>,
|
|
102
|
-
...
|
|
103
|
-
},
|
|
104
|
-
>,
|
|
110
|
+
export type VirtualizedSectionListProps<
|
|
111
|
+
ItemT,
|
|
112
|
+
SectionT = DefaultVirtualizedSectionT,
|
|
113
|
+
> = {
|
|
114
|
+
...RequiredVirtualizedSectionListProps<ItemT, SectionT>,
|
|
115
|
+
...OptionalVirtualizedSectionListProps<ItemT, SectionT>,
|
|
116
|
+
...Omit<VirtualizedListProps, 'data' | 'renderItem'>,
|
|
105
117
|
};
|
|
106
118
|
export type ScrollToLocationParamsType = {
|
|
107
119
|
animated?: ?boolean,
|
|
@@ -119,8 +131,15 @@ type State = {childProps: VirtualizedListProps, ...};
|
|
|
119
131
|
* sections when new props are received, which should be plenty fast for up to ~10,000 items.
|
|
120
132
|
*/
|
|
121
133
|
class VirtualizedSectionList<
|
|
122
|
-
|
|
123
|
-
|
|
134
|
+
ItemT,
|
|
135
|
+
SectionT: SectionBase<
|
|
136
|
+
ItemT,
|
|
137
|
+
DefaultVirtualizedSectionT,
|
|
138
|
+
> = DefaultVirtualizedSectionT,
|
|
139
|
+
> extends React.PureComponent<
|
|
140
|
+
VirtualizedSectionListProps<ItemT, SectionT>,
|
|
141
|
+
State,
|
|
142
|
+
> {
|
|
124
143
|
scrollToLocation(params: ScrollToLocationParamsType) {
|
|
125
144
|
let index = params.itemIndex;
|
|
126
145
|
for (let i = 0; i < params.sectionIndex; i++) {
|
|
@@ -203,10 +222,10 @@ class VirtualizedSectionList<
|
|
|
203
222
|
}
|
|
204
223
|
|
|
205
224
|
_getItem(
|
|
206
|
-
props: VirtualizedSectionListProps<SectionT>,
|
|
207
|
-
sections: ?$ReadOnlyArray<
|
|
225
|
+
props: VirtualizedSectionListProps<ItemT, SectionT>,
|
|
226
|
+
sections: ?$ReadOnlyArray<SectionData<ItemT, SectionT>>,
|
|
208
227
|
index: number,
|
|
209
|
-
): ?
|
|
228
|
+
): ?ItemT {
|
|
210
229
|
if (!sections) {
|
|
211
230
|
return null;
|
|
212
231
|
}
|
|
@@ -219,6 +238,7 @@ class VirtualizedSectionList<
|
|
|
219
238
|
// We intend for there to be overflow by one on both ends of the list.
|
|
220
239
|
// This will be for headers and footers. When returning a header or footer
|
|
221
240
|
// item the section itself is the item.
|
|
241
|
+
// $FlowIgnore[incompatible-return]
|
|
222
242
|
return section;
|
|
223
243
|
} else if (itemIdx < itemCount) {
|
|
224
244
|
// If we are in the bounds of the list's data then return the item.
|
|
@@ -231,23 +251,23 @@ class VirtualizedSectionList<
|
|
|
231
251
|
}
|
|
232
252
|
|
|
233
253
|
// $FlowFixMe[missing-local-annot]
|
|
234
|
-
_keyExtractor = (item:
|
|
254
|
+
_keyExtractor = (item: ItemT, index: number) => {
|
|
235
255
|
const info = this._subExtractor(index);
|
|
236
256
|
return (info && info.key) || String(index);
|
|
237
257
|
};
|
|
238
258
|
|
|
239
259
|
_subExtractor(index: number): ?{
|
|
240
|
-
section: SectionT
|
|
260
|
+
section: SectionData<ItemT, SectionT>,
|
|
241
261
|
// Key of the section or combined key for section + item
|
|
242
262
|
key: string,
|
|
243
263
|
// Relative index within the section
|
|
244
264
|
index: ?number,
|
|
245
265
|
// True if this is the section header
|
|
246
266
|
header?: ?boolean,
|
|
247
|
-
leadingItem?: ?
|
|
248
|
-
leadingSection?: ?SectionT
|
|
249
|
-
trailingItem?: ?
|
|
250
|
-
trailingSection?: ?SectionT
|
|
267
|
+
leadingItem?: ?ItemT,
|
|
268
|
+
leadingSection?: ?SectionData<ItemT, SectionT>,
|
|
269
|
+
trailingItem?: ?ItemT,
|
|
270
|
+
trailingSection?: ?SectionData<ItemT, SectionT>,
|
|
251
271
|
...
|
|
252
272
|
} {
|
|
253
273
|
let itemIndex = index;
|
|
@@ -336,7 +356,7 @@ class VirtualizedSectionList<
|
|
|
336
356
|
_renderItem =
|
|
337
357
|
(listItemCount: number): $FlowFixMe =>
|
|
338
358
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
339
|
-
({item, index}: {item:
|
|
359
|
+
({item, index}: {item: ItemT, index: number, ...}) => {
|
|
340
360
|
const info = this._subExtractor(index);
|
|
341
361
|
if (!info) {
|
|
342
362
|
return null;
|
|
@@ -453,21 +473,21 @@ class VirtualizedSectionList<
|
|
|
453
473
|
};
|
|
454
474
|
}
|
|
455
475
|
|
|
456
|
-
type ItemWithSeparatorCommonProps = $ReadOnly<{
|
|
457
|
-
leadingItem: ?
|
|
476
|
+
type ItemWithSeparatorCommonProps<ItemT> = $ReadOnly<{
|
|
477
|
+
leadingItem: ?ItemT,
|
|
458
478
|
leadingSection: ?Object,
|
|
459
479
|
section: Object,
|
|
460
|
-
trailingItem: ?
|
|
480
|
+
trailingItem: ?ItemT,
|
|
461
481
|
trailingSection: ?Object,
|
|
462
482
|
}>;
|
|
463
483
|
|
|
464
|
-
type ItemWithSeparatorProps = $ReadOnly<{
|
|
465
|
-
...ItemWithSeparatorCommonProps
|
|
484
|
+
type ItemWithSeparatorProps<ItemT> = $ReadOnly<{
|
|
485
|
+
...ItemWithSeparatorCommonProps<ItemT>,
|
|
466
486
|
LeadingSeparatorComponent: ?React.ComponentType<any>,
|
|
467
487
|
SeparatorComponent: ?React.ComponentType<any>,
|
|
468
488
|
cellKey: string,
|
|
469
489
|
index: number,
|
|
470
|
-
item:
|
|
490
|
+
item: ItemT,
|
|
471
491
|
setSelfHighlightCallback: (
|
|
472
492
|
cellKey: string,
|
|
473
493
|
updateFn: ?(boolean) => void,
|
|
@@ -483,7 +503,9 @@ type ItemWithSeparatorProps = $ReadOnly<{
|
|
|
483
503
|
inverted: boolean,
|
|
484
504
|
}>;
|
|
485
505
|
|
|
486
|
-
function ItemWithSeparator(
|
|
506
|
+
function ItemWithSeparator<ItemT>(
|
|
507
|
+
props: ItemWithSeparatorProps<ItemT>,
|
|
508
|
+
): React.Node {
|
|
487
509
|
const {
|
|
488
510
|
LeadingSeparatorComponent,
|
|
489
511
|
// this is the trailing separator and is associated with this item
|
|
@@ -501,18 +523,22 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node {
|
|
|
501
523
|
} = props;
|
|
502
524
|
|
|
503
525
|
const [leadingSeparatorHiglighted, setLeadingSeparatorHighlighted] =
|
|
504
|
-
|
|
526
|
+
useState(false);
|
|
505
527
|
|
|
506
|
-
const [separatorHighlighted, setSeparatorHighlighted] =
|
|
528
|
+
const [separatorHighlighted, setSeparatorHighlighted] = useState(false);
|
|
507
529
|
|
|
508
|
-
const [leadingSeparatorProps, setLeadingSeparatorProps] =
|
|
530
|
+
const [leadingSeparatorProps, setLeadingSeparatorProps] = useState<
|
|
531
|
+
ItemWithSeparatorCommonProps<ItemT>,
|
|
532
|
+
>({
|
|
509
533
|
leadingItem: props.leadingItem,
|
|
510
534
|
leadingSection: props.leadingSection,
|
|
511
535
|
section: props.section,
|
|
512
536
|
trailingItem: props.item,
|
|
513
537
|
trailingSection: props.trailingSection,
|
|
514
538
|
});
|
|
515
|
-
const [separatorProps, setSeparatorProps] =
|
|
539
|
+
const [separatorProps, setSeparatorProps] = useState<
|
|
540
|
+
ItemWithSeparatorCommonProps<ItemT>,
|
|
541
|
+
>({
|
|
516
542
|
leadingItem: props.item,
|
|
517
543
|
leadingSection: props.leadingSection,
|
|
518
544
|
section: props.section,
|
|
@@ -520,7 +546,7 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node {
|
|
|
520
546
|
trailingSection: props.trailingSection,
|
|
521
547
|
});
|
|
522
548
|
|
|
523
|
-
|
|
549
|
+
useEffect(() => {
|
|
524
550
|
setSelfHighlightCallback(cellKey, setSeparatorHighlighted);
|
|
525
551
|
// $FlowFixMe[incompatible-call]
|
|
526
552
|
setSelfUpdatePropsCallback(cellKey, setSeparatorProps);
|
|
@@ -553,7 +579,7 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node {
|
|
|
553
579
|
},
|
|
554
580
|
updateProps: (
|
|
555
581
|
select: 'leading' | 'trailing',
|
|
556
|
-
newProps: Partial<ItemWithSeparatorCommonProps
|
|
582
|
+
newProps: Partial<ItemWithSeparatorCommonProps<ItemT>>,
|
|
557
583
|
) => {
|
|
558
584
|
if (select === 'leading') {
|
|
559
585
|
if (LeadingSeparatorComponent != null) {
|
|
@@ -598,12 +624,25 @@ function ItemWithSeparator(props: ItemWithSeparatorProps): React.Node {
|
|
|
598
624
|
);
|
|
599
625
|
}
|
|
600
626
|
|
|
601
|
-
|
|
627
|
+
const VirtualizedSectionListComponent = VirtualizedSectionList as component<
|
|
628
|
+
ItemT,
|
|
629
|
+
SectionT: SectionBase<
|
|
630
|
+
ItemT,
|
|
631
|
+
DefaultVirtualizedSectionT,
|
|
632
|
+
> = DefaultVirtualizedSectionT,
|
|
633
|
+
>(
|
|
602
634
|
ref: React.RefSetter<
|
|
603
635
|
interface {
|
|
604
636
|
getListRef(): ?VirtualizedList,
|
|
605
637
|
scrollToLocation(params: ScrollToLocationParamsType): void,
|
|
606
638
|
},
|
|
607
639
|
>,
|
|
608
|
-
...VirtualizedSectionListProps<
|
|
640
|
+
...VirtualizedSectionListProps<ItemT, SectionT>
|
|
609
641
|
);
|
|
642
|
+
|
|
643
|
+
export default VirtualizedSectionListComponent;
|
|
644
|
+
|
|
645
|
+
export type AnyVirtualizedSectionList = typeof VirtualizedSectionListComponent<
|
|
646
|
+
any,
|
|
647
|
+
any,
|
|
648
|
+
>;
|
package/Utilities/clamp.js
CHANGED
package/Utilities/infoLog.js
CHANGED
package/index.js
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @format
|
|
8
7
|
* @flow
|
|
8
|
+
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
'use strict';
|
|
12
12
|
|
|
13
|
-
import typeof
|
|
14
|
-
import typeof
|
|
15
|
-
import typeof
|
|
16
|
-
import
|
|
13
|
+
import typeof FillRateHelperT from './Lists/FillRateHelper';
|
|
14
|
+
import typeof ViewabilityHelperT from './Lists/ViewabilityHelper';
|
|
15
|
+
import typeof VirtualizedListT from './Lists/VirtualizedList';
|
|
16
|
+
import type {AnyVirtualizedSectionList as AnyVirtualizedSectionListT} from './Lists/VirtualizedSectionList';
|
|
17
17
|
|
|
18
|
-
import {typeof VirtualizedListContextResetter} from './Lists/VirtualizedListContext';
|
|
18
|
+
import {typeof VirtualizedListContextResetter as VirtualizedListContextResetterT} from './Lists/VirtualizedListContext';
|
|
19
19
|
import {keyExtractor} from './Lists/VirtualizeUtils';
|
|
20
20
|
|
|
21
21
|
export type {
|
|
@@ -29,31 +29,33 @@ export type {
|
|
|
29
29
|
ListRenderItemInfo,
|
|
30
30
|
ListRenderItem,
|
|
31
31
|
Separators,
|
|
32
|
+
VirtualizedListProps,
|
|
32
33
|
} from './Lists/VirtualizedListProps';
|
|
33
34
|
export type {
|
|
34
35
|
VirtualizedSectionListProps,
|
|
35
36
|
ScrollToLocationParamsType,
|
|
36
37
|
SectionBase,
|
|
38
|
+
SectionData,
|
|
37
39
|
} from './Lists/VirtualizedSectionList';
|
|
38
40
|
export type {FillRateInfo} from './Lists/FillRateHelper';
|
|
39
41
|
|
|
40
42
|
export default {
|
|
41
43
|
keyExtractor,
|
|
42
44
|
|
|
43
|
-
get VirtualizedList():
|
|
45
|
+
get VirtualizedList(): VirtualizedListT {
|
|
44
46
|
return require('./Lists/VirtualizedList').default;
|
|
45
47
|
},
|
|
46
|
-
get VirtualizedSectionList():
|
|
48
|
+
get VirtualizedSectionList(): AnyVirtualizedSectionListT {
|
|
47
49
|
return require('./Lists/VirtualizedSectionList').default;
|
|
48
50
|
},
|
|
49
|
-
get VirtualizedListContextResetter():
|
|
51
|
+
get VirtualizedListContextResetter(): VirtualizedListContextResetterT {
|
|
50
52
|
const VirtualizedListContext = require('./Lists/VirtualizedListContext');
|
|
51
53
|
return VirtualizedListContext.VirtualizedListContextResetter;
|
|
52
54
|
},
|
|
53
|
-
get ViewabilityHelper():
|
|
55
|
+
get ViewabilityHelper(): ViewabilityHelperT {
|
|
54
56
|
return require('./Lists/ViewabilityHelper').default;
|
|
55
57
|
},
|
|
56
|
-
get FillRateHelper():
|
|
58
|
+
get FillRateHelper(): FillRateHelperT {
|
|
57
59
|
return require('./Lists/FillRateHelper').default;
|
|
58
60
|
},
|
|
59
61
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-macos/virtualized-lists",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.81.0",
|
|
4
4
|
"description": "Virtualized lists for React Native macOS.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -17,17 +17,41 @@
|
|
|
17
17
|
],
|
|
18
18
|
"bugs": "https://github.com/facebook/react-native/issues",
|
|
19
19
|
"engines": {
|
|
20
|
-
"node": ">=
|
|
20
|
+
"node": ">= 20.19.4"
|
|
21
21
|
},
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"react-native-strict-api": "./types_generated/index.d.ts",
|
|
25
|
+
"types": "./index.d.ts",
|
|
26
|
+
"default": "./index.js"
|
|
27
|
+
},
|
|
28
|
+
"./*": {
|
|
29
|
+
"types": null,
|
|
30
|
+
"default": "./*.js"
|
|
31
|
+
},
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"index.js",
|
|
36
|
+
"index.d.ts",
|
|
37
|
+
"Lists",
|
|
38
|
+
"README.md",
|
|
39
|
+
"types_generated",
|
|
40
|
+
"Utilities",
|
|
41
|
+
"!**/__docs__/**",
|
|
42
|
+
"!**/__fixtures__/**",
|
|
43
|
+
"!**/__mocks__/**",
|
|
44
|
+
"!**/__tests__/**"
|
|
45
|
+
],
|
|
22
46
|
"dependencies": {
|
|
23
47
|
"invariant": "^2.2.4",
|
|
24
48
|
"nullthrows": "^1.1.1"
|
|
25
49
|
},
|
|
26
50
|
"devDependencies": {
|
|
27
|
-
"react-test-renderer": "19.
|
|
51
|
+
"react-test-renderer": "19.1.4"
|
|
28
52
|
},
|
|
29
53
|
"peerDependencies": {
|
|
30
|
-
"@types/react": "^19.
|
|
54
|
+
"@types/react": "^19.1.4",
|
|
31
55
|
"react": "*",
|
|
32
56
|
"react-native": "*"
|
|
33
57
|
},
|
package/CHANGELOG.json
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@react-native-mac/virtualized-lists",
|
|
3
|
-
"entries": [
|
|
4
|
-
{
|
|
5
|
-
"date": "Wed, 06 Sep 2023 19:59:04 GMT",
|
|
6
|
-
"tag": "@react-native-mac/virtualized-lists_v0.72.1",
|
|
7
|
-
"version": "0.72.1",
|
|
8
|
-
"comments": {
|
|
9
|
-
"patch": [
|
|
10
|
-
{
|
|
11
|
-
"author": "adgleitm@microsoft.com",
|
|
12
|
-
"package": "@react-native-mac/virtualized-lists",
|
|
13
|
-
"commit": "fea8f9a9859f8e2e43ac313ff3c8975b6e82b8c4",
|
|
14
|
-
"comment": "Bring in 0.72-stable changes to virtualized-lists"
|
|
15
|
-
}
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Change Log - @react-native-macos/virtualized-lists
|
|
2
|
-
|
|
3
|
-
This log was last generated on Wed, 06 Sep 2023 19:59:04 GMT and should not be manually modified.
|
|
4
|
-
|
|
5
|
-
<!-- Start content -->
|
|
6
|
-
|
|
7
|
-
## 0.72.1
|
|
8
|
-
|
|
9
|
-
Wed, 06 Sep 2023 19:59:04 GMT
|
|
10
|
-
|
|
11
|
-
### Patches
|
|
12
|
-
|
|
13
|
-
- Bring in 0.72-stable changes to virtualized-lists (adgleitm@microsoft.com)
|