react-native-toast-message 1.6.0 → 2.0.1

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +86 -2
  2. package/README.md +19 -252
  3. package/lib/index.d.ts +6 -0
  4. package/lib/index.js +6 -0
  5. package/lib/src/Toast.d.ts +7 -0
  6. package/lib/src/Toast.js +27 -0
  7. package/lib/src/ToastUI.d.ts +11 -0
  8. package/lib/src/ToastUI.js +40 -0
  9. package/lib/src/components/AnimatedContainer.d.ts +16 -0
  10. package/lib/src/components/AnimatedContainer.js +72 -0
  11. package/lib/src/components/AnimatedContainer.styles.d.ts +14 -0
  12. package/lib/src/components/AnimatedContainer.styles.js +15 -0
  13. package/lib/src/components/BaseToast.d.ts +3 -0
  14. package/lib/src/components/BaseToast.js +19 -0
  15. package/lib/src/components/BaseToast.styles.d.ts +41 -0
  16. package/lib/src/components/BaseToast.styles.js +39 -0
  17. package/lib/src/components/ErrorToast.d.ts +3 -0
  18. package/lib/src/components/ErrorToast.js +5 -0
  19. package/lib/src/components/InfoToast.d.ts +3 -0
  20. package/lib/src/components/InfoToast.js +5 -0
  21. package/lib/src/components/SuccessToast.d.ts +3 -0
  22. package/lib/src/components/SuccessToast.js +5 -0
  23. package/lib/src/components/Touchable.d.ts +8 -0
  24. package/lib/src/components/Touchable.js +7 -0
  25. package/lib/src/contexts/LoggerContext.d.ts +12 -0
  26. package/lib/src/contexts/LoggerContext.js +22 -0
  27. package/lib/src/contexts/index.d.ts +1 -0
  28. package/lib/src/contexts/index.js +1 -0
  29. package/lib/src/hooks/index.d.ts +5 -0
  30. package/lib/src/hooks/index.js +5 -0
  31. package/lib/src/hooks/useKeyboard.d.ts +4 -0
  32. package/lib/src/hooks/useKeyboard.js +31 -0
  33. package/lib/src/hooks/usePanResponder.d.ts +15 -0
  34. package/lib/src/hooks/usePanResponder.js +41 -0
  35. package/lib/src/hooks/useSlideAnimation.d.ts +24 -0
  36. package/lib/src/hooks/useSlideAnimation.js +49 -0
  37. package/lib/src/hooks/useTimeout.d.ts +6 -0
  38. package/lib/src/hooks/useTimeout.js +29 -0
  39. package/lib/src/hooks/useViewDimensions.d.ts +13 -0
  40. package/lib/src/hooks/useViewDimensions.js +20 -0
  41. package/lib/src/types/index.d.ts +165 -0
  42. package/lib/src/types/index.js +1 -0
  43. package/lib/src/useToast.d.ts +13 -0
  44. package/lib/src/useToast.js +79 -0
  45. package/lib/src/utils/array.d.ts +2 -0
  46. package/lib/src/utils/array.js +4 -0
  47. package/lib/src/utils/func.d.ts +1 -0
  48. package/lib/src/utils/func.js +1 -0
  49. package/lib/src/utils/number.d.ts +3 -0
  50. package/lib/src/utils/number.js +9 -0
  51. package/lib/src/utils/obj.d.ts +3 -0
  52. package/lib/src/utils/obj.js +11 -0
  53. package/lib/src/utils/platform.d.ts +1 -0
  54. package/lib/src/utils/platform.js +4 -0
  55. package/lib/src/utils/test-id.d.ts +1 -0
  56. package/lib/src/utils/test-id.js +3 -0
  57. package/package.json +46 -35
  58. package/.github/dependabot.yml +0 -17
  59. package/.github/workflows/publish.yml +0 -22
  60. package/.github/workflows/tag.yml +0 -16
  61. package/.github/workflows/tests.yml +0 -44
  62. package/babel.config.js +0 -3
  63. package/index.d.ts +0 -72
  64. package/index.js +0 -7
  65. package/jest.config.js +0 -5
  66. package/jest.setup.js +0 -1
  67. package/src/assets/icons/close.png +0 -0
  68. package/src/assets/icons/close@2x.png +0 -0
  69. package/src/assets/icons/close@3x.png +0 -0
  70. package/src/assets/icons/error.png +0 -0
  71. package/src/assets/icons/error@2x.png +0 -0
  72. package/src/assets/icons/error@3x.png +0 -0
  73. package/src/assets/icons/info.png +0 -0
  74. package/src/assets/icons/info@2x.png +0 -0
  75. package/src/assets/icons/info@3x.png +0 -0
  76. package/src/assets/icons/success.png +0 -0
  77. package/src/assets/icons/success@2x.png +0 -0
  78. package/src/assets/icons/success@3x.png +0 -0
  79. package/src/assets/index.js +0 -15
  80. package/src/colors/index.js +0 -10
  81. package/src/components/base/index.js +0 -134
  82. package/src/components/base/styles.js +0 -54
  83. package/src/components/error.js +0 -19
  84. package/src/components/icon/index.js +0 -40
  85. package/src/components/icon/styles.js +0 -8
  86. package/src/components/info.js +0 -19
  87. package/src/components/success.js +0 -19
  88. package/src/index.js +0 -420
  89. package/src/styles.js +0 -17
  90. package/src/utils/arr.js +0 -3
  91. package/src/utils/obj.js +0 -9
  92. package/src/utils/platform.js +0 -5
  93. package/src/utils/prop-types.js +0 -5
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
-
3
- import BaseToast from './base';
4
- import { icons } from '../assets';
5
- import colors from '../colors';
6
-
7
- function InfoToast(props) {
8
- return (
9
- <BaseToast
10
- {...props}
11
- style={{ borderLeftColor: colors.lightSkyBlue }}
12
- leadingIcon={icons.info}
13
- />
14
- );
15
- }
16
-
17
- InfoToast.propTypes = BaseToast.propTypes;
18
-
19
- export default InfoToast;
@@ -1,19 +0,0 @@
1
- import React from 'react';
2
-
3
- import BaseToast from './base';
4
- import { icons } from '../assets';
5
- import colors from '../colors';
6
-
7
- function SuccessToast(props) {
8
- return (
9
- <BaseToast
10
- {...props}
11
- style={{ borderLeftColor: colors.mantis }}
12
- leadingIcon={icons.success}
13
- />
14
- );
15
- }
16
-
17
- SuccessToast.propTypes = BaseToast.propTypes;
18
-
19
- export default SuccessToast;
package/src/index.js DELETED
@@ -1,420 +0,0 @@
1
- import React, { Component } from 'react';
2
- import { Animated, PanResponder, Keyboard } from 'react-native';
3
- import PropTypes from 'prop-types';
4
-
5
- import SuccessToast from './components/success';
6
- import ErrorToast from './components/error';
7
- import InfoToast from './components/info';
8
- import { complement } from './utils/arr';
9
- import { includeKeys } from './utils/obj';
10
- import { stylePropType } from './utils/prop-types';
11
- import { isIOS } from './utils/platform';
12
- import styles from './styles';
13
-
14
- const FRICTION = 8;
15
-
16
- const defaultComponentsConfig = {
17
- // eslint-disable-next-line react/prop-types
18
- success: ({ hide, ...rest }) => (
19
- <SuccessToast {...rest} onTrailingIconPress={hide} />
20
- ),
21
- // eslint-disable-next-line react/prop-types
22
- error: ({ hide, ...rest }) => (
23
- <ErrorToast {...rest} onTrailingIconPress={hide} />
24
- ),
25
- // eslint-disable-next-line react/prop-types
26
- info: ({ hide, ...rest }) => (
27
- <InfoToast {...rest} onTrailingIconPress={hide} />
28
- )
29
- };
30
-
31
- function shouldSetPanResponder(gesture) {
32
- const { dx, dy } = gesture;
33
- // Fixes onPress handler https://github.com/calintamas/react-native-toast-message/issues/113
34
- return Math.abs(dx) > 2 || Math.abs(dy) > 2;
35
- }
36
-
37
- const getInitialState = ({
38
- topOffset,
39
- bottomOffset,
40
- keyboardOffset,
41
- visibilityTime,
42
- height,
43
- autoHide,
44
- position,
45
- type
46
- }) => ({
47
- // layout
48
- topOffset,
49
- bottomOffset,
50
- keyboardOffset,
51
- height,
52
- position,
53
- type,
54
-
55
- // timing (in ms)
56
- visibilityTime,
57
- autoHide,
58
-
59
- // content
60
- text1: undefined,
61
- text2: undefined,
62
-
63
- onPress: undefined,
64
- onShow: undefined,
65
- onHide: undefined
66
- });
67
-
68
- class Toast extends Component {
69
- static _ref = null;
70
-
71
- static setRef(ref = {}) {
72
- Toast._ref = ref;
73
- }
74
-
75
- static getRef() {
76
- return Toast._ref;
77
- }
78
-
79
- static clearRef() {
80
- Toast._ref = null;
81
- }
82
-
83
- static show(options = {}) {
84
- Toast._ref.show(options);
85
- }
86
-
87
- static hide() {
88
- Toast._ref.hide();
89
- }
90
-
91
- constructor(props) {
92
- super(props);
93
-
94
- this._setState = this._setState.bind(this);
95
- this._animateMovement = this._animateMovement.bind(this);
96
- this._animateRelease = this._animateRelease.bind(this);
97
- this.startTimer = this.startTimer.bind(this);
98
- this.animate = this.animate.bind(this);
99
- this.show = this.show.bind(this);
100
- this.hide = this.hide.bind(this);
101
- this.onLayout = this.onLayout.bind(this);
102
-
103
- this.state = {
104
- ...getInitialState(props),
105
-
106
- inProgress: false,
107
- isVisible: false,
108
- animation: new Animated.Value(0),
109
- keyboardHeight: 0,
110
- keyboardVisible: false,
111
-
112
- customProps: {}
113
- };
114
-
115
- this.panResponder = PanResponder.create({
116
- onMoveShouldSetPanResponder: (event, gesture) =>
117
- shouldSetPanResponder(gesture),
118
- onMoveShouldSetPanResponderCapture: (event, gesture) =>
119
- shouldSetPanResponder(gesture),
120
- onPanResponderMove: (event, gesture) => {
121
- this._animateMovement(gesture);
122
- },
123
- onPanResponderRelease: (event, gesture) => {
124
- this._animateRelease(gesture);
125
- }
126
- });
127
- }
128
-
129
- componentDidMount() {
130
- const noop = {
131
- remove: () => {}
132
- };
133
- this.keyboardDidShowListener = isIOS
134
- ? Keyboard.addListener('keyboardDidShow', this.keyboardDidShow)
135
- : noop;
136
- this.keyboardDidHideListner = isIOS
137
- ? Keyboard.addListener('keyboardDidHide', this.keyboardDidHide)
138
- : noop;
139
- }
140
-
141
- componentWillUnmount() {
142
- this.keyboardDidShowListener.remove();
143
- this.keyboardDidHideListner.remove();
144
- clearTimeout(this.timer);
145
- }
146
-
147
- keyboardDidShow = (e) => {
148
- const { isVisible, position } = this.state;
149
- this.setState({
150
- keyboardHeight: e.endCoordinates.height,
151
- keyboardVisible: true
152
- });
153
-
154
- if (isVisible && position === 'bottom') {
155
- this.animate({ toValue: 2 });
156
- }
157
- };
158
-
159
- keyboardDidHide = () => {
160
- const { isVisible, position } = this.state;
161
- this.setState({
162
- keyboardVisible: false
163
- });
164
- if (isVisible && position === 'bottom') {
165
- this.animate({ toValue: 1 });
166
- }
167
- };
168
-
169
- _setState(reducer) {
170
- return new Promise((resolve) => this.setState(reducer, () => resolve()));
171
- }
172
-
173
- _animateMovement(gesture) {
174
- const { position, animation, keyboardVisible } = this.state;
175
- const { dy } = gesture;
176
- let value = 1 + dy / 100;
177
- const start = keyboardVisible && position === 'bottom' ? 2 : 1;
178
-
179
- if (position === 'bottom') {
180
- value = start - dy / 100;
181
- }
182
-
183
- if (value <= start) {
184
- animation.setValue(value);
185
- }
186
- }
187
-
188
- _animateRelease(gesture) {
189
- const { position, animation, keyboardVisible } = this.state;
190
- const { dy, vy } = gesture;
191
-
192
- const isBottom = position === 'bottom';
193
- let value = 1 + dy / 100;
194
-
195
- if (isBottom) {
196
- value = 1 - dy / 100;
197
- }
198
-
199
- const treshold = 0.65;
200
- if (value <= treshold || Math.abs(vy) >= treshold) {
201
- this.hide({
202
- speed: Math.abs(vy) * 3
203
- });
204
- } else {
205
- Animated.spring(animation, {
206
- toValue: keyboardVisible && isBottom ? 2 : 1,
207
- velocity: vy,
208
- useNativeDriver: true
209
- }).start();
210
- }
211
- }
212
-
213
- async show(options = {}) {
214
- const { inProgress, isVisible } = this.state;
215
- if (inProgress || isVisible) {
216
- await this.hide();
217
- }
218
-
219
- await this._setState((prevState) => ({
220
- ...prevState,
221
- ...getInitialState(this.props), // Reset layout
222
- /*
223
- Preserve the previously computed height (via onLayout).
224
- If the height of the component corresponding to this `show` call is different,
225
- onLayout will be called again and `height` state will adjust.
226
-
227
- This fixes an issue where a succession of calls to components with custom heights (custom Toast types)
228
- fails to hide them completely due to always resetting to the default component height
229
- */
230
- height: prevState.height,
231
- inProgress: true,
232
- ...options,
233
- ...(options?.props ? { customProps: options.props } : { customProps: {} })
234
- }));
235
- await this.animateShow();
236
- await this._setState((prevState) => ({
237
- ...prevState,
238
- isVisible: true,
239
- inProgress: false
240
- }));
241
- this.clearTimer();
242
-
243
- const { autoHide, onShow } = this.state;
244
-
245
- if (autoHide) {
246
- this.startTimer();
247
- }
248
-
249
- if (onShow) {
250
- onShow();
251
- }
252
- }
253
-
254
- async hide({ speed } = {}) {
255
- await this._setState((prevState) => ({
256
- ...prevState,
257
- inProgress: true
258
- }));
259
- await this.animateHide({
260
- speed
261
- });
262
- this.clearTimer();
263
- await this._setState((prevState) => ({
264
- ...prevState,
265
- isVisible: false,
266
- inProgress: false
267
- }));
268
-
269
- const { onHide } = this.state;
270
- if (onHide) {
271
- onHide();
272
- }
273
- }
274
-
275
- animateShow = () => {
276
- const { keyboardVisible, position } = this.state;
277
- const toValue = keyboardVisible && position === 'bottom' ? 2 : 1;
278
- return this.animate({ toValue });
279
- };
280
-
281
- animateHide({ speed } = {}) {
282
- return this.animate({ toValue: 0, speed });
283
- }
284
-
285
- animate({ toValue, speed = 0 }) {
286
- const { animation } = this.state;
287
- return new Promise((resolve) => {
288
- const config = {
289
- toValue,
290
- useNativeDriver: true,
291
- ...(speed > 0 ? { speed } : { friction: FRICTION })
292
- };
293
- Animated.spring(animation, config).start(() => resolve());
294
- });
295
- }
296
-
297
- startTimer() {
298
- const { visibilityTime } = this.state;
299
- this.timer = setTimeout(() => this.hide(), visibilityTime);
300
- }
301
-
302
- clearTimer() {
303
- clearTimeout(this.timer);
304
- this.timer = null;
305
- }
306
-
307
- renderContent({ config }) {
308
- const componentsConfig = {
309
- ...defaultComponentsConfig,
310
- ...config
311
- };
312
-
313
- const { type, customProps } = this.state;
314
- const toastComponent = componentsConfig[type];
315
-
316
- if (!toastComponent) {
317
- // eslint-disable-next-line no-console
318
- console.error(
319
- `Type '${type}' does not exist. Make sure to add it to your 'config'. You can read the documentation here: https://github.com/calintamas/react-native-toast-message/blob/master/README.md`
320
- );
321
- return null;
322
- }
323
-
324
- return toastComponent({
325
- ...includeKeys({
326
- obj: this.state,
327
- keys: [
328
- 'position',
329
- 'type',
330
- 'inProgress',
331
- 'isVisible',
332
- 'text1',
333
- 'text2',
334
- 'hide',
335
- 'show',
336
- 'onPress'
337
- ]
338
- }),
339
- props: { ...customProps },
340
- hide: this.hide,
341
- show: this.show
342
- });
343
- }
344
-
345
- getBaseStyle(position = 'bottom', keyboardHeight) {
346
- const {
347
- topOffset,
348
- bottomOffset,
349
- keyboardOffset,
350
- height,
351
- animation
352
- } = this.state;
353
- const offset = position === 'bottom' ? bottomOffset : topOffset;
354
-
355
- // +5 px to completely hide the toast under StatusBar (on Android)
356
- const range = [height + 5, -offset, -(keyboardOffset + keyboardHeight)];
357
- const outputRange = position === 'bottom' ? range : complement(range);
358
-
359
- const translateY = animation.interpolate({
360
- inputRange: [0, 1, 2],
361
- outputRange
362
- });
363
-
364
- return [
365
- styles.base,
366
- styles[position],
367
- {
368
- transform: [{ translateY }]
369
- }
370
- ];
371
- }
372
-
373
- onLayout(e) {
374
- this.setState({ height: e.nativeEvent.layout.height });
375
- }
376
-
377
- render() {
378
- const { style } = this.props;
379
- const { position, keyboardHeight } = this.state;
380
- const baseStyle = this.getBaseStyle(position, keyboardHeight);
381
-
382
- return (
383
- <Animated.View
384
- testID='animatedView'
385
- onLayout={this.onLayout}
386
- style={[baseStyle, style]}
387
- {...this.panResponder.panHandlers}>
388
- {this.renderContent(this.props)}
389
- </Animated.View>
390
- );
391
- }
392
- }
393
-
394
- Toast.propTypes = {
395
- config: PropTypes.objectOf(PropTypes.func),
396
- style: stylePropType,
397
- topOffset: PropTypes.number,
398
- bottomOffset: PropTypes.number,
399
- keyboardOffset: PropTypes.number,
400
- visibilityTime: PropTypes.number,
401
- autoHide: PropTypes.bool,
402
- height: PropTypes.number,
403
- position: PropTypes.oneOf(['top', 'bottom']),
404
- type: PropTypes.string
405
- };
406
-
407
- Toast.defaultProps = {
408
- config: {},
409
- style: undefined,
410
- topOffset: 30,
411
- bottomOffset: 40,
412
- keyboardOffset: 15,
413
- visibilityTime: 4000,
414
- autoHide: true,
415
- height: 60,
416
- position: 'top',
417
- type: 'success'
418
- };
419
-
420
- export default Toast;
package/src/styles.js DELETED
@@ -1,17 +0,0 @@
1
- import { StyleSheet } from 'react-native';
2
-
3
- export default StyleSheet.create({
4
- base: {
5
- position: 'absolute',
6
- alignItems: 'center',
7
- justifyContent: 'center',
8
- left: 0,
9
- right: 0
10
- },
11
- top: {
12
- top: 0
13
- },
14
- bottom: {
15
- bottom: 0
16
- }
17
- });
package/src/utils/arr.js DELETED
@@ -1,3 +0,0 @@
1
- const complement = (arr) => arr.map((i) => -i);
2
-
3
- export { complement };
package/src/utils/obj.js DELETED
@@ -1,9 +0,0 @@
1
- const includeKeys = ({ obj = {}, keys = [] }) =>
2
- Object.keys(obj).reduce((acc, key) => {
3
- if (keys.includes(key)) {
4
- acc[key] = obj[key];
5
- }
6
- return acc;
7
- }, {});
8
-
9
- export { includeKeys };
@@ -1,5 +0,0 @@
1
- import { Platform } from 'react-native';
2
-
3
- const isIOS = Platform.OS === 'ios';
4
-
5
- export { isIOS };
@@ -1,5 +0,0 @@
1
- import PropTypes from 'prop-types';
2
-
3
- const stylePropType = PropTypes.oneOfType([PropTypes.object, PropTypes.number]);
4
-
5
- export { stylePropType };