rn-toastify 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.MD +29 -0
- package/assets/animated_Icon/ErrorAnimation.json +1 -0
- package/assets/animated_Icon/SuccessAnimation.json +1 -0
- package/babel.config.js +6 -0
- package/docs/Toast.gif +0 -0
- package/index.js +6 -0
- package/jest.config.js +14 -0
- package/jest.setup.js +1 -0
- package/package.json +30 -0
- package/src/Toast.js +119 -0
- package/src/__tests__/Toast.test.js +54 -0
- package/src/animations/customeAnimations.js +31 -0
- package/src/animations/fadeInDown.js +16 -0
- package/src/animations/fadeOutUp.js +16 -0
- package/src/components/CustomeToast.js +26 -0
- package/src/components/EmojiToast.js +33 -0
- package/src/components/ErrorToast.js +47 -0
- package/src/components/LoadingToast.js +28 -0
- package/src/components/SuccessToast.js +47 -0
- package/src/context/ToastContainer.js +60 -0
- package/src/context/ToastManager.js +33 -0
- package/src/hooks/useToast.js +49 -0
- package/src/utils/Pixel/Index.js +28 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Mukesh Prajapati
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.MD
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
|
|
2
|
+
# react-native-toast
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
## Demo
|
|
6
|
+
|
|
7
|
+
Animated toast message component for React Native.
|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- 🚀 Imperative API
|
|
15
|
+
- 🎨 Customizable layouts
|
|
16
|
+
- 🔧 Flexible config
|
|
17
|
+
- 📅 Promise Handling
|
|
18
|
+
- 📍 Position Control
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Documentation
|
|
23
|
+
|
|
24
|
+
This is the Documentation for react-native-toast
|
|
25
|
+
|
|
26
|
+
- [Quick start](https://github.com/muku534/react-native-toast)
|
|
27
|
+
- [API](https://github.com/muku534/react-native-toast)
|
|
28
|
+
- [Create custom layouts](https://github.com/muku534/react-native-toast)
|
|
29
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":"5.5.8","fr":30,"ip":0,"op":60,"w":600,"h":600,"nm":"X","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 147","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-166.707,"ix":10},"p":{"a":0,"k":[306.662,303.115,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,60,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[108,-171],[-84,176]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.2353,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":70,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[0]},{"t":35,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":24,"op":60,"st":24,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-69.001,"ix":10},"p":{"a":0,"k":[296.019,306.184,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[60,60,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[108,-171],[-84,176]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.2353,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":70,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"t":28,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":17,"op":63,"st":17,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Circle2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":19,"s":[161]},{"t":43.0001953125,"s":[270]}],"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[21.701,21.701,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[1900,1900],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.2353,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":180,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"t":50.0001953125,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":18,"s":[0]},{"t":50.0001953125,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":18.2,"op":60,"st":-134.2,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Circle1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"t":0.2,"s":[180]},{"t":25.0001953125,"s":[270]}],"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[21.701,21.701,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[1900,1900],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.2353,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":150,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0.2,"s":[0]},{"t":42.200390625,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0.2,"op":60,"st":-152.2,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Background","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":28,"s":[20]},{"t":40,"s":[20]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[293,305,0],"ix":2},"a":{"a":0,"k":[5,-6,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.671,0.671,0.671],"y":[1,1,1]},"o":{"x":[0.167,0.167,0.167],"y":[0.048,0.048,0.415]},"t":28,"s":[43,43,100]},{"t":40,"s":[685.86,685.86,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[84,84],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.2353,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[6,-7],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":28,"op":67,"st":28,"bm":0}],"markers":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"v":"5.7.4","fr":29.9700012207031,"ip":0,"op":30.0000012219251,"w":250,"h":250,"nm":"Succes 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[89,88.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":2,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.341176480055,0.788235366344,0.180392161012,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":0,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[36,36.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[277.728,277.728],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.669],"y":[1]},"o":{"x":[0.848],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.245],"y":[1]},"o":{"x":[0.13],"y":[0]},"t":12,"s":[15]},{"t":27.0000010997325,"s":[87]}],"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"t":12.00000048877,"s":[77]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":30.0000012219251,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Checklist","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[139.5,104.5,0],"ix":2,"l":2},"a":{"a":0,"k":[125.5,100.5,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-75,0],[-25,50],[75,-50]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.341176470588,0.788235353956,0.180392156863,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[125.494,100.519],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.086],"y":[1]},"o":{"x":[0.693],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.453],"y":[1]},"o":{"x":[0.977],"y":[0]},"t":10,"s":[33]},{"t":29.0000011811942,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":30.0000012219251,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Layer 5 Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.689],"y":[1]},"o":{"x":[0.898],"y":[0]},"t":0,"s":[0]},{"t":29.0000011811942,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[124.5,124.5,0],"ix":2,"l":2},"a":{"a":0,"k":[100.5,100.5,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.488,0.488,0.667],"y":[1,1,1]},"o":{"x":[0.896,0.896,0.333],"y":[0,0,0]},"t":0,"s":[0,0,100]},{"t":29.0000011811942,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-55.229],[55.229,0],[0,55.229],[-55.229,0]],"o":[[0,55.229],[-55.229,0],[0,-55.229],[55.229,0]],"v":[[100,0],[0,100],[-100,0],[0,-100]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.819607902976,0.976470648074,0.674509803922,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[100.5,100.5],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30.0000012219251,"st":0,"bm":0}],"markers":[]}
|
package/babel.config.js
ADDED
package/docs/Toast.gif
ADDED
|
Binary file
|
package/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { toast as default } from './src/Toast';
|
|
2
|
+
export { SuccessToast } from './src/components/SuccessToast';
|
|
3
|
+
export { CustomeToast } from './src/components/CustomeToast';
|
|
4
|
+
export { EmojiToast } from './src/components/EmojiToast';
|
|
5
|
+
export { ErrorToast } from './src/components/ErrorToast';
|
|
6
|
+
export { LoadingToast } from './src/components/LoadingToast';
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
preset: 'react-native',
|
|
3
|
+
testEnvironment: 'node',
|
|
4
|
+
collectCoverage: true,
|
|
5
|
+
collectCoverageFrom: ['src/**/*.{ts,tsx}'],
|
|
6
|
+
setupFilesAfterEnv: [
|
|
7
|
+
'@testing-library/jest-native/extend-expect',
|
|
8
|
+
'./jest.setup.js'
|
|
9
|
+
],
|
|
10
|
+
transformIgnorePatterns: [
|
|
11
|
+
'node_modules/(?!(jest-)?react-native|@react-native|@react-navigation|@react-native-community|@expo)',
|
|
12
|
+
],
|
|
13
|
+
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
|
14
|
+
};
|
package/jest.setup.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@testing-library/jest-native/extend-expect';
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rn-toastify",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple toast notification library for React Native",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "jest"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"react-native",
|
|
11
|
+
"toast",
|
|
12
|
+
"notification",
|
|
13
|
+
"library"
|
|
14
|
+
],
|
|
15
|
+
"author": "Mukesh Prajapati",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@testing-library/jest-native": "^5.4.3",
|
|
19
|
+
"@testing-library/react-native": "^12.5.2",
|
|
20
|
+
"@types/jest": "^28.1.0",
|
|
21
|
+
"@types/react-native": "^0.67.3",
|
|
22
|
+
"events": "^3.3.0",
|
|
23
|
+
"jest": "^28.1.0",
|
|
24
|
+
"lottie-react-native": "^6.7.2",
|
|
25
|
+
"react": "18.2.0",
|
|
26
|
+
"react-native": "0.74.3",
|
|
27
|
+
"react-native-reanimated": "^3.14.0",
|
|
28
|
+
"react-test-renderer": "^17.0.2"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/Toast.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
|
+
import { PanResponder, StyleSheet, Text } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
heightPercentageToDP as hp,
|
|
5
|
+
widthPercentageToDP as wp,
|
|
6
|
+
} from './utils/Pixel/Index';
|
|
7
|
+
import Animated, { useSharedValue, useAnimatedStyle, withTiming, withSpring, runOnJS } from 'react-native-reanimated';
|
|
8
|
+
|
|
9
|
+
const Toast = ({ visible, duration, position, children, onHide, style }) => {
|
|
10
|
+
const opacity = useSharedValue(0);
|
|
11
|
+
const translateY = useSharedValue(-50);
|
|
12
|
+
const translateX = useSharedValue(0);
|
|
13
|
+
const scale = useSharedValue(0.9); // Start with a slightly smaller scale
|
|
14
|
+
|
|
15
|
+
const positionStyle = useMemo(() => {
|
|
16
|
+
return position === 'top' ? styles.top : styles.bottom;
|
|
17
|
+
}, [position]);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (visible) {
|
|
21
|
+
opacity.value = withTiming(1, { duration: 300 });
|
|
22
|
+
translateY.value = withSpring(0, { damping: 8, stiffness: 110 });
|
|
23
|
+
scale.value = withSpring(1, { damping: 8, stiffness: 110 });
|
|
24
|
+
|
|
25
|
+
if (duration !== Infinity) {
|
|
26
|
+
const hideTimeout = setTimeout(() => {
|
|
27
|
+
opacity.value = withTiming(0, { duration: 300 });
|
|
28
|
+
translateY.value = withTiming(-50, { duration: 300 });
|
|
29
|
+
runOnJS(onHide)();
|
|
30
|
+
}, duration);
|
|
31
|
+
|
|
32
|
+
return () => clearTimeout(hideTimeout);
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
opacity.value = withTiming(0, { duration: 300 });
|
|
36
|
+
translateY.value = withTiming(-50, { duration: 300 });
|
|
37
|
+
runOnJS(onHide)();
|
|
38
|
+
}
|
|
39
|
+
}, [visible, duration, onHide]);
|
|
40
|
+
|
|
41
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
42
|
+
return {
|
|
43
|
+
opacity: opacity.value,
|
|
44
|
+
transform: [
|
|
45
|
+
{ translateY: translateY.value },
|
|
46
|
+
{ translateX: translateX.value },
|
|
47
|
+
{ scale: scale.value },
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Set up PanResponder for swipe gestures
|
|
53
|
+
const panResponder = useMemo(() =>
|
|
54
|
+
PanResponder.create({
|
|
55
|
+
onMoveShouldSetPanResponder: (evt, gestureState) => {
|
|
56
|
+
return Math.abs(gestureState.dx) > 20; // Swipe detection threshold
|
|
57
|
+
},
|
|
58
|
+
onPanResponderMove: (evt, gestureState) => {
|
|
59
|
+
translateX.value = gestureState.dx; // Update translateX as the user swipes
|
|
60
|
+
},
|
|
61
|
+
onPanResponderRelease: (evt, gestureState) => {
|
|
62
|
+
if (Math.abs(gestureState.dx) > 100) { // If the swipe distance is more than 100 pixels, remove the toast
|
|
63
|
+
opacity.value = withTiming(0, { duration: 200 });
|
|
64
|
+
runOnJS(onHide)();
|
|
65
|
+
} else {
|
|
66
|
+
// If the swipe is less than the threshold, reset the position
|
|
67
|
+
translateX.value = withSpring(0);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
}), [translateX, opacity, onHide]);
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if (!visible) return null;
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<Animated.View
|
|
77
|
+
{...panResponder.panHandlers}
|
|
78
|
+
style={[
|
|
79
|
+
styles.container,
|
|
80
|
+
animatedStyle,
|
|
81
|
+
positionStyle,
|
|
82
|
+
style,
|
|
83
|
+
]}
|
|
84
|
+
>
|
|
85
|
+
<Animated.View style={[styles.toast, { opacity }]}>
|
|
86
|
+
{typeof children === 'string' ? <Text>{children}</Text> : children}
|
|
87
|
+
</Animated.View>
|
|
88
|
+
</Animated.View>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const styles = StyleSheet.create({
|
|
93
|
+
container: {
|
|
94
|
+
position: 'absolute',
|
|
95
|
+
left: 0,
|
|
96
|
+
right: 0,
|
|
97
|
+
alignItems: 'center',
|
|
98
|
+
zIndex: 9999,
|
|
99
|
+
},
|
|
100
|
+
top: {
|
|
101
|
+
top: 0,
|
|
102
|
+
},
|
|
103
|
+
bottom: {
|
|
104
|
+
bottom: 50,
|
|
105
|
+
},
|
|
106
|
+
toast: {
|
|
107
|
+
marginTop: hp(1),
|
|
108
|
+
// padding: 10,
|
|
109
|
+
backgroundColor: 'white',
|
|
110
|
+
borderRadius: wp(4),
|
|
111
|
+
shadowColor: '#000',
|
|
112
|
+
shadowOffset: { width: 0, height: 1 }, // Adjust to spread the shadow more
|
|
113
|
+
shadowOpacity: 0.5, // Adjust for the desired darkness
|
|
114
|
+
shadowRadius: 10, // Increase for a more spread-out shadow
|
|
115
|
+
elevation: 20, // Higher elevation for Android shadow
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
export default React.memo(Toast);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, act } from '@testing-library/react-native';
|
|
3
|
+
import Toast from '../Toast'; // Adjust the import path as needed
|
|
4
|
+
|
|
5
|
+
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper'); // Mock for animated
|
|
6
|
+
|
|
7
|
+
describe('Toast Component', () => {
|
|
8
|
+
jest.useFakeTimers();
|
|
9
|
+
|
|
10
|
+
it('should render and show toast', () => {
|
|
11
|
+
const { getByText } = render(
|
|
12
|
+
<Toast visible={true} duration={2000} position="bottom">
|
|
13
|
+
Test Toast
|
|
14
|
+
</Toast>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
expect(getByText('Test Toast')).toBeTruthy();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('should hide toast after duration', () => {
|
|
21
|
+
const onHideMock = jest.fn();
|
|
22
|
+
|
|
23
|
+
const { queryByText } = render(
|
|
24
|
+
<Toast visible={true} duration={2000} position="bottom" onHide={onHideMock}>
|
|
25
|
+
Test Toast
|
|
26
|
+
</Toast>
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
act(() => {
|
|
30
|
+
jest.advanceTimersByTime(2000);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(queryByText('Test Toast')).toBeNull();
|
|
34
|
+
expect(onHideMock).toHaveBeenCalled();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should apply correct styles based on position', () => {
|
|
38
|
+
const { getByText, rerender } = render(
|
|
39
|
+
<Toast visible={true} duration={2000} position="top">
|
|
40
|
+
Test Toast
|
|
41
|
+
</Toast>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
expect(getByText('Test Toast').parent.parent.props.style).toContainEqual({ top: 0 });
|
|
45
|
+
|
|
46
|
+
rerender(
|
|
47
|
+
<Toast visible={true} duration={2000} position="bottom">
|
|
48
|
+
Test Toast
|
|
49
|
+
</Toast>
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(getByText('Test Toast').parent.parent.props.style).toContainEqual({ bottom: 50 });
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Animated } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const customEnterAnimation = (opacity, translateY) => {
|
|
4
|
+
return Animated.parallel([
|
|
5
|
+
Animated.timing(opacity, {
|
|
6
|
+
toValue: 1,
|
|
7
|
+
duration: 1000,
|
|
8
|
+
useNativeDriver: true,
|
|
9
|
+
}),
|
|
10
|
+
Animated.spring(translateY, {
|
|
11
|
+
toValue: 0,
|
|
12
|
+
friction: 5,
|
|
13
|
+
useNativeDriver: true,
|
|
14
|
+
}),
|
|
15
|
+
]);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const customExitAnimation = (opacity, translateY) => {
|
|
19
|
+
return Animated.parallel([
|
|
20
|
+
Animated.timing(opacity, {
|
|
21
|
+
toValue: 0,
|
|
22
|
+
duration: 1000,
|
|
23
|
+
useNativeDriver: true,
|
|
24
|
+
}),
|
|
25
|
+
Animated.timing(translateY, {
|
|
26
|
+
toValue: -50,
|
|
27
|
+
duration: 1000,
|
|
28
|
+
useNativeDriver: true,
|
|
29
|
+
}),
|
|
30
|
+
]);
|
|
31
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Animated } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const fadeInDown = (opacity, translateY) => {
|
|
4
|
+
return Animated.parallel([
|
|
5
|
+
Animated.timing(opacity, {
|
|
6
|
+
toValue: 1,
|
|
7
|
+
duration: 500,
|
|
8
|
+
useNativeDriver: true,
|
|
9
|
+
}),
|
|
10
|
+
Animated.timing(translateY, {
|
|
11
|
+
toValue: 0,
|
|
12
|
+
duration: 500,
|
|
13
|
+
useNativeDriver: true,
|
|
14
|
+
}),
|
|
15
|
+
]);
|
|
16
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Animated } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export const fadeOutUp = (opacity, translateY) => {
|
|
4
|
+
return Animated.parallel([
|
|
5
|
+
Animated.timing(opacity, {
|
|
6
|
+
toValue: 0,
|
|
7
|
+
duration: 500,
|
|
8
|
+
useNativeDriver: true,
|
|
9
|
+
}),
|
|
10
|
+
Animated.timing(translateY, {
|
|
11
|
+
toValue: -50,
|
|
12
|
+
duration: 500,
|
|
13
|
+
useNativeDriver: true,
|
|
14
|
+
}),
|
|
15
|
+
]);
|
|
16
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
heightPercentageToDP as hp,
|
|
5
|
+
widthPercentageToDP as wp,
|
|
6
|
+
} from '../utils/Pixel/Index';
|
|
7
|
+
|
|
8
|
+
const CustomToast = ({ content }) => {
|
|
9
|
+
return (
|
|
10
|
+
<View style={styles.customToast}>
|
|
11
|
+
{content}
|
|
12
|
+
</View>
|
|
13
|
+
);
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
customToast: {
|
|
18
|
+
padding: wp(1),
|
|
19
|
+
borderRadius: wp(2),
|
|
20
|
+
backgroundColor: 'white',
|
|
21
|
+
flexDirection: 'row',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default CustomToast;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
heightPercentageToDP as hp,
|
|
5
|
+
widthPercentageToDP as wp,
|
|
6
|
+
} from '../utils/Pixel/Index';
|
|
7
|
+
|
|
8
|
+
const EmojiToast = ({ message, emoji }) => {
|
|
9
|
+
return (
|
|
10
|
+
<View style={styles.emojiToast}>
|
|
11
|
+
<Text style={styles.text}>{emoji} {message}</Text>
|
|
12
|
+
</View>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
const styles = StyleSheet.create({
|
|
16
|
+
emojiToast: {
|
|
17
|
+
width: wp(72),
|
|
18
|
+
height: hp(5.5),
|
|
19
|
+
paddingHorizontal: wp(4),
|
|
20
|
+
borderRadius: wp(4),
|
|
21
|
+
backgroundColor: 'white',
|
|
22
|
+
flexDirection: 'row',
|
|
23
|
+
alignItems: 'center',
|
|
24
|
+
|
|
25
|
+
},
|
|
26
|
+
text: {
|
|
27
|
+
fontSize: hp(2.2),
|
|
28
|
+
color: 'black',
|
|
29
|
+
paddingHorizontal: wp(1.5)
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export default EmojiToast;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import LottieView from 'lottie-react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
4
|
+
import {
|
|
5
|
+
heightPercentageToDP as hp,
|
|
6
|
+
widthPercentageToDP as wp,
|
|
7
|
+
} from '../utils/Pixel/Index';
|
|
8
|
+
|
|
9
|
+
const ErrorToast = ({ message }) => {
|
|
10
|
+
return (
|
|
11
|
+
<View style={styles.container}>
|
|
12
|
+
<LottieView
|
|
13
|
+
source={require('../../assets/animated_Icon/ErrorAnimation.json')} // Replace with your success Lottie animation path
|
|
14
|
+
autoPlay
|
|
15
|
+
loop={false}
|
|
16
|
+
speed={1.5}
|
|
17
|
+
style={styles.lottie}
|
|
18
|
+
/>
|
|
19
|
+
<Text style={styles.text}>{message}</Text>
|
|
20
|
+
</View>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const styles = StyleSheet.create({
|
|
25
|
+
container: {
|
|
26
|
+
width: wp(72),
|
|
27
|
+
height: hp(5.5),
|
|
28
|
+
paddingHorizontal: wp(4),
|
|
29
|
+
borderRadius: wp(4),
|
|
30
|
+
// backgroundColor: '#f8c4c4', // Success color (green)
|
|
31
|
+
backgroundColor: 'white',
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
flexDirection: 'row'
|
|
34
|
+
|
|
35
|
+
},
|
|
36
|
+
text: {
|
|
37
|
+
fontSize: hp(2.1),
|
|
38
|
+
color: 'black',
|
|
39
|
+
paddingHorizontal: wp(1.5)
|
|
40
|
+
},
|
|
41
|
+
lottie: {
|
|
42
|
+
width: wp(8.5),
|
|
43
|
+
height: hp(4.5),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default ErrorToast;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, StyleSheet, ActivityIndicator } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
heightPercentageToDP as hp,
|
|
5
|
+
widthPercentageToDP as wp,
|
|
6
|
+
} from '../utils/Pixel/Index';
|
|
7
|
+
|
|
8
|
+
const LoadingToast = ({ message }) => {
|
|
9
|
+
return (
|
|
10
|
+
<View style={styles.toast}>
|
|
11
|
+
<ActivityIndicator size="large" color={'#a9a9a9'} />
|
|
12
|
+
{/** <Text style={styles.text}>{message}</Text> */}
|
|
13
|
+
</View>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
toast: {
|
|
18
|
+
padding: wp(1),
|
|
19
|
+
borderRadius: wp(10),
|
|
20
|
+
backgroundColor: 'white',
|
|
21
|
+
},
|
|
22
|
+
text: {
|
|
23
|
+
fontSize: hp(2.2),
|
|
24
|
+
color: 'black',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export default LoadingToast;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import LottieView from 'lottie-react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { View, Text, StyleSheet } from 'react-native';
|
|
4
|
+
import {
|
|
5
|
+
heightPercentageToDP as hp,
|
|
6
|
+
widthPercentageToDP as wp,
|
|
7
|
+
} from '../utils/Pixel/Index';
|
|
8
|
+
|
|
9
|
+
const SuccessToast = ({ message }) => {
|
|
10
|
+
return (
|
|
11
|
+
<View style={styles.container}>
|
|
12
|
+
<LottieView
|
|
13
|
+
source={require('../../assets/animated_Icon/SuccessAnimation.json')} // Replace with your success Lottie animation path
|
|
14
|
+
autoPlay
|
|
15
|
+
loop={false}
|
|
16
|
+
style={styles.lottie}
|
|
17
|
+
speed={1.2}
|
|
18
|
+
/>
|
|
19
|
+
<Text style={styles.text}>{message}</Text>
|
|
20
|
+
</View>
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const styles = StyleSheet.create({
|
|
25
|
+
container: {
|
|
26
|
+
width: wp(72),
|
|
27
|
+
height: hp(5.5),
|
|
28
|
+
paddingHorizontal: wp(4),
|
|
29
|
+
borderRadius: wp(4),
|
|
30
|
+
backgroundColor: '#d2f7d2', // Success color (green)
|
|
31
|
+
// backgroundColor: 'white', // Success color (green)
|
|
32
|
+
alignItems: 'center',
|
|
33
|
+
flexDirection: 'row',
|
|
34
|
+
|
|
35
|
+
},
|
|
36
|
+
text: {
|
|
37
|
+
fontSize: hp(2.2),
|
|
38
|
+
color: 'black',
|
|
39
|
+
paddingHorizontal: wp(1.5)
|
|
40
|
+
},
|
|
41
|
+
lottie: {
|
|
42
|
+
width: wp(8),
|
|
43
|
+
height: hp(4),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export default SuccessToast;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { View, StyleSheet } from 'react-native';
|
|
3
|
+
import Toast from '../Toast';
|
|
4
|
+
import toastManagerInstance from './ToastManager';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const ToastContainer = () => {
|
|
8
|
+
const [toasts, setToasts] = useState([]);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const handleShow = (toast) => {
|
|
12
|
+
setToasts((prevToasts) => [...prevToasts, toast]);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const handleRemove = (id) => {
|
|
16
|
+
setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
toastManagerInstance.on('show', handleShow);
|
|
20
|
+
toastManagerInstance.on('remove', handleRemove);
|
|
21
|
+
|
|
22
|
+
return () => {
|
|
23
|
+
toastManagerInstance.off('show', handleShow);
|
|
24
|
+
toastManagerInstance.off('remove', handleRemove);
|
|
25
|
+
};
|
|
26
|
+
}, []);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<View style={styles.container}>
|
|
30
|
+
{toasts.map((toast, index) => (
|
|
31
|
+
<Toast
|
|
32
|
+
key={toast.id}
|
|
33
|
+
visible={true}
|
|
34
|
+
duration={toast.options.duration}
|
|
35
|
+
position={toast.options.position}
|
|
36
|
+
style={[toast.options.style, { top: 0 + index * 60 }]}
|
|
37
|
+
onHide={() => toastManagerInstance.remove(toast.id)}
|
|
38
|
+
>
|
|
39
|
+
{toast.content}
|
|
40
|
+
</Toast>
|
|
41
|
+
))}
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const styles = StyleSheet.create({
|
|
47
|
+
container: {
|
|
48
|
+
position: 'absolute',
|
|
49
|
+
top: 0,
|
|
50
|
+
left: 0,
|
|
51
|
+
right: 0,
|
|
52
|
+
bottom: 0,
|
|
53
|
+
justifyContent: 'center',
|
|
54
|
+
alignItems: 'center',
|
|
55
|
+
zIndex: 9999,
|
|
56
|
+
pointerEvents: 'box-none',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
export default React.memo(ToastContainer);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
|
|
3
|
+
class ToastManager extends EventEmitter {
|
|
4
|
+
show(content, options = {}) {
|
|
5
|
+
const id = Date.now().toString();
|
|
6
|
+
const defaultOptions = {
|
|
7
|
+
duration: 1000,
|
|
8
|
+
position: 'bottom',
|
|
9
|
+
style: {},
|
|
10
|
+
};
|
|
11
|
+
this.emit('show', { id, content, options: { ...defaultOptions, ...options } });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
remove(id) {
|
|
15
|
+
this.emit('remove', id);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async promise(promise, { loading, success, error }) {
|
|
19
|
+
const id = Date.now().toString();
|
|
20
|
+
this.show(loading, { duration: Infinity, position: 'top' });
|
|
21
|
+
try {
|
|
22
|
+
await promise;
|
|
23
|
+
this.remove(id);
|
|
24
|
+
this.show(success, { duration: 1000, position: 'top' });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
this.remove(id);
|
|
27
|
+
this.show(error, { duration: 1000, position: 'top' });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const toastManagerInstance = new ToastManager();
|
|
33
|
+
export default toastManagerInstance;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import toastManagerInstance from '../context/ToastManager';
|
|
3
|
+
import LoadingToast from '../components/LoadingToast';
|
|
4
|
+
import SuccessToast from '../components/SuccessToast';
|
|
5
|
+
import ErrorToast from '../components/ErrorToast';
|
|
6
|
+
import CustomToast from '../components/CustomeToast';
|
|
7
|
+
import EmojiToast from '../components/EmojiToast';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const useToast = () => {
|
|
11
|
+
const show = (content, options) => {
|
|
12
|
+
toastManagerInstance.show(content, options);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const success = (message, options) => {
|
|
16
|
+
show(<SuccessToast message={message} />, options);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const error = (message, options) => {
|
|
20
|
+
show(<ErrorToast message={message} />, options);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const promise = (promise, { loading, success, error }) => {
|
|
24
|
+
toastManagerInstance.promise(promise, {
|
|
25
|
+
loading: <LoadingToast message={loading} />,
|
|
26
|
+
success: <SuccessToast message={success} />,
|
|
27
|
+
error: <ErrorToast message={error} />,
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const custom = (content, options) => {
|
|
32
|
+
show(<CustomToast content={content} />, options);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const emoji = (message, emoji, options) => {
|
|
36
|
+
show(<EmojiToast message={message} emoji={emoji} />, options);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
show,
|
|
41
|
+
success,
|
|
42
|
+
error,
|
|
43
|
+
promise,
|
|
44
|
+
custom,
|
|
45
|
+
emoji,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default useToast;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {Dimensions, PixelRatio} from 'react-native';
|
|
2
|
+
let {width, height} = Dimensions.get('window');
|
|
3
|
+
const widthPercentageToDP = widthPercent => {
|
|
4
|
+
const elemWidth =
|
|
5
|
+
widthPercent === 'number' ? widthPercent : parseFloat(widthPercent);
|
|
6
|
+
|
|
7
|
+
return PixelRatio.roundToNearestPixel((width * elemWidth) / 100);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const heightPercentageToDP = heightPercent => {
|
|
11
|
+
const elemHeight =
|
|
12
|
+
heightPercent === 'number' ? heightPercent : parseFloat(heightPercent);
|
|
13
|
+
|
|
14
|
+
return PixelRatio.roundToNearestPixel((height * elemHeight) / 100);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const listenOrientationChange = that => {
|
|
18
|
+
Dimensions.addEventListener('change', newDimensions => {
|
|
19
|
+
width = newDimensions.window.width;
|
|
20
|
+
height = newDimensions.window.height;
|
|
21
|
+
|
|
22
|
+
that.setState({
|
|
23
|
+
orientation: width < height ? 'portrait' : 'landscape',
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export {widthPercentageToDP, heightPercentageToDP, listenOrientationChange};
|