kureev / react-native-side-menu Goto Github PK
View Code? Open in Web Editor NEWSide menu component for React Native
License: MIT License
Side menu component for React Native
License: MIT License
Within a child component or menu, the menuActions prop seems to be an empty object. Thoughts on why this might be?
On a given scene, how can the menuAction methods be utilized from one of the bar buttons on the top nav bar?
Naturally, I am setting up the navbar buttons in the previous (from where I intend on using the react-native-side-menu). For example, I include the "onRightButtonPress()" function as a parameter when using "this.props.navigator.push()' function in the previous scene.
I have a button which I would like to control the menu with, but I'm not sure of the suggested way to open/collapse the menu from an external component. Is there a way to get the ref and call a .toggle() on the menu?
Edit - seems the solution is pretty simple, you just need something like:
<SideMenu
ref='slideMenu'
menu={menu}>
this.refs.slideMenu.toggleMenu();
I would still recommend putting something into the README about this.
I want create left and right menu.please tell me how to do it?
I am having an issue with an iPad Air in portrait mode. It doesnt take the full height of the screen.
Have also tested using the example on here.
I'm trying to implement a Scrollview or Listview in either a NavigatorIOS or regular Navigator component. In 0.2.4 this doesn't work. In 0.2.3 it does work. Related to: #4
Here is a gist:
https://gist.github.com/swennemans/2cbfce22c388e7b8132d
When we rotate device (for example, rotate iphone left or right), everything will automatically adjust from portrait mode to landscape mode for all react native UI components on ios8 devices. But this feature broken when we add side menu.
Here are some pictures and codes:
We can see that top SegmentedControl and bottom TabBar all stretched correctly, but center content which wrapped in a SideMenu tag will always keep the portrait mode width (Even we start with landscape mode, it will still use portrait width, this is weird)
<SideMenu
ref='sideMenu'
openMenuOffset={Constants.STYLE.SIDE_MENU_WIDTH}
animation={'spring'}
disableGestures={true}
menu={<ReportMenu report={this.props.report}/>}>
<View style={styles.container}>
some contents here
</View>
</SideMenu>
But if we remove side menu, everything works great when we rotate device (see background color):
<View style={styles.container}>
some contents here
</View>
Use flex: 1 style doesn't help. Any solution or suggestion?
I have a view with a horizontal ScrollView
in it and I find myself accidentally opening the menu too often. I've played around with the toleranceX
prop a little bit, and this does help - but not completely.
I find it weird that you can drag somewhere very far away from the edge of the screen and have it still trigger the menu. Would it be possible to add a prop like edgeTolerance
where I could specify 40
and only touches that originate 40px from the edge can trigger the menu?
This would definitely prevent accidental menu openings when interacting with my horizontal ScrollView
I want to use Navigator component with react-native-side-menu. You have mentioned the navigator props in the example but i'm not sure where the navigator is coming from ?
It would be very helpful if you can post an example with some links on sidebar changing the pages on right hand side while retaining the sidebar menu.
I tried to replicate the sidebar menu component on every page with navigator as top level component but it says expected a Component class, got [object Object]
I decided to wrote another example for this. Here is image and code:
On clicking About link, this error occurs!
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var SideMenu = require('react-native-side-menu');
var {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
} = React;
var ContentView = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
});
var TestView = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to another page.
</Text>
<Text style={styles.instructions}>
Testing react native side menu with navigator.
</Text>
</View>
);
}
});
var Menu = React.createClass({
about: function() {
this.props.menuActions.close();
this.props.navigator.push({
component: TestView,
title: 'Test View',
});
},
render: function() {
return (
<View style={styles.sidemenu}>
<Text style={styles.paddingMenuItem}>Menu</Text>
<Text onPress={this.about} style={styles.paddingMenuItem}>About</Text>
</View>
);
}
});
var SideMenuTest = React.createClass({
render: function() {
return (
<Navigator
initialRoute={{
component: Something,
title: 'Something',
}}
configureScene={() => {
return Navigator.SceneConfigs.FadeAndroid;
}}
renderScene={(route, navigator) => {
if(route.component) {
return React.createElement(route.component, { navigator });
}
}}/>
);
}
});
var Something = React.createClass({
render: function() {
var menu = <Menu navigator={this.props.navigator}/>;
return (
<SideMenu menu={menu}>
<ContentView/>
</SideMenu>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
sidemenu: {
paddingTop: 50,
},
paddingMenuItem: {
padding: 10,
},
});
AppRegistry.registerComponent('SideMenuTest', () => SideMenuTest);
<SideMenu menu={menu}>
<Listview ...>
</SideMenu>
Look at the source code, onStartShouldSetPanResponder is true, so maybe scrollview cover.
Do not know how to solve the problem?
In this README.md:
https://github.com/Kureev/react-native-side-menu/blob/master/examples/simple/README.md
this doesn't work for me due to lack of permissions:
"First of all, clone repo to your computer
$ git clone [email protected]:Kureev/react-native-side-menu.git"
this works for me:
git clone https://github.com/Kureev/react-native-side-menu.git
First, thanks for making this great side panel. By far the smoothest animation of all the implementations I've tried! Plus, it does a great job of canceling other events while panning.
I noticed in the latest version there's a typo that causes my apps to crash. It's just a wayward semicolon.
https://github.com/Kureev/react-native-side-menu/blob/master/index.js#L194
The menu example seems to work perfectly in the IOS Simulator. But when I try to run it on my device (iPhone 5S), it doesn't work as expected. The menu shows up once in a while.
Scenario:
I'm using the side menu to open a view for filtering a list. The Filters Component is the "menu" and the Master Component is a table inside a navigator. After selecting an item in my table, the Detail Component is pushed onscreen. At this point, I'd like to disable the side-menu since filters are no longer needed.
I attempted this to no avail:
this.refs.sideMenu.disableGestures = true;
Thoughts?
I'm trying to add a navbar with a button that should toggle the menu, but can't find where menuActions are exposed.
I tried various ideas with this.toggleMenu and having toggleMenu
as a function in the menu class, but don't get it to work.
Any ideas?
var menu = <Menu navigator={nav}/>;
return (
<View>
<View>
<TouchableOpacity onPress={() => menu.toggleMenu()}>
<Text>Click</Text>
</TouchableOpacity>
<View>
<Text>
MyApp
</Text>
</View>
</View>
<SideMenu menu={menu}>
<ItemView navigator={nav} />
</SideMenu>
</View>
);
I made the following change in my app to get the scrolling to be smooth in the main list view. Otherwise it would periodically get stuck because of horizontal movements of the side menu.
handleMoveShouldSetPanResponder: function(e: Object, gestureState: Object) {
var x = Math.round(Math.abs(gestureState.dx));
var y = Math.round(Math.abs(gestureState.dy));
if (x > 10 && y < 10) {
return true;
}
return false;
},
Hi,
Very good job with this menu! I have a problem though...
It's probably me, but I can't find out how to create a navigation that works. By following your example, I just filled the blanks in navigator.push with a title and another component containing a simple View.
Doing this, I keep having the same mistake:
"undefined is not a function (evaluating this.props.navigator.push({title: 'Homepage', component: Homepage})') "
Could you please help me out?
Am I supposed to add a Navigator somewhere?
I've installed the react-native-side-menu
package and it blocks the scrollview for some reason. When I remove the sidemenu, my ListView and ScrollView works as expected. I don't know why is this happening. A simple example could be made by installing the react-native-side-menu and using ListView as sample component or ScrollView with many Text components. It could be seen that UI will have scrolling issues.
Getting this unmet peer dependency error on installation.
npm ERR! peerinvalid The package react-native does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants react-native@>= 0.4
here's the package.json
{
"name": "rn_hn",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node_modules/react-native/packager/packager.sh"
},
"dependencies": {
"firebase": "2.2.6",
"flux": "^2.0.3",
"keymirror": "^0.1.1",
"lodash": "3.9.3",
"moment": "2.10.3",
"object-assign": "^3.0.0",
"q": "1.4.1",
"react-native": "0.6.0-rc",
"react-native-htmlview": "0.1.2",
"url": "0.10.3"
}
}
Does rc qualify as a version ? the ">=0.4" check seems to be failing which is odd, any ideas ?
If you have a ScrollView
as content of SlideMenu
, toleranceX
and toleranceY
are not helping with the current implementation. After digging, I realize that this line, return x != this.props.toleranceX && y < this.props.toleranceY;
needs to be changed to return x > this.props.toleranceX && y < this.props.toleranceY;
in order for them to work properly.
Does it make sense?
As per latest changelog, looks like Dimensions shouldn't be required as a standalone module, but from React package instead, e.g.:
import {Dimensions} from 'react-native';
Currently, it prints warnings.
How would you implement close slide menu if the menu is already open by tapping outside of menu?
Hi,
Thanks a lot for sharing this component!!
Maybe i'm doing something wrong, but i can't incorporate the menu in an empty react-native app :(
Code:
https://gist.github.com/borillo/705123948e706c55c9fe
Thanks a lot in advance!!
ok, I think we need to change couple of things and I want to know your (@Kureev) opinion about it.
based on this ticket, facebook/react-native#1808, we should change some code as follows:
instead of this:
var deviceScreen = require('Dimensions').get('window');
we should do it this way
var { Dimensions } = require('react-native');
var deviceScreen = Dimensions.get('window');
if you don't do it you will get this annoying error from packager
.
Unable to resolve module Dimensions ...
what do you think? I really liked the idea of @providesModule
in comment which makes it a lot easier to find a module. It seems that this feature will be removed. I don't know for sure.
Hey, just finished playing around with the code, and following:
import SideMenu from 'react-native-side-menu';
export default class Menu extends SideMenu {
updatePosition() {
var style = {};
var scaleFactor = this.left > 0
? this.left / this.props.scaleFactor / 100
: 1;
style.transform = [{
scale: scaleFactor
}];
this.sideMenu.setNativeProps({
left: this.left,
style: style
});
}
}
DefaultProps:
Can we implement it by exporting a ScaleMenu
class that will extend Menu
and override the above method + add two more props described above? Simple.
In some of my apps I'm using a to apply background color to the "main content" but this style(https://github.com/Kureev/react-native-side-menu/blob/master/styles.js#L26) overrides that tag.
When I set the backgroundColor to transparent on frontView I'm able to use the LinearGradient correctly.
Can I have it banned in some views? I just need to go back.
Should be a matter of setting a prop disableGesturesWhenMenuOpened
or something + pointerEvents: none
when isOpen. What do you think?
Hi, Thanks for the module, it looks great.
Is their any way of creating a inner shadow to the menu block.
:0)
So it's overridable and we can easily ignore animationKind
and provide own LayoutAnimations. Just an idea, as I am not that happy with the current one and I am investigating changing the LayoutAnimations to something different at all.
There is an issue after version 0.8( till latest version 0.9.2) which mix side menu contents with main contents together.
This happens when main contents wrapped in a ScrollView. If main contents is a WebView, it is OK.
And this issue happens after version 0.8. version 0.7 without any problem.
Here is my code:
<SideMenu
ref='sideMenu'
openMenuOffset={Constants.STYLE.SIDE_MENU_WIDTH}
animation={'spring'}
disableGestures={true}
menu={<ReportMenu report={this.props.report}/>}>
<View style={styles.container}>
<View style={styles.controlBar}>
</View>
<ScrollView>
<View key={index}>
<Text> label: {component.label} </Text>
<Text> Type: {component.type} </Text>
<Text> Sheet: {WptService.getSheetById(component.sheetId).name} </Text>
</View>
</ScrollView>
</View>
</SideMenu>
var styles = StyleSheet.create({
container: {
flex: 1,
},
controlBar: {
flexDirection: 'row',
backgroundColor: Constants.STYLE.LEVEL1_MENU_BACKGROUND,
},
countText: {
flex: 1,
flexDirection: 'column'
},
webView: {
flex: 1,
},
});
menuPosition
property in cases of using menu on the right side (will be opened by slide right-to-left)I was playing around with the package to use in combination with NavigatorIOS. I've got it to work, but I'm not 100% sure if this is the best practice. From the example it looks like you somehow pass NavigatorIOS as props to the menu. However, in my case the <SideMenu/>
is the parent of <NavigatorIOS/>
and therefore I use this.refs
and call the function using this.props
. Here is the gist:
https://gist.github.com/swennemans/59f656f02497d0df6572
Do you take another approach? What is the benefit (besides your approach looks cleaner).
Thanks :)
Do you think we really need bind
for this? I think react will do it automatically. Any thoughts on that?
I've been heavily using this component. if you just try to open the side menu but in the middle of process decided to close the menu, forceUpdate is going to happen which is unnecessary. I will try to provide a PR.
Hi guys,
Thanks for this awesome component, I'm trying to play with it but I don't find any property to open the menu from outside the Menu component (I need to open the menu from my NavBar).
I think we should simply add an isOpen={Boolean}
property on the component and in the componentWillReceiveProps
event, update isOpen and call the toggleMenu method.
What do you think about it ?
When subview has a TouchableOpacity properties, the side menu has not any response?
so that I can not move the Side Menu out... Is that responser conflict to subview's properties?
Here is my project if you need:
https://github.com/leanote/leanote-ios
Thanks a lot :)
Hi! I've been working on this for a couple days now and just can't figure it out. I've gotten the menu to appear vertically instead of horizontally, and messed with some of the offsets & margins to make it align properly. I also eliminated content from overlay, and only kept frontView – with frontView serving as my menu, resting on top of my content that is beneath. I did it this way because I already had a lot of code for the app done, and this seemed simpler (is this my problem?).
So, here's the issue: whenever I launch the app, or navigate to a new screen, the menu appears front and center. Changing variables like touchToClose and isOpen aren't fixing it. Here are more details and some thoughts:
Is it possible that iOS (or react native) doesn’t allow an item to be rendered off screen initially? I ask because of this behavior:
When I change the openMenuOffset to something extreme (too far south), it still appears in the exact same spot for (1). But, for (3), it behaves properly and falls too far south.
Another interesting thing is whenever I load a new screen, menu reappears as in (1).
Any thoughts? I'm also happy to revert back to your menu and redo my vertical implementation if you have a better idea on how to execute. I essentially want my logo in the center to launch a slide-down menu from top to bottom. I'm using react-native-router, and setting
titleComponent:MainMenu
Thank you!
INDEX.js
(Note: I changed "left" to "top", just for my own sake / preventing confusion)
var React = require('react-native');
var deviceScreen = require('Dimensions').get('window');
var styles = require('./styles');
var queueAnimation = require('./animations');
var {
PanResponder,
View,
TouchableWithoutFeedback,
Component,
} = React;
/**
* Default open menu offset. Describes a size of the amount you can
* move content view from the top and release without opening it
* @type {Number}
*/
var openMenuOffset = deviceScreen.height * 1/50;
/**
* Content view offset in the `hidden` state
* @type {Number}
*/
var hiddenMenuOffset = -655;
/**
* Size of the amount you can move content view in the opened menu state and
* release without menu closing
* @type {Number}
*/
var barrierForward = deviceScreen.height / 4;
/**
* Check if the current gesture offset bigger than allowed one
* before opening menu
* @param {Number} dx Gesture offset from the top Top of the window
* @return {Boolean}
*/
function shouldOpenMenu(dx: Number) {
return dx > barrierForward;
}
/**
* no operation function. does nothing.
*/
function noop() {}
class TopMenu extends Component {
constructor(props) {
super(props);
/**
* Current state of the menu, whether it is open or not
* @type {Boolean}
*/
this.isOpen = false;
/**
* Current style `top` attribute
* @todo Check if it's possible to avoid using `top`
* @type {Number}
*/
this.top = 0;
/**
* Default top offset for content view
* @todo Check if it's possible to avoid using `prevtop`
* @type {Number}
*/
this.prevtop = 0;
}
/**
* Creates PanResponders and links to appropriate functions
* @return {Void}
*/
createResponders(disableGestures) {
if (disableGestures || false) {
this.responder = PanResponder.create({});
return;
}
this.responder = PanResponder.create({
onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder.bind(this),
onPanResponderMove: this.handlePanResponderMove.bind(this),
onPanResponderRelease: this.handlePanResponderEnd.bind(this),
});
}
/**
* Set the initial responders
* @return {Void}
*/
componentWillMount() {
this.createResponders(this.props.disableGestures);
}
/**
* Update responders on new props whenever possible
* @return {Void}
*/
componentWillReceiveProps(nextProps) {
this.createResponders(nextProps.disableGestures);
}
/**
* Change `top` style attribute
* Works only if `TopMenu` is a ref to React.Component
* @return {Void}
*/
updatePosition() {
this.TopMenu.setNativeProps({ top: this.top, });
}
/**
* Permission to use responder
* @return {Boolean} true
*/
handleMoveShouldSetPanResponder(e: Object, gestureState: Object) {
var x = Math.round(Math.abs(gestureState.dx));
var y = Math.round(Math.abs(gestureState.dy));
return x > this.props.toleranceX && y < this.props.toleranceY;
}
/**
* Handler on responder move
* @param {Synthetic Event} e
* @param {Object} gestureState
* @return {Void}
*/
handlePanResponderMove(e: Object, gestureState: Object) {
this.top = this.prevtop + gestureState.dx;
if ((this.menuPositionMultiplier() * this.top) > 0) {
this.updatePosition();
}
}
/**
* Returns 1 or -1 depending on the menuPosition
* @return {Number}
*/
menuPositionMultiplier() {
return this.props.menuPosition === 'bottom' ? -1 : 1;
}
/**
* Open menu
* @return {Void}
*/
openMenu() {
queueAnimation(this.props.animation);
this.top = this.menuPositionMultiplier() *
(this.props.openMenuOffset || openMenuOffset);
this.updatePosition();
this.prevtop = this.top;
if (!this.isOpen) {
this.props.onChange(this.isOpen);
this.isOpen = true;
// Force update to make the overlay appear (if touchToClose is set)
if (this.props.touchToClose) {
this.forceUpdate();
}
}
}
/**
* Close menu
* @return {Void}
*/
closeMenu() {
queueAnimation(this.props.animation);
this.top = this.menuPositionMultiplier() *
(this.props.hiddenMenuOffset || hiddenMenuOffset);
this.updatePosition();
this.prevtop = this.top;
if (this.isOpen) {
this.props.onChange(this.isOpen);
this.isOpen = false;
// Force update to make the overlay disappear (if touchToClose is set)
if (this.props.touchToClose) {
this.forceUpdate();
}
}
}
/**
* Toggle menu
* @return {Void}
*/
toggleMenu() {
if (this.isOpen) {
this.closeMenu();
} else {
this.openMenu();
}
}
/**
* Handler on responder move ending
* @param {Synthetic Event} e
* @param {Object} gestureState
* @return {Void}
*/
handlePanResponderEnd(e: Object, gestureState: Object) {
var shouldOpen = this.menuPositionMultiplier() *
(this.top + gestureState.dx);
if (shouldOpenMenu(shouldOpen)) {
this.openMenu();
} else {
this.closeMenu();
}
this.updatePosition();
this.prevtop = this.top;
}
handleOverlayPress(e: Object) {
this.closeMenu();
}
/**
* Get content view. This view will be rendered over menu
* @return {React.Component}
*/
getContentView() {
var getMenuActions = this.getMenuActions();
var overlay = null;
if (this.isOpen && this.props.touchToClose) {
overlay = (
<TouchableWithoutFeedback onPress={this.handleOverlayPress.bind(this)}>
<View style={styles.overlay} />
</TouchableWithoutFeedback>
);
}
var children = React.Children.map(this.props.children, (child) => {
return React.cloneElement(child, {
menuActions: getMenuActions,
});
});
return (
<View
style={styles.frontView}
ref={(TopMenu) => this.TopMenu = TopMenu}
{...this.responder.panHandlers}>
{children}
{overlay}
</View>
);
}
/**
* Get menu actions to expose it to
* menu and children components
* @return {Object} Public API methods
*/
getMenuActions() {
return {
close: this.closeMenu.bind(this),
toggle: this.toggleMenu.bind(this),
open: this.openMenu.bind(this),
};
}
/**
* Get menu view. This view will be rendered under
* content view. Also, this function will decorate
* passed `menu` component with Top menu API
* @return {React.Component}
*/
getMenuView() {
var menuActions = this.getMenuActions();
return (
<View style={styles.menu}>
{React.addons.cloneWithProps(this.props.menu, { menuActions, })}
</View>
);
}
/**
* Compose and render menu and content view
* @return {React.Component}
*/
render() {
return (
<View style={styles.container}>
{this.getContentView()}
</View>
);
}
}
TopMenu.propTypes = {
toleranceX: React.PropTypes.number,
toleranceY: React.PropTypes.number,
onChange: React.PropTypes.func,
touchToClose: React.PropTypes.bool,
};
TopMenu.defaultProps = {
toleranceY: 33,
toleranceX: -30,
onChange: noop,
touchToClose: false,
};
module.exports = TopMenu;
MAINMENU.js
'use strict';
var React = require('react-native');
var Menu = require('../../pages/MenuContent');
var SideMenu = require('react-native-side-menu');
// var Router = require('react-native-router');
var {
AppRegistry,
StyleSheet,
Text,
View,
Image,
ScrollView,
TouchableOpacity,
TouchableHighlight,
Component
} = React;
class Button extends Component {
handlePress(e) {
this.props.menuActions.toggle();
if (this.props.onPress) {
this.props.onPress(e);
}
}
render() {
return (
<TouchableOpacity
onPress={this.handlePress.bind(this)}>
<Text style={this.props.style}>{this.props.children}</Text>
</TouchableOpacity>
);
}
}
class MainMenu extends Component {
constructor(props) {
super(props);
this.state = {
touchToClose: false
};
}
handleOpenWithTouchToClose() {
this.setState({
touchToClose: false
});
}
handleChange(isOpen) {
if (!isOpen) {
this.setState({
touchToClose: false
});
}
}
render() {
return (
<SideMenu
menu={<Menu />}
touchToClose={this.state.touchToClose}
onChange={this.handleChange.bind(this)}>
<View style={styles.container}>
<Text style={styles.welcome}>
HLTHY
</Text>
<Text style={styles.menuItem}>
MENU ITEM 1
</Text>
<Text style={styles.separator}>
_____
</Text>
<Text style={styles.menuItem}>
MENU ITEM 2
</Text>
<Text style={styles.separator}>
_____
</Text>
<Text style={styles.menuItem}>
MENU ITEM 3
</Text>
<Text style={styles.separator}>
_____
</Text>
<Text style={styles.menuItem}>
MENU ITEM 4
</Text>
<Text style={styles.separator}>
_____
</Text>
<Text style={styles.menuItem}>
MENU ITEM 5
</Text>
</View>
<Button style={styles.toggleButton}>
HLTHY
</Button>
</SideMenu>
);
}
}
var styles = StyleSheet.create({
toggleButton: {
position: 'absolute',
bottom: 0,
backgroundColor: 'transparent',
color: 'white',
fontSize: 30,
borderRadius: 20,
marginLeft: -230,
marginTop: 30,
},
welcome: {
fontSize: 30,
textAlign: 'center',
margin: 10,
fontWeight: 'bold',
marginBottom: 30
},
menuItem: {
textAlign: 'center',
color: '#333333',
marginTop: 15,
fontSize: 20,
marginBottom: 15
},
separator: {
textAlign: 'center',
color: '#333333',
marginBottom: 15,
},
caption: {
fontSize: 20,
fontWeight: 'bold',
alignItems: 'center',
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'stretch',
backgroundColor: 'white',
marginLeft: -750,
marginTop: 0,
marginBottom: 30,
},
});
module.exports = MainMenu;
Can someone help me with using react-native-navbar with react-native-side-menu ?
Currently I'm doing like this, but the menu is under navbar :(
/**
* Sample React Native App
* https://github.com/facebook/react-native
*/
'use strict';
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
} = React;
var { Icon, } = require('react-native-icons');
var SideMenu = require('react-native-side-menu');
var NavigationBar = require('react-native-navbar');
var Menu = React.createClass({
about: function() {
this.props.menuActions.close();
// this.props.navigator.push({...});
},
render: function() {
return (
<View>
<Text>Menu</Text>
<Text onPress={this.about}>About</Text>
</View>
);
}
});
var ContentView = React.createClass({
render: function() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Icon
name='fontawesome|facebook-square'
size={70}
color='#3b5998'
style={styles.facebook}
/>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
});
var SideBar = React.createClass({
render: function() {
var menu = <Menu navigator={navigator}/>;
return (
<SideMenu menu={menu}>
<ContentView/>
</SideMenu>
);
}
});
var Docit = React.createClass({
renderScene: function(route, navigator) {
var Component = route.component;
var navBar = route.navigationBar;
if (navBar) {
navBar = React.addons.cloneWithProps(navBar, {
navigator: navigator,
route: route
});
}
return (
<View style={styles.navigator}>
{navBar}
<Component navigator={navigator} route={route} />
</View>
);
},
render: function() {
return (
<Navigator
style={styles.navigator}
renderScene={this.renderScene}
initialRoute={{
component: SideBar,
navigationBar: <NavigationBar title="Initial View"/>
}}
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
facebook: {
width: 70,
height: 70,
margin: 10
},
});
AppRegistry.registerComponent('Docit', () => Docit);
Is there any way SideMenu can update the content whether it's opened or closed?
For example, I need to do something as soon as the SideMenu opens. Any suggestion?
I am having difficulty implementing the side menu with a navigator.
Here is what I have:
var Application = React.createClass({
getInitialState: function() {
return { applicationView: <SourceList /> };
},
handleChange: function(e) {
this.setState({ applicationView: e });
},
render: function() {
var nav = <Navigator ref="nav" initialRoute={{name: 'Sources', index: 0}} renderScene={(scene, navigator) => this.setState({ applicationView: e })} />;
var menu = <Menu hiddenMenuOffset={10} close={true} navigator={nav} onChange={this.handleChange} />;
return (
<SideMenu menu={menu}>
{this.state.applicationView}
</SideMenu>
);
}
});
whenever I access this.props.navigator.push() in my
component, it isundefined
- obviously I am doing this wrong (sorry react noob here) but I cannot find an example of how to do it properly.
Could you elaborate in your readme how to actually implement this properly with a <Navigator />
component?
@Kureev, @skevy, have you guys seen Spotify app? As soon as you start dragging the menu, there is a nice animation happen behind the scene. Unfortunately there is no way for us to do this in current version. So I started to update the onChange
method. So now, as soon as menu gets dragged, onChange method gets called with a value between 0 and 1. Zero means slide menu is completely close, and 1 means that slide menu is opened.
I will do the PR in few mins.
p.s. I think we should start rewrite the code in class
way. I really don't like using .setNativeProps
In linear animation mise to set property: LayoutAnimation.Properties.opacity, see
facebook/react-native#1135 (comment)
Here is code in Animation.js:
linear: { duration: 300, create: { type: LayoutAnimation.Types.linear, }, update: { type: LayoutAnimation.Types.linear, springDamping: 0.7, }, },
It should be:
linear: { duration: 300, create: { type: LayoutAnimation.Types.linear, property: LayoutAnimation.Properties.opacity, }, update: { type: LayoutAnimation.Types.linear, springDamping: 0.7, property: LayoutAnimation.Properties.opacity, }, },
I ran into this issue when trying to render a menu component that was nested inside of another components view which I had no ability to set styles on such as flex: 1 or width and height in order to force layout.
Because of the menu component container view within react-native-side-menu has the style rule
menu: {
position: 'absolute',
top: 0,
left: 0
}
the container has no width or height. Setting an explicit width and height on the menu component with fix this issue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.