import React from 'react'; import { TextInput as RNTextInput, View, Text, StyleSheet, ViewStyle, TextInputProps } from 'react-native'; import { spacing, radius, typography, componentSizes, type ThemePalette } from '../theme/tokens'; import { useColors } from '../theme/colors'; interface InputProps extends TextInputProps { label?: string; error?: string; containerStyle?: ViewStyle; leftIcon?: React.ReactNode; rightIcon?: React.ReactNode; } /** * Matches webmail input.tsx: * - h-10 w-full rounded-md border border-input bg-background * - px-3 py-2 text-sm text-foreground * - placeholder:text-muted-foreground * - hover:border-muted-foreground * - focus:ring-2 ring-ring border-ring * - disabled:opacity-50 */ export default function Input({ label, error, containerStyle, leftIcon, rightIcon, style, ...props }: InputProps) { const c = useColors(); const styles = React.useMemo(() => makeStyles(c), [c]); const [focused, setFocused] = React.useState(false); return ( {label && {label}} {leftIcon && {leftIcon}} { setFocused(true); props.onFocus?.(e); }} onBlur={(e) => { setFocused(false); props.onBlur?.(e); }} /> {rightIcon && {rightIcon}} {error && {error}} ); } function makeStyles(c: ThemePalette) { return StyleSheet.create({ label: { ...typography.bodyMedium, color: c.textSecondary, marginBottom: spacing.sm, }, inputWrapper: { flexDirection: 'row', alignItems: 'center', height: componentSizes.inputHeight, // h-10 = 40px borderWidth: 1, borderColor: c.border, // border-input borderRadius: radius.sm, // rounded-md = 6px backgroundColor: c.background, // bg-background paddingHorizontal: spacing.md, // px-3 = 12px }, inputFocused: { borderColor: c.borderFocus, // border-ring (blue-500) borderWidth: 2, }, inputError: { borderColor: c.error, }, inputDisabled: { opacity: 0.5, }, input: { flex: 1, ...typography.body, // text-sm = 14px color: c.text, // text-foreground paddingVertical: 0, }, iconLeft: { marginRight: spacing.sm, }, iconRight: { marginLeft: spacing.sm, }, errorText: { ...typography.caption, color: c.error, marginTop: spacing.xs, }, }); }