|
| 1 | +## React Native Drawer |
| 2 | +<img width="220px" align="right" src="https://raw.githubusercontent.com/rt2zz/react-native-drawer/master/examples/rn-drawer.gif" /> |
| 3 | + |
| 4 | +**NOTE** there have been some fairly major, and potentially buggy changes in 1.16.0. Please test it out and report feedback. We will troubleshoot asap. |
| 5 | + |
| 6 | +React native drawer, configurable to achieve material design style, slack style, parallax, and more. Works in both iOS and Android. |
| 7 | + |
| 8 | +[](https://www.npmjs.com/package/react-native-drawer) |
| 9 | +[](https://www.npmjs.com/package/react-native-drawer) |
| 10 | + |
| 11 | +**Android**: Android support has been added in v1.3.0! |
| 12 | + |
| 13 | +- [Installation](#installation) |
| 14 | +- [Usage](#usage) |
| 15 | +- [Examples](#examples) |
| 16 | +- [Props](#props) |
| 17 | +- [Demo](#demo) |
| 18 | +- [Credits](#credits) |
| 19 | + |
| 20 | +### Installation |
| 21 | +`npm install react-native-drawer` |
| 22 | + |
| 23 | +### Usage |
| 24 | +```javascript |
| 25 | +import Drawer from 'react-native-drawer' |
| 26 | + |
| 27 | +class Application extends Component { |
| 28 | + closeControlPanel = () => { |
| 29 | + this.drawer.close() |
| 30 | + }; |
| 31 | + openControlPanel = () => { |
| 32 | + this.drawer.open() |
| 33 | + }; |
| 34 | + render () { |
| 35 | + return ( |
| 36 | + <Drawer |
| 37 | + ref="drawer" |
| 38 | + content={<ControlPanel />} |
| 39 | + > |
| 40 | + <MainView /> |
| 41 | + </Drawer> |
| 42 | + ) |
| 43 | + } |
| 44 | +}) |
| 45 | +``` |
| 46 | + |
| 47 | +### Examples |
| 48 | +```js |
| 49 | +//Parallax Effect (slack style) |
| 50 | +<Drawer |
| 51 | + type="static" |
| 52 | + content={<ControlPanel />} |
| 53 | + openDrawerOffset={100} |
| 54 | + styles={{main: {shadowColor: "#000000", shadowOpacity: 0.4, shadowRadius: 3}}} |
| 55 | + tweenHandler={Drawer.tweenPresets.parallax} |
| 56 | + > |
| 57 | + <Main /> |
| 58 | +</Drawer> |
| 59 | + |
| 60 | +//Material Design Style Drawer |
| 61 | +<Drawer |
| 62 | + type="overlay" |
| 63 | + content={<ControlPanel />} |
| 64 | + tapToClose={true} |
| 65 | + openDrawerOffset={0.2} // 20% gap on the right side of drawer |
| 66 | + panCloseMask={0.2} |
| 67 | + closedDrawerOffset={-3} |
| 68 | + styles={{ |
| 69 | + drawer: {shadowColor: '#000000', shadowOpacity: 0.8, shadowRadius: 3}, |
| 70 | + main: {paddingLeft: 3} |
| 71 | + }} |
| 72 | + tweenHandler={(ratio) => ({ |
| 73 | + main: { opacity:(2-ratio)/2 } |
| 74 | + })} |
| 75 | + > |
| 76 | + <Main /> |
| 77 | +</Drawer> |
| 78 | +``` |
| 79 | + |
| 80 | +### Props |
| 81 | +This module supports a wide range of drawer styles, and hence has *a lot* of props. |
| 82 | +##### Important |
| 83 | +- `content` (React.Component) `null` - Menu component |
| 84 | +- `type` (String: displace:overlay:static) `displace`- Type of drawer. |
| 85 | +- `openDrawerOffset` (Number) `0` - Can either be a integer (pixel value) or decimal (ratio of screen width). Defines the right hand margin when the drawer is open. |
| 86 | +- `closedDrawerOffset` (Number) `0` - Same as openDrawerOffset, except defines left hand margin when drawer is closed. |
| 87 | +- `disabled` (Boolean) `false` - If true the drawer can not be opened and will not respond to pans. |
| 88 | + |
| 89 | +##### Animation / Tween |
| 90 | +- `tweenHandler` (Function) `null` - Takes in the pan ratio (decimal 0 to 1) that represents the tween percent. Returns and object of native props to be set on the constituent views { drawer: {/*native props*/}, main: {/*native props*/} } |
| 91 | +- `tweenDuration` (Integer) `250` - The duration of the open/close animation. |
| 92 | + |
| 93 | +##### Event Handlers |
| 94 | +- `onOpen` (Function) - Will be called immediately after the drawer has entered the open state. |
| 95 | +- `onClose` (Function) - Will be called immediately after the drawer has entered the closed state. |
| 96 | + |
| 97 | +##### Gestures |
| 98 | +- `captureGestures` (Boolean) `false` - If true, will capture all gestures inside of the pan mask. Meaning child buttons and scroll views will not trigger. |
| 99 | +- `acceptDoubleTap` (Boolean) `false` - Toggle drawer when double tap occurs within pan mask? |
| 100 | +- `acceptTap` (Boolean) `false` - Toggle drawer when any tap occurs within pan mask? |
| 101 | +- `acceptPan` (Boolean) `true` - Allow for drawer pan (on touch drag). Set to false to effectively disable the drawer while still allowing programmatic control. |
| 102 | +- `tapToClose` (Boolean) `false` - Same as acceptTap, except only for close. |
| 103 | +- `negotiatePan` (Boolean) `false` - If true, attempts to handle only horizontal swipes, making it play well with a child `ScrollView`. |
| 104 | + |
| 105 | +##### Additional Configurations |
| 106 | +- `openDrawerThreshold` (Number) `.25` - Ratio of screen width that must be travelled to trigger a drawer open/close |
| 107 | +- `panOpenMask` (Number) `.05` - Ratio of screen width that is valid for the start of a pan open action. |
| 108 | +- `panCloseMask` (Number) `.25` - Ratio of screen width that is valid for the start of a pan close action. |
| 109 | +- `initializeOpen` (Boolean) `false` - Initialize with drawer open? |
| 110 | +- `side` (String left|right) `left` - which side the drawer should be on. |
| 111 | + |
| 112 | +##### Experimental & Deprecated Props |
| 113 | +**Subject to change or deletion** |
| 114 | +- `onOpenStart` (Boolean) callback fired at the start of an open animation |
| 115 | +- `onCloseStart` (Boolean) callback fired at the start of a close animation |
| 116 | +- `tweenEasing` (String) `linear` - A easing type supported by [tween-functions](https://www.npmjs.com/package/tween-functions) |
| 117 | +- `relativeDrag` (Boolean) `true` - true -> open/close calculation based on pan dx : false -> calculation based on absolute pan position (i.e. touch location) |
| 118 | +- `panStartCompensation` (Boolean) `false` - Should the drawer catch up to the finger drag position? |
| 119 | + |
| 120 | + |
| 121 | +### Tween Handler |
| 122 | +You can achieve pretty much any animation you want using the tween handler with the transformMatrix property. E.G. |
| 123 | +```js |
| 124 | +tweenHandler={(ratio) => { |
| 125 | + var r0 = -ratio/6 |
| 126 | + var r1 = 1-ratio/6 |
| 127 | + var t = [ |
| 128 | + r1, r0, 0, 0, |
| 129 | + -r0, r1, 0, 0, |
| 130 | + 0, 0, 1, 0, |
| 131 | + 0, 0, 0, 1, |
| 132 | + ] |
| 133 | + return { |
| 134 | + main: { |
| 135 | + style: { |
| 136 | + transformMatrix: t, |
| 137 | + opacity: 1 - ratio/2, |
| 138 | + }, |
| 139 | + } |
| 140 | + } |
| 141 | +}} |
| 142 | +``` |
| 143 | +Will result in a skewed fade out animation. |
| 144 | + |
| 145 | +**warning:** Frame rate, and perceived smoothness will vary based on the complexity and speed of the animation. It will likely require some tweaking and compromise to get the animation just right. |
| 146 | + |
| 147 | +### Opening & Closing the Drawer Programmatically |
| 148 | +Two options: |
| 149 | +1. Using the Drawer Ref: |
| 150 | +```js |
| 151 | +onPress={() => {this.drawer.open()}} |
| 152 | +``` |
| 153 | +2. Using Context |
| 154 | +```js |
| 155 | +contextTypes = {drawer: React.PropTypes.object} |
| 156 | +// later... |
| 157 | +this.context.drawer.open() |
| 158 | +``` |
| 159 | + |
| 160 | +### Demo |
| 161 | +* `git clone https://github.com/rt2zz/react-native-drawer.git` |
| 162 | +* `cd react-native-drawer/examples/RNDrawerDemo && npm install` |
| 163 | +* Open ``./examples/RNDrawerDemo/RNDrawerDemo.xcodeproject` in xcode |
| 164 | +* `command+r` (in xcode) |
| 165 | + |
| 166 | +### Credits |
| 167 | +Component was adapted from and inspired by |
| 168 | +[@khanghoang](https://github.com/khanghoang)'s [RNSideMenu](https://github.com/khanghoang/RNSideMenu) |
| 169 | +*AND* |
| 170 | +[@kureevalexey](https://twitter.com/kureevalexey)'s [react-native-side-menu](https://github.com/Kureev/react-native-side-menu) |
0 commit comments