Skip to content

Commit 5d59edf

Browse files
authored
Merge pull request #4 from okwasniewski/feat/chat-example
feat: add Chat example
2 parents 207a077 + a9707d0 commit 5d59edf

15 files changed

+773
-168
lines changed

example/ios/Podfile.lock

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,6 +1230,8 @@ PODS:
12301230
- ReactCommon/turbomodule/bridging
12311231
- ReactCommon/turbomodule/core
12321232
- Yoga
1233+
- react-native-safe-area-context (4.11.0):
1234+
- React-Core
12331235
- React-nativeconfig (0.75.3)
12341236
- React-NativeModulesApple (0.75.3):
12351237
- glog
@@ -1499,6 +1501,49 @@ PODS:
14991501
- React-Core
15001502
- React-jsi
15011503
- ReactTestApp-Resources (1.0.0-dev)
1504+
- RNGestureHandler (2.20.0):
1505+
- DoubleConversion
1506+
- glog
1507+
- RCT-Folly (= 2024.01.01.00)
1508+
- RCTRequired
1509+
- RCTTypeSafety
1510+
- React-Core
1511+
- React-debug
1512+
- React-Fabric
1513+
- React-featureflags
1514+
- React-graphics
1515+
- React-ImageManager
1516+
- React-jsi
1517+
- React-NativeModulesApple
1518+
- React-RCTFabric
1519+
- React-rendererdebug
1520+
- React-utils
1521+
- ReactCodegen
1522+
- ReactCommon/turbomodule/bridging
1523+
- ReactCommon/turbomodule/core
1524+
- Yoga
1525+
- RNScreens (3.34.0):
1526+
- DoubleConversion
1527+
- glog
1528+
- RCT-Folly (= 2024.01.01.00)
1529+
- RCTRequired
1530+
- RCTTypeSafety
1531+
- React-Core
1532+
- React-debug
1533+
- React-Fabric
1534+
- React-featureflags
1535+
- React-graphics
1536+
- React-ImageManager
1537+
- React-jsi
1538+
- React-NativeModulesApple
1539+
- React-RCTFabric
1540+
- React-RCTImage
1541+
- React-rendererdebug
1542+
- React-utils
1543+
- ReactCodegen
1544+
- ReactCommon/turbomodule/bridging
1545+
- ReactCommon/turbomodule/core
1546+
- Yoga
15021547
- SocketRocket (0.7.0)
15031548
- Yoga (0.0.0)
15041549

@@ -1540,6 +1585,7 @@ DEPENDENCIES:
15401585
- React-Mapbuffer (from `../node_modules/react-native/ReactCommon`)
15411586
- React-microtasksnativemodule (from `../node_modules/react-native/ReactCommon/react/nativemodule/microtasks`)
15421587
- react-native-bottom-tabs (from `../..`)
1588+
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
15431589
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
15441590
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
15451591
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@@ -1568,6 +1614,8 @@ DEPENDENCIES:
15681614
- "ReactNativeHost (from `../node_modules/@rnx-kit/react-native-host`)"
15691615
- ReactTestApp-DevSupport (from `../node_modules/react-native-test-app`)
15701616
- ReactTestApp-Resources (from `..`)
1617+
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
1618+
- RNScreens (from `../node_modules/react-native-screens`)
15711619
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
15721620

15731621
SPEC REPOS:
@@ -1645,6 +1693,8 @@ EXTERNAL SOURCES:
16451693
:path: "../node_modules/react-native/ReactCommon/react/nativemodule/microtasks"
16461694
react-native-bottom-tabs:
16471695
:path: "../.."
1696+
react-native-safe-area-context:
1697+
:path: "../node_modules/react-native-safe-area-context"
16481698
React-nativeconfig:
16491699
:path: "../node_modules/react-native/ReactCommon"
16501700
React-NativeModulesApple:
@@ -1701,6 +1751,10 @@ EXTERNAL SOURCES:
17011751
:path: "../node_modules/react-native-test-app"
17021752
ReactTestApp-Resources:
17031753
:path: ".."
1754+
RNGestureHandler:
1755+
:path: "../node_modules/react-native-gesture-handler"
1756+
RNScreens:
1757+
:path: "../node_modules/react-native-screens"
17041758
Yoga:
17051759
:path: "../node_modules/react-native/ReactCommon/yoga"
17061760

@@ -1740,6 +1794,7 @@ SPEC CHECKSUMS:
17401794
React-Mapbuffer: 714f2fae68edcabfc332b754e9fbaa8cfc68fdd4
17411795
React-microtasksnativemodule: 987cf7e0e0e7129250a48b807e70d3b906c726cf
17421796
react-native-bottom-tabs: 894d1fb8fc4e6d525b2da35e83e00e18c420cdf2
1797+
react-native-safe-area-context: 851c62c48dce80ccaa5637b6aa5991a1bc36eca9
17431798
React-nativeconfig: 4a9543185905fe41014c06776bf126083795aed9
17441799
React-NativeModulesApple: 651670a799672bd54469f2981d91493dda361ddf
17451800
React-perflogger: 3bbb82f18e9ac29a1a6931568e99d6305ef4403b
@@ -1768,9 +1823,11 @@ SPEC CHECKSUMS:
17681823
ReactNativeHost: 99c0ffb175cd69de2ac9a70892cd22dac65ea79d
17691824
ReactTestApp-DevSupport: b7cd76a3aeee6167f5e14d82f09685059152c426
17701825
ReactTestApp-Resources: 7db90c026cccdf40cfa495705ad436ccc4d64154
1826+
RNGestureHandler: 18b9b5d65c77c4744a640f69b7fccdd47ed935c0
1827+
RNScreens: 5288a8dbeedb3c5051aa2d5658c1c553c050b80a
17711828
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
1772-
Yoga: 1354c027ab07c7736f99a3bef16172d6f1b12b47
1829+
Yoga: 4ef80d96a5534f0e01b3055f17d1e19a9fc61b63
17731830

17741831
PODFILE CHECKSUM: 539add55dc6c2e7f9754e288b1ce4fd8583819ae
17751832

1776-
COCOAPODS: 1.14.3
1833+
COCOAPODS: 1.15.2

example/package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,16 @@
1414
},
1515
"dependencies": {
1616
"@callstack/react-native-visionos": "^0.75.0",
17+
"@react-navigation/bottom-tabs": "^6.6.1",
18+
"@react-navigation/native": "^6.1.18",
19+
"@react-navigation/native-stack": "^6.11.0",
20+
"@react-navigation/stack": "^6.4.1",
1721
"color": "^4.2.3",
1822
"react": "18.3.1",
19-
"react-native": "0.75.3"
23+
"react-native": "0.75.3",
24+
"react-native-gesture-handler": "^2.20.0",
25+
"react-native-safe-area-context": "^4.11.0",
26+
"react-native-screens": "^3.34.0"
2027
},
2128
"devDependencies": {
2229
"@babel/core": "^7.20.0",

example/src/App.tsx

Lines changed: 95 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,109 @@
1-
import { StyleSheet } from 'react-native';
2-
import TabView, {
3-
type OnPageSelectedEventData,
4-
type TabViewItems,
5-
} from 'react-native-bottom-tabs';
6-
import { Article } from './Screens/Article';
7-
import { Contacts } from './Screens/Contacts';
8-
import { Albums } from './Screens/Albums';
9-
import { useState } from 'react';
1+
import { enableScreens } from 'react-native-screens';
2+
// run this before any screen render(usually in App.js)
3+
enableScreens();
104

11-
const items: TabViewItems = [
12-
{ key: 'article', title: 'Article', icon: 'document.fill', badge: '!' },
13-
{ key: 'albums', title: 'Albums', icon: 'square.grid.2x2.fill', badge: '5' },
14-
{ key: 'contacts', title: 'Contacts', icon: 'person.fill' },
5+
import * as React from 'react';
6+
import {
7+
StyleSheet,
8+
Text,
9+
ScrollView,
10+
TouchableOpacity,
11+
Button,
12+
Alert,
13+
} from 'react-native';
14+
import { NavigationContainer, useNavigation } from '@react-navigation/native';
15+
import { createStackNavigator } from '@react-navigation/stack';
16+
import { createNativeStackNavigator } from '@react-navigation/native-stack';
17+
import { SafeAreaProvider } from 'react-native-safe-area-context';
18+
import JSBottomTabs from './Examples/JSBottomTabs';
19+
import ThreeTabs from './Examples/ThreeTabs';
20+
import FourTabs from './Examples/FourTabs';
21+
22+
const examples = [
23+
{ component: ThreeTabs, name: 'Three Tabs' },
24+
{ component: FourTabs, name: 'Four Tabs' },
25+
{ component: JSBottomTabs, name: 'JS Bottom Tabs' },
1526
];
1627

17-
export default function App() {
18-
const [selectedPage, setSelectedTab] = useState<string>('contacts');
28+
function App() {
29+
const navigation = useNavigation();
30+
return (
31+
<ScrollView>
32+
{examples.map((example) => (
33+
<TouchableOpacity
34+
key={example.name}
35+
testID={example.name}
36+
style={styles.exampleTouchable}
37+
onPress={() => {
38+
//@ts-ignore
39+
navigation.navigate(example.name);
40+
}}
41+
>
42+
<Text style={styles.exampleText}>{example.name}</Text>
43+
</TouchableOpacity>
44+
))}
45+
</ScrollView>
46+
);
47+
}
1948

20-
const handlePageSelected = ({
21-
nativeEvent: { key },
22-
}: {
23-
nativeEvent: OnPageSelectedEventData;
24-
}) => setSelectedTab(key);
49+
const Stack = createStackNavigator();
2550

26-
const goToAlbums = () => {
27-
setSelectedTab('albums');
28-
};
51+
const NativeStack = createNativeStackNavigator();
2952

53+
export default function Navigation() {
54+
const [mode, setMode] = React.useState<'native' | 'js'>('native');
55+
const NavigationStack = mode === 'js' ? Stack : NativeStack;
3056
return (
31-
<TabView
32-
style={styles.fullWidth}
33-
items={items}
34-
tabViewStyle="sidebarAdaptable"
35-
selectedPage={selectedPage}
36-
onPageSelected={handlePageSelected}
37-
>
38-
<Article onClick={goToAlbums} />
39-
<Albums />
40-
<Contacts />
41-
</TabView>
57+
<SafeAreaProvider>
58+
<NavigationContainer>
59+
<NavigationStack.Navigator initialRouteName="BottomTabs Example">
60+
<NavigationStack.Screen
61+
name="BottomTabs Example"
62+
component={App}
63+
options={{
64+
headerRight: () => (
65+
<Button
66+
onPress={() =>
67+
Alert.alert(
68+
'Alert',
69+
`Do you want to change to the ${
70+
mode === 'js' ? 'native stack' : 'js stack'
71+
} ?`,
72+
[
73+
{ text: 'No', onPress: () => {} },
74+
{
75+
text: 'Yes',
76+
onPress: () => {
77+
setMode(mode === 'js' ? 'native' : 'js');
78+
},
79+
},
80+
]
81+
)
82+
}
83+
title={mode === 'js' ? 'JS' : 'NATIVE'}
84+
color="blue"
85+
/>
86+
),
87+
}}
88+
/>
89+
{examples.map((example, index) => (
90+
<NavigationStack.Screen
91+
key={index}
92+
name={example.name}
93+
component={example.component}
94+
/>
95+
))}
96+
</NavigationStack.Navigator>
97+
</NavigationContainer>
98+
</SafeAreaProvider>
4299
);
43100
}
44101

45102
const styles = StyleSheet.create({
46-
container: {
47-
flex: 1,
48-
alignItems: 'center',
49-
justifyContent: 'center',
103+
exampleTouchable: {
104+
padding: 16,
50105
},
51-
fullWidth: {
52-
width: '100%',
53-
height: '100%',
106+
exampleText: {
107+
fontSize: 16,
54108
},
55109
});

example/src/Examples/FourTabs.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { StyleSheet } from 'react-native';
2+
import TabView, {
3+
type OnPageSelectedEventData,
4+
type TabViewItems,
5+
} from 'react-native-bottom-tabs';
6+
import { useState } from 'react';
7+
import { Article } from '../Screens/Article';
8+
import { Albums } from '../Screens/Albums';
9+
import { Chat } from '../Screens/Chat';
10+
import { Contacts } from '../Screens/Contacts';
11+
12+
const items: TabViewItems = [
13+
{ key: 'article', title: 'Article', icon: 'document.fill', badge: '!' },
14+
{ key: 'albums', title: 'Albums', icon: 'square.grid.2x2.fill', badge: '5' },
15+
{ key: 'contacts', title: 'Contacts', icon: 'person.fill' },
16+
{ key: 'chat', title: 'Chat', icon: 'keyboard' },
17+
];
18+
19+
export default function FourTabs() {
20+
const [selectedPage, setSelectedTab] = useState<string>('contacts');
21+
22+
const handlePageSelected = ({
23+
nativeEvent: { key },
24+
}: {
25+
nativeEvent: OnPageSelectedEventData;
26+
}) => setSelectedTab(key);
27+
28+
const goToAlbums = () => {
29+
setSelectedTab('albums');
30+
};
31+
32+
return (
33+
<TabView
34+
style={styles.fullWidth}
35+
items={items}
36+
tabViewStyle="sidebarAdaptable"
37+
selectedPage={selectedPage}
38+
onPageSelected={handlePageSelected}
39+
>
40+
<Article onClick={goToAlbums} />
41+
<Albums />
42+
<Contacts />
43+
<Chat />
44+
</TabView>
45+
);
46+
}
47+
48+
const styles = StyleSheet.create({
49+
fullWidth: {
50+
width: '100%',
51+
height: '100%',
52+
},
53+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
2+
import { Article } from '../Screens/Article';
3+
import { Albums } from '../Screens/Albums';
4+
import { Contacts } from '../Screens/Contacts';
5+
import { Chat } from '../Screens/Chat';
6+
7+
const Tab = createBottomTabNavigator();
8+
9+
function JSBottomTabs() {
10+
return (
11+
<Tab.Navigator screenOptions={{ headerShown: false }}>
12+
<Tab.Screen name="Article" component={Article} />
13+
<Tab.Screen name="Albums" component={Albums} />
14+
<Tab.Screen name="Contacts" component={Contacts} />
15+
<Tab.Screen name="Chat" component={Chat} />
16+
</Tab.Navigator>
17+
);
18+
}
19+
20+
export default JSBottomTabs;

0 commit comments

Comments
 (0)