├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug-report.md │ └── feature_request.md ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── .release-it.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── commitlint.config.js ├── docs ├── animated-icons.md ├── bubble-preset.md ├── flashy-preset.md ├── material-preset.md └── previews │ ├── bubble.gif │ ├── flashy.gif │ ├── material-1.gif │ ├── material-2.gif │ └── material-3.gif ├── example ├── android │ ├── AnimatedTabbarExample.iml │ ├── app │ │ ├── app.iml │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── dev │ │ │ │ └── gorhom │ │ │ │ └── animatedtabbar │ │ │ │ └── ReactNativeFlipper.java │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── dev │ │ │ │ └── gorhom │ │ │ │ └── animatedtabbar │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_foreground.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── index.tsx ├── ios │ ├── AnimatedTabbarExample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── AnimatedTabbarExample.xcscheme │ ├── AnimatedTabbarExample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── AnimatedTabbarExample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon.png │ │ │ │ ├── icon_20pt.png │ │ │ │ ├── icon_20pt@2x-1.png │ │ │ │ ├── icon_20pt@2x.png │ │ │ │ ├── icon_20pt@3x.png │ │ │ │ ├── icon_29pt.png │ │ │ │ ├── icon_29pt@2x-1.png │ │ │ │ ├── icon_29pt@2x.png │ │ │ │ ├── icon_29pt@3x.png │ │ │ │ ├── icon_40pt.png │ │ │ │ ├── icon_40pt@2x-1.png │ │ │ │ ├── icon_40pt@2x.png │ │ │ │ ├── icon_40pt@3x.png │ │ │ │ ├── icon_60pt@2x.png │ │ │ │ ├── icon_60pt@3x.png │ │ │ │ ├── icon_76pt.png │ │ │ │ ├── icon_76pt@2x.png │ │ │ │ └── icon_83.5@2x.png │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── Launch Screen.storyboard │ │ └── main.m │ ├── Podfile │ └── Podfile.lock ├── metro.config.js ├── package.json ├── src │ ├── App.tsx │ ├── components │ │ ├── badge │ │ │ ├── Badge.tsx │ │ │ └── index.ts │ │ ├── button │ │ │ ├── Button.tsx │ │ │ └── index.ts │ │ └── iconWithBadge │ │ │ ├── IconWithBadge.tsx │ │ │ └── index.ts │ ├── screens │ │ ├── Dummy.tsx │ │ ├── Root.tsx │ │ ├── bubble │ │ │ ├── Bubble.tsx │ │ │ ├── BubbleRTL.tsx │ │ │ ├── BubbleStandalone.tsx │ │ │ └── BubbleStyled.tsx │ │ ├── flashy │ │ │ ├── Flashy.tsx │ │ │ ├── FlashyRTL.tsx │ │ │ ├── FlashyStandalone.tsx │ │ │ └── FlashyStyled.tsx │ │ ├── material │ │ │ ├── Material.tsx │ │ │ ├── MaterialRTL.tsx │ │ │ ├── MaterialStandalone.tsx │ │ │ └── MaterialStyled.tsx │ │ └── types.ts │ └── svg │ │ ├── HomeSVG.tsx │ │ ├── LikeSVG.tsx │ │ ├── ProfileSVG.tsx │ │ ├── SearchSVG.tsx │ │ └── types.d.ts └── tsconfig.json ├── logo.png ├── package.json ├── preview.gif ├── release-template.hbs ├── src ├── AnimatedTabBar.tsx ├── AnimatedTabBarView.tsx ├── components │ └── rawButton │ │ ├── RawButton.tsx │ │ └── index.ts ├── hooks │ ├── index.ts │ ├── useStableCallback.ts │ ├── useTabBarItemFocusTransition.ts │ ├── useTabBarItemSpacing.ts │ └── useTabBarVisibility.ts ├── index.ts ├── presets.ts ├── presets │ ├── bubble │ │ ├── BubbleTabBar.tsx │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── item │ │ │ ├── BubbleTabBarItem.tsx │ │ │ ├── index.ts │ │ │ └── styles.ts │ │ ├── styles.ts │ │ └── types.ts │ ├── flashy │ │ ├── FlashyTabBar.tsx │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── item │ │ │ ├── FlashyTabBarItem.tsx │ │ │ ├── index.ts │ │ │ └── styles.ts │ │ ├── styles.ts │ │ └── types.ts │ └── material │ │ ├── MaterialTabBar.tsx │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── item │ │ ├── MaterialTabBarItem.tsx │ │ ├── index.ts │ │ └── styles.ts │ │ ├── ripple │ │ ├── MaterialTabBarRipple.tsx │ │ ├── index.ts │ │ └── styles.ts │ │ ├── styles.ts │ │ └── types.ts ├── types.ts └── utilities │ ├── index.ts │ ├── noop.ts │ └── reanimated.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | # generated by bob 4 | lib/ 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['@react-native-community', 'prettier'], 4 | rules: { 5 | 'prettier/prettier': [ 6 | 'error', 7 | { 8 | singleQuote: true, 9 | tabWidth: 2, 10 | trailingComma: 'es5', 11 | useTabs: false, 12 | }, 13 | ], 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: gorhom 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Bug 11 | 12 | 20 | 21 | ## Environment info 22 | 23 | 26 | 27 | | Library | Version | 28 | | ------------------------------- | ------- | 29 | | @gorhom/animated-tabbar | x.x.x | 30 | | react-native | x.x.x | 31 | | react-native-reanimated | x.x.x | 32 | | react-native-gesture-handler | x.x.x | 33 | | react-native-svg | x.x.x | 34 | 35 | ## Steps To Reproduce 36 | 37 | 43 | 44 | 1. 45 | 2. 46 | 3. 47 | 48 | Describe what you expected to happen: 49 | 50 | 1. 51 | 2. 52 | 53 | ## Reproducible sample code 54 | 55 | 58 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | # Feature Request 11 | 12 | 15 | 16 | ## Why it is needed 17 | 18 | 21 | 22 | ## Possible implementation 23 | 24 | 27 | 28 | ### Code sample 29 | 30 | 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .idea 35 | .gradle 36 | local.properties 37 | android.iml 38 | 39 | # Cocoapods 40 | # 41 | example/ios/Pods 42 | 43 | # node.js 44 | # 45 | node_modules/ 46 | npm-debug.log 47 | yarn-debug.log 48 | yarn-error.log 49 | yarn.lock 50 | example/yarn.lock 51 | 52 | # BUCK 53 | buck-out/ 54 | \.buckd/ 55 | android/app/libs 56 | android/keystores/debug.keystore 57 | 58 | # generated by bob 59 | lib/ 60 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .github 2 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5", 6 | "useTabs": false 7 | } 8 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "push": true, 4 | "tagName": "v${version}", 5 | "commitMessage": "chore: release v${version}", 6 | "changelog": "auto-changelog --stdout --commit-limit false --ignore-commit-pattern \"^chore: release v\" --unreleased --template ./release-template.hbs" 7 | }, 8 | "github": { 9 | "release": true, 10 | "releaseNotes": "auto-changelog --stdout --commit-limit false --ignore-commit-pattern \"^chore: release v\" --unreleased --template ./release-template.hbs" 11 | }, 12 | "npm": { 13 | "publish": false 14 | }, 15 | "plugins": { 16 | "@release-it/conventional-changelog": { 17 | "preset": "angular" 18 | } 19 | }, 20 | "hooks": { 21 | "after:bump": "auto-changelog -p --ignore-commit-pattern \"^chore: release v\"" 22 | } 23 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Mo Gorhom 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/animated-icons.md: -------------------------------------------------------------------------------- 1 | # Animated Icons 2 | 3 | In order to animate the tab icon color, shape & size. You will need to use the provided props `color` & `animatedFocus` that will be provided to the icon. 4 | 5 | This example for `bubble` icon below should explain it better: 6 | 7 | ```tsx 8 | import React from 'react'; 9 | import Animated from 'react-native-reanimated'; 10 | import Svg, { Path } from 'react-native-svg'; 11 | 12 | const AnimatedPath = Animated.createAnimatedComponent(Path); 13 | 14 | interface AnimatedSVGProps { 15 | /** 16 | * The tab animated focus: 17 | * 1 is active 18 | * 0 is inactive 19 | */ 20 | animatedFocus: Animated.Node; 21 | 22 | /** 23 | * Animated color. 24 | */ 25 | color: Animated.Node; 26 | 27 | /** 28 | * Icon size. 29 | */ 30 | size: number; 31 | } 32 | 33 | const AnimatedSVG = ({ animatedFocus, color, size }: AnimatedSVGProps) => { 34 | return ( 35 | 36 | 45 | 46 | ); 47 | }; 48 | 49 | export default AnimatedSVG; 50 | ``` 51 | -------------------------------------------------------------------------------- /docs/bubble-preset.md: -------------------------------------------------------------------------------- 1 | # Bubble Preset 2 | 3 | > This preset is inspired by [Aurélien Salomon](https://dribbble.com/aureliensalomon) works on [Dribbble](https://dribbble.com/shots/5925052-Google-Bottom-Bar-Navigation-Pattern-Mobile-UX-Design). 4 | 5 | Default 6 | 7 | ## Interfaces 8 | 9 | ### BubbleTabBarConfig 10 | 11 | > no preset config 12 | 13 | ### BubbleTabBarItemConfig 14 | 15 | | name | description | required | type | default | 16 | | ---------------- | ------------------------------------------------------------ | -------- | ------------------- | ------- | 17 | | `labelStyle` | This will apply to the tab bar item label. | NO | TextStyle | | 18 | | `icon` | Icon configurations. | YES | object | | 19 | | `├component` | Icon component, this could be a function or class component. | YES | [`ReactNode`](#L46) | | 20 | | `├activeColor` | Icon active color. | YES | string | | 21 | | `└inactiveColor` | Icon inactive color. | YES | string | | 22 | | `background` | Tab bar item background configurations. | YES | object | | 23 | | `├activeColor` | Background active color. | YES | string | | 24 | | `└inactiveColor` | Background inactive color. | YES | string | | 25 | 26 |
27 | TypeScript Interface 28 | 29 | ```ts 30 | export interface BubbleTabBarItemConfig { 31 | /** 32 | * Tab bar item label style. 33 | * @type {TextStyle} 34 | * @default 35 | * { 36 | * color: '#000', 37 | * fontSize: 14, 38 | * fontWeight: '600' 39 | * } 40 | */ 41 | labelStyle: TextStyle; 42 | /** 43 | * Tab bar item icon config. 44 | */ 45 | icon: { 46 | /** 47 | * Tab bar item icon component, this could be a function or class component. 48 | * @type {React.FC | React.ComponentClass} 49 | */ 50 | component: 51 | | React.FC 52 | | React.ComponentClass 53 | | React.ReactNode; 54 | 55 | /** 56 | * Icon active color. 57 | * @type {string} 58 | */ 59 | activeColor: string; 60 | /** 61 | * Icon inactive color. 62 | * @type {string} 63 | */ 64 | inactiveColor: string; 65 | }; 66 | background: { 67 | /** 68 | * Tab bar item background active color. 69 | * @type {string} 70 | */ 71 | activeColor: string; 72 | /** 73 | * Tab bar item background inactive color. 74 | * @type {string} 75 | */ 76 | inactiveColor: string; 77 | }; 78 | } 79 | ``` 80 | 81 |
82 | 83 | ### BubbleTabBarIconProps 84 | 85 | | name | description | required | type | default | 86 | | --------------- | ---------------------------------- | -------- | ------------------------------ | ------- | 87 | | `animatedFocus` | Tab bar item animated focus value. | YES | `Animated.Node` | 88 | | `color` | Tab bar item animated icon color. | YES | `Animated.Node` | | 89 | | `size` | Tab bar item icon size. | YES | number | | 90 | 91 |
92 | TypeScript Interface 93 | 94 | ```ts 95 | export interface MaterialTabBarIconProps { 96 | /** 97 | * Tab bar item animated focus value. 98 | * @type {Animated.Node} 99 | */ 100 | animatedFocus: Animated.Node; 101 | /** 102 | * Tab bar item animated icon color. 103 | * @type {Animated.Node} 104 | */ 105 | color: Animated.Node; 106 | /** 107 | * Tab bar item icon size. 108 | * @type {number} 109 | */ 110 | size: number; 111 | } 112 | ``` 113 | 114 |
115 | -------------------------------------------------------------------------------- /docs/flashy-preset.md: -------------------------------------------------------------------------------- 1 | # Flashy Preset 2 | 3 | > This preset is inspired by [Cuberto](https://dribbble.com/cuberto) works on [Dribbble](https://dribbble.com/shots/5605168-Toolbar-icons-animation). 4 | 5 | Default 6 | 7 | ## Interfaces 8 | 9 | ## FlashyTabBarConfig 10 | 11 | > no preset config 12 | 13 | ### FlashyTabBarItemConfig 14 | 15 | | name | description | required | type | default | 16 | | ------------ | ------------------------------------------------------------ | -------- | ------------------- | ------------- | 17 | | `labelStyle` | This will apply to the tab bar item label. | NO | TextStyle | | 18 | | `icon` | Icon configurations. | YES | object | | 19 | | `├component` | Icon component, this could be a function or class component. | YES | [`ReactNode`](#L45) | | 20 | | `└color` | Icon color. | YES | string | | 21 | | `indicator` | Tab bar item indicator configurations. | YES | object | | 22 | | `├visible` | To show or hide tab bar item indicator. | NO | boolean | true | 23 | | `├size` | Indicator size. | NO | number | 6 | 24 | | `└color` | Indicator color. | NO | string | `label color` | 25 | 26 |
27 | TypeScript Interface 28 | 29 | ```tsx 30 | export interface FlashyTabBarItemConfig { 31 | /** 32 | * Tab bar item label style. 33 | * @type {TextStyle} 34 | * @default 35 | * { 36 | * color: '#000', 37 | * fontSize: 14, 38 | * fontWeight: '600' 39 | * } 40 | */ 41 | labelStyle: TextStyle; 42 | /** 43 | * Tab bar item icon config. 44 | */ 45 | icon: { 46 | /** 47 | * Tab bar item icon component, this could be a function or class component. 48 | * @type {React.FC | React.ComponentClass} 49 | */ 50 | component: 51 | | React.FC 52 | | React.ComponentClass 53 | | React.ReactNode; 54 | /** 55 | * Icon color. 56 | * @type {string} 57 | */ 58 | color: string; 59 | }; 60 | /** 61 | * Tab bar item indicator config. 62 | */ 63 | indicator?: { 64 | /** 65 | * To show or hide tab bar item indicator. 66 | * @type {boolean} 67 | * @default true 68 | */ 69 | visible?: boolean; 70 | 71 | /** 72 | * Indicator color 73 | * @type {boolean} 74 | * @default labelStyle.color|black 75 | */ 76 | color?: string; 77 | 78 | /** 79 | * Indicator size 80 | * @type {number} 81 | * @default 6 82 | */ 83 | size?: number; 84 | }; 85 | } 86 | ``` 87 | 88 |
89 | 90 | ### FlashyTabBarIconProps 91 | 92 | | name | description | required | type | default | 93 | | --------------- | ---------------------------------- | -------- | ----------------------- | ------- | 94 | | `animatedFocus` | Tab bar item animated focus value. | YES | `Animated.Node` | 95 | | `color` | Tab bar item icon color. | YES | number | | 96 | | `size` | Tab bar item icon size. | YES | number | | 97 | 98 |
99 | TypeScript Interface 100 | 101 | ```ts 102 | export interface FlashyTabBarIconProps { 103 | /** 104 | * Tab bar item animated focus value. 105 | * @type {Animated.Node} 106 | */ 107 | animatedFocus: Animated.Node; 108 | /** 109 | * Tab bar item icon color. 110 | * @type {string} 111 | */ 112 | color: string; 113 | /** 114 | * Tab bar item icon size. 115 | * @type {number} 116 | */ 117 | size: number; 118 | } 119 | ``` 120 | 121 |
122 | -------------------------------------------------------------------------------- /docs/material-preset.md: -------------------------------------------------------------------------------- 1 | # Material Preset 2 | 3 | > This preset is inspired by [timomeh](https://github.com/timomeh) works on [react-native-material-bottom-navigation](https://github.com/timomeh/react-native-material-bottom-navigation). 4 | 5 | ### Icon with label 6 | 7 | Icon with label 8 | 9 | ### Icon only 10 | 11 | Icon only 12 | 13 | ### Icon with label on focus 14 | 15 | Icon with label on focus 16 | 17 | ## Interfaces 18 | 19 | ### MaterialTabBarConfig 20 | 21 | | name | description | required | type | default | 22 | | ----------------- | -------------------------------------- | -------- | ------------------------------------------------------- | --------------- | 23 | | `animation` | Material animation preset. | NO | `iconWithLabel` \| `iconOnly` \| `iconWithLabelOnFocus` | `iconWithLabel` | 24 | | `inactiveOpacity` | Tab bar item inactive opacity. | NO | number | 0.75 | 25 | | `inactiveScale` | Tab bar item indicator configurations. | NO | number | 0.85 | 26 | 27 |
28 | TypeScript Interface 29 | 30 | ```ts 31 | export interface MaterialTabBarConfig { 32 | /** 33 | * Material animation preset. 34 | * @type {'iconWithLabel' | 'iconOnly' | 'iconWithLabelOnFocus'} 35 | * @default 'iconWithLabel' 36 | */ 37 | animation?: 'iconWithLabel' | 'iconOnly' | 'iconWithLabelOnFocus'; 38 | /** 39 | * Tab bar item inactive opacity. 40 | * @type {number} 41 | * @default 0.75 42 | */ 43 | inactiveOpacity?: number; 44 | /** 45 | * Tab bar item inactive scale. 46 | * @type {number} 47 | * @default 0.85 48 | */ 49 | inactiveScale?: number; 50 | } 51 | ``` 52 | 53 |
54 | 55 | ### MaterialTabBarItemConfig 56 | 57 | | name | description | required | type | default | 58 | | ------------ | ------------------------------------------------------------ | -------- | ------------------- | ------------- | 59 | | `labelStyle` | This will apply to the tab bar item label. | NO | TextStyle | | 60 | | `icon` | Icon configurations. | YES | object | | 61 | | `├component` | Icon component, this could be a function or class component. | YES | [`ReactNode`](#L45) | | 62 | | `└color` | Icon color. | YES | string | | 63 | | `ripple` | Tab bar item ripple configurations. | YES | object | | 64 | | `└color` | Ripple color. | NO | string | `label color` | 65 | 66 |
67 | TypeScript Interface 68 | 69 | ```ts 70 | export interface MaterialTabBarItemConfig { 71 | /** 72 | * Tab bar item label style. 73 | */ 74 | labelStyle?: StyleProp; 75 | /** 76 | * Tab bar item icon config. 77 | */ 78 | icon: { 79 | /** 80 | * Tab bar item icon component, this could be a function or 81 | * a react node. 82 | * @type {(props: MaterialTabBarIconProps) => React.ReactNode | React.ReactNode} 83 | */ 84 | component: 85 | | React.FC 86 | | React.ComponentClass 87 | | React.ReactNode; 88 | /** 89 | * Icon color. 90 | * @type {string} 91 | */ 92 | color: string; 93 | }; 94 | /** 95 | * Tab bar item ripple config. 96 | */ 97 | ripple: { 98 | /** 99 | * Tab bar item ripple color. 100 | * @type {string} 101 | */ 102 | color: string; 103 | }; 104 | } 105 | ``` 106 | 107 |
108 | 109 | ### MaterialTabBarIconProps 110 | 111 | | name | description | required | type | default | 112 | | --------------- | ---------------------------------- | -------- | ----------------------- | ------- | 113 | | `animatedFocus` | Tab bar item animated focus value. | YES | `Animated.Node` | 114 | | `color` | Tab bar item icon color. | YES | number | | 115 | | `size` | Tab bar item icon size. | YES | number | | 116 | 117 |
118 | TypeScript Interface 119 | 120 | ```ts 121 | export interface MaterialTabBarIconProps { 122 | /** 123 | * Tab bar item animated focus value. 124 | * @type {Animated.Node} 125 | */ 126 | animatedFocus: Animated.Node; 127 | /** 128 | * Tab bar item icon color. 129 | * @type {string} 130 | */ 131 | color: string; 132 | /** 133 | * Tab bar item icon size. 134 | * @type {number} 135 | */ 136 | size: number; 137 | } 138 | ``` 139 | 140 |
141 | -------------------------------------------------------------------------------- /docs/previews/bubble.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/docs/previews/bubble.gif -------------------------------------------------------------------------------- /docs/previews/flashy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/docs/previews/flashy.gif -------------------------------------------------------------------------------- /docs/previews/material-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/docs/previews/material-1.gif -------------------------------------------------------------------------------- /docs/previews/material-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/docs/previews/material-2.gif -------------------------------------------------------------------------------- /docs/previews/material-3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/docs/previews/material-3.gif -------------------------------------------------------------------------------- /example/android/AnimatedTabbarExample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/debug/java/dev/gorhom/animatedtabbar/ReactNativeFlipper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | *

This source code is licensed under the MIT license found in the LICENSE file in the root 5 | * directory of this source tree. 6 | */ 7 | package dev.gorhom.animatedtabbar; 8 | 9 | import android.content.Context; 10 | import com.facebook.flipper.android.AndroidFlipperClient; 11 | import com.facebook.flipper.android.utils.FlipperUtils; 12 | import com.facebook.flipper.core.FlipperClient; 13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; 14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; 15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; 16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping; 17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; 18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; 19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; 20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin; 21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; 22 | import com.facebook.react.ReactInstanceManager; 23 | import com.facebook.react.bridge.ReactContext; 24 | import com.facebook.react.modules.network.NetworkingModule; 25 | import okhttp3.OkHttpClient; 26 | 27 | public class ReactNativeFlipper { 28 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { 29 | if (FlipperUtils.shouldEnableFlipper(context)) { 30 | final FlipperClient client = AndroidFlipperClient.getInstance(context); 31 | 32 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); 33 | client.addPlugin(new ReactFlipperPlugin()); 34 | client.addPlugin(new DatabasesFlipperPlugin(context)); 35 | client.addPlugin(new SharedPreferencesFlipperPlugin(context)); 36 | client.addPlugin(CrashReporterPlugin.getInstance()); 37 | 38 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); 39 | NetworkingModule.setCustomClientBuilder( 40 | new NetworkingModule.CustomClientBuilder() { 41 | @Override 42 | public void apply(OkHttpClient.Builder builder) { 43 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); 44 | } 45 | }); 46 | client.addPlugin(networkFlipperPlugin); 47 | client.start(); 48 | 49 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized 50 | // Hence we run if after all native modules have been initialized 51 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); 52 | if (reactContext == null) { 53 | reactInstanceManager.addReactInstanceEventListener( 54 | new ReactInstanceManager.ReactInstanceEventListener() { 55 | @Override 56 | public void onReactContextInitialized(ReactContext reactContext) { 57 | reactInstanceManager.removeReactInstanceEventListener(this); 58 | reactContext.runOnNativeModulesQueueThread( 59 | new Runnable() { 60 | @Override 61 | public void run() { 62 | client.addPlugin(new FrescoFlipperPlugin()); 63 | } 64 | }); 65 | } 66 | }); 67 | } else { 68 | client.addPlugin(new FrescoFlipperPlugin()); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 13 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/dev/gorhom/animatedtabbar/MainActivity.java: -------------------------------------------------------------------------------- 1 | package dev.gorhom.animatedtabbar; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.ReactRootView; 6 | import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView; 7 | 8 | public class MainActivity extends ReactActivity { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | @Override 15 | protected String getMainComponentName() { 16 | return "AnimatedTabbarExample"; 17 | } 18 | 19 | @Override 20 | protected ReactActivityDelegate createReactActivityDelegate() { 21 | return new ReactActivityDelegate(this, getMainComponentName()) { 22 | @Override 23 | protected ReactRootView createRootView() { 24 | return new RNGestureHandlerEnabledRootView(MainActivity.this); 25 | } 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/dev/gorhom/animatedtabbar/MainApplication.java: -------------------------------------------------------------------------------- 1 | package dev.gorhom.animatedtabbar; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactInstanceManager; 8 | import com.facebook.react.ReactNativeHost; 9 | import com.facebook.react.ReactPackage; 10 | import com.facebook.soloader.SoLoader; 11 | import java.lang.reflect.InvocationTargetException; 12 | import java.util.List; 13 | 14 | 15 | public class MainApplication extends Application implements ReactApplication { 16 | 17 | private final ReactNativeHost mReactNativeHost = 18 | new ReactNativeHost(this) { 19 | @Override 20 | public boolean getUseDeveloperSupport() { 21 | return BuildConfig.DEBUG; 22 | } 23 | 24 | @Override 25 | protected List getPackages() { 26 | @SuppressWarnings("UnnecessaryLocalVariable") 27 | List packages = new PackageList(this).getPackages(); 28 | // Packages that cannot be autolinked yet can be added manually here, for AnimatedTabbarExample: 29 | // packages.add(new MyReactNativePackage()); 30 | return packages; 31 | } 32 | 33 | @Override 34 | protected String getJSMainModuleName() { 35 | return "index"; 36 | } 37 | }; 38 | 39 | @Override 40 | public ReactNativeHost getReactNativeHost() { 41 | return mReactNativeHost; 42 | } 43 | 44 | @Override 45 | public void onCreate() { 46 | super.onCreate(); 47 | SoLoader.init(this, /* native exopackage */ false); 48 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 49 | } 50 | 51 | /** 52 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like 53 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); 54 | * 55 | * @param context 56 | * @param reactInstanceManager 57 | */ 58 | private static void initializeFlipper( 59 | Context context, ReactInstanceManager reactInstanceManager) { 60 | if (BuildConfig.DEBUG) { 61 | try { 62 | /* 63 | We use reflection here to pick up the class that initializes Flipper, 64 | since Flipper library is not available in release mode 65 | */ 66 | Class aClass = Class.forName("com.test.ReactNativeFlipper"); 67 | aClass 68 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) 69 | .invoke(null, context, reactInstanceManager); 70 | } catch (ClassNotFoundException e) { 71 | e.printStackTrace(); 72 | } catch (NoSuchMethodException e) { 73 | e.printStackTrace(); 74 | } catch (IllegalAccessException e) { 75 | e.printStackTrace(); 76 | } catch (InvocationTargetException e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Animated TabBar Example 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "29.0.2" 6 | minSdkVersion = 16 7 | compileSdkVersion = 29 8 | targetSdkVersion = 29 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | mavenLocal() 25 | maven { 26 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 27 | url("$rootDir/../node_modules/react-native/android") 28 | } 29 | maven { 30 | // Android JSC is installed from npm 31 | url("$rootDir/../node_modules/jsc-android/dist") 32 | } 33 | 34 | google() 35 | jcenter() 36 | maven { url 'https://www.jitpack.io' } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useAndroidX=true 21 | android.enableJetifier=true 22 | 23 | # Version of flipper SDK to use with React Native 24 | FLIPPER_VERSION=0.54.0 -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" -------------------------------------------------------------------------------- /example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'AnimatedTabbarExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | 5 | 6 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AnimatedTabbarExample", 3 | "displayName": "AnimatedTabbar Example" 4 | } 5 | -------------------------------------------------------------------------------- /example/index.tsx: -------------------------------------------------------------------------------- 1 | import 'react-native-gesture-handler'; 2 | import { AppRegistry } from 'react-native'; 3 | import App from './src/App'; 4 | import { name as appName } from './app.json'; 5 | 6 | AppRegistry.registerComponent(appName, () => App); 7 | 8 | /** 9 | * @DEV 10 | * this code is helpful to monitor communication that reanimated use 11 | * via the native bridge. 12 | */ 13 | 14 | // import MessageQueue from 'react-native/Libraries/BatchedBridge/MessageQueue.js'; 15 | 16 | // let count = 0; 17 | // const spyFunction = msg => { 18 | // if (msg.module === 'ReanimatedModule') { 19 | // console.log(++count, msg); 20 | // } 21 | // }; 22 | 23 | // MessageQueue.spy(spyFunction); 24 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample.xcodeproj/xcshareddata/xcschemes/AnimatedTabbarExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | #ifdef FB_SONARKIT_ENABLED 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | #import 21 | 22 | static void InitializeFlipper(UIApplication *application) { 23 | FlipperClient *client = [FlipperClient sharedClient]; 24 | SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; 25 | [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; 26 | [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; 27 | [client addPlugin:[FlipperKitReactPlugin new]]; 28 | [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; 29 | [client start]; 30 | } 31 | #endif 32 | 33 | @implementation AppDelegate 34 | 35 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 36 | { 37 | #ifdef FB_SONARKIT_ENABLED 38 | InitializeFlipper(application); 39 | #endif 40 | 41 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 42 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 43 | moduleName:@"AnimatedTabbarExample" 44 | initialProperties:nil]; 45 | 46 | // rootView.backgroundColor = [[UIColor alloc] initWithRed:0.0f green:0.0f blue:0.0f alpha:1]; 47 | rootView.backgroundColor = UIColor.systemBackgroundColor; 48 | 49 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 50 | UIViewController *rootViewController = [UIViewController new]; 51 | rootViewController.view = rootView; 52 | self.window.rootViewController = rootViewController; 53 | [self.window makeKeyAndVisible]; 54 | return YES; 55 | } 56 | 57 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 58 | { 59 | #if DEBUG 60 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 61 | #else 62 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 63 | #endif 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "icon_20pt@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "20x20" 8 | }, 9 | { 10 | "filename" : "icon_20pt@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "20x20" 14 | }, 15 | { 16 | "filename" : "icon_29pt@2x.png", 17 | "idiom" : "iphone", 18 | "scale" : "2x", 19 | "size" : "29x29" 20 | }, 21 | { 22 | "filename" : "icon_29pt@3x.png", 23 | "idiom" : "iphone", 24 | "scale" : "3x", 25 | "size" : "29x29" 26 | }, 27 | { 28 | "filename" : "icon_40pt@2x.png", 29 | "idiom" : "iphone", 30 | "scale" : "2x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "filename" : "icon_40pt@3x.png", 35 | "idiom" : "iphone", 36 | "scale" : "3x", 37 | "size" : "40x40" 38 | }, 39 | { 40 | "filename" : "icon_60pt@2x.png", 41 | "idiom" : "iphone", 42 | "scale" : "2x", 43 | "size" : "60x60" 44 | }, 45 | { 46 | "filename" : "icon_60pt@3x.png", 47 | "idiom" : "iphone", 48 | "scale" : "3x", 49 | "size" : "60x60" 50 | }, 51 | { 52 | "filename" : "icon_20pt.png", 53 | "idiom" : "ipad", 54 | "scale" : "1x", 55 | "size" : "20x20" 56 | }, 57 | { 58 | "filename" : "icon_20pt@2x-1.png", 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "20x20" 62 | }, 63 | { 64 | "filename" : "icon_29pt.png", 65 | "idiom" : "ipad", 66 | "scale" : "1x", 67 | "size" : "29x29" 68 | }, 69 | { 70 | "filename" : "icon_29pt@2x-1.png", 71 | "idiom" : "ipad", 72 | "scale" : "2x", 73 | "size" : "29x29" 74 | }, 75 | { 76 | "filename" : "icon_40pt.png", 77 | "idiom" : "ipad", 78 | "scale" : "1x", 79 | "size" : "40x40" 80 | }, 81 | { 82 | "filename" : "icon_40pt@2x-1.png", 83 | "idiom" : "ipad", 84 | "scale" : "2x", 85 | "size" : "40x40" 86 | }, 87 | { 88 | "filename" : "icon_76pt.png", 89 | "idiom" : "ipad", 90 | "scale" : "1x", 91 | "size" : "76x76" 92 | }, 93 | { 94 | "filename" : "icon_76pt@2x.png", 95 | "idiom" : "ipad", 96 | "scale" : "2x", 97 | "size" : "76x76" 98 | }, 99 | { 100 | "filename" : "icon_83.5@2x.png", 101 | "idiom" : "ipad", 102 | "scale" : "2x", 103 | "size" : "83.5x83.5" 104 | }, 105 | { 106 | "filename" : "Icon.png", 107 | "idiom" : "ios-marketing", 108 | "scale" : "1x", 109 | "size" : "1024x1024" 110 | } 111 | ], 112 | "info" : { 113 | "author" : "xcode", 114 | "version" : 1 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_20pt@3x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_29pt@3x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_40pt@3x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_60pt@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_60pt@3x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_76pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_76pt.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_76pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_76pt@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gorhom/react-native-animated-tabbar/5ba6ec5374314b88235e270ef28540957c1c4cdb/example/ios/AnimatedTabbarExample/Images.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | AnimatedTabbar Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UILaunchStoryboardName 43 | Launch Screen 44 | UIRequiredDeviceCapabilities 45 | 46 | armv7 47 | 48 | UISupportedInterfaceOrientations 49 | 50 | UIInterfaceOrientationPortrait 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/Launch Screen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 25 | 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 | -------------------------------------------------------------------------------- /example/ios/AnimatedTabbarExample/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '10.0' 2 | require_relative '../node_modules/react-native/scripts/react_native_pods' 3 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 4 | 5 | target 'AnimatedTabbarExample' do 6 | config = use_native_modules! 7 | 8 | use_react_native!(:path => config["reactNativePath"]) 9 | 10 | # Enables Flipper. 11 | # 12 | # Note that if you have use_frameworks! enabled, Flipper will not work and 13 | # you should disable these next few lines. 14 | use_flipper!({'Flipper' => '0.75.1', 'Flipper-Folly' => '2.5.3', 'Flipper-RSocket' => '1.3.1'}) 15 | post_install do |installer| 16 | flipper_post_install(installer) 17 | 18 | installer.pods_project.build_configurations.each do |config| 19 | config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const blacklist = require('metro-config/src/defaults/blacklist'); 4 | const escape = require('escape-string-regexp'); 5 | 6 | const root = path.resolve(__dirname, '..'); 7 | const pak = JSON.parse( 8 | fs.readFileSync(path.join(root, 'package.json'), 'utf8') 9 | ); 10 | 11 | const modules = [ 12 | '@babel/runtime', 13 | ...Object.keys({ 14 | ...pak.dependencies, 15 | ...pak.peerDependencies, 16 | }), 17 | ]; 18 | 19 | module.exports = { 20 | projectRoot: __dirname, 21 | watchFolders: [root], 22 | 23 | resolver: { 24 | blacklistRE: blacklist([ 25 | new RegExp(`^${escape(path.join(root, 'node_modules'))}\\/.*$`), 26 | ]), 27 | 28 | extraNodeModules: modules.reduce((acc, name) => { 29 | acc[name] = path.join(__dirname, 'node_modules', name); 30 | return acc; 31 | }, {}), 32 | }, 33 | 34 | transformer: { 35 | getTransformOptions: async () => ({ 36 | transform: { 37 | experimentalImportSupport: false, 38 | inlineRequires: true, 39 | }, 40 | }), 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gorhom/animated-tabbar-example", 3 | "description": "Example app for @gorhom/animated-tabbar", 4 | "version": "0.0.1", 5 | "private": true, 6 | "scripts": { 7 | "android": "react-native run-android", 8 | "ios": "react-native run-ios", 9 | "start": "react-native start" 10 | }, 11 | "dependencies": { 12 | "@gorhom/showcase-template": "^1.0.2", 13 | "@react-native-community/masked-view": "^0.1.10", 14 | "@react-navigation/bottom-tabs": "^5.9.2", 15 | "@react-navigation/native": "^5.7.6", 16 | "@react-navigation/stack": "^5.9.3", 17 | "lodash.isequal": "^4.5.0", 18 | "react": "16.13.1", 19 | "react-native": "0.63.3", 20 | "react-native-gesture-handler": "^1.8.0", 21 | "react-native-reanimated": "1.13.1", 22 | "react-native-redash": "14.2.4", 23 | "react-native-safe-area-context": "^3.1.8", 24 | "react-native-screens": "^2.11.0", 25 | "react-native-svg": "^12.1.0" 26 | }, 27 | "devDependencies": { 28 | "@babel/core": "^7.11.6", 29 | "@babel/runtime": "^7.11.2", 30 | "@types/react": "^16.9.51", 31 | "@types/react-native": "^0.63.25", 32 | "metro-react-native-babel-preset": "^0.63.0", 33 | "rn-snoopy": "^2.0.2", 34 | "typescript": "4.0.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { NavigationContainer } from '@react-navigation/native'; 3 | import { createStackNavigator } from '@react-navigation/stack'; 4 | import RootScreen from './screens/Root'; 5 | 6 | const Stack = createStackNavigator(); 7 | 8 | export default function App() { 9 | return ( 10 | 11 | 12 | 13 | 14 | {/* Bubble Preset */} 15 | require('./screens/bubble/Bubble').default} 18 | /> 19 | require('./screens/bubble/BubbleStyled').default} 22 | /> 23 | require('./screens/bubble/BubbleRTL').default} 26 | /> 27 | 30 | require('./screens/bubble/BubbleStandalone').default 31 | } 32 | /> 33 | 34 | {/* Flashy Preset */} 35 | require('./screens/flashy/Flashy').default} 38 | /> 39 | require('./screens/flashy/FlashyStyled').default} 42 | /> 43 | require('./screens/flashy/FlashyRTL').default} 46 | /> 47 | 50 | require('./screens/flashy/FlashyStandalone').default 51 | } 52 | /> 53 | 54 | {/* Material Preset */} 55 | 58 | require('./screens/material/Material').MaterialIconWithLabelScreen 59 | } 60 | /> 61 | 64 | require('./screens/material/Material').MaterialIconOnlyScreen 65 | } 66 | /> 67 | 70 | require('./screens/material/Material') 71 | .MaterialIconWithLabelOnFocusScreen 72 | } 73 | /> 74 | 77 | require('./screens/material/MaterialStyled').default 78 | } 79 | /> 80 | require('./screens/material/MaterialRTL').default} 83 | /> 84 | 87 | require('./screens/material/MaterialStandalone').default 88 | } 89 | /> 90 | 91 | 92 | ); 93 | } 94 | -------------------------------------------------------------------------------- /example/src/components/badge/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo, useMemo, useState, useEffect } from 'react'; 2 | import { View, StyleSheet, Text } from 'react-native'; 3 | 4 | interface BadgeProps { 5 | iconSize: number; 6 | } 7 | 8 | const BADGE_SIZE = 10; 9 | 10 | const BadgeComponent = ({ iconSize }: BadgeProps) => { 11 | const [count, setCount] = useState(1); 12 | const containerStyle = useMemo( 13 | () => ({ 14 | ...styles.container, 15 | transform: [ 16 | { translateX: (iconSize - BADGE_SIZE / 1.5) / 2 }, 17 | { translateY: (iconSize - BADGE_SIZE / 1.5) / -2 }, 18 | ], 19 | }), 20 | [iconSize] 21 | ); 22 | 23 | useEffect(() => { 24 | const intervalId = setInterval(() => setCount(state => state + 1), 2500); 25 | return () => { 26 | clearInterval(intervalId); 27 | }; 28 | }, []); 29 | 30 | return ( 31 | 32 | {count} 33 | 34 | ); 35 | }; 36 | 37 | const Badge = memo(BadgeComponent); 38 | 39 | const styles = StyleSheet.create({ 40 | container: { 41 | position: 'absolute', 42 | alignSelf: 'center', 43 | minWidth: BADGE_SIZE, 44 | minHeight: BADGE_SIZE, 45 | borderRadius: BADGE_SIZE, 46 | backgroundColor: 'red', 47 | }, 48 | count: { 49 | color: 'white', 50 | fontWeight: 'bold', 51 | textAlign: 'center', 52 | margin: 1, 53 | lineHeight: BADGE_SIZE, 54 | fontSize: 6, 55 | }, 56 | }); 57 | 58 | export default Badge; 59 | -------------------------------------------------------------------------------- /example/src/components/badge/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Badge'; 2 | -------------------------------------------------------------------------------- /example/src/components/button/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text, TouchableOpacity, StyleSheet } from 'react-native'; 3 | 4 | interface ButtonProps { 5 | label: string; 6 | onPress: () => void; 7 | } 8 | 9 | const Button = ({ label, onPress }: ButtonProps) => { 10 | return ( 11 | 12 | {label} 13 | 14 | ); 15 | }; 16 | 17 | const styles = StyleSheet.create({ 18 | container: { 19 | padding: 6, 20 | borderRadius: 2, 21 | backgroundColor: '#eee', 22 | }, 23 | label: { 24 | textTransform: 'capitalize', 25 | }, 26 | }); 27 | 28 | export default Button; 29 | -------------------------------------------------------------------------------- /example/src/components/button/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Button'; 2 | -------------------------------------------------------------------------------- /example/src/components/iconWithBadge/IconWithBadge.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | import HomeSVG from '../../svg/HomeSVG'; 3 | import Badge from '../badge'; 4 | import { SVGProps } from '../../svg/types'; 5 | 6 | const IconWithBadgeComponent = (props: SVGProps) => { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | ); 13 | }; 14 | 15 | const IconWithBadge = memo(IconWithBadgeComponent); 16 | 17 | export default IconWithBadge; 18 | -------------------------------------------------------------------------------- /example/src/components/iconWithBadge/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './IconWithBadge'; 2 | -------------------------------------------------------------------------------- /example/src/screens/Dummy.tsx: -------------------------------------------------------------------------------- 1 | import React, { useMemo, useRef, useEffect, useCallback } from 'react'; 2 | import { Text, View, StyleSheet, Alert } from 'react-native'; 3 | import { FlatList } from 'react-native-gesture-handler'; 4 | import { 5 | useRoute, 6 | RouteProp, 7 | useScrollToTop, 8 | useNavigation, 9 | } from '@react-navigation/native'; 10 | import Button from '../components/button'; 11 | import { MainTabsParams } from './types'; 12 | import { useSafeArea } from 'react-native-safe-area-context'; 13 | 14 | const data = Array(20) 15 | .fill(0) 16 | .map((item, index) => ({ 17 | id: `item-${index}`, 18 | title: `Item ${index}`, 19 | })); 20 | 21 | const DummyScreen = () => { 22 | // safe area 23 | const { top } = useSafeArea(); 24 | 25 | // scroll event 26 | const flatlistRef = useRef(null); 27 | useScrollToTop(flatlistRef); 28 | 29 | // route name 30 | const { name, params } = useRoute>(); 31 | const screeName = useMemo(() => params?.name || name, [params, name]); 32 | const paddingBottom = useMemo(() => params?.paddingBottom || 0, [params]); 33 | const { navigate, addListener } = useNavigation(); 34 | 35 | // style 36 | const rootStyle = useMemo( 37 | () => [ 38 | styles.root, 39 | { 40 | backgroundColor: params?.backgroundColor || 'white', 41 | }, 42 | ], 43 | [params] 44 | ); 45 | const contentContainerStyle = useMemo( 46 | () => [ 47 | styles.flatlistContainer, 48 | { 49 | paddingBottom, 50 | }, 51 | ], 52 | [paddingBottom] 53 | ); 54 | const headerStyle = useMemo( 55 | () => [ 56 | styles.header, 57 | { 58 | paddingTop: top, 59 | backgroundColor: params?.backgroundColor || 'white', 60 | }, 61 | ], 62 | [params, top] 63 | ); 64 | 65 | // effects 66 | useEffect(() => { 67 | // @ts-ignore 68 | const unsubscribe = addListener('tabLongPress', () => { 69 | // Do something 70 | Alert.alert(screeName, 'Long Press !'); 71 | }); 72 | 73 | return unsubscribe; 74 | }, [addListener, screeName]); 75 | 76 | // callbacks 77 | const handleNextScreenPress = useCallback(() => { 78 | navigate(params.nextScreen); 79 | }, [navigate, params]); 80 | 81 | // renders 82 | const renderHeader = () => ( 83 | 84 | {screeName} 85 |