127 lines
2.8 KiB
TypeScript
127 lines
2.8 KiB
TypeScript
import React from "react";
|
|
import {
|
|
StyleSheet,
|
|
View,
|
|
Text,
|
|
TextInput,
|
|
TouchableOpacity,
|
|
TextInputProps,
|
|
} from "react-native";
|
|
import {Ionicons, IoniconsIconName} from "@react-native-vector-icons/ionicons";
|
|
import colors from "../colors";
|
|
|
|
// --- Custom Input ---
|
|
type CustomInputProps = TextInputProps & {
|
|
label?: string;
|
|
icon?: IoniconsIconName;
|
|
error?:string
|
|
};
|
|
|
|
const CustomInput: React.FC<CustomInputProps> = ({
|
|
label,
|
|
icon,
|
|
style,
|
|
error,
|
|
...rest
|
|
}) => {
|
|
return (
|
|
<View style={styles.inputContainer}>
|
|
{label ? <Text style={styles.inputLabel}>{label}</Text> : null}
|
|
<View style={styles.inputWrapper}>
|
|
{icon && <Ionicons name={icon} size={20} color={colors.textDark} style={styles.inputIcon} />}
|
|
<TextInput
|
|
style={[styles.input, icon && { paddingLeft: 36 }, style]}
|
|
placeholderTextColor={colors.textLight}
|
|
{...rest}
|
|
/>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
// --- Custom Button ---
|
|
type CustomButtonProps = {
|
|
title: string;
|
|
onPress: () => void;
|
|
type?: "primary" | "secondary" | "danger";
|
|
icon?: IoniconsIconName;
|
|
style?: object;
|
|
buttonBackground?: string;
|
|
};
|
|
|
|
const CustomButton: React.FC<CustomButtonProps> = ({
|
|
title,
|
|
onPress,
|
|
type = "primary",
|
|
icon,
|
|
style = {},
|
|
buttonBackground,
|
|
}) => {
|
|
const backgroundColor =
|
|
buttonBackground ??
|
|
(type === "secondary"
|
|
? colors.pastelBlue
|
|
: type === "danger"
|
|
? colors.pastelOrange
|
|
: colors.primary);
|
|
|
|
const textColor = type === "secondary" ? colors.textDark : '#000';
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
style={[styles.button, { backgroundColor }, style]}
|
|
onPress={onPress}
|
|
activeOpacity={0.8}
|
|
>
|
|
<View style={styles.buttonContent}>
|
|
{icon && <Ionicons name={icon} size={20} color={textColor} style={{ marginRight: 8 }} />}
|
|
<Text style={[styles.buttonText, { color: textColor }]}>{title}</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|
|
|
|
// --- Styles ---
|
|
const styles = StyleSheet.create({
|
|
inputContainer: { marginBottom: 12 },
|
|
inputLabel: { fontSize: 14, fontWeight: "500", color: colors.textDark, marginBottom: 6 },
|
|
inputWrapper: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
position: "relative",
|
|
},
|
|
inputIcon: {
|
|
position: "absolute",
|
|
left: 10,
|
|
zIndex: 1,
|
|
},
|
|
input: {
|
|
flex: 1,
|
|
borderWidth: 1,
|
|
borderColor: colors.textLight,
|
|
borderRadius: 10,
|
|
padding: 12,
|
|
paddingLeft: 12,
|
|
backgroundColor: colors.white,
|
|
color: colors.textDark,
|
|
fontSize: 15,
|
|
},
|
|
button: {
|
|
paddingVertical: 12,
|
|
borderRadius: 12,
|
|
alignItems: "center",
|
|
marginVertical: 6,
|
|
},
|
|
buttonContent: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
},
|
|
buttonText: {
|
|
fontSize: 16,
|
|
fontWeight: "600",
|
|
},
|
|
});
|
|
|
|
export { CustomInput, CustomButton, styles };
|