@hoddy-ui/core 1.0.17 → 1.0.19
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/index.ts +2 -1
- package/package.json +1 -1
- package/src/Components/Checkbox.tsx +42 -26
- package/src/Components/FlashMessage.tsx +68 -31
- package/src/Components/OTPInput.tsx +47 -0
- package/src/Components/TextField.tsx +4 -1
- package/src/theme/index.tsx +16 -4
- package/src/types.ts +13 -3
package/index.ts
CHANGED
|
@@ -3,13 +3,14 @@ import { initialize } from "./src/config";
|
|
|
3
3
|
// Components
|
|
4
4
|
export { default as AdaptiveStatusBar } from "./src/Components/AdaptiveStatusBar";
|
|
5
5
|
export { default as AlertX } from "./src/Components/AlertX";
|
|
6
|
+
export * from "./src/Components/Animator";
|
|
6
7
|
export { default as Avatar } from "./src/Components/Avatar";
|
|
7
8
|
export * from "./src/Components/Button";
|
|
8
9
|
export { default as Button } from "./src/Components/Button";
|
|
9
10
|
export * from "./src/Components/Checkbox";
|
|
10
11
|
export * from "./src/Components/FlashMessage";
|
|
12
|
+
export * from "./src/Components/FormWrapper";
|
|
11
13
|
export * from "./src/Components/Grid";
|
|
12
|
-
export * from "./src/Components/Animator";
|
|
13
14
|
export * from "./src/Components/Locator";
|
|
14
15
|
export * from "./src/Components/Popup";
|
|
15
16
|
export * from "./src/Components/SafeAreaView";
|
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,93 @@
|
|
|
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();
|
|
21
|
+
const [show, setShow] = useState<null | FlashMessageProps>(null);
|
|
15
22
|
const colors = useColors();
|
|
16
|
-
const
|
|
23
|
+
const type = show?.type || "success";
|
|
24
|
+
|
|
25
|
+
showFlashMessage = (msg: FlashMessageProps) => {
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
setShow(msg);
|
|
28
|
+
}, 50);
|
|
29
|
+
|
|
30
|
+
setTimeout(() => {
|
|
31
|
+
setShow(null);
|
|
32
|
+
}, msg.duration || 2000);
|
|
33
|
+
console.log("done", msg);
|
|
34
|
+
};
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
|
|
37
|
+
console.log("show", show);
|
|
38
|
+
}, [show]);
|
|
39
|
+
|
|
17
40
|
const styles = ScaledSheet.create({
|
|
18
41
|
root: {
|
|
19
42
|
position: "absolute",
|
|
20
|
-
top: 0,
|
|
43
|
+
top: show ? 0 : -200,
|
|
21
44
|
zIndex: 1000,
|
|
22
45
|
left: 0,
|
|
23
46
|
paddingTop: top + 10,
|
|
24
47
|
paddingHorizontal: "15@ms",
|
|
25
48
|
backgroundColor: colors[type].main,
|
|
26
49
|
width: "100%",
|
|
27
|
-
paddingBottom: "
|
|
50
|
+
paddingBottom: "15@ms",
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
action: {
|
|
54
|
+
borderRadius: 20,
|
|
55
|
+
marginTop: "10@vs",
|
|
56
|
+
flexDirection: "row",
|
|
57
|
+
justifyContent: "center",
|
|
58
|
+
paddingHorizontal: "20@ms",
|
|
59
|
+
paddingVertical: "8@vs",
|
|
60
|
+
backgroundColor: "#fff3",
|
|
28
61
|
},
|
|
29
62
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
setShow(false);
|
|
34
|
-
}, 2000);
|
|
35
|
-
}, [message]);
|
|
36
|
-
return show ? (
|
|
63
|
+
|
|
64
|
+
return (
|
|
37
65
|
<View style={styles.root}>
|
|
38
|
-
{
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
<View style={{ flexDirection: "row" }}>
|
|
67
|
+
<View style={{ flex: 1, marginRight: 10 }}>
|
|
68
|
+
{show?.title && (
|
|
69
|
+
<Typography
|
|
70
|
+
variant="h6"
|
|
71
|
+
fontWeight={600}
|
|
72
|
+
gutterBottom={3}
|
|
73
|
+
style={{ color: "#fff" }}
|
|
74
|
+
>
|
|
75
|
+
{show?.title}
|
|
76
|
+
</Typography>
|
|
77
|
+
)}
|
|
78
|
+
<Typography style={{ color: "#fff" }}>{show?.message}</Typography>
|
|
79
|
+
</View>
|
|
80
|
+
{/* <MaterialIcons color="#fff" size={36} name="error-outline" /> */}
|
|
81
|
+
</View>
|
|
82
|
+
|
|
83
|
+
{show?.actions?.map((cur) => (
|
|
84
|
+
<TouchableOpacity style={styles.action}>
|
|
85
|
+
<Typography fontWeight={700} style={{ color: "#fff" }}>
|
|
86
|
+
{cur.title}
|
|
87
|
+
</Typography>
|
|
88
|
+
</TouchableOpacity>
|
|
89
|
+
))}
|
|
51
90
|
</View>
|
|
52
|
-
) : (
|
|
53
|
-
<></>
|
|
54
91
|
);
|
|
55
92
|
};
|
|
56
93
|
|
|
@@ -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
|
+
});
|
|
@@ -26,6 +26,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
26
26
|
onBlur = () => {},
|
|
27
27
|
error,
|
|
28
28
|
start,
|
|
29
|
+
size = "normal",
|
|
29
30
|
rounded,
|
|
30
31
|
disabled = false,
|
|
31
32
|
style = {},
|
|
@@ -40,7 +41,9 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
40
41
|
|
|
41
42
|
const labelAnim = useRef(new Animated.Value(0)).current;
|
|
42
43
|
|
|
43
|
-
const height =
|
|
44
|
+
const height =
|
|
45
|
+
moderateScale(variant === "text" ? 50 : 45) *
|
|
46
|
+
(size === "large" ? 1.2 : size === "small" ? 0.8 : 1);
|
|
44
47
|
|
|
45
48
|
React.useEffect(() => {
|
|
46
49
|
if (focused || value) {
|
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
|
@@ -17,7 +17,6 @@ export type colorTypes =
|
|
|
17
17
|
| "info"
|
|
18
18
|
| "warning"
|
|
19
19
|
| "error"
|
|
20
|
-
| "purple"
|
|
21
20
|
| "blue"
|
|
22
21
|
| "textSecondary";
|
|
23
22
|
|
|
@@ -100,10 +99,20 @@ export interface ButtonProps {
|
|
|
100
99
|
start?: ReactNode;
|
|
101
100
|
end?: ReactNode;
|
|
102
101
|
}
|
|
102
|
+
|
|
103
|
+
export interface CheckboxProps {
|
|
104
|
+
color?: colorTypes;
|
|
105
|
+
label: ReactNode;
|
|
106
|
+
checked?: boolean;
|
|
107
|
+
style?: ViewStyle;
|
|
108
|
+
onChange?: () => void;
|
|
109
|
+
}
|
|
103
110
|
export interface FlashMessageProps {
|
|
104
|
-
message
|
|
111
|
+
message: string;
|
|
105
112
|
title?: string;
|
|
106
|
-
|
|
113
|
+
actions?: Array<{ title: string; onPress?: () => void }>;
|
|
114
|
+
duration?: number;
|
|
115
|
+
type?: "success" | "warning" | "error";
|
|
107
116
|
}
|
|
108
117
|
export interface LinkButtonProps {
|
|
109
118
|
title: string;
|
|
@@ -215,6 +224,7 @@ export interface TextFieldProps extends TextInputProps {
|
|
|
215
224
|
label?: string;
|
|
216
225
|
variant?: "outlined" | "text" | "contained";
|
|
217
226
|
color?: colorTypes;
|
|
227
|
+
size?: "small" | "normal" | "large";
|
|
218
228
|
type?: "email" | "tel" | "password" | "text" | "number" | "search";
|
|
219
229
|
helperText?: string;
|
|
220
230
|
value: any;
|