react-native-toast-message 2.3.3 → 2.5.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/README.md CHANGED
@@ -20,8 +20,6 @@ Animated toast message component for React Native.
20
20
 
21
21
  ## Documentation
22
22
 
23
- > This is the documentation for `react-native-toast-message@v2`, which has a similar API to v1, but contains a few important changes. [Read the complete changelog](https://github.com/calintamas/react-native-toast-message/releases/tag/v2.0.0).
24
-
25
23
  - [Quick start](./docs/quick-start.md)
26
24
  - [API](./docs/api.md)
27
25
  - [Create custom layouts](./docs/custom-layouts.md)
@@ -10,7 +10,7 @@ const defaultToastConfig = {
10
10
  };
11
11
  function renderComponent({ data, options, config, isVisible, show, hide }) {
12
12
  const { text1, text2 } = data;
13
- const { type, onPress, text1Style, text2Style, position, props } = options;
13
+ const { type, onPress, text1Style, text2Style, position, visibilityTime, props } = options;
14
14
  const toastConfig = {
15
15
  ...defaultToastConfig,
16
16
  ...config
@@ -23,6 +23,7 @@ function renderComponent({ data, options, config, isVisible, show, hide }) {
23
23
  position,
24
24
  type,
25
25
  isVisible,
26
+ visibilityTime,
26
27
  text1,
27
28
  text2,
28
29
  text1Style,
@@ -35,8 +36,8 @@ function renderComponent({ data, options, config, isVisible, show, hide }) {
35
36
  }
36
37
  export function ToastUI(props) {
37
38
  const { isVisible, options, hide } = props;
38
- const { position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, swipeable } = options;
39
- return (<AnimatedContainer isVisible={isVisible} position={position} topOffset={topOffset} bottomOffset={bottomOffset} keyboardOffset={keyboardOffset} avoidKeyboard={avoidKeyboard} swipeable={swipeable} onHide={hide}>
39
+ const { position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, swipeable, animationConfig } = options;
40
+ return (<AnimatedContainer isVisible={isVisible} position={position} topOffset={topOffset} bottomOffset={bottomOffset} keyboardOffset={keyboardOffset} avoidKeyboard={avoidKeyboard} swipeable={swipeable} animationConfig={animationConfig} onHide={hide}>
40
41
  {renderComponent(props)}
41
42
  </AnimatedContainer>);
42
43
  }
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { PanResponderGestureState } from 'react-native';
3
- import { ReactChildren, ToastPosition } from '../types';
3
+ import { ReactChildren, ToastAnimationConfig, ToastPosition } from '../types';
4
4
  export declare type AnimatedContainerProps = {
5
5
  children: ReactChildren;
6
6
  isVisible: boolean;
@@ -10,6 +10,7 @@ export declare type AnimatedContainerProps = {
10
10
  bottomOffset: number;
11
11
  keyboardOffset: number;
12
12
  avoidKeyboard: boolean;
13
+ animationConfig?: ToastAnimationConfig;
13
14
  onHide: () => void;
14
15
  onRestorePosition?: () => void;
15
16
  };
@@ -21,4 +22,4 @@ export declare type AnimatedContainerProps = {
21
22
  */
22
23
  export declare function dampingFor(gesture: PanResponderGestureState, position: ToastPosition): number;
23
24
  export declare function animatedValueFor(gesture: PanResponderGestureState, position: ToastPosition, damping: number): number;
24
- export declare function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, onHide, onRestorePosition, swipeable }: AnimatedContainerProps): JSX.Element;
25
+ export declare function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, animationConfig, onHide, onRestorePosition, swipeable }: AnimatedContainerProps): JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Animated, Dimensions } from 'react-native';
3
3
  import { useLogger, useGesture } from '../contexts';
4
- import { usePanResponder, useSlideAnimation, useViewDimensions } from '../hooks';
4
+ import { useIsomorphicLayoutEffect, usePanResponder, useSlideAnimation, useViewDimensions } from '../hooks';
5
5
  import { noop } from '../utils/func';
6
6
  import { bound } from '../utils/number';
7
7
  import { getTestId } from '../utils/test-id';
@@ -37,7 +37,7 @@ export function animatedValueFor(gesture, position, damping) {
37
37
  throw new Error(`Toast position: ${position} not implemented`);
38
38
  }
39
39
  }
40
- export function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, onHide, onRestorePosition = noop, swipeable }) {
40
+ export function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, animationConfig, onHide, onRestorePosition = noop, swipeable }) {
41
41
  const { log } = useLogger();
42
42
  const { panning } = useGesture();
43
43
  const { computeViewDimensions, height } = useViewDimensions();
@@ -47,7 +47,8 @@ export function AnimatedContainer({ children, isVisible, position, topOffset, bo
47
47
  topOffset,
48
48
  bottomOffset,
49
49
  keyboardOffset,
50
- avoidKeyboard
50
+ avoidKeyboard,
51
+ animationConfig
51
52
  });
52
53
  const disable = !swipeable || !isVisible;
53
54
  const onStart = React.useCallback(() => {
@@ -82,7 +83,7 @@ export function AnimatedContainer({ children, isVisible, position, topOffset, bo
82
83
  onEnd,
83
84
  disable,
84
85
  });
85
- React.useLayoutEffect(() => {
86
+ useIsomorphicLayoutEffect(() => {
86
87
  const newAnimationValue = isVisible ? 1 : 0;
87
88
  animate(newAnimationValue);
88
89
  }, [animate, isVisible]);
@@ -1,3 +1,3 @@
1
1
  import React from 'react';
2
2
  import { BaseToastProps } from '../types';
3
- export declare function BaseToast({ text1, text2, onPress, activeOpacity, style, touchableContainerProps, contentContainerStyle, contentContainerProps, text1Style, text1NumberOfLines, text1Props, text2Style, text2NumberOfLines, text2Props, renderLeadingIcon, renderTrailingIcon }: BaseToastProps): React.ReactElement;
3
+ export declare function BaseToast({ testID, text1, text2, onPress, activeOpacity, style, touchableContainerProps, contentContainerStyle, contentContainerProps, text1Style, text1NumberOfLines, text1Props, text2Style, text2NumberOfLines, text2Props, renderLeadingIcon, renderTrailingIcon }: BaseToastProps): React.ReactElement;
@@ -1,15 +1,15 @@
1
1
  import React from 'react';
2
- import { Text, View, TouchableOpacity } from 'react-native';
2
+ import { Text, TouchableOpacity, View } from 'react-native';
3
3
  import { getTestId } from '../utils/test-id';
4
4
  import { styles } from './BaseToast.styles';
5
- export function BaseToast({ text1, text2, onPress, activeOpacity = 1, style, touchableContainerProps, contentContainerStyle, contentContainerProps, text1Style, text1NumberOfLines = 1, text1Props, text2Style, text2NumberOfLines = 1, text2Props, renderLeadingIcon, renderTrailingIcon }) {
6
- return (<TouchableOpacity testID={getTestId('TouchableContainer')} onPress={onPress} activeOpacity={activeOpacity} style={[styles.base, styles.leadingBorder, style]} {...touchableContainerProps}>
5
+ export function BaseToast({ testID = 'toast', text1, text2, onPress, activeOpacity = 1, style, touchableContainerProps, contentContainerStyle, contentContainerProps, text1Style, text1NumberOfLines = 1, text1Props, text2Style, text2NumberOfLines = 1, text2Props, renderLeadingIcon, renderTrailingIcon }) {
6
+ return (<TouchableOpacity testID={getTestId('TouchableContainer', testID)} onPress={onPress} activeOpacity={activeOpacity} style={[styles.base, styles.leadingBorder, style]} {...touchableContainerProps}>
7
7
  {renderLeadingIcon && renderLeadingIcon()}
8
- <View testID={getTestId('ContentContainer')} style={[styles.contentContainer, contentContainerStyle]} {...contentContainerProps}>
9
- {(text1?.length ?? 0) > 0 && (<Text testID={getTestId('Text1')} style={[styles.text1, text1Style]} numberOfLines={text1NumberOfLines} ellipsizeMode='tail' {...text1Props}>
8
+ <View testID={getTestId('ContentContainer', testID)} style={[styles.contentContainer, contentContainerStyle]} {...contentContainerProps}>
9
+ {(text1?.length ?? 0) > 0 && (<Text testID={getTestId('Text1', testID)} style={[styles.text1, text1Style]} numberOfLines={text1NumberOfLines} ellipsizeMode='tail' {...text1Props}>
10
10
  {text1}
11
11
  </Text>)}
12
- {(text2?.length ?? 0) > 0 && (<Text testID={getTestId('Text2')} style={[styles.text2, text2Style]} numberOfLines={text2NumberOfLines} ellipsizeMode='tail' {...text2Props}>
12
+ {(text2?.length ?? 0) > 0 && (<Text testID={getTestId('Text2', testID)} style={[styles.text2, text2Style]} numberOfLines={text2NumberOfLines} ellipsizeMode='tail' {...text2Props}>
13
13
  {text2}
14
14
  </Text>)}
15
15
  </View>
@@ -3,18 +3,26 @@ export declare const WIDTH = 340;
3
3
  export declare const BORDER_RADIUS = 6;
4
4
  export declare const styles: {
5
5
  base: {
6
+ elevation: number;
7
+ backgroundColor: string;
8
+ boxShadow: string;
6
9
  flexDirection: "row";
7
10
  height: number;
8
11
  width: number;
9
12
  borderRadius: number;
10
- shadowOffset: {
11
- width: number;
12
- height: number;
13
- };
14
- shadowOpacity: number;
15
- shadowRadius: number;
13
+ } | {
16
14
  elevation: number;
17
15
  backgroundColor: string;
16
+ shadowOffset?: {
17
+ width: number;
18
+ height: number;
19
+ } | undefined;
20
+ shadowOpacity?: number | undefined;
21
+ shadowRadius?: number | undefined;
22
+ flexDirection: "row";
23
+ height: number;
24
+ width: number;
25
+ borderRadius: number;
18
26
  };
19
27
  leadingBorder: {
20
28
  borderLeftWidth: number;
@@ -1,4 +1,4 @@
1
- import { StyleSheet } from 'react-native';
1
+ import { Platform, StyleSheet } from 'react-native';
2
2
  export const HEIGHT = 60;
3
3
  export const WIDTH = 340;
4
4
  export const BORDER_RADIUS = 6;
@@ -8,9 +8,16 @@ export const styles = StyleSheet.create({
8
8
  height: HEIGHT,
9
9
  width: WIDTH,
10
10
  borderRadius: BORDER_RADIUS,
11
- shadowOffset: { width: 0, height: 0 },
12
- shadowOpacity: 0.1,
13
- shadowRadius: BORDER_RADIUS,
11
+ ...Platform.select({
12
+ web: {
13
+ boxShadow: `0px 0px ${BORDER_RADIUS}px rgba(0, 0, 0, 0.1)`
14
+ },
15
+ default: {
16
+ shadowOffset: { width: 0, height: 0 },
17
+ shadowOpacity: 0.1,
18
+ shadowRadius: BORDER_RADIUS
19
+ }
20
+ }),
14
21
  elevation: 2,
15
22
  backgroundColor: '#FFF'
16
23
  },
@@ -3,3 +3,4 @@ export * from './useSlideAnimation';
3
3
  export * from './useTimeout';
4
4
  export * from './usePanResponder';
5
5
  export * from './useKeyboard';
6
+ export * from './useIsomorphicLayoutEffect';
@@ -3,3 +3,4 @@ export * from './useSlideAnimation';
3
3
  export * from './useTimeout';
4
4
  export * from './usePanResponder';
5
5
  export * from './useKeyboard';
6
+ export * from './useIsomorphicLayoutEffect';
@@ -0,0 +1,2 @@
1
+ import { useEffect } from 'react';
2
+ export declare const useIsomorphicLayoutEffect: typeof useEffect;
@@ -0,0 +1,4 @@
1
+ import { useEffect, useLayoutEffect } from 'react';
2
+ export const useIsomorphicLayoutEffect = typeof globalThis.window !== 'undefined'
3
+ ? useLayoutEffect
4
+ : useEffect;
@@ -17,4 +17,5 @@ export declare function usePanResponder({ animatedValue, computeNewAnimatedValue
17
17
  onGrant: () => void;
18
18
  onMove: (_event: GestureResponderEvent, gesture: PanResponderGestureState) => void;
19
19
  onRelease: (_event: GestureResponderEvent, gesture: PanResponderGestureState) => void;
20
+ onTerminate: () => void;
20
21
  };
@@ -40,18 +40,26 @@ export function usePanResponder({ animatedValue, computeNewAnimatedValueForGestu
40
40
  onRestore();
41
41
  }
42
42
  }, [computeNewAnimatedValueForGesture, onEnd, onDismiss, onRestore, disable]);
43
+ const onTerminate = React.useCallback(() => {
44
+ onEnd();
45
+ if (disable)
46
+ return;
47
+ onRestore();
48
+ }, [onEnd, onRestore, disable]);
43
49
  const panResponder = React.useMemo(() => PanResponder.create({
44
50
  onStartShouldSetPanResponder: startShouldSetPanResponder,
45
51
  onPanResponderGrant: onGrant,
46
52
  onMoveShouldSetPanResponder: moveShouldSetPanResponder,
47
53
  onMoveShouldSetPanResponderCapture: moveShouldSetPanResponder,
48
54
  onPanResponderMove: onMove,
49
- onPanResponderRelease: onRelease
50
- }), [onMove, onRelease, onGrant]);
55
+ onPanResponderRelease: onRelease,
56
+ onPanResponderTerminate: onTerminate
57
+ }), [onMove, onRelease, onTerminate, onGrant]);
51
58
  return {
52
59
  panResponder,
53
60
  onGrant,
54
61
  onMove,
55
62
  onRelease,
63
+ onTerminate
56
64
  };
57
65
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Animated } from 'react-native';
3
- import { ToastPosition } from '../types';
3
+ import { ToastAnimationConfig, ToastPosition } from '../types';
4
4
  declare type UseSlideAnimationParams = {
5
5
  position: ToastPosition;
6
6
  height: number;
@@ -8,11 +8,12 @@ declare type UseSlideAnimationParams = {
8
8
  bottomOffset: number;
9
9
  keyboardOffset: number;
10
10
  avoidKeyboard: boolean;
11
+ animationConfig?: ToastAnimationConfig;
11
12
  };
12
13
  export declare function translateYOutputRangeFor({ position, height, topOffset, bottomOffset, keyboardHeight, keyboardOffset, avoidKeyboard }: UseSlideAnimationParams & {
13
14
  keyboardHeight: number;
14
15
  }): number[];
15
- export declare function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset, avoidKeyboard }: UseSlideAnimationParams): {
16
+ export declare function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, animationConfig }: UseSlideAnimationParams): {
16
17
  animatedValue: React.MutableRefObject<Animated.Value>;
17
18
  animate: (toValue: number) => void;
18
19
  animationStyles: {
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Animated, Platform } from 'react-native';
3
3
  import { additiveInverseArray } from '../utils/array';
4
+ import { resolveAnimationConfig } from '../utils/animationConfig';
4
5
  import { useKeyboard } from './useKeyboard';
5
6
  export function translateYOutputRangeFor({ position, height, topOffset, bottomOffset, keyboardHeight, keyboardOffset, avoidKeyboard }) {
6
7
  const offset = position === 'bottom' ? bottomOffset : topOffset;
@@ -13,16 +14,28 @@ const useNativeDriver = Platform.select({
13
14
  ios: true,
14
15
  default: false
15
16
  });
16
- export function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset, avoidKeyboard }) {
17
+ export function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset, avoidKeyboard, animationConfig }) {
17
18
  const animatedValue = React.useRef(new Animated.Value(0));
18
19
  const { keyboardHeight } = useKeyboard();
19
20
  const animate = React.useCallback((toValue) => {
20
- Animated.spring(animatedValue.current, {
21
- toValue,
22
- useNativeDriver,
23
- friction: 8
24
- }).start();
25
- }, []);
21
+ const resolved = resolveAnimationConfig(animationConfig, toValue === 1 ? 'enter' : 'exit');
22
+ if (resolved.type === 'timing') {
23
+ const { type: _type, ...timingConfig } = resolved;
24
+ Animated.timing(animatedValue.current, {
25
+ ...timingConfig,
26
+ toValue,
27
+ useNativeDriver
28
+ }).start();
29
+ }
30
+ else {
31
+ const { type: _type, ...springConfig } = resolved;
32
+ Animated.spring(animatedValue.current, {
33
+ ...springConfig,
34
+ toValue,
35
+ useNativeDriver
36
+ }).start();
37
+ }
38
+ }, [animationConfig]);
26
39
  const translateY = React.useMemo(() => animatedValue.current.interpolate({
27
40
  inputRange: [0, 1],
28
41
  outputRange: translateYOutputRangeFor({
@@ -1,8 +1,19 @@
1
1
  import React from 'react';
2
- import { StyleProp, TextProps, TextStyle, TouchableOpacityProps, ViewProps, ViewStyle } from 'react-native';
2
+ import { Animated, StyleProp, TextProps, TextStyle, TouchableOpacityProps, ViewProps, ViewStyle } from 'react-native';
3
3
  export declare type ReactChildren = React.ReactNode;
4
4
  export declare type ToastType = 'success' | 'error' | 'info' | (string & {});
5
5
  export declare type ToastPosition = 'top' | 'bottom';
6
+ export declare type ToastSpringAnimationConfig = {
7
+ type: 'spring';
8
+ } & Omit<Parameters<typeof Animated.spring>[1], 'useNativeDriver' | 'toValue'>;
9
+ export declare type ToastTimingAnimationConfig = {
10
+ type: 'timing';
11
+ } & Omit<Parameters<typeof Animated.timing>[1], 'useNativeDriver' | 'toValue'>;
12
+ export declare type ToastSingleAnimationConfig = ToastSpringAnimationConfig | ToastTimingAnimationConfig;
13
+ export declare type ToastAnimationConfig = ToastSingleAnimationConfig | {
14
+ enter?: ToastSingleAnimationConfig;
15
+ exit?: ToastSingleAnimationConfig;
16
+ };
6
17
  export declare type ToastOptions = {
7
18
  /**
8
19
  * Toast type.
@@ -64,9 +75,9 @@ export declare type ToastOptions = {
64
75
  */
65
76
  avoidKeyboard?: boolean;
66
77
  /**
67
- * Called when Toast is shown
78
+ * Called when Toast is shown, receives the show params
68
79
  */
69
- onShow?: () => void;
80
+ onShow?: (params: ToastShowParams) => void;
70
81
  /**
71
82
  * Called when Toast hides
72
83
  */
@@ -81,6 +92,15 @@ export declare type ToastOptions = {
81
92
  * on the Toast instance) that uses the `props` parameter
82
93
  */
83
94
  props?: any;
95
+ /**
96
+ * Configures the enter/exit animation.
97
+ *
98
+ * Pass a single `{ type: 'spring' | 'timing', ...config }` to use the same animation
99
+ * for both phases, or `{ enter, exit }` to configure them separately.
100
+ *
101
+ * Default: `{ type: 'spring', friction: 8 }`
102
+ */
103
+ animationConfig?: ToastAnimationConfig;
84
104
  };
85
105
  export declare type ToastData = {
86
106
  text1?: string;
@@ -89,6 +109,7 @@ export declare type ToastData = {
89
109
  export declare type ToastShowParams = ToastData & ToastOptions;
90
110
  export declare type ToastHideParams = void;
91
111
  export declare type BaseToastProps = {
112
+ testID?: string;
92
113
  text1?: string;
93
114
  text2?: string;
94
115
  onPress?: () => void;
@@ -110,6 +131,7 @@ export declare type ToastConfigParams<Props> = {
110
131
  position: ToastPosition;
111
132
  type: ToastType;
112
133
  isVisible: boolean;
134
+ visibilityTime: number;
113
135
  text1?: string;
114
136
  text2?: string;
115
137
  text1Style?: StyleProp<TextStyle>;
@@ -187,9 +209,9 @@ export declare type ToastProps = {
187
209
  */
188
210
  avoidKeyboard?: boolean;
189
211
  /**
190
- * Called when any Toast is shown
212
+ * Called when any Toast is shown, receives the show params
191
213
  */
192
- onShow?: () => void;
214
+ onShow?: (params: ToastShowParams) => void;
193
215
  /**
194
216
  * Called when any Toast hides
195
217
  */
@@ -198,4 +220,11 @@ export declare type ToastProps = {
198
220
  * Called on any Toast press
199
221
  */
200
222
  onPress?: () => void;
223
+ /**
224
+ * Default enter/exit animation configuration applied to every Toast.
225
+ * Can be overridden per-call via `Toast.show({ animationConfig })`.
226
+ *
227
+ * Default: `{ type: 'spring', friction: 8 }`
228
+ */
229
+ animationConfig?: ToastAnimationConfig;
201
230
  };
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { useLogger, useGesture } from './contexts';
3
3
  import { useTimeout } from './hooks';
4
+ import { DEFAULT_ANIMATION_CONFIG } from './utils/animationConfig';
4
5
  import { noop } from './utils/func';
5
6
  import { mergeIfDefined } from './utils/obj';
6
7
  export const DEFAULT_DATA = {
@@ -22,7 +23,8 @@ export const DEFAULT_OPTIONS = {
22
23
  onShow: noop,
23
24
  onHide: noop,
24
25
  onPress: noop,
25
- props: {}
26
+ props: {},
27
+ animationConfig: DEFAULT_ANIMATION_CONFIG
26
28
  };
27
29
  export function useToast({ defaultOptions }) {
28
30
  const { log } = useLogger();
@@ -50,7 +52,7 @@ export function useToast({ defaultOptions }) {
50
52
  }, [clearTimer, log, options]);
51
53
  const show = React.useCallback((params) => {
52
54
  log(`Showing with params: ${JSON.stringify(params)}`);
53
- const { text1 = DEFAULT_DATA.text1, text2 = DEFAULT_DATA.text2, type = initialOptions.type, text1Style = initialOptions.text1Style, text2Style = initialOptions.text2Style, position = initialOptions.position, autoHide = initialOptions.autoHide, visibilityTime = initialOptions.visibilityTime, topOffset = initialOptions.topOffset, bottomOffset = initialOptions.bottomOffset, keyboardOffset = initialOptions.keyboardOffset, avoidKeyboard = initialOptions.avoidKeyboard, onShow = initialOptions.onShow, onHide = initialOptions.onHide, onPress = initialOptions.onPress, swipeable = initialOptions.swipeable, props = initialOptions.props } = params;
55
+ const { text1 = DEFAULT_DATA.text1, text2 = DEFAULT_DATA.text2, type = initialOptions.type, text1Style = initialOptions.text1Style, text2Style = initialOptions.text2Style, position = initialOptions.position, autoHide = initialOptions.autoHide, visibilityTime = initialOptions.visibilityTime, topOffset = initialOptions.topOffset, bottomOffset = initialOptions.bottomOffset, keyboardOffset = initialOptions.keyboardOffset, avoidKeyboard = initialOptions.avoidKeyboard, onShow = initialOptions.onShow, onHide = initialOptions.onHide, onPress = initialOptions.onPress, swipeable = initialOptions.swipeable, props = initialOptions.props, animationConfig = initialOptions.animationConfig } = params;
54
56
  setData({
55
57
  text1,
56
58
  text2
@@ -70,12 +72,13 @@ export function useToast({ defaultOptions }) {
70
72
  onHide,
71
73
  onPress,
72
74
  swipeable,
73
- props
75
+ props,
76
+ animationConfig
74
77
  }));
75
78
  // TODO: validate input
76
79
  // TODO: use a queue when Toast is already visible
77
80
  setIsVisible(true);
78
- onShow();
81
+ onShow(params);
79
82
  }, [initialOptions, log]);
80
83
  React.useEffect(() => {
81
84
  const { autoHide } = options;
@@ -0,0 +1,4 @@
1
+ import { ToastAnimationConfig, ToastSingleAnimationConfig, ToastSpringAnimationConfig } from '../types';
2
+ export declare const DEFAULT_ANIMATION_CONFIG: ToastSpringAnimationConfig;
3
+ export declare type AnimationPhase = 'enter' | 'exit';
4
+ export declare function resolveAnimationConfig(config: ToastAnimationConfig | undefined, phase: AnimationPhase): ToastSingleAnimationConfig;
@@ -0,0 +1,13 @@
1
+ export const DEFAULT_ANIMATION_CONFIG = {
2
+ type: 'spring',
3
+ friction: 8
4
+ };
5
+ export function resolveAnimationConfig(config, phase) {
6
+ if (!config) {
7
+ return DEFAULT_ANIMATION_CONFIG;
8
+ }
9
+ if ('type' in config) {
10
+ return config;
11
+ }
12
+ return config[phase] ?? DEFAULT_ANIMATION_CONFIG;
13
+ }
@@ -1 +1 @@
1
- export declare function getTestId(elementName: string): string;
1
+ export declare function getTestId(elementName: string, prefix?: string): string;
@@ -1,3 +1,3 @@
1
- export function getTestId(elementName) {
2
- return `toast${elementName}`;
1
+ export function getTestId(elementName, prefix = 'toast') {
2
+ return `${prefix}${elementName}`;
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-toast-message",
3
- "version": "2.3.3",
3
+ "version": "2.5.0",
4
4
  "description": "Toast message component for React Native",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -17,13 +17,14 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "prepare": "husky install",
20
+ "setup": "./scripts/setup.sh",
21
+ "bump": "./scripts/bump.sh",
20
22
  "build": "rm -rf ./lib && tsc",
21
23
  "prettier": "./node_modules/.bin/prettier --write",
22
- "lint": "./node_modules/.bin/eslint --fix",
23
- "lint-staged": "./node_modules/.bin/lint-staged",
24
+ "lint": "./node_modules/.bin/eslint --fix --cache",
24
25
  "test": "./node_modules/.bin/jest",
25
- "yalc:push": "yarn build && yalc publish --push",
26
- "quality": "yarn lint && tsc --noEmit"
26
+ "type-check": "tsc --build --incremental",
27
+ "quality": "yarn type-check && yarn lint && yarn test --coverage"
27
28
  },
28
29
  "author": "Calin Tamas <calintamas2@gmail.com>",
29
30
  "license": "MIT",
@@ -43,8 +44,7 @@
43
44
  "prettier": "^2.4.1",
44
45
  "prettier-plugin-import-sort": "^0.0.7",
45
46
  "react-test-renderer": "^17.0.2",
46
- "typescript": "^4.4.3",
47
- "yalc": "^1.0.0-pre.53"
47
+ "typescript": "^4.4.3"
48
48
  },
49
49
  "peerDependencies": {
50
50
  "react": "*",