root-two / react-native-drawer Goto Github PK
View Code? Open in Web Editor NEWReact Native Drawer
License: MIT License
React Native Drawer
License: MIT License
The var deviceScreen = React.NativeModules.UIManager.Dimensions.window
module is not available in Android, and therefore needs to be updated.
Looking into what's necessary for a PR. Filing for book keeping.
cc @danscan
The spec on the drawer I'm supposed to build is:
I am able to accomplish most of these with the current code:
drawer.open()
when button is hitpanOpenMask={0.0}
to prevent slidingopenDrawerOffset={0.15}
to show 15% of itpanCloseMask={0.0}
to prevent sliding2 and 5 are a little hacky so I'd love it if there was a boolean slides={false}
. This might also allow you to completely stop all the pan listening and recording. I'm not sure the performance impact on that.
However, 4 does not seem to work. There has to be some panning. So the feature request is to be able to tap the "main" content to be able to close it. Ideally it would also prevent it from interacting with the main content.
Thanks.
I'm new to this package so forgive me if I don't have it setup properly. I'm trying to create a left and right drawer, which I have nested as suggested in an older issue.
It appears through some debugging that a dragged touch to close either panel below does not fire the onClose handler. I have a custom nav bar with a left and right button; those buttons call the open/close methods as shown below and the button press method does cause the appropriate drawer to fire it's onClose handler. In fact, it looks like it's firing onOpen of the other drawer.
Any suggestions?
toggleLeftDrawer: function() {
(this.state.leftDrawerOpen) ? this.refs.leftDrawer.close() : this.refs.leftDrawer.open();
},
toggleRightDrawer: function() {
(this.state.rightDrawerOpen) ? this.refs.rightDrawer.close() : this.refs.rightDrawer.open();
}
<Drawer
ref='leftDrawer'
type='static'
side='left'
content={<Text>Left Panel</Text>}
openDrawerOffset={100}
onOpen={this.openLeftDrawer}
onClose={this.closeDrawer}
styles={{main: {shadowColor: '#000000', shadowOpacity: 0.4, shadowRadius: 3}}}
tweenHandler={Drawer.tweenPresets.parallax}
>
<Drawer
ref='rightDrawer'
type='static'
side='right'
content={<Text>Right Panel</Text>}
openDrawerOffset={100}
onOpen={this.openRightDrawer}
onClose={this.closeDrawer}
styles={{main: {shadowColor: '#000000', shadowOpacity: 0.4, shadowRadius: 3}}}
tweenHandler={Drawer.tweenPresets.parallax}
>
<View>
...
</View>
</Drawer>
</Drawer>
Only on first time, second time if any menu item is touched its fine. Please see attached gif.
While testing i also notice that the drawer after menu item select on first time, forces to stay open, even though i am calling close per the code below (handleSection function).
index.ios.js
updateSelection(value){
this.setState({currentView: this.state.views[value]});
console.log('+++++++++was in updateSelection: '+this.state.currentView+' of '+this.state.views.length);
// this.refs.drawer.close()
},
ControlPanel.js
handleSection: function(value) {
console.log('calling handleSection with value ='+value)
this.props.updateSelection(value);
this.props.closeDrawer();
},
render(){
return (
<View style={styles.controlPanel}>
<View style={{paddingTop:50, backgroundColor: 'teal'}}>
<Image source={require('./img/logo.png')} style={{width: 100, height: 60, paddingTop: 40}} >
</Image>
</View>
<Button
onPress={this.props.closeDrawer}
text="Close Drawer"/>
<TouchableHighlight onPress={() => { this.handleSection('0') }} >
<View style={styles.drawerMenuItem}>
<Icon name="navicon" size={30} color="teal" />
<Text style={styles.drawerMenuItem}>
Tax and Audit
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={() => { this.handleSection('1') }}>
<View style={styles.drawerMenuItem}>
<Icon name="navicon" size={30} color="teal" />
<Text style={styles.drawerMenuItem}>
Latest Info
</Text>
</View>
</TouchableHighlight>
<TouchableHighlight onPress={() => { this.handleSection('2') }}>
<View style={styles.drawerMenuItem}>
<Icon name="navicon" size={30} color="teal" />
<Text style={styles.drawerMenuItem}>
Innovation and Technology
</Text>
</View>
</TouchableHighlight>
</View>
)
Ideally I would like to specify:
openDrawerOffset={.33}
openDrawerThreshold={.25}
But in this case, the threshold will apply to the opening of the drawer, but not the closing since it is already past .25
.
Also, it would be rad to specify different thresholds for opening and closing. Maybe that is one solution for this problem, if you want to maintain threshold as a percentage of screen width.
It was working fine with react-native v0.15 until i recently upgraded to v0.16 that I found out that it stucks packaging at react-native-drawer/index.js.
I am getting this twice in the output when running
react-native bundle --minify
Not sure how important it is.
Unable to resolve module Dimensions from /project_path/node_modules/react-native-drawer/index.js
I just cloned the repository locally and tried to run the example app, but I'm always getting the following message:
RNDrawerDemo[2640:380637] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'It looks like the implementationof DEV has changed. Update -[RCTBatchedBridge loadSource:].'
Any ideas?
When I logout a user, I disable the menu.
However, it may still be open, so I need to close it. So I user
componentWillUpdate(){
if(this.state.disabled)
this.refs.drawer.close();
},
However, the close method itself checks for the disabled state before it executes the close, preventing the menu from being closed. Not sure what the best way is to handle this. It's nice to have the control over the it, but it seems to make sense to autoclose when the drawer is disabled in an open state.
Hi man,
Got many warnings when opening or closing the drawer :
jsSchedulingOverhead (-2ms) should be positive.
Have you got any idea ?
Still trying to understand how react-native-drawer
works (maybe react native, more generally). In the below example, the Dashboard component has a ScrollView to allow panning in the vertical direction. This works great, except in the area where react-native-drawer
is waiting for the panGesture (the panOpenMask property). In this area, only a horizontal swipe is recognized and it opens/closes the drawer.
Is this the expected behavior, or can the vertical gestures be left to the ScrollView?
render: function() {
return (
<View style={styles.mainContainer}>
<Drawer
ref='leftDrawer'
content={<LeftDrawer />}
type='static'
side='left'
openDrawerOffset={75}
onOpen={this.openLeftDrawer}
onClose={this.closeDrawers}
styles={{main: {shadowColor: '#000000', shadowOpacity: 0.4, shadowRadius: 3}}}
tweenHandler={Drawer.tweenPresets.parallax}
tweenDuration={100}
>
<View style={styles.container}>
<NavBar toggleLeftDrawer={this.toggleLeftDrawer}/>
<Dashboard />
</View>
</Drawer>
</View>
Hi, do you have any suggestions on the best way to get a reference to the NavigatorIOS object. This will be called in a child of the Drawer. And the menu items in the Drawer will want to transition to the elements in the NavigatorIOS hierarchy.
The existing implementation uses tween-functions with requestAnimationFrame
and setNativeProps
to handle animations. This should actually be very performant, but there is potential to do more:
Animated API
shouldComponentUpdate -> false
temporarily for main and drawer views during animationI would like to have a shadow over the content area that is still visible when the drawer is open.
Ideally, I would like this to fade in as the drawer open and fade out as it closes.
Is this possible?
Using a fresh clone of the latest master (1.4.7), I follow instructions as described in README.md to build and run the example project in Xcode.
Xcode build fails because libRCTNetwork.a library cannot be built due to missing RCTNetworking.h and RCTNetworking.m source files.
Thoughts on a maxDrawerOpen
property? Use case is an app that is sometimes portrait, sometimes landscape.
I use openDrawerOffset={75}
which gives me the open drawer look I'm going for in portrait orientation. But in landscape, the drawer opens too far. My thought is that it'd be nice to have a max open width.
Feedback? Worth adding?
I have a Drawer and inside it a Navigator. When the Navigator is rendering a ListView, I can swipe backwards below the rows (if they don't go to the bottom of the screen) and it will open the drawer, but if I try to do it over the rows, it's captured as a RowPress and the navigator pushes the next route.
I know there is a CaptureGestures prop, but then it seems like there is a ton of necessary logic around allowing the gesture to pass though in every other scenario but I'm not sure how to do it.
One thought I had was to insert a View over the left portion of the screen above the ListView that attempted to conditionally capture the gestures, but then I don't know how to pass that to the Drawer.
Is there a better way? Thoughts on the right way to solve this?
Here is a preview of what I'm talking about:
It's dropped some frames (it glitches back and forth more times than once) but the gif still shows it.
How would you go about having two drawers, Slack style? In Slack there's a left and a right drawer that both can pop out. When trying it with react-native-drawer
I had trouble getting them on their own respective sides. I used the side
property with one on left and one on right but it didn't end up working.
My question relates to some Overlay Toasts I use. For instance, sometimes an overlay may be active when there is no network. Right now, if I activate the drawer it will underlay that existing Overlay, which lives as a child of Drawer.
I suppose that in case of a displace configuration, I would like it to slide out of the way. In the case of an overlay configuration, I would like Drawer to overlay the Overlay/Toast. I guess, I'm looking for a z-index kind of approach.
Is there a handler that fires at the start of an open or close? Or a way to mimic that behavior?
In the example project the jsCodeLocation in AppDelegate.m is set to '192.168.1.5:8081'. This was probably done for device testing, but prevents others from successfully running the project out of the box.
on 9.2 version, tap gesture cannot be recognized for gestureState.moveX is always larger than 25 in below code, unless you tap very very slightly.
handlePanResponderEnd (e, gestureState) {
if (gestureState.moveX < 25 && (Date.now() - this._panStartTime < 500)) {
this._panning = false
this.processTapGestures()
return
}
I get this.refs
as Object {}
and unable to open()
/close()
drawer
currently, in Examples
there's only project for iPhone
It seems like acceptPan={false}
doesn't work. I'm trying to allow only programmatically opening with this code:
<Drawer
ref="drawer"
type="static"
content={<Filter />}
openDrawerOffset={0.4}
side="right"
tapToClose={true}
captureGestures={true}
acceptPan={false}
styles={{
drawer: {shadowColor: 'black', shadowOpacity: 0.8, shadowRadius: 3},
main: {paddingLeft: 5}
}}
tweenHandler={Drawer.tweenPresets.parallax}
>
{this.renderContent()}
</Drawer>
But it only disables the animation. Drawer can still be opened with swipe. Am I doing something wrong?
Perhaps via a orientation prop?
Getting some weirdness after updating.
General transitions now have a blue background and while I have a disabled menu, I can drag from the utmost left and drag the current page away to transition to the previous one in what looks like a kind of reverse menu operation.
I am using this plugin https://github.com/brentvatne/react-native-scrollable-tab-view . I was happy with both of the plugin only till I find that how scroll-tab work by hiding it self on the left.
So the problem happen when I open drawer I see that my hidden scrolled tab are over the drawer.
Is there any suggestion how I can force this scroll-tab to be under or force the drawer to be always on top ?
Hi again,
I am running version 0.4.2 of React-Native.
I just updated the package to 1.1.0-beta1
and am getting the following error:
"Error: undefined is not an object (evaluating 'this.props.styles.main')
stack:
initialize index.ios.bundle:57635
drawer_componentWillMount index.ios.bundle:57708
mountComponent index.ios.bundle:16353
ReactCompositeComponent_mountComponent index.ios.bundle:5057
mountComponent index.ios.bundle:5126
mountComponent index.ios.bundle:16371
ReactCompositeComponent_mountComponent index.ios.bundle:5057
mountComponent index.ios.bundle:5126
mountChildren index.ios.bundle:20355
initializeChildren index.ios.bundle:18231
mountComponent index.ios.bundle:18385
mountComponent index.ios.bundle:5126
mountComponent index.ios.bundle:16371
ReactCompositeComponent_mountComponent index.ios.bundle:5057
mountComponent index.ios.bundle:5126
mountComponentIntoNode index.ios.bundle:15793
perform index.ios.bundle:6189
batchedMountComponentIntoNode index.ios.bundle:15812
batchedUpdates index.ios.bundle:13816
batchedUpdates index.ios.bundle:4721
renderComponent index.ios.bundle:15881
ReactMount__renderNewRootComponent index.ios.bundle:5057
render index.ios.bundle:1351
renderApplication index.ios.bundle:35424
run index.ios.bundle:35365
runApplication index.ios.bundle:35387
jsCall index.ios.bundle:7404
_callFunction index.ios.bundle:7659
<unknown> index.ios.bundle:7686
<unknown> index.ios.bundle:7680
perform index.ios.bundle:6189
batchedUpdates index.ios.bundle:13818
batchedUpdates index.ios.bundle:4721
<unknown> index.ios.bundle:7679
applyWithGuard index.ios.bundle:882
guardReturn index.ios.bundle:7453
processBatch index.ios.bundle:7678
URL: http://192.168.0.13:8081/index.ios.bundle
line: 57635
message: undefined is not an object (evaluating 'this.props.styles.main')"
Hi rt2zz,
Thanks for making such a great RN module. However, after I upgraded to your latest version from 1.3.0, my left drawer menu's width started to appear incorrectly, which spanned the whole screen instead of 45% of it (openDrawerOffset={0.45}). Nevertheless, the width of the tween transition animation was correct. I have tried to fix the problem myself by debugging your index.js, but no luck. Any clue?
Regards,
Guan
Hi,
When I close the drawer and replace the Navigator route at the same time, I get this error:
Unsupported layout animation createConfig property (null)
Here are the contents of my method:
this.refs.controlPanel.closeDrawer();
this.refs.navContainer.replace({
component: LoginView,
navigationBar: <NavigationBar
backgroundColor='#0077BF'
title={data.viewTitle}
titleColor='#FFFFFF'
customPrev={data.customPrev}
/>,
passProps: {foo: 'bar'},
});
I'm not sure if this is a react-native issue or a rn-drawer issue so I thought I'd ask you here first.
Thanks for the help,
-Tim
this will be very useful ๐
This is not directly related to this plugin. But I can't seems to access this.refs when I define my class like this and have a constructor like this. I can't seems to find a way or have a proper understanding how to use it in this case. Some help will be really helpful. Thanks
class Application extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
};
}
openDrawer(){
this.refs.drawer.open()
}
}
Hi,
Has anyone found a solution in order to limit the dragging when pulling the drawing out? When I start from the left and pull it to the right, I can move the drawer to the right border. I'd like to limit this to the openDrawerOffset value.
(sorry, I wanted to make a screenshot but it doesn't seem to work on iOS Simulator)
Hey,
So I'm using the <Drawer />
as a navigation menu together with a <Navigator />
. One thing I noticed is that once I've navigated and then try to open the <Drawer />
menu again (by swiping from left to right), the <Navigator />
will at the same time do the swipe-back mechanism, pushing me to the previous route.
I've tried the navigator.replace(route)
instead of navigator.push(route)
, but then the transition animation no longer plays, and the view is just replaced instantly.
Is there a way to remove the previous route (from the stack) inside the onClose event handler? Or is that bad practice? Kinda stuck here, great if someone got any ideas!
Hi,
Can we have top/bottom offset so that top navbar will be functional even when drawer is opened!..
I haven't looked into what might be causing this problem, but I thought it should be brought to your attention.
When dragging the drawer, opening or closing, if you quickly swipe past the edge of the screen, sometimes it will get stuck.
It also becomes unresponsive to further drag attempts in the same direction, but does allow you to move the drawer in the opposite direction.
Here are some screenshots of what I'm referring to:
Hi,
I'm trying to block every event below pan mask when my drawer is open.
I also would like to close my drawer when I click on pan mask.
This is what I did with success.
<TouchableHighlight onPress={this.closeDrawer}
style={{position: 'absolute',
height: Device.height, width: DRAWER_OFFSET, top:0, left:0, opacity: this.state.isOpen?1:0}}>
<View>
</View>
</TouchableHighlight>
Would it be possible to add this as a parameter ? Or did I miss something ?
First off, thanks for this component, it has worked great and the API has been very easy to use. ๐
I have an app that is a full screen MapView
with a Settings
view as the drawer. What I'm seeing is that (with what I've tried so far) I can't start panning the drawer without the map also panning for the duration of the drawer panning.
I'm not sure if this should (or can) be solved within react-native-drawer
, but if you have any ideas about what could work, I would greatly appreciate it.
Here's the code I'm using currently for my registered component:
const styles = StyleSheet.create({
shadow: {
shadowColor: '#000000',
shadowOpacity: 0.6,
shadowRadius: 15,
flex: 1
},
map: {
flex: 1
}
});
export default React.createClass({
render () {
return (
<Drawer type='static' content={<Settings {...this.state} />}>
<View style={styles.shadow}>
<MapView style={style.map} {...this.state} />
</View>
</Drawer>
);
}
});
Things I've tried:
onPanResponderTerminationRequest: (evt, gestureState) => true
. The docs don't say exactly what this does, but it sounded like the right idea, although it didn't work.PanResponder
.onPanStart
and onPanEnd
methods to the drawer and updating scrollEnabled
of MapView
(caused laggy performance or missed pans).May be useful once this one is finished #12
Update: I figured out how to pass individual functions from navigator like push() using (#15).
Is there a reason the entire navigator object can't be passed? This is done in https://github.com/Kureev/react-native-side-menu.
So, the problem here is that the onTap area remains active in the closed state. So that means that any time the area in say the left 50 pixels gets tapped, e.g. when activating a form element, will open the menu.
I can't imagine any scenario where tapping the left side of the screen should open the menu. A good workaround is to have onTap={this.state.open} in stead of onTap={true} but it stills feels like a bug.
I wanted to test the example project, but Xcode gives the "RCTRootView.h file not found" error.
Hi,
Do you plan on adding a method for disabling the drawer?
Thanks,
-Tim
The drawer could support iPad left side menu.
I have the logout button in the drawer. So, when a user logs out, I want the drawer to close and subsequently disabled.
I've tried doing it like this, both fail. The menu remains open in a disabled state. Any suggestions?
componentDidUpdate(prevProps){
if(!this.props.leftMenu.enabled && prevProps.leftMenu.visible)
this.refs.drawer.close();
}
componentWillUpdate(nextProps){
if(!nextProps.leftMenu.enabled && this.props.leftMenu.visible)
this.refs.drawer.close();
}
I am using a left drawer with a right offset, and want to allow tapping on the right side to close the drawer. However, I don't want to allow tapping on the left side of the screen (when the drawer isn't open) to open the drawer. Is there a way to use acceptTap but only for closing the drawer?
On a related note, when someone taps on the right side of the screen, buttons that are partially visible can still be pressed. Is there a way to make it so tapping on the non-drawer side will just close the drawer, but won't actually use the buttons that may have been tapped?
Trying this (https://gist.github.com/kakoni/83e1f2217610cc2d71ce) example on android and it fails, seeing this exception
Using react 0.13.3/native 0.11.4
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.