RN的NumberInput组件

2021-07-28  本文已影响0人  斡旋_ASL
import React from 'react';
import {StyleSheet, TextInput, TextInputProps, TextStyle} from 'react-native';

interface Props extends Omit<TextInputProps, 'value'> {
  style?: TextStyle;
  min?: number;
  max?: number;
  value?: string;
  onChangeValue: (value?: string) => any;
  minus?: boolean;
  decimal?: boolean;
}
export default function (props: Props) {
  const {decimal = false, minus = false} = props;
  const {style, value = '', onChangeValue, min, max, ...other} = props;

  function onChangeText(val: string) {
    // 没有输入值直接返回
    if (!val) {
      onChangeValue('');
      return;
    }
    // 不能输入小数
    if (!decimal && val.includes('.')) {
      onChangeValue(val.indexOf('.') > 0 ? value : '');
      return;
    }
    // 不能输入负数
    if (!minus && val.includes('-')) {
      onChangeValue('');
      return;
    }
    // 能输入小数但是输入的规则不对
    let boo =
      val.includes('.') &&
      (val.indexOf('.') == 0 || val.replace('.', '').length != val.length - 1);
    if (decimal && boo) {
      onChangeValue(value);
      return;
    }
    // 能输入负数但是输入的规则不对
    boo =
      val.includes('-') &&
      (val.indexOf('-') > 0 || val.replace('-', '').length != val.length - 1);
    if (minus && boo) {
      onChangeValue('');
      return;
    }
    // 能输入负数切只输入了-符号时
    if (val == '-') {
      onChangeValue(val);
      return;
    }
    let v = Number(val);
    // 没有最大值和最小值限制
    if (min == null && max == null) {
      onChangeValue(val);
      return;
    }
    // 最大值和最小值都有
    if (min != null && max != null && v <= max && min <= v) {
      onChangeValue(val);
      return;
    }
    // 只有最小值
    if (min != null && v < min) {
      onChangeValue(value);
      return;
    }
    // 只有最大值
    if (max != null && max <= v) {
      onChangeValue(value);
      return;
    }
  }

  return (
    <TextInput
      {...other}
      style={[st.input, style]}
      keyboardType="numeric"
      value={String(value)}
      onChangeText={onChangeText}
    />
  );
}

const st = StyleSheet.create({
  input: {},
});

上一篇 下一篇

猜你喜欢

热点阅读