@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hoddy-ui/next",
3
- "version": "2.0.16",
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.89",
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": "^13.0.0",
15
+ "@expo/vector-icons": ">=13.0.0",
16
16
  "@react-navigation/native": ">=6.1.7",
17
- "@types/react": "^18.2.6",
18
- "@types/react-native": "^0.72.0",
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": "^18.2.0",
23
+ "react": ">=18.2.0",
24
24
  "react-native": ">=0.71.8",
25
25
  "react-native-safe-area-context": ">=4.5.3",
26
- "typescript": "^5.0.4"
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 { 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}
@@ -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.light,
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.light,
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={{ ...styles.text, ...style }}
57
+ style={[styles.text, style]} // Ensures external styles are applied
53
58
  {...props}
54
59
  >
55
60
  {children}
@@ -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