@fruits-chain/react-native-xiaoshu
Version:
React Native UI library
164 lines (145 loc) • 6.54 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useState, useRef, useCallback, useImperativeHandle, memo, forwardRef } from 'react';
import { View, TextInput as RNTextInput, Platform } from 'react-native';
import IconSvgCross from '../icon/cross';
import { useTheme } from '../theme';
import { usePersistFn, useUpdateEffect } from '../hooks';
import { getDefaultValue, renderTextLikeJSX, noop, isValue, isDef } from '../helpers';
import { createStyles } from './style';
const defaultFormatter = t => t;
const TextInputBase = /*#__PURE__*/forwardRef((_ref, ref) => {
let {
fixGroupStyle,
prefixTextStyle,
suffixTextStyle,
clearable = false,
clearTrigger = 'focus',
formatter,
formatTrigger = 'onChangeText',
prefix,
suffix,
size = 'middle',
bordered = false,
textInputHeight,
// TextInput 的属性
value,
defaultValue,
style,
onChangeText,
onEndEditing,
onFocus,
onBlur,
...resetProps
} = _ref;
const onChangeTextPersistFn = usePersistFn(onChangeText || noop);
const onEndEditingPersistFn = usePersistFn(onEndEditing || noop);
const onFocusPersistFn = usePersistFn(onFocus || noop);
const onBlurPersistFn = usePersistFn(onBlur || noop);
const formatterPersistFn = usePersistFn(formatter || defaultFormatter);
const [localValue, setLocalValue] = useState(isValue(value) ? value : defaultValue);
const [focus, setFocus] = useState(false);
const TextInputRef = useRef(null);
const THEME_VAR = useTheme();
const STYLES = createStyles(THEME_VAR); // 转发实例
useImperativeHandle(ref, () => TextInputRef.current); // 同步外部的数据
useUpdateEffect(() => {
setLocalValue(value);
}, [value]);
/** 显示禁用样子 bordered 才显示 */
const showDisabledInput = bordered && isDef(resetProps.editable) && !resetProps.editable;
/** 输入框最小高度 */
const textInputMinHeight = THEME_VAR[`text_input_${size}_min_height`] || THEME_VAR.text_input_middle_min_height;
/** 所有文字/文案相关的大小 */
const textInputFontSize = THEME_VAR[`text_input_${size}_font_size`] || THEME_VAR.text_input_middle_font_size; // 修正数据
resetProps.selectionColor = getDefaultValue(resetProps.selectionColor, THEME_VAR.text_input_selection_color);
resetProps.placeholderTextColor = getDefaultValue(resetProps.placeholderTextColor, THEME_VAR.text_input_placeholder_text_color);
resetProps.returnKeyType = getDefaultValue(resetProps.returnKeyType, 'done');
/**
* 点击清除按钮
* @description 目前不能在输入框聚焦的时候触发点击,输入框失去焦点后才能触发点击,可能是软键盘的问题?
*/
const onPressClearable = useCallback(() => {
var _TextInputRef$current, _TextInputRef$current2;
(_TextInputRef$current = TextInputRef.current) === null || _TextInputRef$current === void 0 ? void 0 : _TextInputRef$current.clear();
setLocalValue('');
onChangeTextPersistFn('');
(_TextInputRef$current2 = TextInputRef.current) === null || _TextInputRef$current2 === void 0 ? void 0 : _TextInputRef$current2.focus();
}, [onChangeTextPersistFn]);
/**
* 当文字变化
* @description 在这个阶段判断字符长度、格式化数据
*/
const onChangeTextTextInput = useCallback(t => {
if (typeof resetProps.maxLength === 'number' && t.length > resetProps.maxLength) {
t = t.slice(0, resetProps.maxLength);
}
if (formatTrigger === 'onChangeText') {
t = formatterPersistFn(t);
}
setLocalValue(t || undefined);
onChangeTextPersistFn(t);
}, [resetProps.maxLength, formatTrigger, formatterPersistFn, onChangeTextPersistFn]);
/**
* 编辑结束的时候
*/
const onEndEditingTextInput = useCallback(e => {
if (formatTrigger === 'onEndEditing') {
e.nativeEvent.text = formatterPersistFn(e.nativeEvent.text);
}
setLocalValue(e.nativeEvent.text);
onEndEditingPersistFn(e);
}, [onEndEditingPersistFn, formatterPersistFn, formatTrigger]);
/**
* 输入框聚焦
*/
const onFocusTextInput = useCallback(e => {
setFocus(true);
onFocusPersistFn(e);
}, [onFocusPersistFn]);
/**
* 输入框失焦
*/
const onBlurTextInput = useCallback(e => {
setFocus(false);
onBlurPersistFn(e);
}, [onBlurPersistFn]);
/** 输入框不确定是否要排除边框 */
const inputUncertainHeight = bordered ? 2 : 0;
const textInputTextStyle = {
fontSize: textInputFontSize
};
const textFixGroupStyle = [STYLES.fix_group, bordered ? STYLES.fix_group_border : null, fixGroupStyle, showDisabledInput ? STYLES.fix_group_disabled : null];
const textInputStyle = [STYLES.text_input, {
height: textInputMinHeight - inputUncertainHeight,
paddingVertical: (textInputMinHeight - inputUncertainHeight - 22) / 2
}, isDef(textInputHeight) ? Platform.select({
android: {
height: textInputHeight - inputUncertainHeight
},
ios: {
paddingVertical: (textInputHeight - (textInputMinHeight - inputUncertainHeight)) / 2
}
}) : null, style // showDisabledInput ? STYLES.text_input_disabled : null,
];
const prefixJSX = renderTextLikeJSX(prefix, [STYLES.fix_text, STYLES.fix_text_pre, textInputTextStyle, prefixTextStyle]);
const suffixJSX = renderTextLikeJSX(suffix, [STYLES.fix_text, STYLES.fix_text_suf, textInputTextStyle, suffixTextStyle]);
return /*#__PURE__*/React.createElement(View, {
style: textFixGroupStyle
}, prefixJSX, /*#__PURE__*/React.createElement(RNTextInput, _extends({}, resetProps, {
ref: TextInputRef,
style: textInputStyle,
value: isValue(value) ? value : localValue,
defaultValue: defaultValue,
onChangeText: onChangeTextTextInput,
onEndEditing: onEndEditingTextInput,
onFocus: onFocusTextInput,
onBlur: onBlurTextInput
})), clearable && (clearTrigger === 'focus' ? focus : true) && localValue && localValue.length ? /*#__PURE__*/React.createElement(IconSvgCross, {
style: STYLES.clearable,
color: THEME_VAR.text_input_clearable_color,
size: THEME_VAR.text_input_clearable_size / 4 * 3,
onPress: onPressClearable
}) : null, suffixJSX);
});
export default /*#__PURE__*/memo(TextInputBase);
//# sourceMappingURL=index.js.map