@hoddy-ui/core 2.0.0 → 2.0.36
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/README.md +60 -12
- package/next/dist/index.d.mts +113 -41
- package/next/dist/index.d.ts +113 -41
- package/next/dist/index.js +444 -297
- package/next/dist/index.js.map +1 -1
- package/next/dist/index.mjs +460 -307
- package/next/dist/index.mjs.map +1 -1
- package/next/package.json +4 -3
- package/package.json +2 -2
- package/src/Components/AlertX.tsx +4 -4
- package/src/Components/Animators/hooks/useFadeAnimation.ts +1 -3
- package/src/Components/Animators/hooks/useFloatAnimation.ts +9 -9
- package/src/Components/Animators/hooks/useGrowAnimation.ts +5 -4
- package/src/Components/Animators/hooks/useRollAnimation.ts +10 -6
- package/src/Components/Animators/hooks/useSlideAnimation.ts +5 -8
- package/src/Components/Animators/hooks/useThrownUpAnimation.ts +9 -12
- package/src/Components/Avatar.tsx +13 -7
- package/src/Components/Button.tsx +13 -12
- package/src/Components/FlashMessage.tsx +119 -42
- package/src/Components/FormWrapper.tsx +7 -2
- package/src/Components/Grid.tsx +5 -5
- package/src/Components/Locator.tsx +10 -2
- package/src/Components/Popup.tsx +95 -34
- package/src/Components/SafeAreaView.tsx +11 -11
- package/src/Components/SelectMenu.tsx +34 -52
- package/src/Components/TextField.tsx +16 -6
- package/src/Components/Typography.tsx +19 -16
- package/src/config/KeyManager.ts +6 -1
- package/src/config/index.ts +37 -2
- package/src/hooks.ts +21 -14
- package/src/theme/index.tsx +14 -6
- package/src/types.ts +10 -4
- package/src/utility.ts +11 -0
|
@@ -15,6 +15,7 @@ import Typography from "./Typography";
|
|
|
15
15
|
export type predictionType = {
|
|
16
16
|
id: string;
|
|
17
17
|
description: string;
|
|
18
|
+
types: string[];
|
|
18
19
|
};
|
|
19
20
|
export const getPredictionsFromCoords = async (coords: {
|
|
20
21
|
latitude: number;
|
|
@@ -36,10 +37,15 @@ export const getPredictionsFromCoords = async (coords: {
|
|
|
36
37
|
const p = [];
|
|
37
38
|
|
|
38
39
|
for (let key in res.results) {
|
|
39
|
-
const {
|
|
40
|
+
const {
|
|
41
|
+
formatted_address: description,
|
|
42
|
+
place_id,
|
|
43
|
+
types,
|
|
44
|
+
} = res.results[key];
|
|
40
45
|
p.push({
|
|
41
46
|
description,
|
|
42
47
|
id: place_id,
|
|
48
|
+
types,
|
|
43
49
|
latLng: { lst: coords.latitude, lng: coords.longitude },
|
|
44
50
|
});
|
|
45
51
|
}
|
|
@@ -57,10 +63,11 @@ export const getPredictionsFromQuery = async (
|
|
|
57
63
|
|
|
58
64
|
const p = [];
|
|
59
65
|
for (let key in res.predictions) {
|
|
60
|
-
const { description, place_id } = res.predictions[key];
|
|
66
|
+
const { description, place_id, types } = res.predictions[key];
|
|
61
67
|
p.push({
|
|
62
68
|
description,
|
|
63
69
|
id: place_id,
|
|
70
|
+
types,
|
|
64
71
|
});
|
|
65
72
|
}
|
|
66
73
|
return p;
|
|
@@ -115,6 +122,7 @@ export const Locator: React.FC<LocatorProps> = ({
|
|
|
115
122
|
shadowRadius: float ? 15 : 0,
|
|
116
123
|
shadowOffset: {
|
|
117
124
|
height: 10,
|
|
125
|
+
width: 0,
|
|
118
126
|
},
|
|
119
127
|
borderRadius: 10,
|
|
120
128
|
marginBottom: 10,
|
package/src/Components/Popup.tsx
CHANGED
|
@@ -11,12 +11,16 @@ import {
|
|
|
11
11
|
|
|
12
12
|
import React, { useEffect, useState } from "react";
|
|
13
13
|
import Animated, {
|
|
14
|
+
CurvedTransition,
|
|
15
|
+
LinearTransition,
|
|
14
16
|
runOnJS,
|
|
17
|
+
SequencedTransition,
|
|
15
18
|
useAnimatedStyle,
|
|
16
19
|
useSharedValue,
|
|
17
20
|
withTiming,
|
|
18
21
|
} from "react-native-reanimated";
|
|
19
|
-
import {
|
|
22
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
23
|
+
import { ms, ScaledSheet } from "react-native-size-matters";
|
|
20
24
|
import { useColors, useTheme } from "../hooks";
|
|
21
25
|
import { UIThemeProvider } from "../theme";
|
|
22
26
|
import { PopupProps } from "../types";
|
|
@@ -25,7 +29,7 @@ import Typography from "./Typography";
|
|
|
25
29
|
|
|
26
30
|
export const Popup: React.FC<PopupProps> = ({
|
|
27
31
|
title,
|
|
28
|
-
sheet,
|
|
32
|
+
sheet = true,
|
|
29
33
|
bare = false,
|
|
30
34
|
keyboardVerticalOffset,
|
|
31
35
|
children,
|
|
@@ -34,34 +38,69 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
34
38
|
style,
|
|
35
39
|
onModalShow,
|
|
36
40
|
onModalHide,
|
|
41
|
+
disableAutoKeyboardManagement = false,
|
|
37
42
|
}) => {
|
|
38
43
|
const theme = useTheme();
|
|
39
44
|
const colors = useColors();
|
|
40
45
|
const [modalVisible, setModalVisible] = useState(false);
|
|
46
|
+
const [modalOpen, setModalOpen] = useState(false);
|
|
47
|
+
const [keyboardVisible, setKeyboardVisible] = useState(false);
|
|
48
|
+
const { bottom } = useSafeAreaInsets();
|
|
41
49
|
|
|
42
50
|
// Animation values
|
|
43
51
|
const backdropOpacity = useSharedValue(0);
|
|
44
52
|
const contentTranslateY = useSharedValue(1000);
|
|
45
53
|
|
|
54
|
+
// Memoized keyboard vertical offset based on platform and keyboard state
|
|
55
|
+
const keyboardVerticalOffsetValue =
|
|
56
|
+
Platform.OS === "ios" ? -bottom : -bottom * 2;
|
|
57
|
+
|
|
58
|
+
// Keyboard event listeners
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const keyboardDidShowListener = Keyboard.addListener(
|
|
61
|
+
"keyboardDidShow",
|
|
62
|
+
() => {
|
|
63
|
+
setKeyboardVisible(true);
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
const keyboardDidHideListener = Keyboard.addListener(
|
|
67
|
+
"keyboardDidHide",
|
|
68
|
+
() => {
|
|
69
|
+
setKeyboardVisible(false);
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return () => {
|
|
74
|
+
keyboardDidHideListener?.remove();
|
|
75
|
+
keyboardDidShowListener?.remove();
|
|
76
|
+
};
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
const _onModalShow = () => {
|
|
80
|
+
setModalVisible(true);
|
|
81
|
+
onModalShow?.();
|
|
82
|
+
};
|
|
83
|
+
const _onModalHide = () => {
|
|
84
|
+
onModalHide?.();
|
|
85
|
+
setModalOpen(false);
|
|
86
|
+
};
|
|
87
|
+
|
|
46
88
|
// Trigger animations when open prop changes
|
|
47
89
|
useEffect(() => {
|
|
48
90
|
if (open) {
|
|
49
|
-
|
|
91
|
+
setModalOpen(true);
|
|
50
92
|
// Opening animation
|
|
51
93
|
backdropOpacity.value = withTiming(1, { duration: 300 });
|
|
52
94
|
contentTranslateY.value = withTiming(0, { duration: 300 }, () => {
|
|
53
|
-
|
|
54
|
-
runOnJS(onModalShow)();
|
|
55
|
-
}
|
|
95
|
+
runOnJS(_onModalShow)();
|
|
56
96
|
});
|
|
57
97
|
} else {
|
|
58
98
|
// Closing animation
|
|
99
|
+
setModalVisible(false);
|
|
100
|
+
|
|
59
101
|
backdropOpacity.value = withTiming(0, { duration: 200 });
|
|
60
102
|
contentTranslateY.value = withTiming(1000, { duration: 200 }, () => {
|
|
61
|
-
runOnJS(
|
|
62
|
-
if (onModalHide) {
|
|
63
|
-
runOnJS(onModalHide)();
|
|
64
|
-
}
|
|
103
|
+
runOnJS(_onModalHide)();
|
|
65
104
|
});
|
|
66
105
|
}
|
|
67
106
|
}, [open]);
|
|
@@ -81,22 +120,28 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
81
120
|
width: "100%",
|
|
82
121
|
justifyContent: sheet ? "flex-end" : "center",
|
|
83
122
|
},
|
|
123
|
+
keyboardView: {
|
|
124
|
+
flex: 1,
|
|
125
|
+
zIndex: 1000,
|
|
126
|
+
},
|
|
84
127
|
avoidingView: {
|
|
128
|
+
zIndex: 2,
|
|
85
129
|
minHeight: typeof sheet === "number" ? sheet : undefined,
|
|
86
|
-
maxHeight: "
|
|
87
|
-
zIndex: 1000,
|
|
130
|
+
maxHeight: "90%",
|
|
88
131
|
alignSelf: "center",
|
|
89
132
|
maxWidth: sheet ? undefined : "90%",
|
|
90
133
|
width: sheet ? "100%" : undefined,
|
|
134
|
+
marginBottom: Platform.OS === "android" && keyboardVisible ? bottom : 0,
|
|
91
135
|
},
|
|
92
136
|
container: {
|
|
93
|
-
paddingBottom: sheet ?
|
|
94
|
-
backgroundColor: theme === "dark" ? "#111" : colors.white[
|
|
137
|
+
paddingBottom: sheet && !bare ? bottom + ms(10) : undefined,
|
|
138
|
+
backgroundColor: theme === "dark" ? "#111" : colors.white[1],
|
|
95
139
|
borderTopLeftRadius: 20,
|
|
96
140
|
borderTopRightRadius: 20,
|
|
97
141
|
borderBottomRightRadius: sheet ? 0 : 20,
|
|
98
142
|
borderBottomLeftRadius: sheet ? 0 : 20,
|
|
99
143
|
width: "100%",
|
|
144
|
+
overflow: "hidden",
|
|
100
145
|
...style,
|
|
101
146
|
},
|
|
102
147
|
content: {
|
|
@@ -115,7 +160,7 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
115
160
|
backdrop: {
|
|
116
161
|
position: "absolute",
|
|
117
162
|
height: "100%",
|
|
118
|
-
zIndex:
|
|
163
|
+
zIndex: 1,
|
|
119
164
|
width: "100%",
|
|
120
165
|
backgroundColor: "#000b",
|
|
121
166
|
},
|
|
@@ -130,24 +175,40 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
130
175
|
transparent
|
|
131
176
|
animationType="none"
|
|
132
177
|
statusBarTranslucent
|
|
133
|
-
visible={
|
|
178
|
+
visible={modalOpen}
|
|
134
179
|
onRequestClose={closeAction}
|
|
135
180
|
>
|
|
136
|
-
<Animated.View style={[styles.backdrop, backdropAnimatedStyle]} />
|
|
137
181
|
<UIThemeProvider>
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
182
|
+
<Animated.View style={[styles.backdrop, backdropAnimatedStyle]} />
|
|
183
|
+
<KeyboardAvoidingView
|
|
184
|
+
style={styles.keyboardView}
|
|
185
|
+
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
|
186
|
+
keyboardVerticalOffset={
|
|
187
|
+
keyboardVerticalOffset || keyboardVerticalOffsetValue
|
|
188
|
+
}
|
|
189
|
+
>
|
|
190
|
+
<TouchableWithoutFeedback
|
|
191
|
+
onPress={Keyboard.dismiss}
|
|
192
|
+
disabled={disableAutoKeyboardManagement}
|
|
193
|
+
>
|
|
194
|
+
<View style={styles.root}>
|
|
195
|
+
{modalOpen && (
|
|
196
|
+
<Pressable
|
|
197
|
+
style={[StyleSheet.absoluteFill, { zIndex: 1 }]}
|
|
198
|
+
onPress={closeAction}
|
|
199
|
+
/>
|
|
200
|
+
)}
|
|
201
|
+
|
|
202
|
+
<Animated.View
|
|
203
|
+
style={[styles.avoidingView, contentAnimatedStyle]}
|
|
204
|
+
layout={
|
|
205
|
+
modalVisible
|
|
206
|
+
? LinearTransition.springify()
|
|
207
|
+
.stiffness(200)
|
|
208
|
+
.mass(0.5)
|
|
209
|
+
.damping(100)
|
|
210
|
+
: undefined
|
|
211
|
+
}
|
|
151
212
|
>
|
|
152
213
|
<View style={styles.container}>
|
|
153
214
|
{!bare && (
|
|
@@ -167,10 +228,10 @@ export const Popup: React.FC<PopupProps> = ({
|
|
|
167
228
|
|
|
168
229
|
<View style={styles.content}>{children}</View>
|
|
169
230
|
</View>
|
|
170
|
-
</
|
|
171
|
-
</
|
|
172
|
-
</
|
|
173
|
-
</
|
|
231
|
+
</Animated.View>
|
|
232
|
+
</View>
|
|
233
|
+
</TouchableWithoutFeedback>
|
|
234
|
+
</KeyboardAvoidingView>
|
|
174
235
|
</UIThemeProvider>
|
|
175
236
|
</Modal>
|
|
176
237
|
);
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { SafeAreaView as Safe } from "react-native";
|
|
2
1
|
import React from "react";
|
|
2
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { moderateScale } from "react-native-size-matters";
|
|
4
|
+
import { StyleSheet, View } from "react-native";
|
|
6
5
|
import { SafeAreaViewProps } from "../types";
|
|
7
6
|
|
|
8
|
-
const styles = StyleSheet.create({
|
|
9
|
-
droidSafeArea: {
|
|
10
|
-
flex: 1,
|
|
11
|
-
paddingTop: Platform.OS === "android" ? moderateScale(35) : 0,
|
|
12
|
-
},
|
|
13
|
-
});
|
|
14
|
-
|
|
15
7
|
export const SafeAreaView: React.FC<SafeAreaViewProps> = ({
|
|
16
8
|
children,
|
|
17
9
|
style,
|
|
18
10
|
}) => {
|
|
19
|
-
|
|
11
|
+
const { top, bottom } = useSafeAreaInsets();
|
|
12
|
+
const styles = StyleSheet.create({
|
|
13
|
+
root: {
|
|
14
|
+
paddingTop: top,
|
|
15
|
+
paddingBottom: bottom,
|
|
16
|
+
flex: 1,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
return <View style={[styles.root, style]}>{children}</View>;
|
|
20
20
|
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { MaterialIcons } from "@expo/vector-icons";
|
|
2
2
|
import React, { useCallback, useState } from "react";
|
|
3
|
-
import { FlatList,
|
|
3
|
+
import { FlatList, TouchableOpacity, View } from "react-native";
|
|
4
4
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
5
5
|
import { ScaledSheet } from "react-native-size-matters";
|
|
6
6
|
import { useColors } from "../hooks";
|
|
7
7
|
import { SelectMenuProps } from "../types";
|
|
8
|
-
import
|
|
8
|
+
import { Popup } from "./Popup";
|
|
9
9
|
import TextField from "./TextField";
|
|
10
10
|
import Typography from "./Typography";
|
|
11
11
|
|
|
@@ -19,22 +19,15 @@ const SelectMenu: React.FC<SelectMenuProps> = ({
|
|
|
19
19
|
label,
|
|
20
20
|
secondary,
|
|
21
21
|
helperText,
|
|
22
|
+
searchEnabled = false,
|
|
23
|
+
searchPlaceholder = "Search",
|
|
22
24
|
}) => {
|
|
23
25
|
const colors = useColors();
|
|
24
26
|
const { bottom } = useSafeAreaInsets();
|
|
25
27
|
|
|
26
28
|
const [search, setSearch] = useState("");
|
|
27
29
|
const styles: any = ScaledSheet.create({
|
|
28
|
-
root: {
|
|
29
|
-
backgroundColor: colors.white[1],
|
|
30
|
-
flex: 1,
|
|
31
|
-
},
|
|
32
|
-
content: {
|
|
33
|
-
flex: 1,
|
|
34
|
-
paddingHorizontal: "10@ms",
|
|
35
|
-
},
|
|
36
30
|
header: {
|
|
37
|
-
paddingTop: "80@ms",
|
|
38
31
|
marginBottom: "20@vs",
|
|
39
32
|
},
|
|
40
33
|
|
|
@@ -46,11 +39,6 @@ const SelectMenu: React.FC<SelectMenuProps> = ({
|
|
|
46
39
|
alignItems: "center",
|
|
47
40
|
marginBottom: "10@vs",
|
|
48
41
|
},
|
|
49
|
-
footer: {
|
|
50
|
-
paddingBottom: bottom,
|
|
51
|
-
paddingHorizontal: "15@ms",
|
|
52
|
-
paddingTop: "15@ms",
|
|
53
|
-
},
|
|
54
42
|
});
|
|
55
43
|
|
|
56
44
|
const renderItem = useCallback(
|
|
@@ -70,6 +58,7 @@ const SelectMenu: React.FC<SelectMenuProps> = ({
|
|
|
70
58
|
{item.start && <View style={{ marginRight: 10 }}>{item.start}</View>}
|
|
71
59
|
<View style={{ flex: 1 }}>
|
|
72
60
|
<Typography
|
|
61
|
+
variant="body2"
|
|
73
62
|
style={{
|
|
74
63
|
color: item.value === value ? colors.blue.light : colors.black[2],
|
|
75
64
|
}}
|
|
@@ -102,51 +91,44 @@ const SelectMenu: React.FC<SelectMenuProps> = ({
|
|
|
102
91
|
[value, colors]
|
|
103
92
|
);
|
|
104
93
|
return (
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
<Popup
|
|
95
|
+
open={open}
|
|
96
|
+
onClose={onClose}
|
|
97
|
+
title={label}
|
|
98
|
+
disableAutoKeyboardManagement
|
|
99
|
+
>
|
|
100
|
+
<View style={styles.content}>
|
|
101
|
+
<View style={styles.header}>
|
|
102
|
+
{helperText && (
|
|
103
|
+
<Typography variant="body2" color="textSecondary" gutterBottom={5}>
|
|
104
|
+
{helperText}
|
|
111
105
|
</Typography>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
{helperText}
|
|
115
|
-
</Typography>
|
|
116
|
-
) : null}
|
|
117
|
-
|
|
106
|
+
)}
|
|
107
|
+
{searchEnabled && (
|
|
118
108
|
<TextField
|
|
119
|
-
label=
|
|
109
|
+
label={searchPlaceholder}
|
|
120
110
|
value={search}
|
|
121
111
|
type="search"
|
|
122
112
|
onChangeText={setSearch}
|
|
123
113
|
variant="outlined"
|
|
124
114
|
/>
|
|
125
|
-
|
|
126
|
-
<FlatList
|
|
127
|
-
removeClippedSubviews
|
|
128
|
-
keyExtractor={(item) => item.value}
|
|
129
|
-
renderItem={renderItem}
|
|
130
|
-
data={options
|
|
131
|
-
.filter((item) =>
|
|
132
|
-
search.length > 1
|
|
133
|
-
? item.label.toLowerCase().indexOf(search.toLowerCase()) > -1
|
|
134
|
-
: item
|
|
135
|
-
)
|
|
136
|
-
.sort((a, b) => a.label.localeCompare(b.label))}
|
|
137
|
-
/>
|
|
138
|
-
</View>
|
|
139
|
-
<View style={styles.footer}>
|
|
140
|
-
<Button
|
|
141
|
-
color="error"
|
|
142
|
-
variant="outlined"
|
|
143
|
-
fullWidth
|
|
144
|
-
title="Close"
|
|
145
|
-
onPress={onClose}
|
|
146
|
-
/>
|
|
115
|
+
)}
|
|
147
116
|
</View>
|
|
117
|
+
<FlatList
|
|
118
|
+
removeClippedSubviews
|
|
119
|
+
keyExtractor={(item) => item.value}
|
|
120
|
+
bounces={false}
|
|
121
|
+
renderItem={renderItem}
|
|
122
|
+
data={options
|
|
123
|
+
.filter((item) =>
|
|
124
|
+
search.length > 1
|
|
125
|
+
? item.label.toLowerCase().indexOf(search.toLowerCase()) > -1
|
|
126
|
+
: item
|
|
127
|
+
)
|
|
128
|
+
.sort((a, b) => a.label.localeCompare(b.label))}
|
|
129
|
+
/>
|
|
148
130
|
</View>
|
|
149
|
-
</
|
|
131
|
+
</Popup>
|
|
150
132
|
);
|
|
151
133
|
};
|
|
152
134
|
|
|
@@ -7,9 +7,9 @@ import {
|
|
|
7
7
|
ms,
|
|
8
8
|
verticalScale,
|
|
9
9
|
} from "react-native-size-matters";
|
|
10
|
-
import { getConfig } from "../config/KeyManager";
|
|
11
10
|
import { useColors } from "../hooks";
|
|
12
11
|
import { TextFieldProps } from "../types";
|
|
12
|
+
import { getFontFamily } from "../utility";
|
|
13
13
|
import SelectMenu from "./SelectMenu";
|
|
14
14
|
import Typography from "./Typography";
|
|
15
15
|
|
|
@@ -35,6 +35,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
35
35
|
gutterBottom = 0,
|
|
36
36
|
end,
|
|
37
37
|
options,
|
|
38
|
+
selectMenuProps,
|
|
38
39
|
...props
|
|
39
40
|
}) => {
|
|
40
41
|
const colors = useColors();
|
|
@@ -64,7 +65,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
64
65
|
}, [focused, value]);
|
|
65
66
|
const styles: any = ScaledSheet.create({
|
|
66
67
|
root: {
|
|
67
|
-
marginBottom: gutterBottom
|
|
68
|
+
marginBottom: ms(gutterBottom),
|
|
68
69
|
width: "100%",
|
|
69
70
|
...style,
|
|
70
71
|
},
|
|
@@ -98,7 +99,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
98
99
|
paddingLeft: variant === "text" ? 0 : moderateScale(15),
|
|
99
100
|
paddingRight: moderateScale(10),
|
|
100
101
|
paddingTop: "11@vs",
|
|
101
|
-
fontFamily:
|
|
102
|
+
fontFamily: getFontFamily(400),
|
|
102
103
|
color: colors.black[1],
|
|
103
104
|
zIndex: 10,
|
|
104
105
|
// backgroundColor: "#284",
|
|
@@ -110,7 +111,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
110
111
|
paddingTop: "13@ms",
|
|
111
112
|
},
|
|
112
113
|
label: {
|
|
113
|
-
fontFamily:
|
|
114
|
+
fontFamily: getFontFamily(400),
|
|
114
115
|
position: "absolute",
|
|
115
116
|
left: variant === "text" ? 0 : moderateScale(15),
|
|
116
117
|
fontSize: focused || value ? "10@s" : "13@s",
|
|
@@ -269,6 +270,7 @@ const TextField: React.FC<TextFieldProps> = ({
|
|
|
269
270
|
label={label}
|
|
270
271
|
helperText={helperText}
|
|
271
272
|
onChange={onChangeText!}
|
|
273
|
+
{...selectMenuProps}
|
|
272
274
|
/>
|
|
273
275
|
)}
|
|
274
276
|
</>
|
|
@@ -279,6 +281,7 @@ export const TextField2 = React.forwardRef<TextInput, TextFieldProps>(
|
|
|
279
281
|
(
|
|
280
282
|
{
|
|
281
283
|
label,
|
|
284
|
+
labelProps,
|
|
282
285
|
keyboardType,
|
|
283
286
|
color = "primary",
|
|
284
287
|
value,
|
|
@@ -299,6 +302,7 @@ export const TextField2 = React.forwardRef<TextInput, TextFieldProps>(
|
|
|
299
302
|
end,
|
|
300
303
|
options,
|
|
301
304
|
multiline,
|
|
305
|
+
selectMenuProps,
|
|
302
306
|
...props
|
|
303
307
|
},
|
|
304
308
|
ref
|
|
@@ -317,7 +321,7 @@ export const TextField2 = React.forwardRef<TextInput, TextFieldProps>(
|
|
|
317
321
|
|
|
318
322
|
const styles: any = ScaledSheet.create({
|
|
319
323
|
root: {
|
|
320
|
-
marginBottom: gutterBottom
|
|
324
|
+
marginBottom: ms(gutterBottom),
|
|
321
325
|
...style,
|
|
322
326
|
},
|
|
323
327
|
container: {
|
|
@@ -409,7 +413,12 @@ export const TextField2 = React.forwardRef<TextInput, TextFieldProps>(
|
|
|
409
413
|
<>
|
|
410
414
|
<View style={styles.root}>
|
|
411
415
|
{label && (
|
|
412
|
-
<Typography
|
|
416
|
+
<Typography
|
|
417
|
+
variant="body2"
|
|
418
|
+
color="textSecondary"
|
|
419
|
+
gutterBottom={7}
|
|
420
|
+
{...labelProps}
|
|
421
|
+
>
|
|
413
422
|
{label}
|
|
414
423
|
</Typography>
|
|
415
424
|
)}
|
|
@@ -509,6 +518,7 @@ export const TextField2 = React.forwardRef<TextInput, TextFieldProps>(
|
|
|
509
518
|
label={label}
|
|
510
519
|
helperText={helperText}
|
|
511
520
|
onChange={onChangeText!}
|
|
521
|
+
{...selectMenuProps}
|
|
512
522
|
/>
|
|
513
523
|
)}
|
|
514
524
|
</>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React, { forwardRef } from "react";
|
|
2
2
|
import { StyleSheet, Text } from "react-native";
|
|
3
|
-
import { moderateScale, verticalScale } from "react-native-size-matters";
|
|
3
|
+
import { moderateScale, ms, verticalScale } from "react-native-size-matters";
|
|
4
4
|
import { useColors } from "../hooks";
|
|
5
5
|
import { TypographyProps } from "../types";
|
|
6
6
|
import { getConfig } from "../config/KeyManager";
|
|
7
|
+
import { getFontFamily } from "../utility";
|
|
7
8
|
|
|
8
9
|
const Typography: React.FC<TypographyProps> = forwardRef(
|
|
9
10
|
(
|
|
@@ -11,40 +12,42 @@ const Typography: React.FC<TypographyProps> = forwardRef(
|
|
|
11
12
|
children,
|
|
12
13
|
color = "dark",
|
|
13
14
|
style = {},
|
|
14
|
-
textCase
|
|
15
|
+
textCase,
|
|
15
16
|
variant = "body1",
|
|
16
17
|
align = "left",
|
|
17
18
|
gutterBottom = 0,
|
|
18
19
|
adjustsFontSizeToFit,
|
|
19
20
|
fontWeight = 400,
|
|
20
21
|
fontFamily, // NEW PROP ADDED
|
|
22
|
+
fontSize,
|
|
21
23
|
...props
|
|
22
24
|
},
|
|
23
25
|
ref
|
|
24
26
|
) => {
|
|
25
27
|
const colors: any = useColors();
|
|
26
|
-
const
|
|
27
|
-
h1:
|
|
28
|
-
h2:
|
|
29
|
-
h3:
|
|
30
|
-
h4:
|
|
31
|
-
h5:
|
|
32
|
-
h6:
|
|
33
|
-
body1:
|
|
34
|
-
body2:
|
|
35
|
-
caption:
|
|
28
|
+
const _fontSize = {
|
|
29
|
+
h1: ms(42),
|
|
30
|
+
h2: ms(37),
|
|
31
|
+
h3: ms(32),
|
|
32
|
+
h4: ms(27),
|
|
33
|
+
h5: ms(22),
|
|
34
|
+
h6: ms(17),
|
|
35
|
+
body1: ms(15),
|
|
36
|
+
body2: ms(12),
|
|
37
|
+
caption: ms(10),
|
|
36
38
|
};
|
|
37
|
-
|
|
39
|
+
const f = fontSize || _fontSize[variant];
|
|
38
40
|
const styles: any = StyleSheet.create({
|
|
39
41
|
text: {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
lineHeight: f * 1.2,
|
|
43
|
+
fontSize: f,
|
|
44
|
+
marginBottom: ms(gutterBottom) || 0,
|
|
42
45
|
color: colors[color]?.main || color,
|
|
43
46
|
textTransform: textCase,
|
|
44
47
|
alignItems: "center",
|
|
45
48
|
textAlign: align,
|
|
46
49
|
fontWeight: fontWeight,
|
|
47
|
-
fontFamily: fontFamily ||
|
|
50
|
+
fontFamily: fontFamily || getFontFamily(fontWeight),
|
|
48
51
|
},
|
|
49
52
|
});
|
|
50
53
|
|
package/src/config/KeyManager.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
type configTypes = {
|
|
2
2
|
GOOGLE_MAP_API_KEY?: string;
|
|
3
|
-
|
|
3
|
+
TYPOGRAPHY?: {
|
|
4
|
+
fontFamily?: string;
|
|
5
|
+
fontWeights?: {
|
|
6
|
+
[K in 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900]?: string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
4
9
|
EDGE_TO_EDGE?: boolean;
|
|
5
10
|
};
|
|
6
11
|
|
package/src/config/index.ts
CHANGED
|
@@ -3,18 +3,53 @@ import { setExtraColors } from "../theme/colors";
|
|
|
3
3
|
import { extraColorTypes } from "../types";
|
|
4
4
|
import { setConfig } from "./KeyManager";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Configuration options for the Hoddy UI library
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* initialize({
|
|
12
|
+
* googleMapApiKey: "AIzaSyBxxxxxxxxxxxxxxxxxxxxxx",
|
|
13
|
+
* edgeToEdge: true,
|
|
14
|
+
* colors: {
|
|
15
|
+
* primary: "#007AFF",
|
|
16
|
+
* secondary: "#34C759"
|
|
17
|
+
* },
|
|
18
|
+
* typography: {
|
|
19
|
+
* fontFamily: "Inter",
|
|
20
|
+
* fontWeights: {
|
|
21
|
+
* 400: "Inter-Regular",
|
|
22
|
+
* 500: "Inter-Medium",
|
|
23
|
+
* 600: "Inter-SemiBold",
|
|
24
|
+
* 700: "Inter-Bold"
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
6
30
|
type configProps = {
|
|
31
|
+
/** Google Maps API key for map components */
|
|
7
32
|
googleMapApiKey?: string;
|
|
33
|
+
/** Custom color palette overrides */
|
|
8
34
|
colors?: extraColorTypes;
|
|
9
|
-
|
|
35
|
+
/** Enable edge-to-edge display mode */
|
|
10
36
|
edgeToEdge?: boolean;
|
|
37
|
+
/** Typography settings */
|
|
38
|
+
typography?: {
|
|
39
|
+
/** Primary font family */
|
|
40
|
+
fontFamily?: string;
|
|
41
|
+
/** Font family mappings for each weight (Android support) */
|
|
42
|
+
fontWeights?: {
|
|
43
|
+
[K in 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900]?: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
11
46
|
};
|
|
12
47
|
|
|
13
48
|
export function initialize(config: configProps): void {
|
|
14
49
|
try {
|
|
15
50
|
setConfig({
|
|
16
51
|
GOOGLE_MAP_API_KEY: config.googleMapApiKey,
|
|
17
|
-
|
|
52
|
+
TYPOGRAPHY: config.typography,
|
|
18
53
|
EDGE_TO_EDGE: config.edgeToEdge ?? false,
|
|
19
54
|
});
|
|
20
55
|
if (config.colors) setExtraColors(config.colors);
|