react-native-toast-message 1.5.0 → 2.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.
Files changed (93) hide show
  1. package/CHANGELOG.md +86 -2
  2. package/README.md +19 -235
  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 -69
  64. package/index.js +0 -4
  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
@@ -0,0 +1,39 @@
1
+ import { StyleSheet } from 'react-native';
2
+ export const HEIGHT = 60;
3
+ export const WIDTH = 340;
4
+ export const BORDER_RADIUS = 6;
5
+ export const styles = StyleSheet.create({
6
+ base: {
7
+ flexDirection: 'row',
8
+ height: HEIGHT,
9
+ width: WIDTH,
10
+ borderRadius: BORDER_RADIUS,
11
+ shadowOffset: { width: 0, height: 0 },
12
+ shadowOpacity: 0.1,
13
+ shadowRadius: BORDER_RADIUS,
14
+ elevation: 2,
15
+ backgroundColor: '#FFF'
16
+ },
17
+ leadingBorder: {
18
+ borderLeftWidth: 5,
19
+ borderLeftColor: '#D8D8D8'
20
+ },
21
+ contentContainer: {
22
+ paddingHorizontal: 25,
23
+ flex: 1,
24
+ justifyContent: 'center',
25
+ alignItems: 'flex-start' // In case of RTL, the text will start from the right
26
+ },
27
+ text1: {
28
+ fontSize: 12,
29
+ fontWeight: 'bold',
30
+ marginBottom: 2,
31
+ color: '#000',
32
+ width: '100%' // Fixes: https://github.com/calintamas/react-native-toast-message/issues/130
33
+ },
34
+ text2: {
35
+ fontSize: 10,
36
+ color: '#979797',
37
+ width: '100%' // Fixes: https://github.com/calintamas/react-native-toast-message/issues/130
38
+ }
39
+ });
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { BaseToastProps } from '../types';
3
+ export declare function ErrorToast(props: BaseToastProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { BaseToast } from './BaseToast';
3
+ export function ErrorToast(props) {
4
+ return <BaseToast style={{ borderLeftColor: '#FE6301' }} {...props}/>;
5
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { BaseToastProps } from '../types';
3
+ export declare function InfoToast(props: BaseToastProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { BaseToast } from './BaseToast';
3
+ export function InfoToast(props) {
4
+ return <BaseToast style={{ borderLeftColor: '#87CEFA' }} {...props}/>;
5
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import { BaseToastProps } from '../types';
3
+ export declare function SuccessToast(props: BaseToastProps): JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { BaseToast } from './BaseToast';
3
+ export function SuccessToast(props) {
4
+ return <BaseToast style={{ borderLeftColor: '#69C779' }} {...props}/>;
5
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { TouchableOpacityProps } from 'react-native';
3
+ import { ReactChildren } from '../types';
4
+ declare type TouchableProps = {
5
+ children: ReactChildren;
6
+ } & TouchableOpacityProps;
7
+ export declare function Touchable({ children, activeOpacity, ...rest }: TouchableProps): JSX.Element;
8
+ export {};
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { TouchableOpacity } from 'react-native';
3
+ export function Touchable({ children, activeOpacity = 1, ...rest }) {
4
+ return (<TouchableOpacity activeOpacity={activeOpacity} {...rest}>
5
+ {children}
6
+ </TouchableOpacity>);
7
+ }
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { ReactChildren } from '../types';
3
+ export declare type LoggerContextType = {
4
+ log: (...args: unknown[]) => void;
5
+ };
6
+ export declare type LoggerProviderProps = {
7
+ children: ReactChildren;
8
+ enableLogs?: boolean;
9
+ };
10
+ declare function LoggerProvider({ children, enableLogs }: LoggerProviderProps): JSX.Element;
11
+ declare function useLogger(): LoggerContextType;
12
+ export { LoggerProvider, useLogger };
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { noop } from '../utils/func';
3
+ const LoggerContext = React.createContext({
4
+ log: noop
5
+ });
6
+ function LoggerProvider({ children, enableLogs = false }) {
7
+ const log = React.useCallback((...args) => {
8
+ if (enableLogs) {
9
+ // eslint-disable-next-line no-console
10
+ console.log('Toast:', ...args);
11
+ }
12
+ }, [enableLogs]);
13
+ const value = {
14
+ log
15
+ };
16
+ return (<LoggerContext.Provider value={value}>{children}</LoggerContext.Provider>);
17
+ }
18
+ function useLogger() {
19
+ const ctx = React.useContext(LoggerContext);
20
+ return ctx;
21
+ }
22
+ export { LoggerProvider, useLogger };
@@ -0,0 +1 @@
1
+ export * from './LoggerContext';
@@ -0,0 +1 @@
1
+ export * from './LoggerContext';
@@ -0,0 +1,5 @@
1
+ export * from './useViewDimensions';
2
+ export * from './useSlideAnimation';
3
+ export * from './useTimeout';
4
+ export * from './usePanResponder';
5
+ export * from './useKeyboard';
@@ -0,0 +1,5 @@
1
+ export * from './useViewDimensions';
2
+ export * from './useSlideAnimation';
3
+ export * from './useTimeout';
4
+ export * from './usePanResponder';
5
+ export * from './useKeyboard';
@@ -0,0 +1,4 @@
1
+ export declare function useKeyboard(): {
2
+ keyboardHeight: number;
3
+ isKeyboardVisible: boolean;
4
+ };
@@ -0,0 +1,31 @@
1
+ import React from 'react';
2
+ import { Keyboard } from 'react-native';
3
+ import { isIOS } from '../utils/platform';
4
+ export function useKeyboard() {
5
+ const [keyboardHeight, setKeyboardHeight] = React.useState(0);
6
+ const [isKeyboardVisible, setIsKeyboardVisible] = React.useState(false);
7
+ const onShow = React.useCallback((event) => {
8
+ const { height } = event.endCoordinates;
9
+ setKeyboardHeight(height);
10
+ setIsKeyboardVisible(true);
11
+ }, []);
12
+ const onHide = React.useCallback(() => {
13
+ setKeyboardHeight(0);
14
+ setIsKeyboardVisible(false);
15
+ }, []);
16
+ React.useEffect(() => {
17
+ if (!isIOS()) {
18
+ return () => { };
19
+ }
20
+ const didShowListener = Keyboard.addListener('keyboardDidShow', onShow);
21
+ const didHideListener = Keyboard.addListener('keyboardDidHide', onHide);
22
+ return () => {
23
+ didShowListener.remove();
24
+ didHideListener.remove();
25
+ };
26
+ }, [onHide, onShow]);
27
+ return {
28
+ keyboardHeight,
29
+ isKeyboardVisible
30
+ };
31
+ }
@@ -0,0 +1,15 @@
1
+ import { RefObject } from 'react';
2
+ import { Animated, GestureResponderEvent, PanResponderGestureState } from 'react-native';
3
+ export declare function shouldSetPanResponder(_event: GestureResponderEvent, gesture: PanResponderGestureState): boolean;
4
+ export declare function shouldDismissView(newAnimatedValue: number, gesture: PanResponderGestureState): boolean;
5
+ export declare type UsePanResponderParams = {
6
+ animatedValue: RefObject<Animated.Value>;
7
+ computeNewAnimatedValueForGesture: (gesture: PanResponderGestureState) => number;
8
+ onDismiss: () => void;
9
+ onRestore: () => void;
10
+ };
11
+ export declare function usePanResponder({ animatedValue, computeNewAnimatedValueForGesture, onDismiss, onRestore }: UsePanResponderParams): {
12
+ panResponder: import("react-native").PanResponderInstance;
13
+ onMove: (_event: GestureResponderEvent, gesture: PanResponderGestureState) => void;
14
+ onRelease: (_event: GestureResponderEvent, gesture: PanResponderGestureState) => void;
15
+ };
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { PanResponder } from 'react-native';
3
+ export function shouldSetPanResponder(_event, gesture) {
4
+ const { dx, dy } = gesture;
5
+ // Fixes onPress handler
6
+ // https://github.com/calintamas/react-native-toast-message/issues/113
7
+ const offset = 2;
8
+ return Math.abs(dx) > offset || Math.abs(dy) > offset;
9
+ }
10
+ export function shouldDismissView(newAnimatedValue, gesture) {
11
+ const dismissThreshold = 0.65;
12
+ const { vy, dy } = gesture;
13
+ return (newAnimatedValue <= dismissThreshold ||
14
+ (Math.abs(vy) >= dismissThreshold && dy < 0));
15
+ }
16
+ export function usePanResponder({ animatedValue, computeNewAnimatedValueForGesture, onDismiss, onRestore }) {
17
+ const onMove = React.useCallback((_event, gesture) => {
18
+ const newAnimatedValue = computeNewAnimatedValueForGesture(gesture);
19
+ animatedValue.current?.setValue(newAnimatedValue);
20
+ }, [animatedValue, computeNewAnimatedValueForGesture]);
21
+ const onRelease = React.useCallback((_event, gesture) => {
22
+ const newAnimatedValue = computeNewAnimatedValueForGesture(gesture);
23
+ if (shouldDismissView(newAnimatedValue, gesture)) {
24
+ onDismiss();
25
+ }
26
+ else {
27
+ onRestore();
28
+ }
29
+ }, [computeNewAnimatedValueForGesture, onDismiss, onRestore]);
30
+ const panResponder = React.useMemo(() => PanResponder.create({
31
+ onMoveShouldSetPanResponder: shouldSetPanResponder,
32
+ onMoveShouldSetPanResponderCapture: shouldSetPanResponder,
33
+ onPanResponderMove: onMove,
34
+ onPanResponderRelease: onRelease
35
+ }), [onMove, onRelease]);
36
+ return {
37
+ panResponder,
38
+ onMove,
39
+ onRelease
40
+ };
41
+ }
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Animated } from 'react-native';
3
+ import { ToastPosition } from '../types';
4
+ declare type UseSlideAnimationParams = {
5
+ position: ToastPosition;
6
+ height: number;
7
+ topOffset: number;
8
+ bottomOffset: number;
9
+ keyboardOffset: number;
10
+ };
11
+ export declare function translateYOutputRangeFor({ position, height, topOffset, bottomOffset, keyboardHeight, keyboardOffset }: UseSlideAnimationParams & {
12
+ keyboardHeight: number;
13
+ }): number[];
14
+ export declare function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset }: UseSlideAnimationParams): {
15
+ animatedValue: React.MutableRefObject<Animated.Value>;
16
+ animate: (toValue: number) => void;
17
+ animationStyles: {
18
+ opacity: Animated.AnimatedInterpolation;
19
+ transform: {
20
+ translateY: Animated.AnimatedInterpolation;
21
+ }[];
22
+ };
23
+ };
24
+ export {};
@@ -0,0 +1,49 @@
1
+ import React from 'react';
2
+ import { Animated } from 'react-native';
3
+ import { additiveInverseArray } from '../utils/array';
4
+ import { useKeyboard } from './useKeyboard';
5
+ export function translateYOutputRangeFor({ position, height, topOffset, bottomOffset, keyboardHeight, keyboardOffset }) {
6
+ const offset = position === 'bottom' ? bottomOffset : topOffset;
7
+ const keyboardAwareOffset = position === 'bottom' ? keyboardHeight + keyboardOffset : 0;
8
+ const range = [-(height * 2), Math.max(offset, keyboardAwareOffset)];
9
+ const outputRange = position === 'bottom' ? additiveInverseArray(range) : range;
10
+ return outputRange;
11
+ }
12
+ export function useSlideAnimation({ position, height, topOffset, bottomOffset, keyboardOffset }) {
13
+ const animatedValue = React.useRef(new Animated.Value(0));
14
+ const { keyboardHeight } = useKeyboard();
15
+ const animate = React.useCallback((toValue) => {
16
+ Animated.spring(animatedValue.current, {
17
+ toValue,
18
+ useNativeDriver: true,
19
+ friction: 8
20
+ }).start();
21
+ }, []);
22
+ const translateY = animatedValue.current.interpolate({
23
+ inputRange: [0, 1],
24
+ outputRange: translateYOutputRangeFor({
25
+ position,
26
+ height,
27
+ topOffset,
28
+ bottomOffset,
29
+ keyboardHeight,
30
+ keyboardOffset
31
+ })
32
+ });
33
+ const opacity = animatedValue.current.interpolate({
34
+ inputRange: [0, 0.7, 1],
35
+ outputRange: [0, 1, 1]
36
+ });
37
+ return {
38
+ animatedValue,
39
+ animate,
40
+ animationStyles: {
41
+ opacity,
42
+ transform: [
43
+ {
44
+ translateY
45
+ }
46
+ ]
47
+ }
48
+ };
49
+ }
@@ -0,0 +1,6 @@
1
+ declare function useTimeout<CbParams>(cb: (params?: CbParams) => void, delayMs?: number): {
2
+ startTimer: () => void;
3
+ clearTimer: () => void;
4
+ isActive: boolean;
5
+ };
6
+ export { useTimeout };
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { useLogger } from '../contexts';
3
+ function useTimeout(cb, delayMs = 0) {
4
+ const { log } = useLogger();
5
+ const ref = React.useRef();
6
+ const clearTimer = React.useCallback(() => {
7
+ if (ref.current) {
8
+ log('Clearing timer', ref.current);
9
+ clearTimeout(ref.current);
10
+ ref.current = undefined;
11
+ }
12
+ }, [log]);
13
+ const startTimer = React.useCallback(() => {
14
+ clearTimer();
15
+ ref.current = setTimeout(() => {
16
+ cb();
17
+ log('Running timer', ref.current);
18
+ ref.current = undefined;
19
+ }, delayMs);
20
+ log('Starting timer', ref.current);
21
+ }, [clearTimer, delayMs, log, cb]);
22
+ React.useEffect(() => () => clearTimer(), [clearTimer]);
23
+ return {
24
+ startTimer,
25
+ clearTimer,
26
+ isActive: ref.current !== undefined
27
+ };
28
+ }
29
+ export { useTimeout };
@@ -0,0 +1,13 @@
1
+ import { LayoutChangeEvent } from 'react-native';
2
+ export declare type UseViewDimensionsParams = {
3
+ heightOffset?: number;
4
+ widthOffset?: number;
5
+ };
6
+ /**
7
+ * Retrieves View dimensions (height, width) from a LayoutChangeEvent and sets them on state
8
+ */
9
+ export declare function useViewDimensions({ heightOffset, widthOffset }?: UseViewDimensionsParams): {
10
+ computeViewDimensions: (event: LayoutChangeEvent) => void;
11
+ height: number;
12
+ width: number;
13
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ const getLayoutValue = (key) => (event) => event?.nativeEvent?.layout?.[key] ?? 0;
3
+ /**
4
+ * Retrieves View dimensions (height, width) from a LayoutChangeEvent and sets them on state
5
+ */
6
+ export function useViewDimensions({ heightOffset = 0, widthOffset = 0 } = {}) {
7
+ const [height, setHeight] = React.useState(0);
8
+ const [width, setWidth] = React.useState(0);
9
+ const computeViewDimensions = React.useCallback((event) => {
10
+ const h = getLayoutValue('height')(event);
11
+ const w = getLayoutValue('width')(event);
12
+ setHeight(h + heightOffset);
13
+ setWidth(w + widthOffset);
14
+ }, [heightOffset, widthOffset]);
15
+ return {
16
+ computeViewDimensions,
17
+ height,
18
+ width
19
+ };
20
+ }
@@ -0,0 +1,165 @@
1
+ import React from 'react';
2
+ import { TextStyle, TouchableOpacityProps, ViewStyle } from 'react-native';
3
+ export declare type ReactChildren = React.ReactNode;
4
+ export declare type ToastType = string;
5
+ export declare type ToastPosition = 'top' | 'bottom';
6
+ export declare type ToastOptions = {
7
+ /**
8
+ * Toast type.
9
+ * Default value: `success`
10
+ */
11
+ type?: ToastType;
12
+ /**
13
+ * Toast position.
14
+ * Default value: `top`
15
+ */
16
+ position?: ToastPosition;
17
+ /**
18
+ * When `true`, the visible Toast automatically hides after a certain number of seconds,
19
+ * specified by the `visibilityTime` prop.
20
+ * Default value: `true`
21
+ */
22
+ autoHide?: boolean;
23
+ /**
24
+ * Number of seconds after which Toast automatically hides.
25
+ * Has effect only in conjunction with `autoHide` prop set to `true`.
26
+ * Default value: `4000`
27
+ */
28
+ visibilityTime?: number;
29
+ /**
30
+ * Offset from the top of the screen (in px).
31
+ * Has effect only when `position` is `top`
32
+ * Default value: `40`
33
+ */
34
+ topOffset?: number;
35
+ /**
36
+ * Offset from the bottom of the screen (in px)
37
+ * Has effect only when `position` is `bottom`
38
+ * Default value: `40`
39
+ */
40
+ bottomOffset?: number;
41
+ /**
42
+ * Offset from the Keyboard (in px)
43
+ * Has effect only when `position` is `bottom` and Keyboard is visible
44
+ * Default value: `10`
45
+ */
46
+ keyboardOffset?: number;
47
+ /**
48
+ * Called when Toast is shown
49
+ */
50
+ onShow?: () => void;
51
+ /**
52
+ * Called when Toast hides
53
+ */
54
+ onHide?: () => void;
55
+ /**
56
+ * Called on Toast press
57
+ */
58
+ onPress?: () => void;
59
+ /**
60
+ * Any custom props passed to the specified Toast type.
61
+ * Has effect only when there is a custom Toast type (configured via the `config` prop
62
+ * on the Toast instance) that uses the `props` parameter
63
+ */
64
+ props?: any;
65
+ };
66
+ export declare type ToastData = {
67
+ text1?: string;
68
+ text2?: string;
69
+ };
70
+ export declare type ToastShowParams = ToastData & ToastOptions;
71
+ export declare type ToastHideParams = void;
72
+ export declare type BaseToastProps = {
73
+ text1?: string;
74
+ text2?: string;
75
+ onPress?: () => void;
76
+ activeOpacity?: number;
77
+ style?: ViewStyle;
78
+ touchableContainerProps?: TouchableOpacityProps;
79
+ contentContainerStyle?: ViewStyle;
80
+ contentContainerProps?: ViewStyle;
81
+ text1Style?: TextStyle;
82
+ text1NumberOfLines?: number;
83
+ text1Props?: TextStyle;
84
+ text2Style?: TextStyle;
85
+ text2NumberOfLines?: number;
86
+ text2Props?: TextStyle;
87
+ renderLeadingIcon?: () => React.ReactNode;
88
+ renderTrailingIcon?: () => React.ReactNode;
89
+ };
90
+ export declare type ToastConfigParams<Props> = {
91
+ position: ToastPosition;
92
+ type: ToastType;
93
+ isVisible: boolean;
94
+ text1?: string;
95
+ text2?: string;
96
+ show: (params: ToastShowParams) => void;
97
+ hide: (params: ToastHideParams) => void;
98
+ onPress: () => void;
99
+ props: Props;
100
+ };
101
+ export declare type ToastConfig = {
102
+ [key: string]: (params: ToastConfigParams<any>) => React.ReactNode;
103
+ };
104
+ /**
105
+ * `props` that can be set on the Toast instance.
106
+ * They act as defaults for all Toasts that are shown.
107
+ */
108
+ export declare type ToastProps = {
109
+ /**
110
+ * Layout configuration for custom Toast types
111
+ */
112
+ config?: ToastConfig;
113
+ /**
114
+ * Toast type.
115
+ * Default value: `success`
116
+ */
117
+ type?: ToastType;
118
+ /**
119
+ * Toast position.
120
+ * Default value: `top`
121
+ */
122
+ position?: ToastPosition;
123
+ /**
124
+ * Number of milliseconds after which Toast automatically hides.
125
+ * Has effect only in conjunction with `autoHide` prop set to `true`.
126
+ * Default value: `4000`
127
+ */
128
+ visibilityTime?: number;
129
+ /**
130
+ * When `true`, the visible Toast automatically hides after a certain number of milliseconds,
131
+ * specified by the `visibilityTime` prop.
132
+ * Default value: `true`
133
+ */
134
+ autoHide?: boolean;
135
+ /**
136
+ * Offset from the top of the screen (in px).
137
+ * Has effect only when `position` is `top`
138
+ * Default value: `40`
139
+ */
140
+ topOffset?: number;
141
+ /**
142
+ * Offset from the bottom of the screen (in px)
143
+ * Has effect only when `position` is `bottom`
144
+ * Default value: `40`
145
+ */
146
+ bottomOffset?: number;
147
+ /**
148
+ * Offset from the Keyboard (in px)
149
+ * Has effect only when `position` is `bottom` and Keyboard is visible (iOS only)
150
+ * Default value: `10`
151
+ */
152
+ keyboardOffset?: number;
153
+ /**
154
+ * Called when any Toast is shown
155
+ */
156
+ onShow?: () => void;
157
+ /**
158
+ * Called when any Toast hides
159
+ */
160
+ onHide?: () => void;
161
+ /**
162
+ * Called on any Toast press
163
+ */
164
+ onPress?: () => void;
165
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { ToastData, ToastOptions, ToastProps, ToastShowParams } from './types';
2
+ export declare const DEFAULT_DATA: ToastData;
3
+ export declare const DEFAULT_OPTIONS: Required<ToastOptions>;
4
+ export declare type UseToastParams = {
5
+ defaultOptions: Omit<ToastProps, 'config'>;
6
+ };
7
+ export declare function useToast({ defaultOptions }: UseToastParams): {
8
+ isVisible: boolean;
9
+ data: ToastData;
10
+ options: Required<ToastOptions>;
11
+ show: (params: ToastShowParams) => void;
12
+ hide: () => void;
13
+ };
@@ -0,0 +1,79 @@
1
+ import React from 'react';
2
+ import { useLogger } from './contexts';
3
+ import { useTimeout } from './hooks';
4
+ import { noop } from './utils/func';
5
+ import { mergeIfDefined } from './utils/obj';
6
+ export const DEFAULT_DATA = {
7
+ text1: undefined,
8
+ text2: undefined
9
+ };
10
+ export const DEFAULT_OPTIONS = {
11
+ type: 'success',
12
+ position: 'top',
13
+ autoHide: true,
14
+ visibilityTime: 4000,
15
+ topOffset: 40,
16
+ bottomOffset: 40,
17
+ keyboardOffset: 10,
18
+ onShow: noop,
19
+ onHide: noop,
20
+ onPress: noop,
21
+ props: {}
22
+ };
23
+ export function useToast({ defaultOptions }) {
24
+ const { log } = useLogger();
25
+ const [isVisible, setIsVisible] = React.useState(false);
26
+ const [data, setData] = React.useState(DEFAULT_DATA);
27
+ const initialOptions = mergeIfDefined(DEFAULT_OPTIONS, defaultOptions);
28
+ const [options, setOptions] = React.useState(initialOptions);
29
+ const onAutoHide = React.useCallback(() => {
30
+ log('Auto hiding');
31
+ setIsVisible(false);
32
+ options.onHide();
33
+ }, [log, options]);
34
+ const { startTimer, clearTimer } = useTimeout(onAutoHide, options.visibilityTime);
35
+ const hide = React.useCallback(() => {
36
+ log('Hiding');
37
+ setIsVisible(false);
38
+ clearTimer();
39
+ options.onHide();
40
+ }, [clearTimer, log, options]);
41
+ const show = React.useCallback((params) => {
42
+ log(`Showing with params: ${JSON.stringify(params)}`);
43
+ const { text1 = DEFAULT_DATA.text1, text2 = DEFAULT_DATA.text2, type = initialOptions.type, position = initialOptions.position, autoHide = initialOptions.autoHide, visibilityTime = initialOptions.visibilityTime, topOffset = initialOptions.topOffset, bottomOffset = initialOptions.bottomOffset, keyboardOffset = initialOptions.keyboardOffset, onShow = initialOptions.onShow, onHide = initialOptions.onHide, onPress = initialOptions.onPress, props = initialOptions.props } = params;
44
+ // TODO: validate input
45
+ // TODO: use a queue when Toast is already visible
46
+ setIsVisible(true);
47
+ setData({
48
+ text1,
49
+ text2
50
+ });
51
+ setOptions(mergeIfDefined(initialOptions, {
52
+ type,
53
+ position,
54
+ autoHide,
55
+ visibilityTime,
56
+ topOffset,
57
+ bottomOffset,
58
+ keyboardOffset,
59
+ onShow,
60
+ onHide,
61
+ onPress,
62
+ props
63
+ }));
64
+ onShow();
65
+ }, [initialOptions, log]);
66
+ React.useEffect(() => {
67
+ const { autoHide } = options;
68
+ if (isVisible && autoHide) {
69
+ startTimer();
70
+ }
71
+ }, [isVisible, options, startTimer]);
72
+ return {
73
+ isVisible,
74
+ data,
75
+ options,
76
+ show,
77
+ hide
78
+ };
79
+ }
@@ -0,0 +1,2 @@
1
+ declare function additiveInverseArray(arr: number[]): number[];
2
+ export { additiveInverseArray };
@@ -0,0 +1,4 @@
1
+ function additiveInverseArray(arr) {
2
+ return arr.map((i) => -i);
3
+ }
4
+ export { additiveInverseArray };