dhre-ui-kit 0.0.56 → 0.0.58
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/package.json +1 -1
- package/src/App.tsx +8 -35
- package/src/components/toast/Toast.interface.ts +25 -7
- package/src/components/toast/Toast.test.tsx +2 -10
- package/src/components/toast/Toast.tsx +64 -38
- package/src/components/toast/ToastProvider.tsx +61 -0
- package/src/components/toast/typings.ts +17 -0
- package/src/components/toast/yourCompo.tsx +21 -0
- package/src/index.ts +2 -1
package/package.json
CHANGED
package/src/App.tsx
CHANGED
|
@@ -1,42 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {View} from 'react-native';
|
|
6
|
-
import CustomButton from './components/button/Button';
|
|
2
|
+
import {SafeAreaView} from 'react-native';
|
|
3
|
+
import ToastProvider from './components/toast/ToastProvider';
|
|
4
|
+
import YourComponent from './components/toast/yourCompo';
|
|
7
5
|
|
|
8
6
|
const App = () => {
|
|
9
7
|
return (
|
|
10
|
-
<
|
|
11
|
-
<
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
style={{margin: 20}}
|
|
16
|
-
iconName={<CalenderDots width={20} height={20} />}
|
|
17
|
-
textStyle={{color: 'black'}}
|
|
18
|
-
iconStyle={{}}
|
|
19
|
-
/>
|
|
20
|
-
<Line />
|
|
21
|
-
<CustomButton
|
|
22
|
-
title="Yes"
|
|
23
|
-
onPress={() => console.log('Yes Button Pressed')}
|
|
24
|
-
leftIcon={<ArrowLeft />}
|
|
25
|
-
// titleColor={color.CONTENT_SECONDRY[currentTheme]}
|
|
26
|
-
titleVariant="L2_REGULAR"
|
|
27
|
-
containerStyle={[
|
|
28
|
-
{
|
|
29
|
-
borderWidth: 1,
|
|
30
|
-
borderRadius: 20,
|
|
31
|
-
|
|
32
|
-
height: 40,
|
|
33
|
-
},
|
|
34
|
-
]}
|
|
35
|
-
// iconStyle={styles.iconStyle}
|
|
36
|
-
imagePosition="left"
|
|
37
|
-
/>
|
|
38
|
-
</View>
|
|
39
|
-
</ThemeProvider>
|
|
8
|
+
<ToastProvider>
|
|
9
|
+
<SafeAreaView style={{flex: 1}}>
|
|
10
|
+
<YourComponent />
|
|
11
|
+
</SafeAreaView>
|
|
12
|
+
</ToastProvider>
|
|
40
13
|
);
|
|
41
14
|
};
|
|
42
15
|
|
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
// export type ShowToast = (
|
|
2
|
+
// message: string,
|
|
3
|
+
// duration?: number,
|
|
4
|
+
// isSuccess?: boolean,
|
|
5
|
+
// btnText?: string | null,
|
|
6
|
+
// onBtnPress?: (() => void) | null,
|
|
7
|
+
// ) => void;
|
|
8
|
+
|
|
9
|
+
export interface ToastRef {
|
|
10
|
+
showToast: (
|
|
11
|
+
message: string,
|
|
12
|
+
duration?: number,
|
|
13
|
+
isSuccess?: boolean,
|
|
14
|
+
buttonText?: string | null,
|
|
15
|
+
buttonAction?: (() => void) | null,
|
|
16
|
+
) => void;
|
|
8
17
|
}
|
|
18
|
+
|
|
19
|
+
export type ShowToast = (
|
|
20
|
+
message: string,
|
|
21
|
+
duration?: number,
|
|
22
|
+
isSuccess?: boolean,
|
|
23
|
+
buttonText?: string | null,
|
|
24
|
+
buttonAction?: (() => void) | null,
|
|
25
|
+
) => void;
|
|
26
|
+
export interface ToastProps {}
|
|
@@ -7,15 +7,7 @@ jest.mock('react-native-progress', () => ({
|
|
|
7
7
|
}));
|
|
8
8
|
|
|
9
9
|
describe('Toast Component', () => {
|
|
10
|
-
it('Component
|
|
11
|
-
|
|
12
|
-
<Toast
|
|
13
|
-
message="Test message"
|
|
14
|
-
setToast={jest.fn()}
|
|
15
|
-
btnText="Undo"
|
|
16
|
-
onBtnPress={jest.fn()}
|
|
17
|
-
/>,
|
|
18
|
-
);
|
|
19
|
-
expect(getByTestId('TOAST')).toBeTruthy();
|
|
10
|
+
it('Component renders correctly', () => {
|
|
11
|
+
render(<Toast />);
|
|
20
12
|
});
|
|
21
13
|
});
|
|
@@ -1,78 +1,101 @@
|
|
|
1
|
-
import React, {useEffect, useState} from 'react';
|
|
1
|
+
import React, {useEffect, useState, useRef} from 'react';
|
|
2
2
|
import {View, Animated, Pressable} from 'react-native';
|
|
3
3
|
import * as Progress from 'react-native-progress';
|
|
4
4
|
import {CrossIcon, CircleTick} from '../../assets';
|
|
5
5
|
import CustomTypography from '../customTypography/CustomTypography';
|
|
6
|
-
import {horizontalScale,
|
|
7
|
-
import {ToastProps} from './Toast.interface';
|
|
6
|
+
import {horizontalScale, width} from '../../utils/stylehelper';
|
|
7
|
+
import {ToastRef, ShowToast, ToastProps} from './Toast.interface'; // Import the interfaces
|
|
8
8
|
import styles from './Toast.styles';
|
|
9
9
|
|
|
10
|
-
const Toast = ({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
isSuccess = true
|
|
14
|
-
btnText,
|
|
15
|
-
onBtnPress,
|
|
16
|
-
setToast,
|
|
17
|
-
}: ToastProps) => {
|
|
10
|
+
const Toast = React.forwardRef<ToastRef, ToastProps>((_props, ref) => {
|
|
11
|
+
const [visible, setVisible] = useState(false);
|
|
12
|
+
const [message, setMessage] = useState('');
|
|
13
|
+
const [isSuccess, setIsSuccess] = useState(true);
|
|
14
|
+
const [btnText, setBtnText] = useState<string | null>(null);
|
|
15
|
+
const [onBtnPress, setOnBtnPress] = useState<(() => void) | null>(null);
|
|
18
16
|
const [progress, setProgress] = useState(0);
|
|
19
|
-
const bottom = React.useRef(new Animated.Value(-80)).current;
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
const bottom = useRef(new Animated.Value(-80)).current;
|
|
19
|
+
|
|
20
|
+
const showToast: ShowToast = (
|
|
21
|
+
toastMessage,
|
|
22
|
+
duration = 3000,
|
|
23
|
+
success = true,
|
|
24
|
+
buttonText = null,
|
|
25
|
+
buttonAction = null,
|
|
26
|
+
) => {
|
|
27
|
+
setMessage(toastMessage);
|
|
28
|
+
setIsSuccess(success);
|
|
29
|
+
setBtnText(buttonText);
|
|
30
|
+
setOnBtnPress(() => buttonAction);
|
|
31
|
+
setVisible(true);
|
|
32
|
+
|
|
22
33
|
Animated.timing(bottom, {
|
|
23
34
|
toValue: 20,
|
|
24
|
-
duration:
|
|
35
|
+
duration: 500,
|
|
36
|
+
useNativeDriver: false,
|
|
37
|
+
}).start();
|
|
38
|
+
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
hideToast();
|
|
41
|
+
}, duration);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const hideToast = () => {
|
|
45
|
+
Animated.timing(bottom, {
|
|
46
|
+
toValue: -80,
|
|
47
|
+
duration: 500,
|
|
25
48
|
useNativeDriver: false,
|
|
26
49
|
}).start(() => {
|
|
27
|
-
|
|
50
|
+
setVisible(false);
|
|
51
|
+
setMessage('');
|
|
28
52
|
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
animate();
|
|
33
|
-
}, []);
|
|
53
|
+
};
|
|
34
54
|
|
|
35
55
|
const simulateProgress = () => {
|
|
36
56
|
setProgress(prev => (prev + 0.1 > 1 ? 1 : prev + 0.1));
|
|
37
57
|
};
|
|
38
58
|
|
|
39
59
|
useEffect(() => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
if (visible) {
|
|
61
|
+
setProgress(0);
|
|
62
|
+
const interval = setInterval(simulateProgress, 180);
|
|
63
|
+
return () => clearInterval(interval);
|
|
64
|
+
}
|
|
65
|
+
}, [visible]);
|
|
66
|
+
|
|
67
|
+
React.useImperativeHandle(ref, () => ({
|
|
68
|
+
showToast,
|
|
69
|
+
}));
|
|
43
70
|
|
|
44
|
-
return (
|
|
71
|
+
return visible ? (
|
|
45
72
|
<Animated.View
|
|
46
73
|
style={[
|
|
47
74
|
styles.container,
|
|
48
75
|
{bottom},
|
|
49
76
|
{backgroundColor: isSuccess ? '#04743F' : '#DB3056'},
|
|
50
77
|
]}
|
|
51
|
-
testID=
|
|
78
|
+
testID="TOAST">
|
|
52
79
|
<View style={styles.toastContainer}>
|
|
53
80
|
<View style={styles.innerContainer}>
|
|
54
|
-
{
|
|
55
|
-
width: moderateScale(20),
|
|
56
|
-
height: moderateScale(20),
|
|
57
|
-
style: styles.icon,
|
|
58
|
-
})}
|
|
81
|
+
{isSuccess ? <CircleTick /> : <CrossIcon />}
|
|
59
82
|
<CustomTypography
|
|
60
|
-
variant=
|
|
83
|
+
variant="L2_REGULAR"
|
|
61
84
|
text={message}
|
|
62
85
|
style={styles.messageText}
|
|
63
86
|
/>
|
|
64
|
-
{btnText
|
|
87
|
+
{btnText && (
|
|
65
88
|
<Pressable
|
|
66
89
|
style={styles.button}
|
|
67
|
-
onPress={onBtnPress}
|
|
68
|
-
testID=
|
|
90
|
+
onPress={onBtnPress || undefined}
|
|
91
|
+
testID="TOAST-BTN">
|
|
69
92
|
<CustomTypography
|
|
70
|
-
variant=
|
|
93
|
+
variant="L2_BOLD"
|
|
71
94
|
text={btnText}
|
|
72
95
|
style={styles.buttonText}
|
|
73
96
|
/>
|
|
74
97
|
</Pressable>
|
|
75
|
-
)
|
|
98
|
+
)}
|
|
76
99
|
</View>
|
|
77
100
|
</View>
|
|
78
101
|
<Progress.Bar
|
|
@@ -83,7 +106,10 @@ const Toast = ({
|
|
|
83
106
|
borderColor="transparent"
|
|
84
107
|
/>
|
|
85
108
|
</Animated.View>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
109
|
+
) : null;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Set the display name for debugging purposes
|
|
113
|
+
Toast.displayName = 'Toast';
|
|
88
114
|
|
|
89
115
|
export default Toast;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
createContext,
|
|
3
|
+
useRef,
|
|
4
|
+
useImperativeHandle,
|
|
5
|
+
useContext,
|
|
6
|
+
forwardRef,
|
|
7
|
+
} from 'react';
|
|
8
|
+
import Toast from './Toast';
|
|
9
|
+
import {ShowToast, ToastRef} from './Toast.interface';
|
|
10
|
+
|
|
11
|
+
const ToastContext = createContext<{showToast: ShowToast} | undefined>(
|
|
12
|
+
undefined,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const ToastProvider = forwardRef<ToastRef, React.PropsWithChildren<object>>(
|
|
16
|
+
(props, ref) => {
|
|
17
|
+
const toastRef = useRef<ToastRef>(null);
|
|
18
|
+
|
|
19
|
+
useImperativeHandle(ref, () => ({
|
|
20
|
+
showToast: (message, duration, isSuccess, btnText, onBtnPress) => {
|
|
21
|
+
toastRef.current?.showToast(
|
|
22
|
+
message,
|
|
23
|
+
duration,
|
|
24
|
+
isSuccess,
|
|
25
|
+
btnText,
|
|
26
|
+
onBtnPress,
|
|
27
|
+
);
|
|
28
|
+
},
|
|
29
|
+
}));
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<ToastContext.Provider
|
|
33
|
+
value={{
|
|
34
|
+
showToast: (message, duration, isSuccess, btnText, onBtnPress) => {
|
|
35
|
+
toastRef.current?.showToast(
|
|
36
|
+
message,
|
|
37
|
+
duration,
|
|
38
|
+
isSuccess,
|
|
39
|
+
btnText,
|
|
40
|
+
onBtnPress,
|
|
41
|
+
);
|
|
42
|
+
},
|
|
43
|
+
}}>
|
|
44
|
+
{props.children}
|
|
45
|
+
<Toast ref={toastRef} />
|
|
46
|
+
</ToastContext.Provider>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
ToastProvider.displayName = 'ToastProvider';
|
|
52
|
+
|
|
53
|
+
export const useToast = () => {
|
|
54
|
+
const context = useContext(ToastContext);
|
|
55
|
+
if (!context) {
|
|
56
|
+
throw new Error('useToast must be used within a ToastProvider');
|
|
57
|
+
}
|
|
58
|
+
return context;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export default ToastProvider;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
export type ShowToast = (text: string, duration?: number) => void;
|
|
4
|
+
|
|
5
|
+
export type Provider = React.FunctionComponent & {
|
|
6
|
+
ref: ToastRef | null;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type RegisterRef = (ref: ToastRef) => void;
|
|
10
|
+
|
|
11
|
+
export interface ToastRef {
|
|
12
|
+
showToast: ShowToast;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ToastProps {
|
|
16
|
+
ref: (ref: ToastRef) => void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {View, Button} from 'react-native';
|
|
3
|
+
import {useToast} from './ToastProvider'; // Adjust the path as necessary
|
|
4
|
+
|
|
5
|
+
const YourComponent = () => {
|
|
6
|
+
const {showToast} = useToast();
|
|
7
|
+
|
|
8
|
+
const handleShowToast = () => {
|
|
9
|
+
showToast('This is a toast message!', 3000, true, 'Close', () => {
|
|
10
|
+
console.log('Button pressed!');
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<View>
|
|
16
|
+
<Button title="Show Toast" onPress={handleShowToast} />
|
|
17
|
+
</View>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default YourComponent;
|
package/src/index.ts
CHANGED
|
@@ -49,5 +49,6 @@ export {
|
|
|
49
49
|
} from './utils/stylehelper';
|
|
50
50
|
|
|
51
51
|
export {default} from './theme/themes';
|
|
52
|
-
|
|
52
|
+
export {default as useToast} from './components/toast/ToastProvider';
|
|
53
|
+
export {default as ToastProvider} from './components/toast/ToastProvider';
|
|
53
54
|
export {default as CustomTextTest} from '../__mocks__/custom-text.mock';
|