react-native-use-modal

A way to create modals that are easily reusable, encapsulated, and handle the results.
The goal of react-native-use-modal is to make all the functions of react-native-modal available and convenient to use at the same time.
Feature
- Show modal and get result as promise
- Easy to show multiple modal continuously
- Pass parameters to modal when call
show
- Get result data from modal when hide (as promise)
- modal encapsulation
- No need to explicitly place modal at component tree
- Fully customizable
Table of Contents
Installation
yarn add react-native-use-modal
npm i react-native-use-modal
Place ModalProvider at your app's root component
import {ModalProvider} from 'react-native-use-modal';
const App = () => {
return <ModalProvider>
// ...
</ModalProvider>;
};
If you are already using a different provider, make the ModalProvider a child of the other provider.
Otherwise, the modal will not get the values broadcast by other providers.
import {Provider} from 'react-redux';
const App = () => {
return (
<Provider store={store}>
<FooProvider>
<BarProvider>
<ModalProvider>
// ...
</ModalProvider>
</BarProvider>
</FooProvider>
</Provider>
);
};
Usage
Declare modal as hook with createUseModal
createUseModal function receives a functional component of the specified type as the first argument.
This component will later be displayed as a modal.
import {createUseModal} from 'react-native-use-modal';
const useSimpleModal = createUseModal(
({
confirm, // Call this function to finish (confirm) modal
cancel, // Call this function to finish (cancel) modal
}) => {
return (
<View>
/* any view to presentation */
<Button onPress={confirm}>Ok</Button>
<Button onPress={cancel}>Cancel</Button>
</View>
);
},
);
Show modal using hook
..from any other react component
const FooView = () => {
const simpleModal = useSimpleModal();
const handlePressButton = () => {
simpleModal.show();
};
};
Handling the modal's result
You can wait for modal to return the result with await
const handlePressButton = async () => {
const result = await simpleModal.show();
if (result.type === ModalResultType.CONFIRM) {
} else {
}
};
Declare modal that require parameters
We sometimes need parameters to configure the modal.
createUseModal receives two generic types, the first is the type of data to be included in the result of modal, and the second is the type of parameter passed when calling modal.
If not used, just declare it as void type. The default is void.
import {createUseModal} from 'react-native-use-modal';
const useAlertModal = createUseModal<
void,
{title: string; message: string}
>(({confirm, cancel, param}) => {
return (
<View>
<Title>{param.title}</Title>
<Paragraph>{param.message}</Paragraph>
<View>
<Button onPress={confirm}>Ok</Button>
<Button onPress={cancel}>Cancel</Button>
</View>
</View>
);
});
Show modal that require parameters
const BarView = () => {
const alertModal = useAlertModal();
const handlePressButton = () => {
alertModal.show({
title: 'Title',
message: 'Message',
});
};
};
Declare modal that return values
Sometimes we may want to return a result from Modal.
export const useTextInputModal = createUseModal<string>(({confirm, cancel}) => {
const [value, setValue] = useState('');
const handlePressConfirm = () => confirm(value);
return (
<View style={styles.container}>
<TextInput
value={value}
onChangeText={setValue}
/>
<View >
<Button onPress={handlePressConfirm}>Confirm</Button>
<Button onPress={cancel}>Cancel</Button>
</View>
</View>
);
});
Handling the modal's result with value
const BazView = () => {
const textInputModal = useTextInputModal();
const handlePressButton = async () => {
const result = await textInputModal.show();
if (result.type === ModalResultType.CONFIRM) {
console.log('entered: ' + result.data);
} else {
}
};
};
Customize modal config
This package depends on react-native-modal and accept all its props.
You can set this in the second argument of the createUseModal.
For example, an animation could be set up like this:
export const useSimpleModal = createUseModal(
({confirm, cancel}) => {
},
{
modalProps: {
animationIn: 'fadeIn',
animationOut: 'fadeOut',
},
},
);
createUseModal supports all props, except for the isVisible property. We internally manage this property.
Make cancelable when press backdrop or back button
With these option, modal will cancel when press backdrop or back button.
Each option can be set independently.
export const useSimpleModal = createUseModal(
({confirm, cancel}) => {
},
{
cancelOnBackButtonPress: true,
cancelOnBackdropPress: true,
},
);
Creating a preconfigured createUseModal
You can use the createCreateUseModal function to create createUseModal with predefined options.
For example, if you need to create several bottom sheet modal, you can use it in a way such as defining the modalOption value for creating a bottom sheet modal in advance.
An example usage can be found at create-use-bottom-sheet-modal.tsx.
Making a third-party modal or an existing modal into a 'hook'
Using createUseForwardedModal, You can make a normal modal (modal that receives the visible property as props) a 'hook'.
It can be used when you want to make a modal component provided by the design component library into a 'hook' or to make an existing modal component into a 'hook' with minimal effort.
An example usage can be found at forwarded-alert-modal-example-screen.tsx.
Workflow example
You can clone this project and test examples by running the following command:
# iOS
yarn && yarn example ios
# Android
yarn && yarn example android
Examples provided are:
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
License
MIT