Skip to content

Commit 46c12e3

Browse files
AlecColasPierre Poupin
authored andcommitted
refactor(ItemWithIndex): remove ItemWithIndex type (#129)
* feat(virtualizedList): pass index in props of itemContainerWithAnimatedStyle * feat(virtualizedListWithNodes): pass index in props of itemWrapperWithVirtualParentContext * feat(virtualizedListWithScroll): pass index as props of itemWrapperWithScrollContext * feat(virtualizedGrid): pass index in renderHeader, GridRow then ItemWrapper * refactor(virtualizedGrid): stop using ItemWithIndex type * refactor(virtualizedList): stop using ItemWithIndex type in layers of list * refactor(virtualizedList): delete ItemWithIndex type * refactor(SNvirtualizedList): stop indexing data in first layer * refactor(Lists): delete addIndex helper * fix(virtualizedGrid): fix index of row by taking header into account
1 parent 2c4b579 commit 46c12e3

8 files changed

Lines changed: 66 additions & 70 deletions

File tree

packages/lib/src/spatial-navigation/components/virtualizedGrid/SpatialNavigationVirtualizedGrid.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import React, { ReactNode, useCallback, useEffect, useMemo } from 'react';
22
import { View, ViewStyle, StyleSheet } from 'react-native';
33
import range from 'lodash/range';
44

5-
import { ItemWithIndex } from '../virtualizedList/VirtualizedList';
65
import { SpatialNavigationVirtualizedList } from '../virtualizedList/SpatialNavigationVirtualizedList';
76
import {
87
PointerScrollProps,
@@ -13,7 +12,7 @@ import { ParentIdContext, useParentId } from '../../context/ParentIdContext';
1312
import { typedMemo } from '../../helpers/TypedMemo';
1413
import { convertToGrid } from './helpers/convertToGrid';
1514

16-
type SpatialNavigationVirtualizedGridProps<T extends ItemWithIndex> = Pick<
15+
type SpatialNavigationVirtualizedGridProps<T> = Pick<
1716
SpatialNavigationVirtualizedListWithScrollProps<T>,
1817
| 'data'
1918
| 'renderItem'
@@ -40,9 +39,8 @@ type SpatialNavigationVirtualizedGridProps<T extends ItemWithIndex> = Pick<
4039
rowContainerStyle?: ViewStyle;
4140
};
4241

43-
export type GridRowType<T extends ItemWithIndex> = {
42+
export type GridRowType<T> = {
4443
items: T[];
45-
index: number;
4644
};
4745

4846
const useRegisterGridRowVirtualNodes = ({ numberOfColumns }: { numberOfColumns: number }) => {
@@ -84,45 +82,51 @@ const useRegisterGridRowVirtualNodes = ({ numberOfColumns }: { numberOfColumns:
8482
};
8583

8684
const ItemWrapperWithVirtualParentContext = typedMemo(
87-
<T extends ItemWithIndex>({
85+
<T,>({
8886
virtualParentID,
8987
item,
88+
index,
9089
renderItem,
9190
}: {
9291
virtualParentID: string;
9392
item: T;
93+
index: number;
9494
renderItem: (args: { item: T; index: number }) => JSX.Element;
9595
}) => (
9696
<ParentIdContext.Provider value={virtualParentID}>
97-
{renderItem({ item, index: item.index })}
97+
{renderItem({ item, index })}
9898
</ParentIdContext.Provider>
9999
),
100100
);
101101
ItemWrapperWithVirtualParentContext.displayName = 'ItemWrapperWithVirtualParentContext';
102102

103-
const GridRow = <T extends ItemWithIndex>({
103+
const GridRow = <T,>({
104104
renderItem,
105105
numberOfColumns,
106106
row,
107+
rowIndex,
107108
rowContainerStyle,
108109
}: {
109110
renderItem: (args: { item: T; index: number }) => JSX.Element;
110111
numberOfColumns: number;
111112
row: GridRowType<T>;
113+
rowIndex: number;
112114
rowContainerStyle?: ViewStyle;
113115
}) => {
114116
const { getNthVirtualNodeID } = useRegisterGridRowVirtualNodes({ numberOfColumns });
115117

116118
return (
117119
<HorizontalContainer style={rowContainerStyle}>
118-
{row.items.map((item, index) => {
120+
{row.items.map((item, columnIndex) => {
121+
const itemIndex = rowIndex * numberOfColumns + columnIndex;
119122
return (
120123
/* This view is important to reset flex direction to vertical */
121-
<View key={index}>
124+
<View key={columnIndex}>
122125
<ItemWrapperWithVirtualParentContext
123-
virtualParentID={getNthVirtualNodeID(index)}
126+
virtualParentID={getNthVirtualNodeID(columnIndex)}
124127
renderItem={renderItem}
125128
item={item}
129+
index={itemIndex}
126130
/>
127131
</View>
128132
);
@@ -181,7 +185,7 @@ const GridRow = <T extends ItemWithIndex>({
181185
*/
182186

183187
export const SpatialNavigationVirtualizedGrid = typedMemo(
184-
<T extends ItemWithIndex>({
188+
<T,>({
185189
renderItem,
186190
data,
187191
numberOfColumns,
@@ -221,24 +225,27 @@ export const SpatialNavigationVirtualizedGrid = typedMemo(
221225
const itemSize = hasHeader ? itemSizeAsAFunction : itemHeight;
222226

223227
const renderRow = useCallback(
224-
({ item: row }: { item: GridRowType<T> }) => (
228+
({ item: row, index }: { item: GridRowType<T>; index: number }) => (
225229
<GridRow
226230
renderItem={renderItem}
227231
numberOfColumns={numberOfColumns}
228232
row={row}
233+
rowIndex={index}
229234
rowContainerStyle={rowContainerStyle}
230235
/>
231236
),
232237
[renderItem, numberOfColumns, rowContainerStyle],
233238
);
234239
const renderHeaderThenRows = useCallback(
235-
({ item }: { item: GridRowType<T> | JSX.Element }) => {
240+
({ item, index }: { item: GridRowType<T> | JSX.Element; index: number }) => {
236241
if (React.isValidElement(item)) {
237242
return item;
238243
}
239-
return renderRow({ item: item as GridRowType<T> });
244+
//We do this to have index taking into account the header
245+
const computedIndex = hasHeader ? index - 1 : index;
246+
return renderRow({ item: item as GridRowType<T>, index: computedIndex });
240247
},
241-
[renderRow],
248+
[hasHeader, renderRow],
242249
);
243250

244251
return (

packages/lib/src/spatial-navigation/components/virtualizedGrid/helpers/convertToGrid.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import chunk from 'lodash/chunk';
22
import { GridRowType } from '../SpatialNavigationVirtualizedGrid';
3-
import { ItemWithIndex } from '../../virtualizedList/VirtualizedList';
3+
44
import { NodeOrientation } from '../../../types/orientation';
55

6-
export const convertToGrid = <T extends ItemWithIndex>(
6+
export const convertToGrid = <T>(
77
data: T[],
88
numberOfColumns: number,
99
header?: JSX.Element,

packages/lib/src/spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedList.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import { ForwardedRef, useMemo } from 'react';
1+
import { ForwardedRef } from 'react';
22
import { SpatialNavigationNode } from '../Node';
33
import {
44
PointerScrollProps,
55
SpatialNavigationVirtualizedListWithScroll,
66
SpatialNavigationVirtualizedListWithScrollProps,
77
} from './SpatialNavigationVirtualizedListWithScroll';
88
import { typedMemo } from '../../helpers/TypedMemo';
9-
import { addIndex } from './helpers/addIndex';
10-
import { ItemWithIndex } from './VirtualizedList';
9+
1110
import { typedForwardRef } from '../../helpers/TypedForwardRef';
1211
import { SpatialNavigationVirtualizedListRef } from '../../types/SpatialNavigationVirtualizedListRef';
1312

@@ -21,18 +20,12 @@ export const SpatialNavigationVirtualizedList = typedMemo(
2120
props: SpatialNavigationVirtualizedListWithScrollProps<T> & PointerScrollProps,
2221
ref: ForwardedRef<SpatialNavigationVirtualizedListRef>,
2322
) => {
24-
const indexedData = useMemo(() => addIndex(props.data), [props.data]);
25-
2623
return (
2724
<SpatialNavigationNode
2825
alignInGrid={props.isGrid ?? false}
2926
orientation={props.orientation ?? 'horizontal'}
3027
>
31-
<SpatialNavigationVirtualizedListWithScroll<T & ItemWithIndex>
32-
{...props}
33-
data={indexedData}
34-
ref={ref}
35-
/>
28+
<SpatialNavigationVirtualizedListWithScroll<T> {...props} ref={ref} />
3629
</SpatialNavigationNode>
3730
);
3831
},

packages/lib/src/spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedListWithScroll.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ForwardedRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react';
2-
import { VirtualizedListProps, ItemWithIndex } from './VirtualizedList';
2+
import { VirtualizedListProps } from './VirtualizedList';
33

44
import {
55
SpatialNavigationVirtualizedListWithVirtualNodes,
@@ -20,30 +20,32 @@ import { typedForwardRef } from '../../helpers/TypedForwardRef';
2020
import { SpatialNavigationVirtualizedListRef } from '../../types/SpatialNavigationVirtualizedListRef';
2121

2222
const ItemWrapperWithScrollContext = typedMemo(
23-
<T extends ItemWithIndex>({
23+
<T,>({
2424
setCurrentlyFocusedItemIndex,
2525
item,
26+
index,
2627
renderItem,
2728
}: {
2829
setCurrentlyFocusedItemIndex: (i: number) => void;
2930
item: T;
31+
index: number;
3032
renderItem: VirtualizedListProps<T>['renderItem'];
3133
}) => {
3234
const { scrollToNodeIfNeeded: makeParentsScrollToNodeIfNeeded } =
3335
useSpatialNavigatorParentScroll();
3436

3537
const scrollToItem: ScrollToNodeCallback = useCallback(
3638
(newlyFocusedElementRef, additionalOffset) => {
37-
setCurrentlyFocusedItemIndex(item.index);
39+
setCurrentlyFocusedItemIndex(index);
3840
// We need to propagate the scroll event for parents if we have nested ScrollViews/VirtualizedLists.
3941
makeParentsScrollToNodeIfNeeded(newlyFocusedElementRef, additionalOffset);
4042
},
41-
[makeParentsScrollToNodeIfNeeded, setCurrentlyFocusedItemIndex, item.index],
43+
[makeParentsScrollToNodeIfNeeded, setCurrentlyFocusedItemIndex, index],
4244
);
4345

4446
return (
4547
<SpatialNavigatorParentScrollContext.Provider value={scrollToItem}>
46-
{renderItem({ item, index: item.index })}
48+
{renderItem({ item, index })}
4749
</SpatialNavigatorParentScrollContext.Provider>
4850
);
4951
},
@@ -63,14 +65,14 @@ export type PointerScrollProps = {
6365
scrollInterval?: number;
6466
};
6567

66-
const useRemotePointerVirtualizedListScrollProps = ({
68+
const useRemotePointerVirtualizedListScrollProps = <T,>({
6769
setCurrentlyFocusedItemIndex,
6870
scrollInterval,
6971
data,
7072
}: {
7173
setCurrentlyFocusedItemIndex: React.Dispatch<React.SetStateAction<number>>;
7274
scrollInterval: number;
73-
data: ItemWithIndex[];
75+
data: T[];
7476
}) => {
7577
const {
7678
deviceType,
@@ -166,7 +168,7 @@ const useRemotePointerVirtualizedListScrollProps = ({
166168
*/
167169
export const SpatialNavigationVirtualizedListWithScroll = typedMemo(
168170
typedForwardRef(
169-
<T extends ItemWithIndex>(
171+
<T,>(
170172
props: SpatialNavigationVirtualizedListWithScrollProps<T> & PointerScrollProps,
171173
ref: ForwardedRef<SpatialNavigationVirtualizedListRef>,
172174
) => {
@@ -210,11 +212,12 @@ export const SpatialNavigationVirtualizedListWithScroll = typedMemo(
210212
);
211213

212214
const renderWrappedItem: typeof props.renderItem = useCallback(
213-
({ item }) => (
215+
({ item, index }) => (
214216
<ItemWrapperWithScrollContext
215217
setCurrentlyFocusedItemIndex={setCurrentlyFocusedItemIndexCallback}
216218
renderItem={renderItem}
217219
item={item}
220+
index={index}
218221
/>
219222
),
220223
[setCurrentlyFocusedItemIndexCallback, renderItem],

packages/lib/src/spatial-navigation/components/virtualizedList/SpatialNavigationVirtualizedListWithVirtualNodes.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import uniqueId from 'lodash.uniqueid';
22
import { useCallback, useEffect, useImperativeHandle, useRef } from 'react';
3-
import { VirtualizedListProps, ItemWithIndex } from './VirtualizedList';
3+
import { VirtualizedListProps } from './VirtualizedList';
44
import { useSpatialNavigator } from '../../context/SpatialNavigatorContext';
55
import { ParentIdContext, useParentId } from '../../context/ParentIdContext';
66
import { updateVirtualNodeRegistration } from './helpers/updateVirtualNodeRegistration';
@@ -73,7 +73,7 @@ const useUpdateRegistration = <T,>({
7373
}, [allItems]);
7474
};
7575

76-
const useRegisterVirtualNodes = <T extends ItemWithIndex>({
76+
const useRegisterVirtualNodes = <T,>({
7777
allItems,
7878
orientation,
7979
isGrid,
@@ -118,17 +118,19 @@ const useRegisterVirtualNodes = <T extends ItemWithIndex>({
118118
};
119119

120120
const ItemWrapperWithVirtualParentContext = typedMemo(
121-
<T extends ItemWithIndex>({
121+
<T,>({
122122
virtualParentID,
123+
index,
123124
item,
124125
renderItem,
125126
}: {
126127
virtualParentID: string;
127128
item: T;
129+
index: number;
128130
renderItem: VirtualizedListProps<T>['renderItem'];
129131
}) => (
130132
<ParentIdContext.Provider value={virtualParentID}>
131-
{renderItem({ item, index: item.index })}
133+
{renderItem({ item, index: index })}
132134
</ParentIdContext.Provider>
133135
),
134136
);
@@ -170,7 +172,7 @@ export type SpatialNavigationVirtualizedListWithVirtualNodesRef = {
170172
* Framed letters correspond to rendered components.
171173
*/
172174
export const SpatialNavigationVirtualizedListWithVirtualNodes = typedMemo(
173-
<T extends ItemWithIndex>(
175+
<T,>(
174176
props: SpatialNavigationVirtualizedListWithVirtualNodesProps<T> & {
175177
getNodeIdRef: React.Ref<SpatialNavigationVirtualizedListWithVirtualNodesRef>;
176178
},
@@ -191,11 +193,12 @@ export const SpatialNavigationVirtualizedListWithVirtualNodes = typedMemo(
191193

192194
const { renderItem } = props;
193195
const renderWrappedItem: typeof props.renderItem = useCallback(
194-
({ item }) => (
196+
({ item, index }) => (
195197
<ItemWrapperWithVirtualParentContext
196-
virtualParentID={getNthVirtualNodeID(item.index)}
198+
virtualParentID={getNthVirtualNodeID(index)}
197199
renderItem={renderItem}
198200
item={item}
201+
index={index}
199202
/>
200203
),
201204
[getNthVirtualNodeID, renderItem],

0 commit comments

Comments
 (0)