-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Expand file tree
/
Copy pathTabsIconList.tsx
More file actions
117 lines (105 loc) · 3.36 KB
/
TabsIconList.tsx
File metadata and controls
117 lines (105 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import React, { useImperativeHandle, forwardRef, useMemo } from 'react';
import { Box } from '@metamask/design-system-react-native';
import { GestureDetector } from 'react-native-gesture-handler';
import TabsIconBar from '../TabsIconBar/TabsIconBar';
import type { IconName } from '../../../components/Icons/Icon/Icon.types';
import {
TabsIconListProps,
TabsIconListRef,
TabsIconItem,
} from './TabsIconList.types';
import { useTabsList } from '../hooks/useTabsList';
const TabsIconList = forwardRef<TabsIconListRef, TabsIconListProps>(
(
{
children,
initialActiveIndex = 0,
onChangeTab,
testID,
tabsBarProps,
tabsListContentTwClassName,
...boxProps
},
ref,
) => {
const tabs: TabsIconItem[] = useMemo(
() =>
React.Children.toArray(children)
.filter((child) => React.isValidElement(child))
.map((child, index) => {
const props = (child as React.ReactElement).props as {
tabLabel?: string;
tabIcon?: IconName;
isDisabled?: boolean;
testID?: string;
keepMounted?: boolean;
};
const tabLabel = props.tabLabel || `Tab ${index + 1}`;
const isDisabled = props.isDisabled || false;
return {
key:
(child as React.ReactElement).key?.toString() || `tab-${index}`,
label: tabLabel,
iconName: props.tabIcon as IconName,
content: child,
isDisabled,
isLoaded: false,
testID: props.testID,
keepMounted: props.keepMounted ?? true,
};
}),
[children],
);
const { activeIndex, loadedTabs, handleTabPress, swipeGesture } =
useTabsList({ tabs, initialActiveIndex, onChangeTab });
useImperativeHandle(
ref,
() => ({
goToTabIndex: (tabIndex: number) => {
handleTabPress(tabIndex);
},
getCurrentIndex: () => activeIndex,
}),
[activeIndex, handleTabPress],
);
const tabBarPropsComputed = useMemo(
() => ({
tabs,
activeIndex,
onTabPress: handleTabPress,
testID: testID ? `${testID}-bar` : undefined,
...tabsBarProps,
}),
[tabs, activeIndex, handleTabPress, testID, tabsBarProps],
);
return (
<Box twClassName="flex-1" testID={testID} {...boxProps}>
<TabsIconBar {...tabBarPropsComputed} />
<GestureDetector gesture={swipeGesture}>
<Box
twClassName={`flex-1 ${tabsListContentTwClassName || ''}`}
testID={testID ? `${testID}-content` : undefined}
>
{tabs.map((tab, index) => {
const isActive = index === activeIndex;
const isLoaded = loadedTabs.has(index);
if (!isLoaded) return null;
if (!isActive && !tab.keepMounted) return null;
return (
<Box
key={tab.key}
twClassName={isActive ? 'flex-1' : 'hidden'}
pointerEvents={!isActive ? 'none' : 'auto'}
>
{tab.content}
</Box>
);
})}
</Box>
</GestureDetector>
</Box>
);
},
);
TabsIconList.displayName = 'TabsIconList';
export default TabsIconList;