Skip to content

Commit b591689

Browse files
authored
Merge pull request #3 from teamplanes/hooks-1.0.0
Hooks 1.0.0
2 parents 0abb97e + becc4c3 commit b591689

File tree

13 files changed

+1065
-2963
lines changed

13 files changed

+1065
-2963
lines changed

.eslintrc.js

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
11
module.exports = {
2-
parser: 'babel-eslint',
3-
extends: 'airbnb',
4-
plugins: ['react', 'react-native'],
5-
rules: {
6-
'react/jsx-filename-extension': 0,
7-
'no-use-before-define': 0,
8-
'import/no-unresolved': ['error', { ignore: ['^react'] }],
9-
'import/extensions': ['error', { ignore: ['^react'] }]
2+
"parser": "@typescript-eslint/parser",
3+
"plugins": ["@typescript-eslint", "prettier"],
4+
"extends": [
5+
"airbnb",
6+
"plugin:@typescript-eslint/recommended",
7+
"prettier",
8+
"prettier/@typescript-eslint",
9+
"prettier/react"
10+
],
11+
"settings": {
12+
"import/resolver": {
13+
"node": {
14+
"extensions": [".js", ".jsx", ".ts", ".tsx"]
15+
}
16+
}
1017
},
11-
};
18+
"rules": {
19+
"react/jsx-filename-extension": ["error", { "extensions": [".ts", ".tsx", ".js", ".jsx"] }],
20+
"import/prefer-default-export": 0,
21+
"import/no-default-export": 2,
22+
"prettier/prettier": "error",
23+
"react/destructuring-assignment": 0,
24+
"@typescript-eslint/explicit-function-return-type": 0,
25+
"@typescript-eslint/no-explicit-any": 0
26+
}
27+
}

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
node_modules
2+
package-lock.json
3+
lib

README.md

Lines changed: 68 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,180 +1,78 @@
1-
## React Native Modal Controller
1+
## React Native Modal Controller 🕹
22

3-
Modals can be fiddly in React Native. Lets say for example you have a mostly-fullscreen modal with a form in it and you want to show an error modal after an incorrect submission - you'd have to close the form modal and once `onDismiss` is called open the error modal.
3+
A more ergonomic interface for opening and managing modals in your react native
4+
app.
45

5-
React Native Modal Controller aims to solve this by providing a control component that manages your one or many modals. It does this by opening a single React Native Modal with a single backdrop.
6+
- 🎣 Uses React hooks
7+
- 🍆 Written in TypeScript
8+
- 💥 Open multiple modals at once (tray and an alert, or whatever)
9+
- 🎩 Fancy animations using `react-native-animatable`
610

7-
For example, you might want to have a modal and a tray with a picker in it:
11+
For example, you might want to have a modal and a tray:
812

913
<img src="https://i.imgur.com/6JhOGID.gif" width="200" />
1014

11-
The code for the above looks like:
12-
13-
```js
14-
import React from 'react';
15-
import { StyleSheet, Text, View, Button } from 'react-native';
16-
import showModal, { PRIORITIES, ModalController } from 'react-native-modal-controller';
17-
import AlertModal from './components/alert';
18-
import TrayModal from './components/tray';
19-
20-
export default class App extends React.Component {
21-
handleShowtray = () => {
22-
showModal({
23-
name: 'TRAY',
24-
priority: PRIORITIES.OVERRIDE,
25-
modalProps: {
26-
message: 'Hey tray.',
27-
onOpenAlert: () => this.handleOpen(PRIORITIES.STANDARD),
28-
},
29-
});
30-
};
31-
handleOpen = (priority) => {
32-
showModal({
33-
name: 'ALERT',
34-
priority: priority || PRIORITIES.OVERRIDE,
35-
modalProps: {
36-
message: 'Hello, modal.',
37-
onOpenAnother: this.handleOpen,
38-
onOpenTray: this.handleShowtray
39-
},
40-
});
41-
};
42-
43-
render() {
44-
return (
45-
<View style={styles.container}>
46-
<Button title="Open Modal" onPress={this.handleOpen} />
47-
<ModalController
48-
customAnimations={{
49-
slideTrayUp: {
50-
from: { bottom: -300 },
51-
to: { bottom: 0 }
52-
},
53-
slideTrayDown: {
54-
from: { bottom: 0 },
55-
to: { bottom: -300 }
56-
}
57-
}}
58-
modals={{
59-
ALERT: {
60-
animationIn: 'zoomInDown',
61-
animationOut: 'lightSpeedOut',
62-
Component: AlertModal
63-
},
64-
TRAY: {
65-
animationIn: 'slideTrayUp',
66-
animationOut: 'slideTrayDown',
67-
Component: TrayModal,
68-
absolutePositioning: {
69-
bottom: 0,
70-
left: 0,
71-
right: 0,
72-
},
73-
},
74-
}}
75-
/>
76-
</View>
77-
);
78-
}
79-
}
80-
81-
```
82-
83-
Modal Control is implemented in a very similar way to [react-native-modal](https://github.com/react-native-community/react-native-modal), by using [react-native-animatable](https://github.com/oblador/react-native-animatable). So you'll notice in the above example that you can use any of the animatable animations - or implement your own.
84-
85-
### Priorities
86-
87-
**`PRIORITIES.STANDARD`** - Open the modal alongside (on-top-of) the existing modals - if any.
88-
89-
**`PRIORITIES.OVERRIDE`** - Open the modal and close all existing modals.
90-
91-
### `ModalController`
92-
93-
`ModalController` should be mounted at the route of your app and only mounted once, similar to how you'd set up routing.
94-
95-
#### Props
96-
97-
##### `modals` - required
98-
---
99-
100-
```js
101-
type ModalsPropType = {
102-
[name: string]: {
103-
Component: React.Component, // required
104-
animationIn?: string,
105-
animationOut?: string,
106-
animationInDuration?: number,
107-
animationOutDuration?: number,
108-
absolutePositioning?: Object, // Position the modal absolutely with given styles
109-
}
15+
## Example Usage:
16+
17+
```tsx
18+
// Your basic popup component
19+
const MyModal = (props: ModalComponentProps<any>) => (
20+
<View style={{height: 300, width: 300, backgroundColor: 'white'}}>
21+
{/* Opens another modal from within */}
22+
<TouchableOpacity onPress={() => props.onShowModal({name: 'myModal'})}>
23+
<Text>Open another</Text>
24+
</TouchableOpacity>
25+
</View>
26+
);
27+
28+
const MyScreen = () => {
29+
// The Hook!
30+
const modal = useModalController();
31+
return (
32+
<View style={{flex: 1}}>
33+
<TouchableOpacity
34+
onPress={() =>
35+
// Show the `myModal` popup declared in the the provider
36+
modal.onShowModal({
37+
name: 'myModal',
38+
priority: Priority.Override,
39+
})
40+
}>
41+
<Text>Show Modal</Text>
42+
</TouchableOpacity>
43+
</View>
44+
);
11045
};
111-
```
112-
113-
##### `customAnimations` - optional
114-
---
11546

116-
```js
117-
type CustomAnimationsProp = ?{
118-
[name: string]: {
119-
from: Object,
120-
to: Object,
121-
}
47+
// Your app entry point - define your Modals and pass into the Context Provider
48+
const App = () => {
49+
return (
50+
<ModalControllerProvider
51+
modals={[
52+
{
53+
// Your unique name/key for this modal to be opened
54+
name: 'myModal',
55+
// Define whether, when opened, this modal should override or exist in parallel
56+
priority: Priority.Override,
57+
animation: {
58+
inDuration: 500,
59+
outDuration: 500,
60+
// Using react-native-animatable animations or your own
61+
in: 'fadeInDown' as Animation,
62+
out: 'fadeOutUp' as Animation,
63+
},
64+
Component: MyModal,
65+
},
66+
]}
67+
// Customise the backdrop
68+
backdrop={{
69+
activeOpacity: 0.5,
70+
transitionInTiming: 500,
71+
transitionOutTiming: 500,
72+
}}>
73+
<MyScreen />
74+
</ModalControllerProvider>
75+
);
12276
};
123-
```
124-
125-
##### `activeBackdropOpacity` - optional
126-
---
127-
128-
```js
129-
type ActiveBackdropOpacityProp = ?number;
130-
```
131-
132-
133-
##### `backdropTransitionInTiming` - optional
134-
---
135-
136-
```js
137-
type BackdropTransitionInTimingProp = ?number;
138-
```
139-
140-
##### `backdropTransitionOutTiming` - optional
141-
---
142-
143-
```js
144-
type BackdropTransitionOutTimingProp = ?number;
145-
```
146-
147-
### `showModal`
148-
149-
`showModal` is the default export and can be used to show one of your modals based on the config you pass it.
150-
151-
#### Args
152-
153-
##### `name` - required
154-
---
155-
156-
```js
157-
type name = string; // The key used in your modals prop of ModalController
158-
```
159-
160-
##### `modalProps` - optional
161-
---
162-
163-
```js
164-
type modalProps = Object; // Props passed to your Component
165-
```
166-
167-
##### `priority` - optional
168-
---
169-
170-
```js
171-
type priority = $Keys<typeof PRIORITIES>;
172-
```
173-
174-
#### Overrides
175-
176-
You can also pass in any of the `ModalsPropType`s apart from Component to override your defaults.
177-
178-
179-
18077

78+
```

index.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)