@hoddy-ui/core 1.0.18 → 1.0.20
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/Components/Checkbox.tsx +42 -26
- package/src/Components/FlashMessage.tsx +73 -31
- package/src/Components/OTPInput.tsx +47 -0
- package/src/theme/index.tsx +16 -4
- package/src/types.ts +12 -2
package/package.json
CHANGED
|
@@ -1,36 +1,52 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
Pressable,
|
|
3
|
+
StyleSheet,
|
|
4
|
+
Text,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
View,
|
|
7
|
+
} from "react-native";
|
|
8
|
+
import React, { FC } from "react";
|
|
3
9
|
import { MaterialCommunityIcons } from "@expo/vector-icons";
|
|
10
|
+
import { useColors } from "../hooks";
|
|
11
|
+
import { CheckboxProps } from "../types";
|
|
12
|
+
import { ScaledSheet } from "react-native-size-matters";
|
|
4
13
|
|
|
5
|
-
const CheckBox = (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
const CheckBox: FC<CheckboxProps> = ({
|
|
15
|
+
color = "primary",
|
|
16
|
+
checked,
|
|
17
|
+
label,
|
|
18
|
+
style = {},
|
|
19
|
+
onChange,
|
|
20
|
+
}) => {
|
|
21
|
+
const iconName = checked ? "checkbox-marked" : "checkbox-blank-outline";
|
|
22
|
+
const colors = useColors();
|
|
23
|
+
|
|
24
|
+
const styles = ScaledSheet.create({
|
|
25
|
+
container: {
|
|
26
|
+
alignItems: "center",
|
|
27
|
+
flexDirection: "row",
|
|
28
|
+
...style,
|
|
29
|
+
},
|
|
30
|
+
title: {
|
|
31
|
+
fontSize: 16,
|
|
32
|
+
color: "#000",
|
|
33
|
+
marginLeft: 5,
|
|
34
|
+
fontWeight: "600",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
9
37
|
|
|
10
38
|
return (
|
|
11
39
|
<View style={styles.container}>
|
|
12
|
-
<
|
|
13
|
-
<MaterialCommunityIcons
|
|
14
|
-
|
|
40
|
+
<TouchableOpacity onPress={onChange}>
|
|
41
|
+
<MaterialCommunityIcons
|
|
42
|
+
name={iconName}
|
|
43
|
+
size={24}
|
|
44
|
+
color={colors[color].main}
|
|
45
|
+
/>
|
|
46
|
+
</TouchableOpacity>
|
|
47
|
+
{label}
|
|
15
48
|
</View>
|
|
16
49
|
);
|
|
17
50
|
};
|
|
18
51
|
|
|
19
52
|
export default CheckBox;
|
|
20
|
-
|
|
21
|
-
const styles = StyleSheet.create({
|
|
22
|
-
container: {
|
|
23
|
-
justifyContent: "flex-start",
|
|
24
|
-
alignItems: "center",
|
|
25
|
-
flexDirection: "row",
|
|
26
|
-
width: 20,
|
|
27
|
-
marginTop: 5,
|
|
28
|
-
marginRight: 10,
|
|
29
|
-
},
|
|
30
|
-
title: {
|
|
31
|
-
fontSize: 16,
|
|
32
|
-
color: "#000",
|
|
33
|
-
marginLeft: 5,
|
|
34
|
-
fontWeight: "600",
|
|
35
|
-
},
|
|
36
|
-
});
|
|
@@ -1,56 +1,98 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
LayoutAnimation,
|
|
4
|
+
Touchable,
|
|
5
|
+
TouchableOpacity,
|
|
6
|
+
View,
|
|
7
|
+
} from "react-native";
|
|
3
8
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
4
9
|
import { ScaledSheet } from "react-native-size-matters";
|
|
5
10
|
import { useColors } from "../hooks";
|
|
11
|
+
import { MaterialIcons } from "@expo/vector-icons";
|
|
6
12
|
import { FlashMessageProps } from "../types";
|
|
7
13
|
import Typography from "./Typography";
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
export let showFlashMessage: (msg: FlashMessageProps) => void = () => {
|
|
16
|
+
console.log("hi");
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const FlashMessage: React.FC = () => {
|
|
14
20
|
const { top } = useSafeAreaInsets();
|
|
15
|
-
const
|
|
21
|
+
const [message, setMessage] = useState<null | FlashMessageProps>(null);
|
|
16
22
|
const [show, setShow] = useState(false);
|
|
23
|
+
const colors = useColors();
|
|
24
|
+
const type = message?.type || "success";
|
|
25
|
+
|
|
26
|
+
showFlashMessage = (msg: FlashMessageProps) => {
|
|
27
|
+
setMessage(msg);
|
|
28
|
+
setTimeout(() => {
|
|
29
|
+
setShow(true);
|
|
30
|
+
}, 50);
|
|
31
|
+
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
setShow(false);
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
setMessage(null);
|
|
36
|
+
}, 500);
|
|
37
|
+
}, msg.duration || 2000);
|
|
38
|
+
|
|
39
|
+
console.log("done", msg);
|
|
40
|
+
};
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
43
|
+
}, [show]);
|
|
44
|
+
|
|
17
45
|
const styles = ScaledSheet.create({
|
|
18
46
|
root: {
|
|
19
47
|
position: "absolute",
|
|
20
|
-
top: 0,
|
|
48
|
+
top: show ? 0 : -200,
|
|
21
49
|
zIndex: 1000,
|
|
22
50
|
left: 0,
|
|
23
51
|
paddingTop: top + 10,
|
|
24
52
|
paddingHorizontal: "15@ms",
|
|
25
53
|
backgroundColor: colors[type].main,
|
|
26
54
|
width: "100%",
|
|
27
|
-
paddingBottom: "
|
|
55
|
+
paddingBottom: "15@ms",
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
action: {
|
|
59
|
+
borderRadius: 20,
|
|
60
|
+
marginTop: "10@vs",
|
|
61
|
+
flexDirection: "row",
|
|
62
|
+
justifyContent: "center",
|
|
63
|
+
paddingHorizontal: "20@ms",
|
|
64
|
+
paddingVertical: "8@vs",
|
|
65
|
+
backgroundColor: "#fff3",
|
|
28
66
|
},
|
|
29
67
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
setShow(false);
|
|
34
|
-
}, 2000);
|
|
35
|
-
}, [message]);
|
|
36
|
-
return show ? (
|
|
68
|
+
|
|
69
|
+
return (
|
|
37
70
|
<View style={styles.root}>
|
|
38
|
-
{
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
<View style={{ flexDirection: "row" }}>
|
|
72
|
+
<View style={{ flex: 1, marginRight: 10 }}>
|
|
73
|
+
{message?.title && (
|
|
74
|
+
<Typography
|
|
75
|
+
variant="h6"
|
|
76
|
+
fontWeight={600}
|
|
77
|
+
gutterBottom={3}
|
|
78
|
+
style={{ color: "#fff" }}
|
|
79
|
+
>
|
|
80
|
+
{message?.title}
|
|
81
|
+
</Typography>
|
|
82
|
+
)}
|
|
83
|
+
<Typography style={{ color: "#fff" }}>{message?.message}</Typography>
|
|
84
|
+
</View>
|
|
85
|
+
{/* <MaterialIcons color="#fff" size={36} name="error-outline" /> */}
|
|
86
|
+
</View>
|
|
87
|
+
|
|
88
|
+
{message?.actions?.map((cur) => (
|
|
89
|
+
<TouchableOpacity style={styles.action}>
|
|
90
|
+
<Typography fontWeight={700} style={{ color: "#fff" }}>
|
|
91
|
+
{cur.title}
|
|
92
|
+
</Typography>
|
|
93
|
+
</TouchableOpacity>
|
|
94
|
+
))}
|
|
51
95
|
</View>
|
|
52
|
-
) : (
|
|
53
|
-
<></>
|
|
54
96
|
);
|
|
55
97
|
};
|
|
56
98
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { View, TextInput, StyleSheet, Button } from "react-native";
|
|
3
|
+
|
|
4
|
+
export const OTPInput = () => {
|
|
5
|
+
const [numFields, setNumFields] = useState(1);
|
|
6
|
+
const [inputTexts, setInputTexts] = useState(Array(numFields).fill(""));
|
|
7
|
+
|
|
8
|
+
const handleInputChange = (text, index) => {
|
|
9
|
+
const updatedInputTexts = [...inputTexts];
|
|
10
|
+
updatedInputTexts[index] = text;
|
|
11
|
+
setInputTexts(updatedInputTexts);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const addField = () => {
|
|
15
|
+
setNumFields(numFields + 1);
|
|
16
|
+
setInputTexts([...inputTexts, ""]);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<View style={styles.container}>
|
|
21
|
+
{inputTexts.map((inputText, index) => (
|
|
22
|
+
<TextInput
|
|
23
|
+
key={index}
|
|
24
|
+
style={styles.input}
|
|
25
|
+
placeholder={`Enter text ${index + 1}`}
|
|
26
|
+
value={inputText}
|
|
27
|
+
onChangeText={(text) => handleInputChange(text, index)}
|
|
28
|
+
/>
|
|
29
|
+
))}
|
|
30
|
+
<Button title="Add Field" onPress={addField} />
|
|
31
|
+
</View>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const styles = StyleSheet.create({
|
|
36
|
+
container: {
|
|
37
|
+
marginTop: 20,
|
|
38
|
+
paddingHorizontal: 16,
|
|
39
|
+
},
|
|
40
|
+
input: {
|
|
41
|
+
height: 40,
|
|
42
|
+
borderColor: "gray",
|
|
43
|
+
borderWidth: 1,
|
|
44
|
+
paddingHorizontal: 10,
|
|
45
|
+
marginBottom: 10,
|
|
46
|
+
},
|
|
47
|
+
});
|
package/src/theme/index.tsx
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
2
2
|
import * as NavigationBar from "expo-navigation-bar";
|
|
3
3
|
import * as SystemUI from "expo-system-ui";
|
|
4
|
-
import React, { createContext, useReducer } from "react";
|
|
4
|
+
import React, { createContext, useReducer, useState } from "react";
|
|
5
5
|
import { Platform, useColorScheme } from "react-native";
|
|
6
6
|
import {
|
|
7
|
+
FlashMessageProps,
|
|
7
8
|
ThemeActionTypes,
|
|
8
9
|
ThemeContext,
|
|
9
10
|
ThemeProviderProps,
|
|
10
11
|
ThemeState,
|
|
11
12
|
ThemeTypes,
|
|
12
13
|
} from "../types";
|
|
14
|
+
import FlashMessage from "../Components/FlashMessage";
|
|
15
|
+
import { SafeAreaProvider } from "react-native-safe-area-context";
|
|
13
16
|
|
|
14
17
|
export const UIThemeContext = createContext<ThemeContext>({
|
|
15
18
|
themeState: { mode: "default", value: "light" },
|
|
@@ -52,6 +55,7 @@ export const UIThemeProvider = ({ children }: ThemeProviderProps) => {
|
|
|
52
55
|
mode: "default",
|
|
53
56
|
value: "light",
|
|
54
57
|
});
|
|
58
|
+
|
|
55
59
|
const colorScheme: ThemeTypes = useColorScheme()!;
|
|
56
60
|
|
|
57
61
|
React.useEffect(() => {
|
|
@@ -75,8 +79,16 @@ export const UIThemeProvider = ({ children }: ThemeProviderProps) => {
|
|
|
75
79
|
});
|
|
76
80
|
}, [colorScheme]);
|
|
77
81
|
return (
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
<SafeAreaProvider>
|
|
83
|
+
<UIThemeContext.Provider
|
|
84
|
+
value={{
|
|
85
|
+
themeState,
|
|
86
|
+
themeDispatch,
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
{children}
|
|
90
|
+
<FlashMessage />
|
|
91
|
+
</UIThemeContext.Provider>
|
|
92
|
+
</SafeAreaProvider>
|
|
81
93
|
);
|
|
82
94
|
};
|
package/src/types.ts
CHANGED
|
@@ -99,10 +99,20 @@ export interface ButtonProps {
|
|
|
99
99
|
start?: ReactNode;
|
|
100
100
|
end?: ReactNode;
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
export interface CheckboxProps {
|
|
104
|
+
color?: colorTypes;
|
|
105
|
+
label: ReactNode;
|
|
106
|
+
checked?: boolean;
|
|
107
|
+
style?: ViewStyle;
|
|
108
|
+
onChange?: () => void;
|
|
109
|
+
}
|
|
102
110
|
export interface FlashMessageProps {
|
|
103
|
-
message
|
|
111
|
+
message: string;
|
|
104
112
|
title?: string;
|
|
105
|
-
|
|
113
|
+
actions?: Array<{ title: string; onPress?: () => void }>;
|
|
114
|
+
duration?: number;
|
|
115
|
+
type?: "success" | "warning" | "error";
|
|
106
116
|
}
|
|
107
117
|
export interface LinkButtonProps {
|
|
108
118
|
title: string;
|