@hoddy-ui/core 1.0.88 → 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.
@@ -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 { getApiKey } from "../config/KeyManager";
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 } = getApiKey();
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 } = getApiKey();
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, useState } from "react";
2
- import { TextInput, View } from "react-native";
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]}
@@ -75,15 +75,22 @@ export const Popup: React.FC<PopupProps> = ({
75
75
  });
76
76
 
77
77
  React.useEffect(() => {
78
- setShow(open);
79
- setTimeout(() => {
80
- setShowSecondary(open);
81
- }, 500);
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
- setShow(false);
86
- onClose();
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, { startTransition, useRef, useState } from "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 && <View style={{ marginRight: 20 }}>{end}</View>}
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 style={{ marginRight: 20 }}>
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}
@@ -260,7 +278,6 @@ const TextField: React.FC<TextFieldProps> = ({
260
278
  export const TextField2: React.FC<TextFieldProps> = ({
261
279
  label,
262
280
  keyboardType,
263
- variant,
264
281
  color = "primary",
265
282
  value,
266
283
  type,
@@ -284,33 +301,15 @@ export const TextField2: React.FC<TextFieldProps> = ({
284
301
  const colors = useColors();
285
302
  const [focused, _setFocused] = useState(false);
286
303
  const [showPassword, setShowPassword] = useState(false);
287
- const labelAnim = useRef(new Animated.Value(0)).current;
288
304
 
289
305
  const height = moderateScale(
290
306
  props.multiline ? 50 + (props.numberOfLines || 1) * 18 : 50
291
307
  );
292
308
 
293
309
  const setFocused = (value: boolean) => {
294
- startTransition(() => {
295
- _setFocused(value);
296
- });
310
+ _setFocused(value);
297
311
  };
298
312
 
299
- React.useEffect(() => {
300
- if (focused || value) {
301
- Animated.timing(labelAnim, {
302
- toValue: verticalScale(5),
303
- duration: 300,
304
- useNativeDriver: false,
305
- }).start();
306
- } else {
307
- Animated.timing(labelAnim, {
308
- toValue: height / moderateScale(3),
309
- duration: 300,
310
- useNativeDriver: false,
311
- }).start();
312
- }
313
- }, [focused, value]);
314
313
  const styles: any = ScaledSheet.create({
315
314
  root: {
316
315
  marginBottom: gutterBottom + "@vs",
@@ -337,13 +336,13 @@ export const TextField2: React.FC<TextFieldProps> = ({
337
336
  alignSelf: "stretch",
338
337
  paddingLeft: moderateScale(10),
339
338
  paddingRight: moderateScale(10),
340
- color: colors.dark.light,
339
+ color: colors.dark.main,
341
340
  zIndex: 10,
342
341
  // backgroundColor: "#284",
343
342
  },
344
343
  inputText: {
345
344
  fontSize: "14@ms",
346
- color: colors.dark.light,
345
+ color: colors.dark.main,
347
346
  paddingLeft: moderateScale(10),
348
347
  },
349
348
  placeholder: {
@@ -1,54 +1,66 @@
1
- import React from "react";
2
- import { Text, StyleSheet } from "react-native";
3
- import { moderateScale, scale, verticalScale } from "react-native-size-matters";
1
+ import React, { forwardRef } from "react";
2
+ import { StyleSheet, Text } from "react-native";
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
- const Typography: React.FC<TypographyProps> = ({
8
- children,
9
- color = "dark",
10
- style = {},
11
- textCase = null,
12
- variant = "body1",
13
- align = "left",
14
- gutterBottom = 0,
15
- numberOfLines,
16
- adjustsFontSizeToFit,
17
- fontWeight = 400,
18
- }) => {
19
- const colors: any = useColors();
20
- const fontSize = {
21
- h1: moderateScale(42),
22
- h2: moderateScale(37),
23
- h3: moderateScale(32),
24
- h4: moderateScale(27),
25
- h5: moderateScale(22),
26
- h6: moderateScale(17),
27
- body1: moderateScale(15),
28
- body2: moderateScale(12),
29
- caption: moderateScale(10),
30
- };
31
- const styles: any = StyleSheet.create({
32
- text: {
33
- fontSize: fontSize[variant],
34
- marginBottom: verticalScale(gutterBottom) || 0,
35
- color: colors[color]?.main || color,
36
- textTransform: textCase,
37
- alignItems: "center",
38
- textAlign: align,
39
- fontWeight: fontWeight.toString(),
8
+ const Typography: React.FC<TypographyProps> = forwardRef(
9
+ (
10
+ {
11
+ children,
12
+ color = "dark",
13
+ style = {},
14
+ textCase = null,
15
+ variant = "body1",
16
+ align = "left",
17
+ gutterBottom = 0,
18
+ numberOfLines,
19
+ adjustsFontSizeToFit,
20
+ fontWeight = 400,
21
+ fontFamily, // NEW PROP ADDED
22
+ ...props
40
23
  },
41
- });
42
- return (
43
- <Text
44
- numberOfLines={numberOfLines}
45
- adjustsFontSizeToFit={adjustsFontSizeToFit}
46
- style={{ ...styles.text, ...style }}
47
- >
48
- {children}
49
- </Text>
50
- );
51
- };
24
+ ref
25
+ ) => {
26
+ const colors: any = useColors();
27
+ const fontSize = {
28
+ h1: moderateScale(42),
29
+ h2: moderateScale(37),
30
+ h3: moderateScale(32),
31
+ h4: moderateScale(27),
32
+ h5: moderateScale(22),
33
+ h6: moderateScale(17),
34
+ body1: moderateScale(15),
35
+ body2: moderateScale(12),
36
+ caption: moderateScale(10),
37
+ };
38
+
39
+ const styles: any = StyleSheet.create({
40
+ text: {
41
+ fontSize: fontSize[variant],
42
+ marginBottom: verticalScale(gutterBottom) || 0,
43
+ color: colors[color]?.main || color,
44
+ textTransform: textCase,
45
+ alignItems: "center",
46
+ textAlign: align,
47
+ fontWeight: fontWeight.toString(),
48
+ fontFamily: fontFamily || getConfig().DEFAULT_FONT_FAMILY || "System", // Use custom font if provided, else default
49
+ },
50
+ });
51
+
52
+ return (
53
+ <Text
54
+ ref={ref as any}
55
+ numberOfLines={numberOfLines}
56
+ adjustsFontSizeToFit={adjustsFontSizeToFit}
57
+ style={[styles.text, style]} // Ensures external styles are applied
58
+ {...props}
59
+ >
60
+ {children}
61
+ </Text>
62
+ );
63
+ }
64
+ );
52
65
 
53
- <Typography color="#f90">col</Typography>;
54
66
  export default Typography;
@@ -1,15 +1,16 @@
1
- type apikeys = {
1
+ type configTypes = {
2
2
  GOOGLE_MAP_API_KEY?: string;
3
+ DEFAULT_FONT_FAMILY?: string;
3
4
  };
4
5
 
5
- let apiKey: apikeys = {
6
+ let config: configTypes = {
6
7
  GOOGLE_MAP_API_KEY: "",
7
8
  };
8
9
 
9
- export function setApiKey(key: apikeys): void {
10
- apiKey = key;
10
+ export function setConfig(key: configTypes): void {
11
+ config = key;
11
12
  }
12
13
 
13
- export function getApiKey(): apikeys {
14
- return apiKey;
14
+ export function getConfig(): configTypes {
15
+ return config;
15
16
  }
@@ -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 { setApiKey } from "./KeyManager";
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
- setApiKey({
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