Skip to content

Commit a6107eb

Browse files
committed
Extract children if in fragment to ensure type check is valid
1 parent 6bf236e commit a6107eb

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

packages/core/src/components/SectionList/SectionList.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react";
22
import { FlashListProps, FlashList } from "@shopify/flash-list";
33
import { FlatListProps, FlatList } from "react-native";
44
import SectionHeader, { DefaultSectionHeader } from "./SectionHeader";
5+
import { extractIfNestedInFragment } from "../../utilities";
56

67
type ListComponentType = "FlatList" | "FlashList";
78

@@ -88,9 +89,10 @@ const SectionList = <T extends { [key: string]: any }>({
8889
}
8990

9091
const props = element.props || {};
91-
const children = React.Children.toArray(props.children).map(
92-
(child) => child as React.ReactElement
92+
const children = React.Children.toArray(props.children).map((child) =>
93+
extractIfNestedInFragment(child as React.ReactElement)
9394
);
95+
9496
if (element.type === SectionHeader) {
9597
return element;
9698
} else {

packages/core/src/components/SwipeableItem/SwipeableItem.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
extractBorderAndMarginStyles,
1313
extractEffectStyles,
1414
extractFlexItemStyles,
15+
extractIfNestedInFragment,
1516
extractPositionStyles,
1617
extractSizeStyles,
1718
extractStyles,
@@ -74,7 +75,7 @@ type Props = SwipeableItemProps & RightSwipeProps & LeftSwipeProps;
7475
const SwipeableItem: React.FC<React.PropsWithChildren<Props>> = ({
7576
theme,
7677
style,
77-
children,
78+
children: childrenProp,
7879
Icon,
7980
closeOnPress,
8081
leftOpenValue,
@@ -124,9 +125,18 @@ const SwipeableItem: React.FC<React.PropsWithChildren<Props>> = ({
124125
const [componentWidth, setComponentWidth] = React.useState<number | null>(
125126
null
126127
);
128+
129+
const children: React.ReactNode[] = React.useMemo(
130+
() =>
131+
React.Children.toArray(childrenProp).map((child) =>
132+
extractIfNestedInFragment(child as React.ReactElement)
133+
),
134+
[childrenProp]
135+
);
136+
127137
const leftSwipeButtons = React.useMemo(
128138
() =>
129-
React.Children.toArray(children).filter(
139+
children.filter(
130140
(child) =>
131141
React.isValidElement(child) &&
132142
child.type === SwipeableItemButton &&
@@ -137,7 +147,7 @@ const SwipeableItem: React.FC<React.PropsWithChildren<Props>> = ({
137147

138148
const rightSwipeButtons = React.useMemo(
139149
() =>
140-
React.Children.toArray(children).filter(
150+
children.filter(
141151
(child) =>
142152
React.isValidElement(child) &&
143153
child.type === SwipeableItemButton &&

packages/core/src/components/TabView/TabView.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import TabViewItem from "./TabViewItem";
1212
import type { IconSlot } from "../../interfaces/Icon";
1313
import { withTheme } from "../../theming";
1414
import type { Theme } from "../../styles/DefaultTheme";
15-
import { extractStyles } from "../../utilities";
15+
import { extractIfNestedInFragment, extractStyles } from "../../utilities";
1616

1717
type SceneProps = SceneRendererProps & {
1818
route: Route;
@@ -54,20 +54,28 @@ const TabViewComponent: React.FC<React.PropsWithChildren<TabViewProps>> = ({
5454
tabsBackgroundColor,
5555
style,
5656
theme,
57-
children,
57+
children: childrenProp,
5858
}) => {
5959
const [index, setIndex] = React.useState(0);
6060
const [routes, setRoutes] = React.useState<Route[]>([]);
6161
const [tabScenes, setTabScenes] = React.useState<{ [key: string]: any }>({});
6262

6363
const { textStyles, viewStyles } = extractStyles(style);
6464

65+
const children: React.ReactNode[] = React.useMemo(
66+
() =>
67+
React.Children.toArray(childrenProp).map((child) =>
68+
extractIfNestedInFragment(child as React.ReactElement)
69+
),
70+
[childrenProp]
71+
);
72+
6573
//Populate routes and scenes based on children
6674
React.useEffect(() => {
6775
const newRoutes: Route[] = [];
6876
const scenes: { [key: string]: React.ReactElement } = {};
6977

70-
React.Children.toArray(children)
78+
children
7179
.filter(
7280
(child) => React.isValidElement(child) && child.type === TabViewItem
7381
)

packages/core/src/utilities.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from "react";
12
import { StyleSheet, StyleProp, TextStyle } from "react-native";
23
import { isString, isNumber, pick, pickBy, identity } from "lodash";
34

@@ -228,3 +229,19 @@ export function getValueForRadioButton(value: string | number) {
228229
throw new Error(`Invalid value: ${value}`);
229230
}
230231
}
232+
233+
export function extractIfNestedInFragment(
234+
component: React.ReactElement
235+
): React.ReactElement {
236+
if (component.type === React.Fragment) {
237+
const children = React.Children.toArray(
238+
(component.props as any)?.children
239+
) as React.ReactElement[];
240+
241+
if (children.length === 1) {
242+
return children[0];
243+
}
244+
}
245+
246+
return component;
247+
}

0 commit comments

Comments
 (0)