react-native-toast-message 1.4.9 → 2.0.0-beta.2
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/CHANGELOG.md +14 -1
- package/README.md +18 -198
- package/lib/index.d.ts +6 -0
- package/lib/index.js +6 -0
- package/lib/src/Toast.d.ts +7 -0
- package/lib/src/Toast.js +27 -0
- package/lib/src/ToastUI.d.ts +11 -0
- package/lib/src/ToastUI.js +40 -0
- package/lib/src/components/AnimatedContainer.d.ts +16 -0
- package/lib/src/components/AnimatedContainer.js +72 -0
- package/lib/src/components/AnimatedContainer.styles.d.ts +14 -0
- package/lib/src/components/AnimatedContainer.styles.js +15 -0
- package/lib/src/components/BaseToast.d.ts +3 -0
- package/lib/src/components/BaseToast.js +19 -0
- package/lib/src/components/BaseToast.styles.d.ts +41 -0
- package/lib/src/components/BaseToast.styles.js +39 -0
- package/lib/src/components/ErrorToast.d.ts +3 -0
- package/lib/src/components/ErrorToast.js +5 -0
- package/lib/src/components/InfoToast.d.ts +3 -0
- package/lib/src/components/InfoToast.js +5 -0
- package/lib/src/components/SuccessToast.d.ts +3 -0
- package/lib/src/components/SuccessToast.js +5 -0
- package/lib/src/components/Touchable.d.ts +8 -0
- package/lib/src/components/Touchable.js +7 -0
- package/lib/src/contexts/LoggerContext.d.ts +12 -0
- package/lib/src/contexts/LoggerContext.js +22 -0
- package/lib/src/contexts/index.d.ts +1 -0
- package/lib/src/contexts/index.js +1 -0
- package/lib/src/hooks/index.d.ts +5 -0
- package/lib/src/hooks/index.js +5 -0
- package/lib/src/hooks/useKeyboard.d.ts +4 -0
- package/lib/src/hooks/useKeyboard.js +31 -0
- package/lib/src/hooks/usePanResponder.d.ts +15 -0
- package/lib/src/hooks/usePanResponder.js +41 -0
- package/lib/src/hooks/useSlideAnimation.d.ts +24 -0
- package/lib/src/hooks/useSlideAnimation.js +49 -0
- package/lib/src/hooks/useTimeout.d.ts +6 -0
- package/lib/src/hooks/useTimeout.js +29 -0
- package/lib/src/hooks/useViewDimensions.d.ts +13 -0
- package/lib/src/hooks/useViewDimensions.js +20 -0
- package/lib/src/types/index.d.ts +165 -0
- package/lib/src/types/index.js +1 -0
- package/lib/src/useToast.d.ts +13 -0
- package/lib/src/useToast.js +79 -0
- package/lib/src/utils/array.d.ts +2 -0
- package/lib/src/utils/array.js +4 -0
- package/lib/src/utils/func.d.ts +1 -0
- package/lib/src/utils/func.js +1 -0
- package/lib/src/utils/number.d.ts +3 -0
- package/lib/src/utils/number.js +9 -0
- package/lib/src/utils/obj.d.ts +3 -0
- package/lib/src/utils/obj.js +11 -0
- package/lib/src/utils/platform.d.ts +1 -0
- package/lib/src/utils/platform.js +4 -0
- package/lib/src/utils/test-id.d.ts +1 -0
- package/lib/src/utils/test-id.js +3 -0
- package/package.json +47 -45
- package/.github/workflows/publish.yml +0 -22
- package/.github/workflows/tag.yml +0 -16
- package/.github/workflows/tests.yml +0 -44
- package/babel.config.js +0 -3
- package/index.d.ts +0 -67
- package/index.js +0 -4
- package/jest.config.js +0 -5
- package/jest.setup.js +0 -1
- package/src/assets/icons/close.png +0 -0
- package/src/assets/icons/close@2x.png +0 -0
- package/src/assets/icons/close@3x.png +0 -0
- package/src/assets/icons/error.png +0 -0
- package/src/assets/icons/error@2x.png +0 -0
- package/src/assets/icons/error@3x.png +0 -0
- package/src/assets/icons/info.png +0 -0
- package/src/assets/icons/info@2x.png +0 -0
- package/src/assets/icons/info@3x.png +0 -0
- package/src/assets/icons/success.png +0 -0
- package/src/assets/icons/success@2x.png +0 -0
- package/src/assets/icons/success@3x.png +0 -0
- package/src/assets/index.js +0 -15
- package/src/colors/index.js +0 -10
- package/src/components/base/index.js +0 -134
- package/src/components/base/styles.js +0 -54
- package/src/components/error.js +0 -19
- package/src/components/icon/index.js +0 -40
- package/src/components/icon/styles.js +0 -8
- package/src/components/info.js +0 -19
- package/src/components/success.js +0 -19
- package/src/index.js +0 -420
- package/src/styles.js +0 -17
- package/src/utils/arr.js +0 -3
- package/src/utils/obj.js +0 -9
- package/src/utils/platform.js +0 -5
- package/src/utils/prop-types.js +0 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
|
7
7
|
|
|
8
8
|
Headers are one of:
|
|
9
9
|
|
|
10
|
-
- `Added`, `Changed`, `Removed` or `
|
|
10
|
+
- `Added`, `Changed`, `Removed`, `Fixed` or `Breaking`.
|
|
11
|
+
|
|
12
|
+
## [1.6.0]
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Export all default Toast components (`BaseToast`, `SuccessToast`, `InfoToast`, `ErrorToast`) to be able to reuse them with custom props ([#225](https://github.com/calintamas/react-native-toast-message/pull/225))
|
|
17
|
+
|
|
18
|
+
## [1.5.0]
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Move `show` method options to separate `ToastShowOptions` interface ([#242](https://github.com/calintamas/react-native-toast-message/pull/242))
|
|
23
|
+
- Use `StyleProp` in type definition file, to allow different types of style to be used (eg. `style={[styles.one, styles.two]}`) ([#243](https://github.com/calintamas/react-native-toast-message/pull/243))
|
|
11
24
|
|
|
12
25
|
## [1.4.9]
|
|
13
26
|
|
package/README.md
CHANGED
|
@@ -3,211 +3,31 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/react-native-toast-message)
|
|
4
4
|
[](https://www.npmjs.com/package/react-native-toast-message)
|
|
5
5
|
[](https://github.com/calintamas/react-native-toast-message/actions?query=workflow%3Atests)
|
|
6
|
+
[](https://coveralls.io/github/calintamas/react-native-toast-message)
|
|
6
7
|
[](https://github.com/prettier/prettier)
|
|
7
8
|
|
|
8
9
|
Animated toast message component for React Native.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
- Keyboard aware
|
|
12
|
-
- Flexible config
|
|
11
|
+

|
|
13
12
|
|
|
14
|
-
##
|
|
13
|
+
## Features
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
- 🚀 Imperative API
|
|
16
|
+
- 📦 Very lightweight (~40 kB)
|
|
17
|
+
- ⌨️ Keyboard-aware
|
|
18
|
+
- 🎨 Customizable layouts
|
|
19
|
+
- 🔧 Flexible config
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
## Documentation
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
- [Quick start](./docs/quick-start.md)
|
|
24
|
+
- [API](./docs/api.md)
|
|
25
|
+
- [Create custom layouts](./docs/custom-layouts.md)
|
|
26
|
+
- FAQ
|
|
27
|
+
- [How to show the Toast inside a Modal?](./docs/modal-usage.md)
|
|
28
|
+
- [How to render the Toast when using a Navigation library?](./docs/navigation-usage.md)
|
|
29
|
+
- [How to mock the library for testing with jest?](./docs/jest-testing.md)
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
## License
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
// App.jsx
|
|
28
|
-
import Toast from 'react-native-toast-message';
|
|
29
|
-
|
|
30
|
-
function App(props) {
|
|
31
|
-
return (
|
|
32
|
-
<>
|
|
33
|
-
{/* ... */}
|
|
34
|
-
<Toast ref={(ref) => Toast.setRef(ref)} />
|
|
35
|
-
</>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default App;
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
Then use it anywhere in your app (even outside React components), by calling any `Toast` method directly:
|
|
43
|
-
|
|
44
|
-
```js
|
|
45
|
-
import Toast from 'react-native-toast-message';
|
|
46
|
-
|
|
47
|
-
function SomeComponent() {
|
|
48
|
-
React.useEffect(() => {
|
|
49
|
-
Toast.show({
|
|
50
|
-
text1: 'Hello',
|
|
51
|
-
text2: 'This is some something 👋'
|
|
52
|
-
});
|
|
53
|
-
}, []);
|
|
54
|
-
|
|
55
|
-
return <View />;
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## API
|
|
60
|
-
|
|
61
|
-
### `show(options = {})`
|
|
62
|
-
|
|
63
|
-
When calling the `show` method, you can use the following `options` to suit your needs. Everything is optional, unless specified otherwise.
|
|
64
|
-
|
|
65
|
-
The usage of `|` below, means that only one of the values show should be used.
|
|
66
|
-
If only one value is shown, that's the default.
|
|
67
|
-
|
|
68
|
-
```js
|
|
69
|
-
Toast.show({
|
|
70
|
-
type: 'success | error | info',
|
|
71
|
-
position: 'top | bottom',
|
|
72
|
-
text1: 'Hello',
|
|
73
|
-
text2: 'This is some something 👋',
|
|
74
|
-
visibilityTime: 4000,
|
|
75
|
-
autoHide: true,
|
|
76
|
-
topOffset: 30,
|
|
77
|
-
bottomOffset: 40,
|
|
78
|
-
onShow: () => {},
|
|
79
|
-
onHide: () => {},
|
|
80
|
-
onPress: () => {}
|
|
81
|
-
});
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### `hide()`
|
|
85
|
-
|
|
86
|
-
```js
|
|
87
|
-
Toast.hide();
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## props
|
|
91
|
-
|
|
92
|
-
Props that can be set on the `Toast` instance. They act as defaults for all Toasts that are shown.
|
|
93
|
-
|
|
94
|
-
```js
|
|
95
|
-
const props = {
|
|
96
|
-
config: Object,
|
|
97
|
-
style: ViewStyle,
|
|
98
|
-
topOffset: Number,
|
|
99
|
-
bottomOffset: Number,
|
|
100
|
-
keyboardOffset: Number,
|
|
101
|
-
visibilityTime: Number,
|
|
102
|
-
autoHide: Boolean,
|
|
103
|
-
height: Number,
|
|
104
|
-
position: 'top' | 'bottom',
|
|
105
|
-
type: String
|
|
106
|
-
};
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
> Default `Animated.View` styles can be found in [styles.js](https://github.com/calintamas/react-native-toast-message/blob/master/src/styles.js#L4). They can be extended using the `style` prop.
|
|
110
|
-
|
|
111
|
-
## Customize Toast types
|
|
112
|
-
|
|
113
|
-
If you want to add custom types - or overwrite the existing ones - you can add a `config` prop when rendering the `Toast` in your app `root`.
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
// App.jsx
|
|
117
|
-
import Toast from 'react-native-toast-message';
|
|
118
|
-
|
|
119
|
-
const toastConfig = {
|
|
120
|
-
success: ({ text1, props, ...rest }) => (
|
|
121
|
-
<View style={{ height: 60, width: '100%', backgroundColor: 'pink' }}>
|
|
122
|
-
<Text>{text1}</Text>
|
|
123
|
-
<Text>{props.guid}</Text>
|
|
124
|
-
</View>
|
|
125
|
-
),
|
|
126
|
-
error: () => {},
|
|
127
|
-
info: () => {},
|
|
128
|
-
any_custom_type: () => {}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
function App(props) {
|
|
132
|
-
return (
|
|
133
|
-
<>
|
|
134
|
-
{/* ... */}
|
|
135
|
-
<Toast config={toastConfig} ref={(ref) => Toast.setRef(ref)} />
|
|
136
|
-
</>
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export default App;
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Then just use the library as before
|
|
144
|
-
|
|
145
|
-
```js
|
|
146
|
-
Toast.show({
|
|
147
|
-
type: 'any_custom_type',
|
|
148
|
-
props: { onPress: () => {}, guid: 'guid-id' }
|
|
149
|
-
});
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
## Change default Toast style
|
|
153
|
-
|
|
154
|
-
In addition to creating Toast styles from scratch (shown above), you can use the default `BaseToast` style and adjust its layout.
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
// App.jsx
|
|
158
|
-
import Toast, { BaseToast } from 'react-native-toast-message';
|
|
159
|
-
|
|
160
|
-
const toastConfig = {
|
|
161
|
-
success: ({ text1, ...rest }) => (
|
|
162
|
-
<BaseToast
|
|
163
|
-
{...rest}
|
|
164
|
-
style={{ borderLeftColor: 'pink' }}
|
|
165
|
-
contentContainerStyle={{ paddingHorizontal: 15 }}
|
|
166
|
-
text1Style={{
|
|
167
|
-
fontSize: 15,
|
|
168
|
-
fontWeight: 'semibold'
|
|
169
|
-
}}
|
|
170
|
-
text1={text1}
|
|
171
|
-
text2={null}
|
|
172
|
-
/>
|
|
173
|
-
)
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
function App(props) {
|
|
177
|
-
return (
|
|
178
|
-
<>
|
|
179
|
-
{/* ... */}
|
|
180
|
-
<Toast config={toastConfig} ref={(ref) => Toast.setRef(ref)} />
|
|
181
|
-
</>
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export default App;
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
Available `props` on `BaseToast`:
|
|
189
|
-
|
|
190
|
-
```js
|
|
191
|
-
const baseToastProps = {
|
|
192
|
-
leadingIcon: ImageSource,
|
|
193
|
-
trailingIcon: ImageSource,
|
|
194
|
-
text1: String,
|
|
195
|
-
text2: String,
|
|
196
|
-
onPress: Function,
|
|
197
|
-
onLeadingIconPress: Function,
|
|
198
|
-
onTrailingIconPress: Function,
|
|
199
|
-
style: ViewStyle,
|
|
200
|
-
leadingIconContainerStyle: ViewStyle,
|
|
201
|
-
trailingIconContainerStyle: ViewStyle,
|
|
202
|
-
leadingIconStyle: ViewStyle,
|
|
203
|
-
trailingIconStyle: ViewStyle,
|
|
204
|
-
contentContainerStyle: ViewStyle,
|
|
205
|
-
text1Style: ViewStyle,
|
|
206
|
-
text2Style: ViewStyle,
|
|
207
|
-
activeOpacity: Number
|
|
208
|
-
};
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
## Credits
|
|
212
|
-
|
|
213
|
-
The icons for the default `success`, `error` and `info` types are made by [Pixel perfect](https://www.flaticon.com/authors/pixel-perfect) from [flaticon.com](www.flaticon.com).
|
|
33
|
+
MIT
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Toast as default } from './src/Toast';
|
|
2
|
+
export { BaseToast } from './src/components/BaseToast';
|
|
3
|
+
export { SuccessToast } from './src/components/SuccessToast';
|
|
4
|
+
export { ErrorToast } from './src/components/ErrorToast';
|
|
5
|
+
export { InfoToast } from './src/components/InfoToast';
|
|
6
|
+
export * from './src/types';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Toast as default } from './src/Toast';
|
|
2
|
+
export { BaseToast } from './src/components/BaseToast';
|
|
3
|
+
export { SuccessToast } from './src/components/SuccessToast';
|
|
4
|
+
export { ErrorToast } from './src/components/ErrorToast';
|
|
5
|
+
export { InfoToast } from './src/components/InfoToast';
|
|
6
|
+
export * from './src/types';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ToastProps, ToastShowParams } from './types';
|
|
3
|
+
export declare function Toast(props: ToastProps): JSX.Element;
|
|
4
|
+
export declare namespace Toast {
|
|
5
|
+
var show: (params: ToastShowParams) => void;
|
|
6
|
+
var hide: (params?: void | undefined) => void;
|
|
7
|
+
}
|
package/lib/src/Toast.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LoggerProvider } from './contexts';
|
|
3
|
+
import { ToastUI } from './ToastUI';
|
|
4
|
+
import { useToast } from './useToast';
|
|
5
|
+
const ToastRoot = React.forwardRef((props, ref) => {
|
|
6
|
+
const { config, ...defaultOptions } = props;
|
|
7
|
+
const { show, hide, isVisible, options, data } = useToast({
|
|
8
|
+
defaultOptions
|
|
9
|
+
});
|
|
10
|
+
React.useImperativeHandle(ref, () => ({
|
|
11
|
+
show,
|
|
12
|
+
hide
|
|
13
|
+
}));
|
|
14
|
+
return (<ToastUI isVisible={isVisible} options={options} data={data} hide={hide} show={show} config={config}/>);
|
|
15
|
+
});
|
|
16
|
+
const toastRef = React.createRef();
|
|
17
|
+
export function Toast(props) {
|
|
18
|
+
return (<LoggerProvider enableLogs={false}>
|
|
19
|
+
<ToastRoot ref={toastRef} {...props}/>
|
|
20
|
+
</LoggerProvider>);
|
|
21
|
+
}
|
|
22
|
+
Toast.show = (params) => {
|
|
23
|
+
toastRef.current?.show(params);
|
|
24
|
+
};
|
|
25
|
+
Toast.hide = (params) => {
|
|
26
|
+
toastRef.current?.hide(params);
|
|
27
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { ToastConfig, ToastData, ToastHideParams, ToastOptions, ToastShowParams } from './types';
|
|
3
|
+
export declare type ToastUIProps = {
|
|
4
|
+
isVisible: boolean;
|
|
5
|
+
options: Required<ToastOptions>;
|
|
6
|
+
data: ToastData;
|
|
7
|
+
show: (params: ToastShowParams) => void;
|
|
8
|
+
hide: (params: ToastHideParams) => void;
|
|
9
|
+
config?: ToastConfig;
|
|
10
|
+
};
|
|
11
|
+
export declare function ToastUI(props: ToastUIProps): JSX.Element;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { AnimatedContainer } from './components/AnimatedContainer';
|
|
3
|
+
import { ErrorToast } from './components/ErrorToast';
|
|
4
|
+
import { InfoToast } from './components/InfoToast';
|
|
5
|
+
import { SuccessToast } from './components/SuccessToast';
|
|
6
|
+
const defaultToastConfig = {
|
|
7
|
+
success: (props) => <SuccessToast {...props}/>,
|
|
8
|
+
error: (props) => <ErrorToast {...props}/>,
|
|
9
|
+
info: (props) => <InfoToast {...props}/>
|
|
10
|
+
};
|
|
11
|
+
function renderComponent({ data, options, config, isVisible, show, hide }) {
|
|
12
|
+
const { text1, text2 } = data;
|
|
13
|
+
const { type, onPress, position, props } = options;
|
|
14
|
+
const toastConfig = {
|
|
15
|
+
...defaultToastConfig,
|
|
16
|
+
...config
|
|
17
|
+
};
|
|
18
|
+
const ToastComponent = toastConfig[type];
|
|
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`);
|
|
21
|
+
}
|
|
22
|
+
return ToastComponent({
|
|
23
|
+
position,
|
|
24
|
+
type,
|
|
25
|
+
isVisible,
|
|
26
|
+
text1,
|
|
27
|
+
text2,
|
|
28
|
+
show,
|
|
29
|
+
hide,
|
|
30
|
+
onPress,
|
|
31
|
+
props
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export function ToastUI(props) {
|
|
35
|
+
const { isVisible, options, hide } = props;
|
|
36
|
+
const { position, topOffset, bottomOffset, keyboardOffset } = options;
|
|
37
|
+
return (<AnimatedContainer isVisible={isVisible} position={position} topOffset={topOffset} bottomOffset={bottomOffset} keyboardOffset={keyboardOffset} onHide={hide}>
|
|
38
|
+
{renderComponent(props)}
|
|
39
|
+
</AnimatedContainer>);
|
|
40
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { PanResponderGestureState } from 'react-native';
|
|
3
|
+
import { ReactChildren, ToastPosition } from '../types';
|
|
4
|
+
export declare type AnimatedContainerProps = {
|
|
5
|
+
children: ReactChildren;
|
|
6
|
+
isVisible: boolean;
|
|
7
|
+
position: ToastPosition;
|
|
8
|
+
topOffset: number;
|
|
9
|
+
bottomOffset: number;
|
|
10
|
+
keyboardOffset: number;
|
|
11
|
+
onHide: () => void;
|
|
12
|
+
onRestorePosition?: () => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function dampingFor(gesture: PanResponderGestureState, position: ToastPosition): number;
|
|
15
|
+
export declare function animatedValueFor(gesture: PanResponderGestureState, position: ToastPosition, damping: number): number;
|
|
16
|
+
export declare function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, onHide, onRestorePosition }: AnimatedContainerProps): JSX.Element;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Animated, Dimensions } from 'react-native';
|
|
3
|
+
import { useLogger } from '../contexts';
|
|
4
|
+
import { usePanResponder, useSlideAnimation, useViewDimensions } from '../hooks';
|
|
5
|
+
import { noop } from '../utils/func';
|
|
6
|
+
import { bound } from '../utils/number';
|
|
7
|
+
import { getTestId } from '../utils/test-id';
|
|
8
|
+
import { styles } from './AnimatedContainer.styles';
|
|
9
|
+
export function dampingFor(gesture, position) {
|
|
10
|
+
const { moveY } = gesture;
|
|
11
|
+
switch (position) {
|
|
12
|
+
case 'bottom': {
|
|
13
|
+
const { height: screenHeight } = Dimensions.get('screen');
|
|
14
|
+
return screenHeight - moveY;
|
|
15
|
+
}
|
|
16
|
+
case 'top':
|
|
17
|
+
return moveY;
|
|
18
|
+
default:
|
|
19
|
+
throw new Error(`Toast position: ${position} not implemented`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function animatedValueFor(gesture, position, damping) {
|
|
23
|
+
const boundValue = (val) => bound(val, 0, 2);
|
|
24
|
+
const { dy } = gesture;
|
|
25
|
+
switch (position) {
|
|
26
|
+
case 'bottom':
|
|
27
|
+
return boundValue(1 - dy / damping);
|
|
28
|
+
case 'top':
|
|
29
|
+
return boundValue(1 + dy / damping);
|
|
30
|
+
default:
|
|
31
|
+
throw new Error(`Toast position: ${position} not implemented`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function AnimatedContainer({ children, isVisible, position, topOffset, bottomOffset, keyboardOffset, onHide, onRestorePosition = noop }) {
|
|
35
|
+
const { log } = useLogger();
|
|
36
|
+
const { computeViewDimensions, height } = useViewDimensions();
|
|
37
|
+
const { animatedValue, animate, animationStyles } = useSlideAnimation({
|
|
38
|
+
position,
|
|
39
|
+
height,
|
|
40
|
+
topOffset,
|
|
41
|
+
bottomOffset,
|
|
42
|
+
keyboardOffset
|
|
43
|
+
});
|
|
44
|
+
const onDismiss = React.useCallback(() => {
|
|
45
|
+
log('Swipe, dismissing');
|
|
46
|
+
animate(0);
|
|
47
|
+
onHide();
|
|
48
|
+
}, [animate, log, onHide]);
|
|
49
|
+
const onRestore = React.useCallback(() => {
|
|
50
|
+
log('Swipe, restoring to original position');
|
|
51
|
+
animate(1);
|
|
52
|
+
onRestorePosition();
|
|
53
|
+
}, [animate, log, onRestorePosition]);
|
|
54
|
+
const computeNewAnimatedValueForGesture = React.useCallback((gesture) => {
|
|
55
|
+
const damping = dampingFor(gesture, position);
|
|
56
|
+
const newAnimatedValue = animatedValueFor(gesture, position, damping);
|
|
57
|
+
return newAnimatedValue;
|
|
58
|
+
}, [position]);
|
|
59
|
+
const { panResponder } = usePanResponder({
|
|
60
|
+
animatedValue,
|
|
61
|
+
computeNewAnimatedValueForGesture,
|
|
62
|
+
onDismiss,
|
|
63
|
+
onRestore
|
|
64
|
+
});
|
|
65
|
+
React.useLayoutEffect(() => {
|
|
66
|
+
const newAnimationValue = isVisible ? 1 : 0;
|
|
67
|
+
animate(newAnimationValue);
|
|
68
|
+
}, [animate, isVisible]);
|
|
69
|
+
return (<Animated.View testID={getTestId('AnimatedContainer')} onLayout={computeViewDimensions} style={[styles.base, styles[position], animationStyles]} {...panResponder.panHandlers}>
|
|
70
|
+
{children}
|
|
71
|
+
</Animated.View>);
|
|
72
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { StyleSheet } from 'react-native';
|
|
2
|
+
export const styles = StyleSheet.create({
|
|
3
|
+
base: {
|
|
4
|
+
position: 'absolute',
|
|
5
|
+
alignItems: 'center',
|
|
6
|
+
justifyContent: 'center',
|
|
7
|
+
alignSelf: 'center'
|
|
8
|
+
},
|
|
9
|
+
top: {
|
|
10
|
+
top: 0
|
|
11
|
+
},
|
|
12
|
+
bottom: {
|
|
13
|
+
bottom: 0
|
|
14
|
+
}
|
|
15
|
+
});
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
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): JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Text, View } from 'react-native';
|
|
3
|
+
import { getTestId } from '../utils/test-id';
|
|
4
|
+
import { styles } from './BaseToast.styles';
|
|
5
|
+
import { Touchable } from './Touchable';
|
|
6
|
+
export function BaseToast({ text1, text2, onPress, activeOpacity, style, touchableContainerProps, contentContainerStyle, contentContainerProps, text1Style, text1NumberOfLines = 1, text1Props, text2Style, text2NumberOfLines = 1, text2Props, renderLeadingIcon, renderTrailingIcon }) {
|
|
7
|
+
return (<Touchable testID={getTestId('TouchableContainer')} onPress={onPress} activeOpacity={activeOpacity} style={[styles.base, styles.leadingBorder, style]} {...touchableContainerProps}>
|
|
8
|
+
{renderLeadingIcon && renderLeadingIcon()}
|
|
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}>
|
|
11
|
+
{text1}
|
|
12
|
+
</Text>)}
|
|
13
|
+
{text2 && text2?.length > 0 && (<Text testID={getTestId('Text2')} style={[styles.text2, text2Style]} numberOfLines={text2NumberOfLines} ellipsizeMode='tail' {...text2Props}>
|
|
14
|
+
{text2}
|
|
15
|
+
</Text>)}
|
|
16
|
+
</View>
|
|
17
|
+
{renderTrailingIcon && renderTrailingIcon()}
|
|
18
|
+
</Touchable>);
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const HEIGHT = 60;
|
|
2
|
+
export declare const WIDTH = 340;
|
|
3
|
+
export declare const BORDER_RADIUS = 6;
|
|
4
|
+
export declare const styles: {
|
|
5
|
+
base: {
|
|
6
|
+
flexDirection: "row";
|
|
7
|
+
height: number;
|
|
8
|
+
width: number;
|
|
9
|
+
borderRadius: number;
|
|
10
|
+
shadowOffset: {
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
};
|
|
14
|
+
shadowOpacity: number;
|
|
15
|
+
shadowRadius: number;
|
|
16
|
+
elevation: number;
|
|
17
|
+
backgroundColor: string;
|
|
18
|
+
};
|
|
19
|
+
leadingBorder: {
|
|
20
|
+
borderLeftWidth: number;
|
|
21
|
+
borderLeftColor: string;
|
|
22
|
+
};
|
|
23
|
+
contentContainer: {
|
|
24
|
+
paddingHorizontal: number;
|
|
25
|
+
flex: number;
|
|
26
|
+
justifyContent: "center";
|
|
27
|
+
alignItems: "flex-start";
|
|
28
|
+
};
|
|
29
|
+
text1: {
|
|
30
|
+
fontSize: number;
|
|
31
|
+
fontWeight: "bold";
|
|
32
|
+
marginBottom: number;
|
|
33
|
+
color: string;
|
|
34
|
+
width: string;
|
|
35
|
+
};
|
|
36
|
+
text2: {
|
|
37
|
+
fontSize: number;
|
|
38
|
+
color: string;
|
|
39
|
+
width: string;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -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,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,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 };
|