├── .gitignore
├── .prettierrc
├── README.md
├── package.json
├── src
└── index.tsx
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 2,
3 | "semi": true,
4 | "singleQuote": true,
5 | "trailingComma": "all",
6 | "bracketSpacing": true,
7 | "jsxBracketSameLine": false,
8 | "arrowParens": "always"
9 | }
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-dev-menu-on-touch
2 |
3 |
4 | [](https://npmjs.com/package/react-native-dev-menu-on-touch)
5 |
6 | Open dev menu with 3 fingers touch instead of shake.
7 |
8 | 
9 |
10 | > *when you want to reload the app*
11 |
12 | ## Why?
13 |
14 | It's annoying to shake real device every time you need dev menu. Also - it looks quite awkward if you have co-workers sitting next to you and you shake your phone every 2 minutes.
15 |
16 | ## How to use
17 |
18 | Wrap entire app inside this component
19 |
20 | ```jsx
21 | import DevMenuOnTouch from 'react-native-dev-menu-on-touch';
22 | // or: import { DevMenuOnTouch } from 'react-native-dev-menu-on-touch'
23 |
24 | class YourRootApp extends Component {
25 | render() {
26 | return (
27 |
28 |
29 |
30 | );
31 | }
32 | }
33 | ```
34 |
35 | or use with higher order component
36 |
37 | ```jsx
38 | import { withDevMenuOnTouch } from 'react-native-dev-menu-on-touch';
39 | const YourAppRoot = withDevMenuOnTouch(YourApp);
40 | ```
41 |
42 | ## Notes
43 |
44 | - It's enabled only in dev mode - in production it'll return normal view without changing anything (so it's safe to use in production)
45 | - It's inspider by comment of @slicejunk https://github.com/facebook/react-native/issues/10191#issuecomment-277208461
46 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-dev-menu-on-touch",
3 | "version": "1.0.3",
4 | "main": "dist/index.js",
5 | "types": "dist/index.d.ts",
6 | "license": "MIT",
7 | "scripts": {
8 | "build": "tsc"
9 | },
10 | "peerDependencies": {
11 | "react": "^16.0.0",
12 | "react-native": "^0.57.5"
13 | },
14 | "devDependencies": {
15 | "@types/react": "^16.7.20",
16 | "@types/react-native": "^0.57.12",
17 | "typescript": "^3.1.6"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component, ComponentType } from 'react';
2 | import { NativeModules, PanResponder, View } from 'react-native';
3 |
4 | export class DevMenuOnTouch extends Component {
5 | private panResponder = PanResponder.create({
6 | onStartShouldSetPanResponder: (evt, gestureState) => {
7 | if (gestureState.numberActiveTouches === 3) {
8 | NativeModules.DevMenu.show();
9 | }
10 | return false;
11 | },
12 | });
13 |
14 | public render() {
15 | const { children } = this.props;
16 |
17 | // return children;
18 | const panHandlers = __DEV__ ? this.panResponder.panHandlers : {};
19 | return (
20 |
21 | {children}
22 |
23 | );
24 | }
25 | }
26 |
27 | export function withDevMenuOnTouch
(TargetComponent: ComponentType
) {
28 | return class WithDevMenuOnTouch extends Component
{
29 | public render() {
30 | return (
31 |
32 |
33 |
34 | );
35 | }
36 | };
37 | }
38 |
39 | export default DevMenuOnTouch;
40 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "allowSyntheticDefaultImports": true,
6 | "jsx": "react-native",
7 | "declaration": true,
8 | "outDir": "./dist",
9 | "strict": true,
10 | "lib": ["es2015"],
11 | "skipLibCheck": true
12 | },
13 | "exclude": ["./node_modules/*", "./dist"]
14 | }
15 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@types/prop-types@*":
6 | version "15.5.6"
7 | resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.5.6.tgz#9c03d3fed70a8d517c191b7734da2879b50ca26c"
8 |
9 | "@types/react-native@^0.57.12":
10 | version "0.57.12"
11 | resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.57.12.tgz#cd012ea3f4f30e70af580a14f5805d85827f92e6"
12 | dependencies:
13 | "@types/prop-types" "*"
14 | "@types/react" "*"
15 |
16 | "@types/react@*":
17 | version "16.7.6"
18 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.6.tgz#80e4bab0d0731ad3ae51f320c4b08bdca5f03040"
19 | dependencies:
20 | "@types/prop-types" "*"
21 | csstype "^2.2.0"
22 |
23 | "@types/react@^16.7.20":
24 | version "16.7.20"
25 | resolved "https://registry.yarnpkg.com/@types/react/-/react-16.7.20.tgz#13ae752c012710d0fa800985ca809814b51d3b58"
26 | dependencies:
27 | "@types/prop-types" "*"
28 | csstype "^2.2.0"
29 |
30 | csstype@^2.2.0:
31 | version "2.5.7"
32 | resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.5.7.tgz#bf9235d5872141eccfb2d16d82993c6b149179ff"
33 |
34 | "js-tokens@^3.0.0 || ^4.0.0":
35 | version "4.0.0"
36 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
37 |
38 | loose-envify@^1.1.0, loose-envify@^1.3.1:
39 | version "1.4.0"
40 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
41 | dependencies:
42 | js-tokens "^3.0.0 || ^4.0.0"
43 |
44 | object-assign@^4.1.1:
45 | version "4.1.1"
46 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
47 |
48 | prop-types@^15.6.2:
49 | version "15.6.2"
50 | resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
51 | dependencies:
52 | loose-envify "^1.3.1"
53 | object-assign "^4.1.1"
54 |
55 | react@^16.7.0:
56 | version "16.7.0"
57 | resolved "https://registry.yarnpkg.com/react/-/react-16.7.0.tgz#b674ec396b0a5715873b350446f7ea0802ab6381"
58 | dependencies:
59 | loose-envify "^1.1.0"
60 | object-assign "^4.1.1"
61 | prop-types "^15.6.2"
62 | scheduler "^0.12.0"
63 |
64 | scheduler@^0.12.0:
65 | version "0.12.0"
66 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.12.0.tgz#8ab17699939c0aedc5a196a657743c496538647b"
67 | dependencies:
68 | loose-envify "^1.1.0"
69 | object-assign "^4.1.1"
70 |
71 | typescript@^3.1.6:
72 | version "3.1.6"
73 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.6.tgz#b6543a83cfc8c2befb3f4c8fba6896f5b0c9be68"
74 |
--------------------------------------------------------------------------------