import classNames from 'classnames' import PropTypes, { InferProps } from 'prop-types' import React from 'react' import { Input, Label, Text, View } from '@tarojs/components' import { BaseEventOrig, ITouchEvent } from '@tarojs/components/types/common' import { InputProps } from '@tarojs/components/types/Input' import { AtInputProps, BlurEventDetail, ConfirmEventDetail, FocusEventDetail, InputEventDetail, KeyboardHeightEventDetail } from '../../../types/input' import '../../style/components/input.scss' import AtIcon from '../icon' type PickAtInputProps = Pick< AtInputProps, 'maxLength' | 'maxlength' | 'disabled' | 'password' > type GetInputPropsReturn = PickAtInputProps & Pick function getInputProps(props: AtInputProps): GetInputPropsReturn { const actualProps = { type: props.type, maxLength: props.maxLength || props.maxlength, disabled: props.disabled, password: false } switch (actualProps.type) { case 'phone': actualProps.type = 'number' actualProps.maxLength = 11 break case 'password': actualProps.type = 'text' actualProps.password = true break default: break } if (!props.disabled && !props.editable) { actualProps.disabled = true } return actualProps as GetInputPropsReturn } export default class AtInput extends React.Component { public static defaultProps: AtInputProps public static propTypes: InferProps // TODO: 有待考证是否为合理方式处理 #840 private inputClearing = false private handleInput = (event: BaseEventOrig): void => this.props.onChange(event.detail.value, event) private handleFocus = (event: BaseEventOrig): void => { if (typeof this.props.onFocus === 'function') { this.props.onFocus(event.detail.value, event) } } private handleBlur = (event: BaseEventOrig): void => { if (typeof this.props.onBlur === 'function') { this.props.onBlur(event.detail.value, event) } if (event.type === 'blur' && !this.inputClearing) { // fix # 583 AtInput 不触发 onChange 的问题 this.props.onChange( event.detail.value, event as BaseEventOrig ) } // 还原状态 this.inputClearing = false } private handleConfirm = (event: BaseEventOrig): void => { if (typeof this.props.onConfirm === 'function') { this.props.onConfirm(event.detail.value, event) } } private handleClick = (event: ITouchEvent): void => { if (!this.props.editable && typeof this.props.onClick === 'function') { this.props.onClick(event) } } private handleClearValue = (event: ITouchEvent): void => { this.inputClearing = true this.props.onChange('', event) } private handleKeyboardHeightChange = ( event: BaseEventOrig ): void => { if (typeof this.props.onKeyboardHeightChange === 'function') { this.props.onKeyboardHeightChange(event) } } private handleErrorClick = (event: ITouchEvent): void => { if (typeof this.props.onErrorClick === 'function') { this.props.onErrorClick(event) } } public render(): JSX.Element { const { className, customStyle, name, cursorSpacing, confirmType, cursor, selectionStart, selectionEnd, adjustPosition, border, title, error, clear, placeholder, placeholderStyle, placeholderClass, autoFocus, focus, value, required } = this.props const { type, maxLength, disabled, password } = getInputProps(this.props) const overlayCls = classNames('at-input__overlay', { 'at-input__overlay--hidden': !disabled }) const placeholderCls = classNames('placeholder', placeholderClass) const id = name && { id: name } return ( {title && ( {required && *} )} {clear && value && ( )} {error && ( )} {this.props.children} ) } } AtInput.defaultProps = { className: '', customStyle: {}, value: '', name: '', placeholder: '', placeholderStyle: '', placeholderClass: '', title: '', cursorSpacing: 50, confirmType: 'done', selectionStart: -1, selectionEnd: -1, adjustPosition: true, maxlength: 140, maxLength: 140, type: 'text', disabled: false, border: true, editable: true, error: false, clear: false, autoFocus: false, focus: false, required: false, // eslint-disable-next-line @typescript-eslint/no-empty-function onChange: (): void => {} } AtInput.propTypes = { className: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), customStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), name: PropTypes.string, placeholder: PropTypes.string, placeholderStyle: PropTypes.string, placeholderClass: PropTypes.string, title: PropTypes.string, confirmType: PropTypes.string, cursor: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), selectionStart: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), selectionEnd: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), adjustPosition: PropTypes.bool, cursorSpacing: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), maxlength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), maxLength: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), type: PropTypes.string, disabled: PropTypes.bool, border: PropTypes.bool, editable: PropTypes.bool, error: PropTypes.bool, clear: PropTypes.bool, autoFocus: PropTypes.bool, focus: PropTypes.bool, onChange: PropTypes.func, onFocus: PropTypes.func, onBlur: PropTypes.func, onConfirm: PropTypes.func, onErrorClick: PropTypes.func, onClick: PropTypes.func, required: PropTypes.bool }