Skip to content

Commit 35f6ed1

Browse files
huntiefacebook-github-bot
authored andcommitted
Update SectionList to accept React elements for separators (#53599)
Summary: Pull Request resolved: #53599 Runtime and types fix for the `ItemSeparatorComponent` prop on `virtualized-list` components (`FlatList`, `SectionList`, `VirtualizedList`). - Docs source, where this prop (adjacent to other `*Component` props) is documented as accepting elements: https://reactnative.dev/docs/virtualizedlist#itemseparatorcomponent. - Existing runtime behaviour matching this definition: https://github.com/facebook/react-native/blob/8d33e1c205b12fe27f4319e6566bb0c088197810/packages/virtualized-lists/Lists/VirtualizedListCellRenderer.js#L197-L203 **Changes** - Update Flow, manual TS type defs. - Align runtime behaviour in `VirtualizedSectionList` to add matching `React.isValidElement()` behaviour. Resolves #53531. Changelog: [General][Fixed] - The `ItemSeparatorComponent` prop on list components now accepts a React element as well as a component function. Reviewed By: cortinico Differential Revision: D81675423 fbshipit-source-id: 3eed93b1bea89554988d6e20fa61b72e17be55df
1 parent f59a6f9 commit 35f6ed1

File tree

6 files changed

+58
-35
lines changed

6 files changed

+58
-35
lines changed

packages/react-native/Libraries/Lists/SectionList.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ export interface SectionBase<ItemT, SectionT = DefaultSectionT> {
3535

3636
renderItem?: SectionListRenderItem<ItemT, SectionT> | undefined;
3737

38-
ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
38+
ItemSeparatorComponent?:
39+
| React.ComponentType<any>
40+
| React.ReactElement
41+
| null
42+
| undefined;
3943

4044
keyExtractor?: ((item: ItemT, index: number) => string) | undefined;
4145
}

packages/react-native/ReactNativeApi.d.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<0a0286ba0bc29af2abd2e8fd836077fb>>
7+
* @generated SignedSource<<4ccde3daef50fa7522f10bc7146c0cc6>>
88
*
99
* This file was generated by scripts/js-api/build-types/index.js.
1010
*/
@@ -3498,7 +3498,7 @@ declare type OptionalVirtualizedListProps = {
34983498
initialNumToRender?: number
34993499
initialScrollIndex?: number
35003500
inverted?: boolean
3501-
ItemSeparatorComponent?: React.ComponentType<any>
3501+
ItemSeparatorComponent?: React.ComponentType<any> | React.JSX.Element
35023502
keyExtractor?: (item: Item, index: number) => string
35033503
ListEmptyComponent?: React.ComponentType<any> | React.JSX.Element
35043504
ListFooterComponent?: React.ComponentType<any> | React.JSX.Element
@@ -4578,7 +4578,7 @@ declare type SectionBase<
45784578
SectionT = DefaultVirtualizedSectionT,
45794579
> = {
45804580
data: ReadonlyArray<SectionItemT>
4581-
ItemSeparatorComponent?: React.ComponentType<any>
4581+
ItemSeparatorComponent?: React.ComponentType<any> | React.JSX.Element
45824582
key?: string
45834583
renderItem?: (info: {
45844584
index: number
@@ -6013,8 +6013,8 @@ export {
60136013
EventSubscription, // b8d084aa
60146014
ExtendedExceptionData, // 5a6ccf5a
60156015
FilterFunction, // bf24c0e3
6016-
FlatList, // 4f1b407e
6017-
FlatListProps, // b225fb7a
6016+
FlatList, // cbb48cbe
6017+
FlatListProps, // 451be810
60186018
FocusEvent, // 529b43eb
60196019
FontVariant, // 7c7558bb
60206020
GestureResponderEvent, // b466f6d6
@@ -6151,12 +6151,12 @@ export {
61516151
ScrollViewPropsAndroid, // 84e2134b
61526152
ScrollViewPropsIOS, // d83c9733
61536153
ScrollViewScrollToOptions, // 3313411e
6154-
SectionBase, // 0ccaedac
6155-
SectionList, // a1a4786b
6156-
SectionListData, // 1c80bb2e
6157-
SectionListProps, // 7fb5371e
6158-
SectionListRenderItem, // cffebb53
6159-
SectionListRenderItemInfo, // 946c2128
6154+
SectionBase, // b376bddc
6155+
SectionList, // ff1193b2
6156+
SectionListData, // 119baf83
6157+
SectionListProps, // c9ac8e07
6158+
SectionListRenderItem, // 1fad0435
6159+
SectionListRenderItemInfo, // 745e1992
61606160
Separators, // 6a45f7e3
61616161
Settings, // 4282b0da
61626162
Share, // e4591b32
@@ -6219,9 +6219,9 @@ export {
62196219
ViewStyle, // c2db0e6e
62206220
VirtualViewMode, // 85a69ef6
62216221
VirtualizedList, // 4d513939
6222-
VirtualizedListProps, // be716140
6222+
VirtualizedListProps, // a99d36db
62236223
VirtualizedSectionList, // 446ba0df
6224-
VirtualizedSectionListProps, // a6899dfb
6224+
VirtualizedSectionListProps, // 6cd4b378
62256225
WrapperComponentProvider, // 9cf3844c
62266226
codegenNativeCommands, // e16d62f7
62276227
codegenNativeComponent, // ed4c8103

packages/virtualized-lists/Lists/VirtualizedList.d.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ export interface VirtualizedListWithoutRenderItemProps<ItemT>
152152
/**
153153
* Rendered in between each item, but not at the top or bottom
154154
*/
155-
ItemSeparatorComponent?: React.ComponentType<any> | null | undefined;
155+
ItemSeparatorComponent?:
156+
| React.ComponentType<any>
157+
| React.ReactElement
158+
| null
159+
| undefined;
156160

157161
/**
158162
* Rendered when the list is empty. Can be a React Component Class, a render function, or

packages/virtualized-lists/Lists/VirtualizedListCellRenderer.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ import {StyleSheet, View} from 'react-native';
2424

2525
export type Props<ItemT> = {
2626
CellRendererComponent?: ?React.ComponentType<CellRendererProps<ItemT>>,
27-
ItemSeparatorComponent: ?React.ComponentType<
28-
any | {highlighted: boolean, leadingItem: ?ItemT},
29-
>,
27+
ItemSeparatorComponent?: ?(
28+
| React.ComponentType<any | {highlighted: boolean, leadingItem: ?ItemT}>
29+
| React.MixedElement
30+
),
3031
ListItemComponent?: ?(React.ComponentType<any> | React.MixedElement),
3132
cellKey: string,
3233
horizontal: ?boolean,
@@ -199,6 +200,8 @@ export default class CellRenderer<ItemT> extends React.PureComponent<
199200
ItemSeparatorComponent
200201
: // $FlowFixMe[incompatible-type]
201202
ItemSeparatorComponent && (
203+
// $FlowFixMe[incompatible-type]
204+
// $FlowFixMe[not-a-component]
202205
<ItemSeparatorComponent {...this.state.separatorProps} />
203206
);
204207
const cellStyle = inversionStyle

packages/virtualized-lists/Lists/VirtualizedListProps.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ type OptionalVirtualizedListProps = {
129129
* which will update the `highlighted` prop, but you can also add custom props with
130130
* `separators.updateProps`.
131131
*/
132-
ItemSeparatorComponent?: ?React.ComponentType<any>,
132+
ItemSeparatorComponent?: ?(React.ComponentType<any> | React.MixedElement),
133133
/**
134134
* Takes an item from `data` and renders it into the list. Example usage:
135135
*

packages/virtualized-lists/Lists/VirtualizedSectionList.js

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export type SectionBase<SectionItemT, SectionT = DefaultVirtualizedSectionT> = {
5050
},
5151
...
5252
}) => null | React.MixedElement,
53-
ItemSeparatorComponent?: ?React.ComponentType<any>,
53+
ItemSeparatorComponent?: ?(React.ComponentType<any> | React.MixedElement),
5454
keyExtractor?: (item: ?SectionItemT, index?: ?number) => string,
5555
...
5656
};
@@ -450,7 +450,7 @@ class VirtualizedSectionList<
450450
index: number,
451451
info?: ?Object,
452452
listItemCount: number,
453-
): ?React.ComponentType<any> {
453+
): ?(React.ComponentType<any> | React.MixedElement) {
454454
info = info || this._subExtractor(index);
455455
if (!info) {
456456
return null;
@@ -488,8 +488,8 @@ type ItemWithSeparatorCommonProps<ItemT> = $ReadOnly<{
488488

489489
type ItemWithSeparatorProps<ItemT> = $ReadOnly<{
490490
...ItemWithSeparatorCommonProps<ItemT>,
491-
LeadingSeparatorComponent: ?React.ComponentType<any>,
492-
SeparatorComponent: ?React.ComponentType<any>,
491+
LeadingSeparatorComponent: ?(React.ComponentType<any> | React.MixedElement),
492+
SeparatorComponent: ?(React.ComponentType<any> | React.MixedElement),
493493
cellKey: string,
494494
index: number,
495495
item: ItemT,
@@ -604,18 +604,30 @@ function ItemWithSeparator<ItemT>(
604604
section,
605605
separators,
606606
});
607-
const leadingSeparator = LeadingSeparatorComponent != null && (
608-
<LeadingSeparatorComponent
609-
highlighted={leadingSeparatorHiglighted}
610-
{...leadingSeparatorProps}
611-
/>
612-
);
613-
const separator = SeparatorComponent != null && (
614-
<SeparatorComponent
615-
highlighted={separatorHighlighted}
616-
{...separatorProps}
617-
/>
618-
);
607+
const leadingSeparator =
608+
LeadingSeparatorComponent != null &&
609+
((React.isValidElement(LeadingSeparatorComponent) ? (
610+
LeadingSeparatorComponent
611+
) : (
612+
// $FlowFixMe[not-a-component]
613+
// $FlowFixMe[incompatible-type]
614+
<LeadingSeparatorComponent
615+
highlighted={leadingSeparatorHiglighted}
616+
{...leadingSeparatorProps}
617+
/>
618+
)): any);
619+
const separator =
620+
SeparatorComponent != null &&
621+
((React.isValidElement(SeparatorComponent) ? (
622+
SeparatorComponent
623+
) : (
624+
// $FlowFixMe[not-a-component]
625+
// $FlowFixMe[incompatible-type]
626+
<SeparatorComponent
627+
highlighted={separatorHighlighted}
628+
{...separatorProps}
629+
/>
630+
)): any);
619631
const RenderSeparator = leadingSeparator || separator;
620632
const firstSeparator = inverted === false ? leadingSeparator : separator;
621633
const secondSeparator = inverted === false ? separator : leadingSeparator;

0 commit comments

Comments
 (0)