Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 2x 7x 7x 7x 2x 7x | import React, { forwardRef } from "react";
import {
Text,
TextInput as RNTextInput,
TextInputProps,
View,
} from "react-native";
import { makeStyles } from "@repo/ui/themes/makeStyles";
import { useTheme } from "@repo/ui/themes/ThemeContext";
type InputProps = TextInputProps & {
leftIcon?: React.ReactNode;
label?: string;
errorMessage?: string;
disabled?: boolean;
testID?: string;
};
export const Input = forwardRef<RNTextInput, InputProps>(
(
{ leftIcon, label, errorMessage, value, disabled = false, testID, ...rest },
ref,
) => {
const { theme } = useTheme();
const styles = useStyles();
return (
<View style={styles.container}>
{label && <Text style={styles.label}>{label}</Text>}
<View
style={[styles.inputWrapper, disabled && styles.inputWrapperDisabled]}
>
{leftIcon && (
<View style={[styles.leftIcon, disabled && styles.iconDisabled]}>
{leftIcon}
</View>
)}
<RNTextInput
ref={ref}
style={[styles.input, disabled && styles.inputDisabled]}
placeholderTextColor={theme.colors.text.tertiary}
value={value}
editable={!disabled}
accessibilityLabel={
rest.accessibilityLabel || label || "Input field"
}
testID={testID}
{...rest}
/>
</View>
{errorMessage && (
<Text style={styles.errorMessage} accessibilityLiveRegion="polite">
{errorMessage}
</Text>
)}
</View>
);
},
);
Input.displayName = "Input";
const useStyles = makeStyles((theme) => ({
container: {
marginVertical: theme.metrics.spacing[2],
},
label: {
marginBottom: theme.metrics.spacing[1],
fontSize: theme.metrics.textSize[14],
fontWeight: theme.metrics.fontWeight.medium,
color: theme.colors.text.info,
},
inputWrapper: {
position: "relative",
flexDirection: "row",
alignItems: "center",
borderWidth: theme.metrics.borderWidth.default,
borderColor: theme.colors.border.tertiary,
borderRadius: theme.metrics.borderRadius[1],
height: theme.metrics.spacing[12.5],
paddingHorizontal: theme.metrics.spacing[4],
backgroundColor: theme.colors.background.default,
},
leftIcon: {
marginRight: theme.metrics.spacing[2],
},
input: {
flex: 1,
fontSize: theme.metrics.textSize[16],
borderWidth: theme.metrics.borderWidth[0],
color: theme.colors.text.default,
backgroundColor: "transparent",
},
errorMessage: {
position: "absolute",
bottom: -18,
fontSize: theme.metrics.textSize[12],
color: theme.colors.text.error,
},
inputWrapperDisabled: {
backgroundColor: theme.colors.background.disabled,
borderColor: theme.colors.border.disabled,
},
inputDisabled: {
color: theme.colors.text.tertiary,
},
iconDisabled: {
opacity: theme.metrics.opacity[40],
},
}));
|