├── .gitattributes ├── .npmignore ├── LICENSE ├── ModernNavItem.js ├── README.md ├── Untitled.png ├── btn-shadow.png ├── chevron-up.png ├── img.gif ├── img1.gif ├── img2.gif ├── img3.gif ├── index.js ├── package.json └── shadow.png /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | 12 | 13 | # Xcode 14 | # 15 | build/ 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | *.xccheckout 26 | *.moved-aside 27 | DerivedData 28 | *.hmap 29 | *.ipa 30 | *.xcuserstate 31 | project.xcworkspace 32 | 33 | 34 | # Android/IntelliJ 35 | # 36 | build/ 37 | .idea 38 | .gradle 39 | local.properties 40 | *.iml 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Sajjad Asadi 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 | -------------------------------------------------------------------------------- /ModernNavItem.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | View, 4 | TouchableOpacity, 5 | Dimensions, 6 | ScrollView, 7 | ImageBackground, Animated,Image 8 | } from 'react-native'; 9 | 10 | let {height, width} = Dimensions.get('window'); 11 | 12 | export default class ModernNavItem extends Component { 13 | constructor(props) { 14 | super(props); 15 | this.state = { 16 | isOnTop: true, 17 | offsetY: new Animated.Value(40), 18 | fadeIn: new Animated.Value(0) 19 | }; 20 | openFab = openFab.bind(this); 21 | closeFab = closeFab.bind(this); 22 | } 23 | 24 | render() { 25 | return ( 26 | 27 | this.scrollView = ref} 28 | nestedScrollEnabled onMomentumScrollEnd={this.handleScroll}> 29 | 30 | 39 | 45 | {this.props.item.view} 46 | 47 | 48 | 49 | {!this.state.isOnTop && 50 | 59 | 63 | { 74 | this.scrollView.scrollTo({x: 0, y: 0, animated: true}) 75 | closeFab() 76 | } 77 | } 78 | > 79 | 80 | 81 | 82 | 83 | } 84 | 85 | ); 86 | } 87 | 88 | handleScroll = (event: Object) => { 89 | console.log(event.nativeEvent); 90 | if (this.state.isOnTop && parseInt(event.nativeEvent.contentOffset.y) > 0) { 91 | this.setState({isOnTop: false},()=>{ 92 | openFab() 93 | }) 94 | } else if (!this.state.isOnTop && parseInt(event.nativeEvent.contentOffset.y) <= 200) { 95 | console.log(event.nativeEvent.contentOffset.y); 96 | closeFab(); 97 | } 98 | } 99 | } 100 | 101 | export function openFab() { 102 | 103 | this.setState({open: true}, () => { 104 | Animated.parallel([ 105 | Animated.timing( 106 | this.state.fadeIn, 107 | { 108 | toValue: 1, 109 | duration: 500, 110 | useNativeDriver: true 111 | } 112 | ), 113 | Animated.timing( 114 | this.state.offsetY, 115 | { 116 | toValue: 0, 117 | duration: 300, 118 | useNativeDriver: true 119 | } 120 | ) 121 | ]).start(); 122 | 123 | }); 124 | 125 | 126 | } 127 | 128 | export function closeFab() { 129 | Animated.parallel([ 130 | Animated.timing( 131 | this.state.fadeIn, 132 | { 133 | toValue: 0, 134 | duration: 500, 135 | useNativeDriver: true 136 | } 137 | ), 138 | Animated.timing( 139 | this.state.offsetY, 140 | { 141 | toValue: 40, 142 | duration: 300, 143 | useNativeDriver: true 144 | } 145 | ) 146 | 147 | ]).start(() => this.setState({isOnTop: true})); 148 | 149 | } 150 | 151 | 152 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # install react-native-fancy-carousel-viewpager [![npm version](https://img.shields.io/npm/v/react-native-fancy-carousel-viewpager.svg)](https://www.npmjs.com/package/react-native-fancy-carousel-viewpager) 3 | 4 | 5 | 6 | 7 | 8 | ## Getting started 9 | 10 | `$ npm install react-native-fancy-carousel-viewpager --save` 11 | 12 | ## Usage 13 | ```javascript 14 | import React, {Component} from 'react'; 15 | import {StyleSheet, Text, View, Image, TouchableOpacity, Dimensions} from 'react-native'; 16 | import ModernNav,{openNav,closeNav} from 'react-native-fancy-carousel-viewpager'; // <-------------------- import library here 17 | import BrickList from 'react-native-masonry-brick-list'; 18 | import App21 from './App21'; 19 | import MyHeader from './MyHeader'; 20 | 21 | let {height, width} = Dimensions.get('window'); 22 | 23 | type Props = {}; 24 | export default class App extends Component { 25 | constructor(props) { 26 | super(props); 27 | this.state = { 28 | pageNumber: 1, 29 | listData: [ 30 | {id: '1', title: "Red", color: "#f44336", span: 1}, 31 | {id: '2', title: "Pink", color: "#E91E63", span: 2}, 32 | {id: '3', title: "Purple", color: "#9C27B0", span: 3}, 33 | {id: '4', title: "Deep Purple", color: "#673AB7", span: 1}, 34 | {id: '5', title: "Indigo", color: "#3F51B5", span: 1}, 35 | {id: '6', title: "Blue", color: "#2196F3", span: 1}, 36 | {id: '7', title: "Light Blue", color: "#03A9F4", span: 3}, 37 | {id: '8', title: "Cyan", color: "#00BCD4", span: 2}, 38 | {id: '9', title: "Teal", color: "#009688", span: 1}, 39 | {id: '10', title: "Green", color: "#4CAF50", span: 1}, 40 | {id: '11', title: "Light Green", color: "#8BC34A", span: 2}, 41 | {id: '12', title: "Lime", color: "#CDDC39", span: 3}, 42 | {id: '13', title: "Yellow", color: "#FFEB3B", span: 2}, 43 | {id: '14', title: "Amber", color: "#FFC107", span: 1}, 44 | {id: '15', title: "Orange", color: "#FF5722", span: 3}, 45 | ], 46 | } 47 | } 48 | 49 | 50 | render() { 51 | // an array of view (any your pages components 52 | // if your page just have a listview you can just put it in view i have scrollview inside) 53 | const data = [ 54 | { 55 | view: this.renderView(prop)} 58 | columns={3} 59 | /> 60 | }, 61 | { 62 | view: 63 | Welcome to React Native! 64 | To get started, edit App.js 65 | 66 | }, 67 | {view: }, 68 | ]; 69 | 70 | return ( 71 | 72 | 73 | {/** 74 | header can be a component showing when nothing scrolled at first 75 | data array page components 76 | pageChanged is event when you change a page 77 | **/} 78 | { 87 | this.setState({pageNumber}) 88 | }} 89 | //color of button when scroll a view bottom right 90 | topButtonColor={'#2196F3'} 91 | // inner navigation settings----------------- 92 | // if you want use navigation drawer inside of component 93 | useInnerNavigationDrawer={true} 94 | // if you want use navigation menu button top left of screen (false to hide button) 95 | useInnerNavigationButton={true} 96 | //icon that displayed on navigation menu button top left of screen you can use image or any icon library 97 | menuButtonIcon={} 98 | //color of navigation menu button top left of screen 99 | menuButtonColor={'#2196F3'} 100 | //navigation drawer item press event 101 | onNavigationItemPress={(item)=>{ 102 | console.log(item); 103 | closeNav(); 104 | }} 105 | //navigation drawer items list 106 | navigationData = {this.state.listData} 107 | //if you want to use image on navigation drawer like avatar image 108 | showImageOnNavigation={false} 109 | //image of navigation drawer 110 | navigationImageUri ='https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTwu7s_Ic3YioDVl9AmoJGsKbBuCKFVp2cD3KCPzdYlBLOcGmeV' 111 | /> 112 | 113 | ); 114 | } 115 | 116 | //render your header view here or you can pass another component 117 | renderHeader() { 118 | return ( 119 | 125 | 129 | page {this.state.pageNumber} 130 | Welcome to React Native! 131 | To get started, edit App.js 132 | 133 | ) 134 | } 135 | 136 | renderView = (prop) => { 137 | return ( 138 | 146 | {prop.title} 147 | 148 | ) 149 | }; 150 | } 151 | 152 | const styles = StyleSheet.create({ 153 | container: { 154 | flex: 1, 155 | justifyContent: 'center', 156 | alignItems: 'center', 157 | backgroundColor: '#EEEEEE', 158 | }, 159 | welcome: { 160 | fontSize: 20, 161 | textAlign: 'center', 162 | margin: 10, 163 | }, 164 | 165 | instructions: { 166 | textAlign: 'center', 167 | color: '#333333', 168 | marginBottom: 5, 169 | }, 170 | instructions2: { 171 | textAlign: 'center', 172 | color: 'white', 173 | marginBottom: 5, 174 | }, 175 | 176 | }); 177 | 178 | 179 | ``` 180 | -------------------------------------------------------------------------------- /Untitled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/Untitled.png -------------------------------------------------------------------------------- /btn-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/btn-shadow.png -------------------------------------------------------------------------------- /chevron-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/chevron-up.png -------------------------------------------------------------------------------- /img.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/img.gif -------------------------------------------------------------------------------- /img1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/img1.gif -------------------------------------------------------------------------------- /img2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/img2.gif -------------------------------------------------------------------------------- /img3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/img3.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Dimensions, 6 | ScrollView, 7 | Animated, 8 | TouchableOpacity, 9 | FlatList, 10 | Text, 11 | ImageBackground 12 | } from 'react-native'; 13 | import ModernNavItem from './ModernNavItem'; 14 | 15 | let {height, width} = Dimensions.get('window'); 16 | let lastPageNumber = 1; 17 | export default class ModernNav extends Component { 18 | 19 | constructor(props) { 20 | super(props); 21 | openNav = openNav.bind(this); 22 | closeNav = closeNav.bind(this); 23 | this.state = { 24 | showNavigation: false, 25 | fadeIn: new Animated.Value(0), 26 | } 27 | } 28 | 29 | render() { 30 | return ( 31 | 32 | 33 | 34 | {this.props.backgroundView} 35 | 36 | this.scrollView = ref} onMomentumScrollEnd={this.handleScroll} 37 | nestedScrollEnabled 38 | style={{flex: 1, borderRadius: 16, zIndex: 0}} horizontal={true}> 39 | 40 | {this.props.data.map((prop, index) => { 41 | return 47 | })} 48 | 49 | 50 | {this.state.showNavigation && this.props.useInnerNavigationDrawer && 51 | 60 | {this.props.showImageOnNavigation && 61 | 72 | } 73 | item.id} 78 | renderItem={this._renderItem} 79 | /> 80 | 81 | 82 | } 83 | {this.props.useInnerNavigationButton && 84 | 87 | { 90 | this.state.showNavigation ? closeNav() : openNav() 91 | }} 92 | > 93 | {this.props.menuButtonIcon} 94 | 95 | 96 | 97 | } 98 | 99 | 100 | 101 | ); 102 | } 103 | 104 | _renderItem = ({item}) => ( 105 | this.props.onNavigationItemPress(item)}> 106 | 107 | 108 | {item.title} 109 | 110 | 111 | 112 | ); 113 | handleScroll = (event: Object) => { 114 | const pageNumber = (Math.round(event.nativeEvent.contentOffset.x / (width + 8)) * (width + 8)) / (width + 8) + 1; 115 | 116 | this.scrollView.scrollTo({ 117 | x: Math.round(event.nativeEvent.contentOffset.x / (width + 8)) * (width + 8), 118 | y: 0, 119 | animated: true 120 | }) 121 | if (pageNumber !== lastPageNumber) { 122 | lastPageNumber = pageNumber; 123 | this.props.pageChanged(pageNumber) 124 | } 125 | } 126 | } 127 | 128 | 129 | const styles = StyleSheet.create({ 130 | container: { 131 | position: 'absolute', 132 | width: width, 133 | height: height, 134 | flexDirection: 'row', 135 | alignItems: 'center', 136 | justifyContent: 'center', 137 | }, 138 | header: { 139 | width: width, 140 | height: height 141 | }, 142 | customListContainer: { 143 | top: 0, 144 | left: 0, 145 | position: 'absolute', 146 | right: 0, 147 | }, 148 | headerContainer: { 149 | height: '100%', 150 | width: '100%', 151 | position: 'absolute', 152 | paddingBottom: '33%' 153 | }, 154 | navButton: { 155 | width: 60, 156 | height: 46, 157 | 158 | borderBottomRightRadius: 8, 159 | borderTopRightRadius: 8, 160 | alignItems: 'center', 161 | justifyContent: 'center', 162 | }, 163 | }); 164 | 165 | export function openNav() { 166 | 167 | this.setState({showNavigation: true}, () => { 168 | Animated.parallel([ 169 | Animated.timing( 170 | this.state.fadeIn, 171 | { 172 | toValue: 1, 173 | duration: 500, 174 | useNativeDriver: true 175 | } 176 | ) 177 | ]).start(); 178 | 179 | }); 180 | 181 | 182 | } 183 | 184 | export function closeNav() { 185 | Animated.parallel([ 186 | Animated.timing( 187 | this.state.fadeIn, 188 | { 189 | toValue: 0, 190 | duration: 500, 191 | useNativeDriver: true 192 | } 193 | ) 194 | 195 | ]).start(() => this.setState({showNavigation: false})); 196 | 197 | } 198 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | "author": { 4 | "name": "Sajjad Asadi", 5 | "email": "lvlr.xaus@gmail.com" 6 | }, 7 | "homepage": "https://github.com/lvlrSajjad/react-native-fancy-carousel-viewpager", 8 | "keywords": [ 9 | "react-native", 10 | "react-native-viewpager", 11 | "react-native-fancy-carousel", 12 | "react-native-carousel", 13 | "react-native-fancy-carousel-viewpager" 14 | ], 15 | "license": "MIT", 16 | "main": "index.js", 17 | "maintainers": [ 18 | { 19 | "name": "lvlrsajjad", 20 | "email": "lvlr.xaus@gmail.com" 21 | } 22 | ], 23 | "name": "react-native-fancy-carousel-viewpager", 24 | "optionalDependencies": {}, 25 | "peerDependencies": { 26 | "react-native": "^0.41.2", 27 | "react-native-windows": "0.41.0-rc.1" 28 | }, 29 | "readme": "ERROR: No README data found!", 30 | "scripts": { 31 | "test": "echo \"Error: no test specified\" && exit 1" 32 | }, 33 | "version": "1.0.4" 34 | } 35 | -------------------------------------------------------------------------------- /shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvlrSajjad/react-native-fancy-carousel-viewpager/afa58ac1a2ea6699147776998407758791899108/shadow.png --------------------------------------------------------------------------------