react-native-toast-message 2.1.5 → 2.2.0-beta.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 (58) hide show
  1. package/lib/src/Toast.d.ts +1 -1
  2. package/lib/src/Toast.js +5 -3
  3. package/lib/src/ToastUI.js +1 -1
  4. package/lib/src/__helpers__/PanResponder.d.ts +3 -0
  5. package/lib/src/__helpers__/PanResponder.js +26 -0
  6. package/lib/src/__helpers__/testing-library/react-hooks.d.ts +9 -0
  7. package/lib/src/__helpers__/testing-library/react-hooks.js +13 -0
  8. package/lib/src/__helpers__/testing-library/react-native.d.ts +9 -0
  9. package/lib/src/__helpers__/testing-library/react-native.js +13 -0
  10. package/lib/src/__mocks__/EnvironmentProviderMock.d.ts +7 -0
  11. package/lib/src/__mocks__/EnvironmentProviderMock.js +9 -0
  12. package/lib/src/__tests__/Toast.test.d.ts +1 -0
  13. package/lib/src/__tests__/Toast.test.js +190 -0
  14. package/lib/src/__tests__/ToastUI.test.d.ts +1 -0
  15. package/lib/src/__tests__/ToastUI.test.js +52 -0
  16. package/lib/src/__tests__/useToast.test.d.ts +1 -0
  17. package/lib/src/__tests__/useToast.test.js +142 -0
  18. package/lib/src/components/AnimatedContainer.js +2 -2
  19. package/lib/src/components/BaseToast.js +2 -2
  20. package/lib/src/components/__tests__/AnimatedContainer.test.d.ts +1 -0
  21. package/lib/src/components/__tests__/AnimatedContainer.test.js +147 -0
  22. package/lib/src/components/__tests__/BaseToast.test.d.ts +1 -0
  23. package/lib/src/components/__tests__/BaseToast.test.js +81 -0
  24. package/lib/src/components/__tests__/ErrorToast.test.d.ts +1 -0
  25. package/lib/src/components/__tests__/ErrorToast.test.js +20 -0
  26. package/lib/src/components/__tests__/InfoToast.test.d.ts +1 -0
  27. package/lib/src/components/__tests__/InfoToast.test.js +20 -0
  28. package/lib/src/components/__tests__/SuccessToast.test.d.ts +1 -0
  29. package/lib/src/components/__tests__/SuccessToast.test.js +20 -0
  30. package/lib/src/contexts/EnvironmentContext.d.ts +8 -0
  31. package/lib/src/contexts/EnvironmentContext.js +22 -0
  32. package/lib/src/contexts/__tests__/EnvironmentContext.test.d.ts +1 -0
  33. package/lib/src/contexts/__tests__/EnvironmentContext.test.js +29 -0
  34. package/lib/src/contexts/__tests__/LoggerContext.test.d.ts +1 -0
  35. package/lib/src/contexts/__tests__/LoggerContext.test.js +35 -0
  36. package/lib/src/contexts/index.d.ts +4 -1
  37. package/lib/src/contexts/index.js +2 -1
  38. package/lib/src/hooks/__tests__/useKeyboard.test.d.ts +1 -0
  39. package/lib/src/hooks/__tests__/useKeyboard.test.js +60 -0
  40. package/lib/src/hooks/__tests__/usePanResponder.test.d.ts +1 -0
  41. package/lib/src/hooks/__tests__/usePanResponder.test.js +112 -0
  42. package/lib/src/hooks/__tests__/useSlideAnimation.test.d.ts +1 -0
  43. package/lib/src/hooks/__tests__/useSlideAnimation.test.js +88 -0
  44. package/lib/src/hooks/__tests__/useTimeout.test.d.ts +1 -0
  45. package/lib/src/hooks/__tests__/useTimeout.test.js +54 -0
  46. package/lib/src/hooks/__tests__/useViewDimensions.test.d.ts +1 -0
  47. package/lib/src/hooks/__tests__/useViewDimensions.test.js +51 -0
  48. package/lib/src/hooks/useSlideAnimation.d.ts +6 -2
  49. package/lib/src/hooks/useSlideAnimation.js +35 -10
  50. package/lib/src/types/index.d.ts +9 -0
  51. package/lib/src/utils/__tests__/number.test.d.ts +1 -0
  52. package/lib/src/utils/__tests__/number.test.js +15 -0
  53. package/lib/src/utils/__tests__/obj.test.d.ts +1 -0
  54. package/lib/src/utils/__tests__/obj.test.js +21 -0
  55. package/package.json +21 -11
  56. package/CHANGELOG.md +0 -311
  57. package/lib/src/utils/array.d.ts +0 -2
  58. package/lib/src/utils/array.js +0 -4
@@ -1,6 +1,6 @@
1
1
  /// <reference types="react" />
2
2
  import { ToastProps, ToastShowParams } from './types';
3
- export declare function Toast(props: ToastProps): JSX.Element;
3
+ export declare function Toast({ useNativeDriver, ...props }: ToastProps): JSX.Element;
4
4
  export declare namespace Toast {
5
5
  var show: (params: ToastShowParams) => void;
6
6
  var hide: (params?: void | undefined) => void;
package/lib/src/Toast.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { LoggerProvider } from './contexts';
2
+ import { EnvironmentProvider, LoggerProvider } from './contexts';
3
3
  import { ToastUI } from './ToastUI';
4
4
  import { useToast } from './useToast';
5
5
  const ToastRoot = React.forwardRef((props, ref) => {
@@ -33,7 +33,7 @@ function addNewRef(newRef) {
33
33
  function removeOldRef(oldRef) {
34
34
  refs = refs.filter((r) => r.current !== oldRef);
35
35
  }
36
- export function Toast(props) {
36
+ export function Toast({ useNativeDriver, ...props }) {
37
37
  const toastRef = React.useRef(null);
38
38
  /*
39
39
  This must use `useCallback` to ensure the ref doesn't get set to null and then a new ref every render.
@@ -53,7 +53,9 @@ export function Toast(props) {
53
53
  }
54
54
  }, []);
55
55
  return (<LoggerProvider enableLogs={false}>
56
- <ToastRoot ref={setRef} {...props}/>
56
+ <EnvironmentProvider useNativeDriver={useNativeDriver}>
57
+ <ToastRoot ref={setRef} {...props}/>
58
+ </EnvironmentProvider>
57
59
  </LoggerProvider>);
58
60
  }
59
61
  /**
@@ -17,7 +17,7 @@ function renderComponent({ data, options, config, isVisible, show, hide }) {
17
17
  };
18
18
  const ToastComponent = toastConfig[type];
19
19
  if (!ToastComponent) {
20
- throw new Error(`Toast type: '${type}' does not exist. You can add it via the 'config' prop on the Toast instance. Learn more: https://github.com/calintamas/react-native-toast-message/blob/master/README.md`);
20
+ throw new Error(`Toast type: '${type}' does not exist. You can add it via the 'config' prop on the Toast instance. Learn more: https://github.com/calintamas/react-native-toast-message/blob/HEAD/docs/custom-layouts.md`);
21
21
  }
22
22
  return ToastComponent({
23
23
  position,
@@ -0,0 +1,3 @@
1
+ import { PanResponderGestureState } from 'react-native';
2
+ export declare const mockGestureValues: PanResponderGestureState;
3
+ export declare function mockPanResponder(): void;
@@ -0,0 +1,26 @@
1
+ import { PanResponder } from 'react-native';
2
+ export const mockGestureValues = {
3
+ moveY: 0,
4
+ moveX: 0,
5
+ y0: 0,
6
+ x0: 0,
7
+ dx: 0,
8
+ dy: 10,
9
+ stateID: 123,
10
+ vx: 0,
11
+ vy: 0,
12
+ numberActiveTouches: 1,
13
+ _accountsForMovesUpTo: 1
14
+ };
15
+ export function mockPanResponder() {
16
+ jest
17
+ .spyOn(PanResponder, 'create')
18
+ .mockImplementation(({ onMoveShouldSetPanResponder, onMoveShouldSetPanResponderCapture, onPanResponderMove, onPanResponderRelease }) => ({
19
+ panHandlers: {
20
+ onMoveShouldSetResponder: onMoveShouldSetPanResponder,
21
+ onMoveShouldSetResponderCapture: onMoveShouldSetPanResponderCapture,
22
+ onResponderMove: onPanResponderMove,
23
+ onResponderRelease: onPanResponderRelease
24
+ }
25
+ }));
26
+ }
@@ -0,0 +1,9 @@
1
+ import { renderHook as renderHookFn } from '@testing-library/react-hooks';
2
+ /**
3
+ * Custom `renderHook` function implementation to be able to easily wrap test environment providers
4
+ *
5
+ * https://testing-library.com/docs/react-testing-library/setup/#custom-render
6
+ */
7
+ export declare const renderHook: typeof renderHookFn;
8
+ export { act } from '@testing-library/react-hooks';
9
+ export type { RenderResult } from '@testing-library/react-hooks';
@@ -0,0 +1,13 @@
1
+ /* eslint-disable no-restricted-imports */
2
+ import { renderHook as renderHookFn } from '@testing-library/react-hooks';
3
+ import { EnvironmentProviderMock } from '~/__mocks__/EnvironmentProviderMock';
4
+ /**
5
+ * Custom `renderHook` function implementation to be able to easily wrap test environment providers
6
+ *
7
+ * https://testing-library.com/docs/react-testing-library/setup/#custom-render
8
+ */
9
+ export const renderHook = (cb, options) => renderHookFn(cb, {
10
+ wrapper: EnvironmentProviderMock,
11
+ ...options
12
+ });
13
+ export { act } from '@testing-library/react-hooks';
@@ -0,0 +1,9 @@
1
+ import { render as renderFn } from '@testing-library/react-native';
2
+ /**
3
+ * Custom `render` function implementation to be able to easily wrap test environment providers
4
+ *
5
+ * https://testing-library.com/docs/react-testing-library/setup/#custom-render
6
+ */
7
+ export declare const render: typeof renderFn;
8
+ export { waitFor, fireEvent, act, cleanup } from '@testing-library/react-native';
9
+ export type { RenderOptions, RenderAPI, GetByAPI } from '@testing-library/react-native';
@@ -0,0 +1,13 @@
1
+ /* eslint-disable no-restricted-imports */
2
+ import { render as renderFn } from '@testing-library/react-native';
3
+ import { EnvironmentProviderMock } from '../../__mocks__/EnvironmentProviderMock';
4
+ /**
5
+ * Custom `render` function implementation to be able to easily wrap test environment providers
6
+ *
7
+ * https://testing-library.com/docs/react-testing-library/setup/#custom-render
8
+ */
9
+ export const render = (component, options) => renderFn(component, {
10
+ wrapper: EnvironmentProviderMock,
11
+ ...options
12
+ });
13
+ export { waitFor, fireEvent, act, cleanup } from '@testing-library/react-native';
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { EnvironmentContextType } from '../contexts';
3
+ export declare const environmentMock: EnvironmentContextType;
4
+ /**
5
+ * Provides test implementations for injected dependencies
6
+ */
7
+ export declare const EnvironmentProviderMock: React.FC;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { EnvironmentProvider } from '../contexts';
3
+ export const environmentMock = {
4
+ useNativeDriver: false
5
+ };
6
+ /**
7
+ * Provides test implementations for injected dependencies
8
+ */
9
+ export const EnvironmentProviderMock = ({ children }) => (<EnvironmentProvider {...environmentMock}>{children}</EnvironmentProvider>);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,190 @@
1
+ /* eslint-env jest */
2
+ import React from 'react';
3
+ import { Button, Modal, Text } from 'react-native';
4
+ import { act, fireEvent, render, waitFor } from '~/__helpers__/testing-library/react-native';
5
+ import { Toast } from '../Toast';
6
+ /*
7
+ The Modal component is automatically mocked by RN and apparently contains a bug which makes the Modal
8
+ (and its children) to always be visible in the test tree.
9
+
10
+ This fixes the issue:
11
+ */
12
+ jest.mock('react-native/Libraries/Modal/Modal', () => {
13
+ const ActualModal = jest.requireActual('react-native/Libraries/Modal/Modal');
14
+ return (props) => <ActualModal {...props}/>;
15
+ });
16
+ jest.mock('react-native/Libraries/LogBox/LogBox');
17
+ describe('test Toast component', () => {
18
+ it('creates imperative handle', () => {
19
+ const onShow = jest.fn();
20
+ const onHide = jest.fn();
21
+ render(<Toast onShow={onShow} onHide={onHide}/>);
22
+ expect(Toast.show).toBeDefined();
23
+ expect(Toast.hide).toBeDefined();
24
+ act(() => {
25
+ Toast.show({
26
+ text1: 'test'
27
+ });
28
+ });
29
+ expect(onShow).toHaveBeenCalled();
30
+ act(() => {
31
+ Toast.hide();
32
+ });
33
+ expect(onHide).toHaveBeenCalled();
34
+ });
35
+ it('shows Toast inside a Modal', async () => {
36
+ const onShow = jest.fn();
37
+ const onHide = jest.fn();
38
+ const onShowInsideModal = jest.fn();
39
+ const onHideInsideModal = jest.fn();
40
+ const ModalWrapper = () => {
41
+ const [isVisible, setIsVisible] = React.useState(false);
42
+ return (<>
43
+ <Toast onShow={onShow} onHide={onHide}/>
44
+ <Text>Outside modal</Text>
45
+ <Button title='Show modal' onPress={() => setIsVisible(true)}/>
46
+ <Modal visible={isVisible}>
47
+ <Text>Inside modal</Text>
48
+ <Button title='Hide modal' onPress={() => setIsVisible(false)}/>
49
+ <Toast onShow={onShowInsideModal} onHide={onHideInsideModal}/>
50
+ </Modal>
51
+ </>);
52
+ };
53
+ const utils = render(<ModalWrapper />);
54
+ expect(utils.queryByText('Outside modal')).toBeTruthy();
55
+ expect(Toast.show).toBeDefined();
56
+ expect(Toast.hide).toBeDefined();
57
+ // Test the Toast instance that's outside the Modal
58
+ act(() => {
59
+ Toast.show({
60
+ text1: 'test'
61
+ });
62
+ });
63
+ expect(onShow).toHaveBeenCalled();
64
+ act(() => {
65
+ Toast.hide();
66
+ });
67
+ expect(onHide).toHaveBeenCalled();
68
+ // Show the Modal
69
+ const showModalButton = utils.getByText('Show modal');
70
+ expect(showModalButton).toBeTruthy();
71
+ fireEvent.press(showModalButton);
72
+ await waitFor(() => {
73
+ expect(utils.queryByText('Inside modal')).toBeTruthy();
74
+ });
75
+ // Test the Toast instance that's inside the Modal
76
+ act(() => {
77
+ Toast.show({
78
+ text1: 'test'
79
+ });
80
+ });
81
+ expect(onShowInsideModal).toHaveBeenCalled();
82
+ act(() => {
83
+ Toast.hide();
84
+ });
85
+ expect(onHideInsideModal).toHaveBeenCalled();
86
+ // Hide modal
87
+ const hideModalButton = utils.getByText('Hide modal');
88
+ expect(hideModalButton).toBeTruthy();
89
+ fireEvent.press(hideModalButton);
90
+ await waitFor(() => {
91
+ expect(utils.queryByText('Inside modal')).toBeFalsy();
92
+ });
93
+ // Now that the Modal is hidden, the the outside Toast instance again
94
+ act(() => {
95
+ Toast.show({
96
+ text1: 'test'
97
+ });
98
+ });
99
+ expect(onShow).toHaveBeenCalledTimes(2);
100
+ expect(onShowInsideModal).toHaveBeenCalledTimes(1);
101
+ act(() => {
102
+ Toast.hide();
103
+ });
104
+ expect(onHide).toHaveBeenCalledTimes(2);
105
+ expect(onHideInsideModal).toHaveBeenCalledTimes(1);
106
+ });
107
+ it(`doesn't show a Toast if there is no active ref`, () => {
108
+ const onShow = jest.fn();
109
+ const onHide = jest.fn();
110
+ const ModalWrapper = () => (<>
111
+ <Modal visible={false}>
112
+ <Text>Inside modal</Text>
113
+ <Toast onShow={onShow} onHide={onHide}/>
114
+ </Modal>
115
+ </>);
116
+ render(<ModalWrapper />);
117
+ act(() => {
118
+ Toast.show({
119
+ text1: 'test'
120
+ });
121
+ });
122
+ expect(onShow).not.toHaveBeenCalled();
123
+ });
124
+ it('when autoHide: true, the Toast only hides when timer reaches visibilityTime', () => {
125
+ jest.useFakeTimers();
126
+ const onShow = jest.fn();
127
+ const onHide = jest.fn();
128
+ const visibilityTime = 1500;
129
+ render(<Toast onShow={onShow} onHide={onHide} autoHide={true} visibilityTime={visibilityTime}/>);
130
+ act(() => {
131
+ Toast.show({
132
+ text1: 'I am auto hiding, by default'
133
+ });
134
+ });
135
+ expect(onShow).toHaveBeenCalled();
136
+ // Advance time by 1/4 visibilityTime
137
+ // Toast should not hide yet
138
+ jest.advanceTimersByTime(visibilityTime / 4);
139
+ expect(onHide).not.toHaveBeenCalled();
140
+ // Do it again 1/4 visibilityTime
141
+ // Toast should still be visible
142
+ jest.advanceTimersByTime(visibilityTime / 4);
143
+ expect(onHide).not.toHaveBeenCalled();
144
+ // Advance time by the remaining 1/2 visibilityTime
145
+ act(() => {
146
+ jest.advanceTimersByTime(visibilityTime / 2);
147
+ });
148
+ // Now the Toast should hide
149
+ expect(onHide).toHaveBeenCalled();
150
+ jest.useRealTimers();
151
+ });
152
+ it('clears previous autoHide: true timer when a new Toast is presented with autoHide: false', () => {
153
+ jest.useFakeTimers();
154
+ const onShow = jest.fn();
155
+ const onHide = jest.fn();
156
+ const visibilityTime = 1500;
157
+ render(<Toast onShow={onShow} onHide={onHide} autoHide={true} visibilityTime={visibilityTime}/>);
158
+ act(() => {
159
+ Toast.show({
160
+ text1: 'I am auto hiding, by default'
161
+ });
162
+ });
163
+ expect(onShow).toHaveBeenCalled();
164
+ // Advance by 1/2 visibilityTime
165
+ // Toast should not hide
166
+ jest.advanceTimersByTime(visibilityTime / 2);
167
+ expect(onHide).not.toHaveBeenCalled();
168
+ // Now, show another Toast, before the previous one has the chance to hide
169
+ act(() => {
170
+ Toast.show({
171
+ text1: 'I am NOT auto hiding',
172
+ autoHide: false
173
+ });
174
+ });
175
+ // Advance time to the end of visibilityTime
176
+ act(() => {
177
+ jest.advanceTimersByTime(visibilityTime / 2);
178
+ });
179
+ // The new Toast should NOT hide
180
+ // (the previous timer should have been cleared before reaching the end)
181
+ expect(onHide).not.toHaveBeenCalled();
182
+ // And even go beyond visibilityTime
183
+ act(() => {
184
+ jest.advanceTimersByTime(1000);
185
+ });
186
+ // The new Toast should still not hide
187
+ expect(onHide).not.toHaveBeenCalled();
188
+ jest.useRealTimers();
189
+ });
190
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ /* eslint-env jest */
2
+ import React from 'react';
3
+ import { render } from '~/__helpers__/testing-library/react-native';
4
+ import { ToastUI } from '../ToastUI';
5
+ import { DEFAULT_OPTIONS } from '../useToast';
6
+ const setup = (props) => {
7
+ const show = jest.fn();
8
+ const hide = jest.fn();
9
+ const utils = render(<ToastUI isVisible options={DEFAULT_OPTIONS} data={{
10
+ text1: 'text1',
11
+ text2: 'text2'
12
+ }} show={show} hide={hide} {...props}/>);
13
+ return {
14
+ ...utils
15
+ };
16
+ };
17
+ describe('test ToastUI component', () => {
18
+ it('renders defaults', () => {
19
+ const { queryByText } = setup();
20
+ expect(queryByText('text1')).toBeDefined();
21
+ expect(queryByText('text2')).toBeDefined();
22
+ });
23
+ it('renders error type Toast', () => {
24
+ const { queryByText } = setup({
25
+ options: {
26
+ ...DEFAULT_OPTIONS,
27
+ type: 'error'
28
+ }
29
+ });
30
+ expect(queryByText('text1')).toBeDefined();
31
+ expect(queryByText('text2')).toBeDefined();
32
+ });
33
+ it('renders info type Toast', () => {
34
+ const { queryByText } = setup({
35
+ options: {
36
+ ...DEFAULT_OPTIONS,
37
+ type: 'info'
38
+ }
39
+ });
40
+ expect(queryByText('text1')).toBeDefined();
41
+ expect(queryByText('text2')).toBeDefined();
42
+ });
43
+ it('throws when trying to render an undefined Toast type', () => {
44
+ const type = 'mock';
45
+ expect(() => setup({
46
+ options: {
47
+ ...DEFAULT_OPTIONS,
48
+ type
49
+ }
50
+ })).toThrow(new Error(`Toast type: '${type}' does not exist. You can add it via the 'config' prop on the Toast instance. Learn more: https://github.com/calintamas/react-native-toast-message/blob/HEAD/docs/custom-layouts.md`));
51
+ });
52
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,142 @@
1
+ /* eslint-env jest */
2
+ import { act, renderHook } from '~/__helpers__/testing-library/react-hooks';
3
+ import { DEFAULT_DATA, DEFAULT_OPTIONS, useToast } from '../useToast';
4
+ const setup = () => {
5
+ const utils = renderHook(() => useToast({
6
+ defaultOptions: DEFAULT_OPTIONS
7
+ }));
8
+ return {
9
+ ...utils
10
+ };
11
+ };
12
+ describe('test useToast hook', () => {
13
+ it('returns defaults', () => {
14
+ const { result } = setup();
15
+ const { isVisible, data, options, show, hide } = result.current;
16
+ expect(isVisible).toBe(false);
17
+ expect(data).toEqual(DEFAULT_DATA);
18
+ expect(options).toEqual(DEFAULT_OPTIONS);
19
+ expect(show).toBeDefined();
20
+ expect(hide).toBeDefined();
21
+ });
22
+ it('set isVisible: true when show is called', () => {
23
+ const { result } = setup();
24
+ act(() => {
25
+ result.current.show({
26
+ text1: 'test'
27
+ });
28
+ });
29
+ expect(result.current.isVisible).toBe(true);
30
+ expect(result.current.data.text1).toBe('test');
31
+ });
32
+ it('calls onShow when Toast is shown', () => {
33
+ const { result } = setup();
34
+ const onShow = jest.fn();
35
+ act(() => {
36
+ result.current.show({
37
+ text1: 'test',
38
+ onShow
39
+ });
40
+ });
41
+ expect(result.current.isVisible).toBe(true);
42
+ expect(result.current.data.text1).toBe('test');
43
+ expect(onShow).toHaveBeenCalled();
44
+ });
45
+ it('set isVisible: false when hide is called', () => {
46
+ const { result } = setup();
47
+ act(() => {
48
+ result.current.show({
49
+ text1: 'test'
50
+ });
51
+ });
52
+ expect(result.current.isVisible).toBe(true);
53
+ expect(result.current.data.text1).toBe('test');
54
+ act(() => {
55
+ result.current.hide();
56
+ });
57
+ expect(result.current.isVisible).toBe(false);
58
+ });
59
+ it('calls onHide when Toast is shown', () => {
60
+ const { result } = setup();
61
+ const onHide = jest.fn();
62
+ act(() => {
63
+ result.current.show({
64
+ text1: 'test',
65
+ onHide
66
+ });
67
+ });
68
+ expect(result.current.isVisible).toBe(true);
69
+ expect(result.current.data.text1).toBe('test');
70
+ act(() => {
71
+ result.current.hide();
72
+ });
73
+ expect(result.current.isVisible).toBe(false);
74
+ expect(onHide).toHaveBeenCalled();
75
+ });
76
+ it('sets data values on show', () => {
77
+ const { result } = setup();
78
+ act(() => {
79
+ result.current.show({
80
+ text1: 'text1',
81
+ text2: 'text2'
82
+ });
83
+ });
84
+ expect(result.current.isVisible).toBe(true);
85
+ expect(result.current.data.text1).toBe('text1');
86
+ expect(result.current.data.text2).toBe('text2');
87
+ });
88
+ it('sets option values on show', () => {
89
+ const { result } = setup();
90
+ const options = {
91
+ type: 'info',
92
+ position: 'bottom',
93
+ autoHide: false,
94
+ visibilityTime: 20,
95
+ topOffset: 120,
96
+ bottomOffset: 130,
97
+ keyboardOffset: 5,
98
+ onShow: jest.fn(),
99
+ onHide: jest.fn(),
100
+ onPress: jest.fn(),
101
+ props: {
102
+ foo: 'bar'
103
+ }
104
+ };
105
+ act(() => {
106
+ result.current.show({
107
+ text1: 'test',
108
+ ...options
109
+ });
110
+ });
111
+ expect(result.current.isVisible).toBe(true);
112
+ expect(result.current.options).toEqual(options);
113
+ });
114
+ it('automatically hides when autoHide: true', () => {
115
+ jest.useFakeTimers();
116
+ const { result } = setup();
117
+ const onHide = jest.fn();
118
+ act(() => {
119
+ result.current.show({
120
+ text1: 'test',
121
+ autoHide: true,
122
+ onHide
123
+ });
124
+ });
125
+ expect(result.current.isVisible).toBe(true);
126
+ act(() => {
127
+ jest.runAllTimers();
128
+ });
129
+ expect(result.current.isVisible).toBe(false);
130
+ expect(onHide).toHaveBeenCalled();
131
+ });
132
+ it('shows using only text2', () => {
133
+ const { result } = setup();
134
+ act(() => {
135
+ result.current.show({
136
+ text2: 'text2'
137
+ });
138
+ });
139
+ expect(result.current.isVisible).toBe(true);
140
+ expect(result.current.data.text2).toBe('text2');
141
+ });
142
+ });
@@ -40,7 +40,7 @@ export function animatedValueFor(gesture, position, damping) {
40
40
  export function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, onHide, onRestorePosition = noop }) {
41
41
  const { log } = useLogger();
42
42
  const { computeViewDimensions, height } = useViewDimensions();
43
- const { animatedValue, animate, animationStyles } = useSlideAnimation({
43
+ const { animatedValue, animate, defaultStyles, animationStyles } = useSlideAnimation({
44
44
  position,
45
45
  height,
46
46
  topOffset,
@@ -72,7 +72,7 @@ export function AnimatedContainer({ children, isVisible, position, topOffset, bo
72
72
  const newAnimationValue = isVisible ? 1 : 0;
73
73
  animate(newAnimationValue);
74
74
  }, [animate, isVisible]);
75
- return (<Animated.View testID={getTestId('AnimatedContainer')} onLayout={computeViewDimensions} style={[styles.base, styles[position], animationStyles]}
75
+ return (<Animated.View testID={getTestId('AnimatedContainer')} onLayout={computeViewDimensions} style={[styles.base, styles[position], defaultStyles, animationStyles]}
76
76
  // This container View is never the target of touch events but its subviews can be.
77
77
  // By doing this, tapping buttons behind the Toast is allowed
78
78
  pointerEvents='box-none' {...panResponder.panHandlers}>
@@ -7,10 +7,10 @@ export function BaseToast({ text1, text2, onPress, activeOpacity, style, touchab
7
7
  return (<Touchable testID={getTestId('TouchableContainer')} onPress={onPress} activeOpacity={activeOpacity} style={[styles.base, styles.leadingBorder, style]} {...touchableContainerProps}>
8
8
  {renderLeadingIcon && renderLeadingIcon()}
9
9
  <View testID={getTestId('ContentContainer')} style={[styles.contentContainer, contentContainerStyle]} {...contentContainerProps}>
10
- {text1 && text1.length > 0 && (<Text testID={getTestId('Text1')} style={[styles.text1, text1Style]} numberOfLines={text1NumberOfLines} ellipsizeMode='tail' {...text1Props}>
10
+ {(text1?.length ?? 0) > 0 && (<Text testID={getTestId('Text1')} style={[styles.text1, text1Style]} numberOfLines={text1NumberOfLines} ellipsizeMode='tail' {...text1Props}>
11
11
  {text1}
12
12
  </Text>)}
13
- {text2 && text2?.length > 0 && (<Text testID={getTestId('Text2')} style={[styles.text2, text2Style]} numberOfLines={text2NumberOfLines} ellipsizeMode='tail' {...text2Props}>
13
+ {(text2?.length ?? 0) > 0 && (<Text testID={getTestId('Text2')} style={[styles.text2, text2Style]} numberOfLines={text2NumberOfLines} ellipsizeMode='tail' {...text2Props}>
14
14
  {text2}
15
15
  </Text>)}
16
16
  </View>