import React, { useState, useEffect } from 'react' import { ScrollView, View, Text, TextInput, TextStyle, ViewStyle, StyleProp, StyleSheet, TouchableWithoutFeedback, TextInputProps } from 'react-native'; import { FieldRefType } from '../types' import Icon from '../Icon' import renderNode from '../helpers/renderNode' /** * todo 要怎么定义字体大小? * todo 报错了 React.ComponentPropsWithRef & */ interface Props extends TextInputProps { type?: string, disabled?: boolean; disabledInputStyle?: StyleProp; label?: string; // todo 字体大小 这个字段是否需要 我认为label只需要简单提供就好了 所以不用太精细 labelFontSize?: number, labelStyle?: StyleProp; style?: StyleProp; rightIcon?: string | React.ReactElement<{}> onRightIconClick?: () => void; clearable?: boolean; clearIcon?: string,//清除图标的icon name clearIconColor?: string//清除图标的icon 颜色 onInput?: (value: string) => void border?: boolean//是否显示边框 borderStyle?: StyleProp; maxlength?: number showWordLimit?: boolean //是否显示字数统计 fieldStyle?: StyleProp; } type TextInputHandles = FieldRefType const Field = React.forwardRef(({ onRightIconClick, clearable, style, type, border = true, ...rest }: Props, ref) => { /** * 传递ref节点添加方法 */ const root = React.useRef(null); React.useImperativeHandle(ref, () => { const input = root.current; if (input) { return { focus: () => input.focus(), clear: () => input.clear(), // setNativeProps: (args: TextInputProps) => input.setNativeProps(args), isFocused: () => input.isFocused(), blur: () => input.blur(), }; } const noop = () => { throw new Error('TextInput is not available'); }; return { focus: noop, clear: noop, blur: noop, isFocused: noop }; }); const clearableHandel = () => { rest?.onInput && rest?.onInput("") root.current?.clear() } /** * [Props]type * 输入框形态 * 软键盘形态 */ const keyboardType = (type === 'number' ? 'numeric' : 'default') return ( {rest.label && ( {rest.label}: ) } {clearable && ( )} {rest.rightIcon && ( {renderNode(Icon, rest.rightIcon)} ) } { (rest.showWordLimit && rest.maxlength) && {rest.value?.length}/{rest.maxlength} } {/* 自定义右边内容 */} ) }) const styles = StyleSheet.create({ container: { width: "100%", flexDirection: 'row', alignItems: 'center', padding: 8, backgroundColor: '#fff', position: "relative", }, inputMain: { flexDirection: 'row', alignItems: 'center', flex: 1, paddingLeft: 8, paddingRight: 8, }, border: { borderWidth: 1, borderColor: "#ccc", borderRadius: 6, }, input: { flex: 1, fontSize: 16, minHeight: 40, }, textarea: { minHeight: 80, textAlignVertical: 'top' }, disabledInput: { opacity: 0.5, }, showWordLimit: { position: "absolute", right: 12, bottom: 0 } }); export default Field