You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.1 KiB
72 lines
2.1 KiB
import { useState } from 'react';
|
|
import { Ionicons } from '@expo/vector-icons';
|
|
import { Pressable, StyleSheet, TextInput, View } from 'react-native';
|
|
import { PASSWORD_MAX_LENGTH } from '../constants';
|
|
import { colors } from '../theme';
|
|
|
|
interface Props {
|
|
value: string;
|
|
onChangeText: (t: string) => void;
|
|
placeholder?: string;
|
|
/** 最大长度,默认取密码规则上限 */
|
|
maxLength?: number;
|
|
/** 失焦回调,供页面触发规则校验提示 */
|
|
onBlur?: () => void;
|
|
}
|
|
|
|
/**
|
|
* 密码输入行:下划线样式 + 明文切换(眼睛图标)+ 一键清空。
|
|
* 登录页、重置密码页、账号安全改密页共用,避免三处各写一份输入样式。
|
|
*/
|
|
export function PasswordField({
|
|
value,
|
|
onChangeText,
|
|
placeholder = '请输入密码',
|
|
maxLength = PASSWORD_MAX_LENGTH,
|
|
onBlur,
|
|
}: Props) {
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
return (
|
|
<>
|
|
<View style={styles.row}>
|
|
<TextInput
|
|
style={styles.input}
|
|
value={value}
|
|
onChangeText={onChangeText}
|
|
placeholder={placeholder}
|
|
placeholderTextColor={colors.textHint}
|
|
secureTextEntry={!visible}
|
|
autoCapitalize="none"
|
|
autoCorrect={false}
|
|
maxLength={maxLength}
|
|
onBlur={onBlur}
|
|
/>
|
|
{value.length > 0 ? (
|
|
<Pressable onPress={() => onChangeText('')} hitSlop={8}>
|
|
<Ionicons name="close-circle" size={18} color={colors.textDisabled} />
|
|
</Pressable>
|
|
) : null}
|
|
<Pressable onPress={() => setVisible((v) => !v)} hitSlop={8}>
|
|
<Ionicons
|
|
name={visible ? 'eye-off-outline' : 'eye-outline'}
|
|
size={20}
|
|
color={colors.textHint}
|
|
/>
|
|
</Pressable>
|
|
</View>
|
|
<View style={styles.underline} />
|
|
</>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
row: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
height: 56,
|
|
gap: 10,
|
|
},
|
|
input: { flex: 1, fontSize: 17, color: colors.textPrimary, padding: 0 },
|
|
underline: { height: 1, backgroundColor: colors.borderLight },
|
|
});
|
|
|