@hoddy-ui/core 1.0.89 → 1.0.90
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/next/dist/index.d.mts +4 -2
- package/next/dist/index.d.ts +4 -2
- package/next/dist/index.js +100 -54
- package/next/dist/index.js.map +1 -1
- package/next/dist/index.mjs +104 -55
- package/next/dist/index.mjs.map +1 -1
- package/next/package.json +3 -2
- package/package.json +6 -6
- package/src/Components/Button.tsx +3 -0
- package/src/Components/Locator.tsx +3 -8
- package/src/Components/OTPInput.tsx +45 -26
- package/src/Components/Popup.tsx +13 -6
- package/src/Components/TextField.tsx +26 -8
- package/src/Components/Typography.tsx +6 -1
- package/src/config/KeyManager.ts +7 -6
- package/src/config/index.ts +4 -2
- package/src/types.ts +4 -1
package/next/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoddy-ui/next",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.27",
|
|
4
4
|
"description": "Core rich react native components written in typescript, with support for expo-router",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"private": false,
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsup"
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"deploy": "yarn build && yarn publish"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
20
21
|
"@expo/vector-icons": ">=13.0.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoddy-ui/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.90",
|
|
4
4
|
"description": "Core rich react native components written in typescript",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"repository": {
|
|
@@ -12,18 +12,18 @@
|
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"private": false,
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@expo/vector-icons": "
|
|
15
|
+
"@expo/vector-icons": ">=13.0.0",
|
|
16
16
|
"@react-navigation/native": ">=6.1.7",
|
|
17
|
-
"@types/react": "
|
|
18
|
-
"@types/react-native": "
|
|
17
|
+
"@types/react": ">=18.2.6",
|
|
18
|
+
"@types/react-native": ">=0.72.0",
|
|
19
19
|
"expo-haptics": ">=12.4.0",
|
|
20
20
|
"expo-location": ">=15.1.1",
|
|
21
21
|
"expo-navigation-bar": ">=2.1.1",
|
|
22
22
|
"expo-system-ui": ">=2.2.1",
|
|
23
|
-
"react": "
|
|
23
|
+
"react": ">=18.2.0",
|
|
24
24
|
"react-native": ">=0.71.8",
|
|
25
25
|
"react-native-safe-area-context": ">=4.5.3",
|
|
26
|
-
"typescript": "
|
|
26
|
+
"typescript": ">=5.0.4"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|
|
29
29
|
"react-native",
|
|
@@ -2,6 +2,7 @@ import { Ionicons, MaterialIcons } from "@expo/vector-icons";
|
|
|
2
2
|
import React, { forwardRef } from "react";
|
|
3
3
|
import { ActivityIndicator, Text, TouchableOpacity } from "react-native";
|
|
4
4
|
import { ScaledSheet, moderateScale } from "react-native-size-matters";
|
|
5
|
+
import { getConfig } from "../config/KeyManager";
|
|
5
6
|
import { useColors, useTheme } from "../hooks";
|
|
6
7
|
import { ButtonProps, IconButtonProps, LinkButtonProps } from "../types";
|
|
7
8
|
|
|
@@ -20,6 +21,7 @@ export const LinkButton: React.FC<LinkButtonProps> = ({
|
|
|
20
21
|
text: {
|
|
21
22
|
fontSize: moderateScale(fontSize),
|
|
22
23
|
fontWeight: fontWeight,
|
|
24
|
+
fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System",
|
|
23
25
|
color: disabled ? "#777" : colors[color].main,
|
|
24
26
|
},
|
|
25
27
|
});
|
|
@@ -154,6 +156,7 @@ const Button: React.FC<ButtonProps> = forwardRef(
|
|
|
154
156
|
],
|
|
155
157
|
fontWeight: variant === "outlined" ? "700" : "500",
|
|
156
158
|
fontSize: size === "small" ? "12@ms" : "16@ms",
|
|
159
|
+
fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System",
|
|
157
160
|
},
|
|
158
161
|
});
|
|
159
162
|
|
|
@@ -9,20 +9,15 @@ import { ScaledSheet } from "react-native-size-matters";
|
|
|
9
9
|
import { useColors } from "../hooks";
|
|
10
10
|
import { LocatorProps } from "../types";
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { getConfig } from "../config/KeyManager";
|
|
13
13
|
import Typography from "./Typography";
|
|
14
14
|
|
|
15
|
-
setTimeout(() => {
|
|
16
|
-
const { GOOGLE_MAP_API_KEY } = getApiKey();
|
|
17
|
-
if (GOOGLE_MAP_API_KEY) Location.setGoogleApiKey(GOOGLE_MAP_API_KEY);
|
|
18
|
-
}, 500);
|
|
19
|
-
|
|
20
15
|
type predictionType = {
|
|
21
16
|
id: string;
|
|
22
17
|
description: string;
|
|
23
18
|
};
|
|
24
19
|
export const getPredictionsFromCoords = async (coords: any) => {
|
|
25
|
-
const { GOOGLE_MAP_API_KEY } =
|
|
20
|
+
const { GOOGLE_MAP_API_KEY } = getConfig();
|
|
26
21
|
|
|
27
22
|
if (!GOOGLE_MAP_API_KEY)
|
|
28
23
|
console.error(
|
|
@@ -63,7 +58,7 @@ export const Locator: React.FC<LocatorProps> = ({
|
|
|
63
58
|
float = true,
|
|
64
59
|
country = "ng",
|
|
65
60
|
}) => {
|
|
66
|
-
const { GOOGLE_MAP_API_KEY } =
|
|
61
|
+
const { GOOGLE_MAP_API_KEY } = getConfig();
|
|
67
62
|
|
|
68
63
|
const [changed, setChanged] = useState(false);
|
|
69
64
|
const [value, setValue] = useState("");
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import React, { FC, useMemo
|
|
2
|
-
import {
|
|
1
|
+
import React, { FC, useMemo } from "react";
|
|
2
|
+
import {
|
|
3
|
+
TextInput,
|
|
4
|
+
TouchableOpacity,
|
|
5
|
+
TouchableWithoutFeedback,
|
|
6
|
+
View,
|
|
7
|
+
} from "react-native";
|
|
3
8
|
import { ScaledSheet, ms } from "react-native-size-matters";
|
|
4
9
|
import { useColors } from "../hooks";
|
|
5
10
|
import { OTPInputProps } from "../types";
|
|
@@ -20,6 +25,42 @@ export const OTPInput: FC<OTPInputProps> = ({
|
|
|
20
25
|
[length]
|
|
21
26
|
);
|
|
22
27
|
|
|
28
|
+
console.log("v", value);
|
|
29
|
+
|
|
30
|
+
const onChangeHandler = (val: string, index: number) => {
|
|
31
|
+
if (value.length >= length && val.length > 0) return;
|
|
32
|
+
// Handle pasting of full OTP
|
|
33
|
+
if (val.length > 1) {
|
|
34
|
+
console.log("reached", val);
|
|
35
|
+
|
|
36
|
+
const digits = val.replace(/\D/g, "").slice(0, length);
|
|
37
|
+
onChange(digits);
|
|
38
|
+
if (digits.length === length) {
|
|
39
|
+
inputRefs[length - 1].current?.focus();
|
|
40
|
+
}
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Handle backspace
|
|
44
|
+
if (val.length === 0) {
|
|
45
|
+
const newValue = value.slice(0, index) + value.slice(index + 1);
|
|
46
|
+
onChange(newValue);
|
|
47
|
+
if (index > 0) {
|
|
48
|
+
inputRefs[index - 1].current?.focus();
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// Only allow numbers and take first digit
|
|
53
|
+
const digit = val.replace(/\D/g, "").slice(0, 1);
|
|
54
|
+
if (!digit) return;
|
|
55
|
+
// Create new value string
|
|
56
|
+
const newValue = value.slice(0, index) + digit + value.slice(index + 1);
|
|
57
|
+
onChange(newValue);
|
|
58
|
+
// Auto advance to next input if not at end
|
|
59
|
+
if (index < length - 1) {
|
|
60
|
+
inputRefs[index + 1].current?.focus();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
23
64
|
const colors = useColors();
|
|
24
65
|
const styles = ScaledSheet.create({
|
|
25
66
|
root: {},
|
|
@@ -45,32 +86,10 @@ export const OTPInput: FC<OTPInputProps> = ({
|
|
|
45
86
|
{[...Array(length)].map((_, index) => (
|
|
46
87
|
<TextInput
|
|
47
88
|
ref={inputRefs[index]}
|
|
48
|
-
onChangeText={(val) =>
|
|
49
|
-
if (val.length === 1) {
|
|
50
|
-
if (index !== length - 1) inputRefs[index + 1].current?.focus();
|
|
51
|
-
let text = value;
|
|
52
|
-
|
|
53
|
-
text = text.slice(0, index) + val + text.slice(index + 1);
|
|
54
|
-
onChange(text);
|
|
55
|
-
} else if (val.length === 0) {
|
|
56
|
-
if (index !== 0) {
|
|
57
|
-
inputRefs[index - 1].current?.focus();
|
|
58
|
-
let text = value;
|
|
59
|
-
|
|
60
|
-
text = text.slice(0, index);
|
|
61
|
-
onChange(text);
|
|
62
|
-
} else onChange("");
|
|
63
|
-
} else {
|
|
64
|
-
let text = val.replace(/\D/g, "").slice(0, length);
|
|
65
|
-
onChange(text);
|
|
66
|
-
inputRefs[
|
|
67
|
-
text.length < length - 1 ? text.length : length - 1
|
|
68
|
-
]?.current?.focus();
|
|
69
|
-
}
|
|
70
|
-
}}
|
|
89
|
+
onChangeText={(val) => onChangeHandler(val, index)}
|
|
71
90
|
value={value[index] || ""}
|
|
72
|
-
// maxLength={1}
|
|
73
91
|
blurOnSubmit={false}
|
|
92
|
+
// maxLength={1}
|
|
74
93
|
keyboardType="number-pad"
|
|
75
94
|
key={index}
|
|
76
95
|
style={[styles.input]}
|
package/src/Components/Popup.tsx
CHANGED
|
@@ -75,15 +75,22 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
React.useEffect(() => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
if (open) {
|
|
79
|
+
setShow(open);
|
|
80
|
+
setTimeout(() => {
|
|
81
|
+
setShowSecondary(open);
|
|
82
|
+
}, 500);
|
|
83
|
+
} else {
|
|
84
|
+
closeAction();
|
|
85
|
+
}
|
|
82
86
|
}, [open]);
|
|
83
87
|
|
|
84
88
|
const closeAction = () => {
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
setShowSecondary(false);
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
setShow(false);
|
|
92
|
+
onClose();
|
|
93
|
+
}, 300);
|
|
87
94
|
};
|
|
88
95
|
|
|
89
96
|
return (
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Ionicons, MaterialIcons } from "@expo/vector-icons";
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
3
|
import { Animated, TextInput, TouchableOpacity, View } from "react-native";
|
|
4
4
|
import {
|
|
5
5
|
ScaledSheet,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
ms,
|
|
8
8
|
verticalScale,
|
|
9
9
|
} from "react-native-size-matters";
|
|
10
|
+
import { getConfig } from "../config/KeyManager";
|
|
10
11
|
import { useColors } from "../hooks";
|
|
11
12
|
import { TextFieldProps } from "../types";
|
|
12
13
|
import SelectMenu from "./SelectMenu";
|
|
@@ -38,13 +39,14 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
38
39
|
}) => {
|
|
39
40
|
const colors = useColors();
|
|
40
41
|
const [focused, setFocused] = useState(false);
|
|
41
|
-
|
|
42
|
-
const labelAnim = useRef(new Animated.Value(0)).current;
|
|
43
|
-
|
|
44
42
|
const height =
|
|
45
43
|
moderateScale(variant === "text" ? 50 : 45) *
|
|
46
44
|
(size === "large" ? 1.2 : size === "small" ? 0.8 : 1);
|
|
47
45
|
|
|
46
|
+
const labelAnim = useRef(
|
|
47
|
+
new Animated.Value(height / moderateScale(variant === "text" ? 2.5 : 3.2))
|
|
48
|
+
).current;
|
|
49
|
+
|
|
48
50
|
React.useEffect(() => {
|
|
49
51
|
if (focused || value) {
|
|
50
52
|
Animated.timing(labelAnim, {
|
|
@@ -96,6 +98,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
96
98
|
paddingLeft: variant === "text" ? 0 : moderateScale(15),
|
|
97
99
|
paddingRight: moderateScale(10),
|
|
98
100
|
paddingTop: "11@vs",
|
|
101
|
+
fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System",
|
|
99
102
|
color: colors.black[1],
|
|
100
103
|
zIndex: 10,
|
|
101
104
|
// backgroundColor: "#284",
|
|
@@ -107,6 +110,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
107
110
|
paddingTop: "13@ms",
|
|
108
111
|
},
|
|
109
112
|
label: {
|
|
113
|
+
fontFamily: getConfig().DEFAULT_FONT_FAMILY || "System",
|
|
110
114
|
position: "absolute",
|
|
111
115
|
left: variant === "text" ? 0 : moderateScale(15),
|
|
112
116
|
fontSize: focused || value ? "10@s" : "13@s",
|
|
@@ -213,9 +217,23 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
213
217
|
style={styles.input}
|
|
214
218
|
/>
|
|
215
219
|
)}
|
|
216
|
-
{end &&
|
|
220
|
+
{end && (
|
|
221
|
+
<View
|
|
222
|
+
style={{
|
|
223
|
+
marginRight: 20,
|
|
224
|
+
paddingTop: variant === "text" ? ms(13) : 0,
|
|
225
|
+
}}
|
|
226
|
+
>
|
|
227
|
+
{end}
|
|
228
|
+
</View>
|
|
229
|
+
)}
|
|
217
230
|
{options && (
|
|
218
|
-
<View
|
|
231
|
+
<View
|
|
232
|
+
style={{
|
|
233
|
+
marginRight: variant === "text" ? 0 : 20,
|
|
234
|
+
paddingTop: variant === "text" ? ms(13) : 0,
|
|
235
|
+
}}
|
|
236
|
+
>
|
|
219
237
|
<Ionicons
|
|
220
238
|
name="chevron-down"
|
|
221
239
|
color={colors.textSecondary.main}
|
|
@@ -318,13 +336,13 @@ export const TextField2: React.FC<TextFieldProps> = ({
|
|
|
318
336
|
alignSelf: "stretch",
|
|
319
337
|
paddingLeft: moderateScale(10),
|
|
320
338
|
paddingRight: moderateScale(10),
|
|
321
|
-
color: colors.dark.
|
|
339
|
+
color: colors.dark.main,
|
|
322
340
|
zIndex: 10,
|
|
323
341
|
// backgroundColor: "#284",
|
|
324
342
|
},
|
|
325
343
|
inputText: {
|
|
326
344
|
fontSize: "14@ms",
|
|
327
|
-
color: colors.dark.
|
|
345
|
+
color: colors.dark.main,
|
|
328
346
|
paddingLeft: moderateScale(10),
|
|
329
347
|
},
|
|
330
348
|
placeholder: {
|
|
@@ -3,6 +3,7 @@ import { StyleSheet, Text } from "react-native";
|
|
|
3
3
|
import { moderateScale, verticalScale } from "react-native-size-matters";
|
|
4
4
|
import { useColors } from "../hooks";
|
|
5
5
|
import { TypographyProps } from "../types";
|
|
6
|
+
import { getConfig } from "../config/KeyManager";
|
|
6
7
|
|
|
7
8
|
const Typography: React.FC<TypographyProps> = forwardRef(
|
|
8
9
|
(
|
|
@@ -17,6 +18,7 @@ const Typography: React.FC<TypographyProps> = forwardRef(
|
|
|
17
18
|
numberOfLines,
|
|
18
19
|
adjustsFontSizeToFit,
|
|
19
20
|
fontWeight = 400,
|
|
21
|
+
fontFamily, // NEW PROP ADDED
|
|
20
22
|
...props
|
|
21
23
|
},
|
|
22
24
|
ref
|
|
@@ -33,6 +35,7 @@ const Typography: React.FC<TypographyProps> = forwardRef(
|
|
|
33
35
|
body2: moderateScale(12),
|
|
34
36
|
caption: moderateScale(10),
|
|
35
37
|
};
|
|
38
|
+
|
|
36
39
|
const styles: any = StyleSheet.create({
|
|
37
40
|
text: {
|
|
38
41
|
fontSize: fontSize[variant],
|
|
@@ -42,14 +45,16 @@ const Typography: React.FC<TypographyProps> = forwardRef(
|
|
|
42
45
|
alignItems: "center",
|
|
43
46
|
textAlign: align,
|
|
44
47
|
fontWeight: fontWeight.toString(),
|
|
48
|
+
fontFamily: fontFamily || getConfig().DEFAULT_FONT_FAMILY || "System", // Use custom font if provided, else default
|
|
45
49
|
},
|
|
46
50
|
});
|
|
51
|
+
|
|
47
52
|
return (
|
|
48
53
|
<Text
|
|
49
54
|
ref={ref as any}
|
|
50
55
|
numberOfLines={numberOfLines}
|
|
51
56
|
adjustsFontSizeToFit={adjustsFontSizeToFit}
|
|
52
|
-
style={
|
|
57
|
+
style={[styles.text, style]} // Ensures external styles are applied
|
|
53
58
|
{...props}
|
|
54
59
|
>
|
|
55
60
|
{children}
|
package/src/config/KeyManager.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
type
|
|
1
|
+
type configTypes = {
|
|
2
2
|
GOOGLE_MAP_API_KEY?: string;
|
|
3
|
+
DEFAULT_FONT_FAMILY?: string;
|
|
3
4
|
};
|
|
4
5
|
|
|
5
|
-
let
|
|
6
|
+
let config: configTypes = {
|
|
6
7
|
GOOGLE_MAP_API_KEY: "",
|
|
7
8
|
};
|
|
8
9
|
|
|
9
|
-
export function
|
|
10
|
-
|
|
10
|
+
export function setConfig(key: configTypes): void {
|
|
11
|
+
config = key;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
export function
|
|
14
|
-
return
|
|
14
|
+
export function getConfig(): configTypes {
|
|
15
|
+
return config;
|
|
15
16
|
}
|
package/src/config/index.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
// import * as fs from "fs";
|
|
2
2
|
import { setExtraColors } from "../theme/colors";
|
|
3
3
|
import { extraColorTypes } from "../types";
|
|
4
|
-
import {
|
|
4
|
+
import { setConfig } from "./KeyManager";
|
|
5
5
|
|
|
6
6
|
type configProps = {
|
|
7
7
|
googleMapApiKey?: string;
|
|
8
8
|
colors?: extraColorTypes;
|
|
9
|
+
fontFamily?: string;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
export function initialize(config: configProps): void {
|
|
12
13
|
try {
|
|
13
|
-
|
|
14
|
+
setConfig({
|
|
14
15
|
GOOGLE_MAP_API_KEY: config.googleMapApiKey,
|
|
16
|
+
DEFAULT_FONT_FAMILY: config.fontFamily,
|
|
15
17
|
});
|
|
16
18
|
if (config.colors) setExtraColors(config.colors);
|
|
17
19
|
} catch (error) {
|
package/src/types.ts
CHANGED
|
@@ -2,7 +2,9 @@ import { ReactNode } from "react";
|
|
|
2
2
|
import {
|
|
3
3
|
NativeScrollEvent,
|
|
4
4
|
NativeSyntheticEvent,
|
|
5
|
+
Text,
|
|
5
6
|
TextInputProps,
|
|
7
|
+
TextProps,
|
|
6
8
|
TextStyle,
|
|
7
9
|
ViewStyle,
|
|
8
10
|
} from "react-native";
|
|
@@ -252,7 +254,7 @@ export interface TextFieldProps extends TextInputProps {
|
|
|
252
254
|
onBlur?: () => void;
|
|
253
255
|
}
|
|
254
256
|
|
|
255
|
-
export interface TypographyProps {
|
|
257
|
+
export interface TypographyProps extends TextProps {
|
|
256
258
|
children: ReactNode;
|
|
257
259
|
color?: colorTypes | (string & {});
|
|
258
260
|
style?: TextStyle | ViewStyle;
|
|
@@ -271,6 +273,7 @@ export interface TypographyProps {
|
|
|
271
273
|
gutterBottom?: number;
|
|
272
274
|
numberOfLines?: number;
|
|
273
275
|
adjustsFontSizeToFit?: boolean;
|
|
276
|
+
fontFamily?: string;
|
|
274
277
|
fontWeight?: 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
|
|
275
278
|
}
|
|
276
279
|
|