Skip to content

Commit 343a255

Browse files
authored
feat: support standalone usage (#38)
* chore: extract tabbar view from default animated tabbar * chore: remove react-navigation dependencies * chore: updated space interface * refactor: updated bubble preset styling * chore: added outer space flashy preset * chore: updated examples and add standalone * chore: updated svg icons * chore: updated bubble standalone example * chore: added itemcontainerwidth prop * docs: updated contributing doc * docs: updated readme file to include itemcontainerwidth * docs: updated logo link * docs: updated usage in rn4 * docs: updated standalone example styling
1 parent c86b529 commit 343a255

28 files changed

+751
-267
lines changed

CONTRIBUTING.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ The `package.json` file contains various scripts for common tasks:
7171
- `yarn bootstrap`: setup project by installing all dependencies and pods.
7272
- `yarn typescript`: type-check files with TypeScript.
7373
- `yarn lint`: lint files with ESLint.
74-
- `yarn test`: run unit tests with Jest.
7574
- `yarn example start`: start the Metro server for the example app.
7675
- `yarn example android`: run the example app on Android.
7776
- `yarn example ios`: run the example app on iOS.

README.md

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<img src="./preview.gif">
77

8-
A **60fps** animated tab bar to be used with `React Navigation v4 & v5` with a variety of cool animation presets 😎.
8+
A **60FPS** animated tab bar with a variety of cool animation presets 😎
99

1010
</div>
1111

@@ -36,6 +36,82 @@ npm install @gorhom/animated-tabbar
3636
3737
## Usage
3838

39+
Originally `Animated TabBar` worked only with `React Navigation`, but I notice that it could be use as a standalone component and be more useful for the community.
40+
41+
<details>
42+
<summary>Standalone Component</summary>
43+
44+
```tsx
45+
import React, { useState } from 'react';
46+
import { View, Text, StyleSheet } from 'react-native';
47+
import AnimatedTabBar, {TabsConfig, BubbleTabConfig} from '@gorhom/animated-tabbar';
48+
49+
const tabs: TabsConfig<BubbleTabConfig> = {
50+
Home: {
51+
labelStyle: {
52+
color: '#5B37B7',
53+
},
54+
icon: {
55+
component: /* ICON COMPONENT */,
56+
activeColor: 'rgba(91,55,183,1)',
57+
inactiveColor: 'rgba(0,0,0,1)',
58+
},
59+
background: {
60+
activeColor: 'rgba(223,215,243,1)',
61+
inactiveColor: 'rgba(223,215,243,0)',
62+
},
63+
},
64+
Profile: {
65+
labelStyle: {
66+
color: '#1194AA',
67+
},
68+
icon: {
69+
component: /* ICON COMPONENT */,
70+
activeColor: 'rgba(17,148,170,1)',
71+
inactiveColor: 'rgba(0,0,0,1)',
72+
},
73+
background: {
74+
activeColor: 'rgba(207,235,239,1)',
75+
inactiveColor: 'rgba(207,235,239,0)',
76+
},
77+
},
78+
};
79+
80+
const styles = StyleSheet.create({
81+
container: {
82+
flex: 1,
83+
justifyContent: 'center',
84+
alignItems: 'center',
85+
backgroundColor: '#999',
86+
},
87+
tabBarContainer: {
88+
borderRadius: 25,
89+
},
90+
});
91+
92+
export default function App() {
93+
const [index, setIndex] = useState(0);
94+
return (
95+
<View style={styles.container}>
96+
<Text>{index}</Text>
97+
<AnimatedTabBarView
98+
tabs={tabs}
99+
itemOuterSpace={{
100+
horizontal: 6,
101+
vertical: 12,
102+
}}
103+
itemInnerSpace={12}
104+
iconSize={20}
105+
style={styles.tabBarContainer}
106+
index={index}
107+
onIndexChange={setIndex}
108+
/>
109+
</View>
110+
)
111+
}
112+
```
113+
114+
</details>
39115
<details>
40116
<summary>React Navigation v5</summary>
41117

@@ -109,7 +185,6 @@ export default function App() {
109185
import React from 'react';
110186
import {createAppContainer} from 'react-navigation';
111187
import {createBottomTabNavigator} from 'react-navigation-tabs';
112-
import {createStackNavigator} from 'react-navigation-stack';
113188
import {SafeAreaProvider} from 'react-native-safe-area-context';
114189
import AnimatedTabBar, {TabsConfig, BubbleTabConfig} from '@gorhom/animated-tabbar';
115190

@@ -184,12 +259,13 @@ export default () => (
184259

185260
### [TabBarItemConfigurableProps](./src/types.ts#L26)
186261

187-
| name | description | required | type | default |
188-
| ---------------- | --------------------------------------------------------------------------------- | -------- | --------------------------------------- | ------- |
189-
| `itemInnerSpace` | Inner space to be added to the tab item, this may not be applied on some presets. | NO | number \| [`Space`](./src/types.ts#L21) | 12 |
190-
| `itemOuterSpace` | Outer space to be added to the tab item, this may not be applied on some presets. | NO | number \| [`Space`](./src/types.ts#L21) | 12 |
191-
| `iconSize` | Tab item icon size. | NO | number | 24 |
192-
| `isRTL` | Tab bar layout and animation direction. | NO | boolean | false |
262+
| name | description | required | type | default |
263+
| -------------------- | --------------------------------------------------------------------------------- | -------- | --------------------------------------- | ------- |
264+
| `itemInnerSpace` | Inner space to be added to the tab item, this may not be applied on some presets. | NO | number \| [`Space`](./src/types.ts#L21) | 12 |
265+
| `itemOuterSpace` | Outer space to be added to the tab item, this may not be applied on some presets. | NO | number \| [`Space`](./src/types.ts#L21) | 12 |
266+
| `itemContainerWidth` | Tab Item width stretch strategy, this may not be applied on some presets. | NO | 'auto' \| 'fill' | 'auto' |
267+
| `iconSize` | Tab item icon size. | NO | number | 24 |
268+
| `isRTL` | Tab bar layout and animation direction. | NO | boolean | false |
193269

194270
## Presets
195271

@@ -210,12 +286,11 @@ Originally `Animated TabBar` started with `Bubble` as the only animation preset
210286
- [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler)
211287
- [react-native-redash](https://github.com/wcandillon/react-native-redash)
212288
- [react-native-svg](https://github.com/react-native-community/react-native-svg)
213-
- [react-navigation](https://github.com/react-navigation/react-navigation)
214289
- [@react-native-community/bob](https://github.com/react-native-community/bob)
215290

216291
## Author
217292

218-
- [Mo Gorhom](https://twitter.com/gorhom)
293+
- [Mo Gorhom](https://gorhom.dev/)
219294

220295
## License
221296

@@ -232,5 +307,5 @@ Liked the library? 😇
232307
---
233308

234309
<p align="center">
235-
<a href="https://twitter.com/gorhom"><img src="./logo.png"></a>
310+
<a href="https://gorhom.dev" target="_blank"><img alt="Mo Gorhom" src="./logo.png"></a>
236311
</p>

example/android/app/app.iml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,11 +138,11 @@
138138
<orderEntry type="library" name="Gradle: com.facebook.fresco:nativeimagetranscoder:2.0.0@aar" level="project" />
139139
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline-okhttp3:2.0.0@aar" level="project" />
140140
<orderEntry type="library" name="Gradle: org.webkit:android-jsc:r245459@aar" level="project" />
141-
<orderEntry type="module" module-name="masked-view-android-react-native-community_masked-view" />
142-
<orderEntry type="module" module-name="react-native-gesture-handler-android-react-native-gesture-handler" />
143-
<orderEntry type="module" module-name="react-native-reanimated-android-react-native-reanimated" />
144-
<orderEntry type="module" module-name="react-native-safe-area-context-android-react-native-safe-area-context" />
145-
<orderEntry type="module" module-name="react-native-screens-android-react-native-screens" />
141+
<orderEntry type="module" module-name="react-native-community_masked-view" />
142+
<orderEntry type="module" module-name="react-native-gesture-handler" />
143+
<orderEntry type="module" module-name="react-native-reanimated" />
144+
<orderEntry type="module" module-name="react-native-safe-area-context" />
145+
<orderEntry type="module" module-name="react-native-screens" />
146146
<orderEntry type="module" module-name="react-native-svg" />
147147
</component>
148148
</module>

example/src/App.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import RootScreen from './screens/Root';
55
import BubbleScreen from './screens/Bubble';
66
import BubbleStyledScreen from './screens/BubbleStyled';
77
import BubbleRTLScreen from './screens/BubbleRTL';
8+
import BubbleStandaloneScreen from './screens/BubbleStandalone';
89
import FlashyScreen from './screens/Flashy';
910
import FlashyStyledScreen from './screens/FlashyStyled';
1011
import FlashyRTLScreen from './screens/FlashyRTL';
12+
import FlashyStandaloneScreen from './screens/FlashyStandalone';
1113

1214
const Stack = createStackNavigator();
1315

@@ -19,9 +21,17 @@ export default function App() {
1921
<Stack.Screen name="Bubble" component={BubbleScreen} />
2022
<Stack.Screen name="BubbleStyled" component={BubbleStyledScreen} />
2123
<Stack.Screen name="BubbleRTL" component={BubbleRTLScreen} />
24+
<Stack.Screen
25+
name="BubbleStandalone"
26+
component={BubbleStandaloneScreen}
27+
/>
2228
<Stack.Screen name="Flashy" component={FlashyScreen} />
2329
<Stack.Screen name="FlashyStyled" component={FlashyStyledScreen} />
2430
<Stack.Screen name="FlashyRTL" component={FlashyRTLScreen} />
31+
<Stack.Screen
32+
name="FlashyStandalone"
33+
component={FlashyStandaloneScreen}
34+
/>
2535
</Stack.Navigator>
2636
</NavigationContainer>
2737
);
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import React, { useState, useMemo } from 'react';
2+
import { View, StyleSheet, Button, StatusBar } from 'react-native';
3+
import {
4+
AnimatedTabBarView,
5+
TabsConfig,
6+
BubbleTabConfig,
7+
} from '@gorhom/animated-tabbar';
8+
import HomeSVG from '../svg/HomeSVG';
9+
import LikeSVG from '../svg/LikeSVG';
10+
import SearchSVG from '../svg/SearchSVG';
11+
import ProfileSVG from '../svg/ProfileSVG';
12+
import { MainTabsParams } from './types';
13+
14+
const tabs: TabsConfig<BubbleTabConfig, MainTabsParams> = {
15+
Home: {
16+
labelStyle: {
17+
color: '#5B37B7',
18+
},
19+
icon: {
20+
component: HomeSVG,
21+
activeColor: 'rgba(91,55,183,1)',
22+
inactiveColor: 'rgba(0,0,0,1)',
23+
},
24+
background: {
25+
activeColor: 'rgba(223,215,243,1)',
26+
inactiveColor: 'rgba(223,215,243,0)',
27+
},
28+
},
29+
Likes: {
30+
labelStyle: {
31+
color: '#C9379D',
32+
},
33+
icon: {
34+
component: LikeSVG,
35+
activeColor: 'rgba(201,55,157,1)',
36+
inactiveColor: 'rgba(0,0,0,1)',
37+
},
38+
background: {
39+
activeColor: 'rgba(247,215,243,1)',
40+
inactiveColor: 'rgba(247,215,243,0)',
41+
},
42+
},
43+
Search: {
44+
labelStyle: {
45+
color: '#E6A919',
46+
},
47+
icon: {
48+
component: SearchSVG,
49+
activeColor: 'rgba(230,169,25,1)',
50+
inactiveColor: 'rgba(0,0,0,1)',
51+
},
52+
background: {
53+
activeColor: 'rgba(251,239,211,1)',
54+
inactiveColor: 'rgba(251,239,211,0)',
55+
},
56+
},
57+
Profile: {
58+
labelStyle: {
59+
color: '#1194AA',
60+
},
61+
icon: {
62+
component: ProfileSVG,
63+
activeColor: 'rgba(17,148,170,1)',
64+
inactiveColor: 'rgba(0,0,0,1)',
65+
},
66+
background: {
67+
activeColor: 'rgba(207,235,239,1)',
68+
inactiveColor: 'rgba(207,235,239,0)',
69+
},
70+
},
71+
};
72+
73+
const BubbleStandaloneScreen = () => {
74+
const [index, setIndex] = useState(0);
75+
76+
const containerStyle = useMemo(
77+
() => [
78+
styles.container,
79+
{
80+
// @ts-ignore
81+
backgroundColor: tabs[Object.keys(tabs)[index]].labelStyle.color,
82+
},
83+
],
84+
[index]
85+
);
86+
return (
87+
<View style={containerStyle}>
88+
<StatusBar barStyle="dark-content" />
89+
<AnimatedTabBarView
90+
preset="bubble"
91+
tabs={tabs}
92+
itemOuterSpace={{
93+
horizontal: 6,
94+
vertical: 12,
95+
}}
96+
itemInnerSpace={12}
97+
iconSize={20}
98+
style={styles.tabBarContainer}
99+
index={index}
100+
onIndexChange={setIndex}
101+
/>
102+
103+
<Button
104+
title="Set Index to 0"
105+
color={'white'}
106+
onPress={() => setIndex(0)}
107+
/>
108+
<Button
109+
title="Set Index to 1"
110+
color={'white'}
111+
onPress={() => setIndex(1)}
112+
/>
113+
<Button
114+
title="Set Index to 2"
115+
color={'white'}
116+
onPress={() => setIndex(2)}
117+
/>
118+
<Button
119+
title="Set Index to 3"
120+
color={'white'}
121+
onPress={() => setIndex(3)}
122+
/>
123+
</View>
124+
);
125+
};
126+
127+
const styles = StyleSheet.create({
128+
container: {
129+
flex: 1,
130+
justifyContent: 'center',
131+
alignItems: 'center',
132+
},
133+
tabBarContainer: {
134+
borderRadius: 25,
135+
},
136+
});
137+
138+
export default BubbleStandaloneScreen;

example/src/screens/Flashy.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,7 @@ const FlashyScreen = () => {
5656
return (
5757
<Tab.Navigator
5858
tabBar={props => (
59-
<AnimatedTabBar
60-
preset="flashy"
61-
duration={1000}
62-
tabs={tabs}
63-
{...props}
64-
/>
59+
<AnimatedTabBar preset="flashy" tabs={tabs} {...props} />
6560
)}
6661
>
6762
<Tab.Screen

example/src/screens/FlashyRTL.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,8 @@ const FlashyStyledScreen = () => {
6363
tabBar={props => (
6464
<AnimatedTabBar
6565
preset="flashy"
66-
duration={1000}
6766
tabs={tabs}
6867
iconSize={20}
69-
itemInnerSpace={24}
7068
isRTL={true}
7169
{...props}
7270
/>

0 commit comments

Comments
 (0)