UNPKG

react-pin-input

Version:
134 lines (118 loc) 3.18 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; const styles = { input: { padding: 0, margin: '0 2px', textAlign: 'center', border: '1px solid', background: 'transparent', width: '50px', height: '50px', }, inputFocus: { outline: 'none', boxShadow: 'none', }, }; /** */ class PinItem extends Component { constructor(props) { super(props); this.state = { value: '', focus: false, }; this.onChange = this.onChange.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onFocus = this.onFocus.bind(this); this.onBlur = this.onBlur.bind(this); } onKeyDown(e) { if (e.keyCode === 8 && (!this.state.value || !this.state.value.length)) { this.props.onBackspace(); } } clear() { this.setState({ value: '' }); } onChange(e) { const value = this.validate(e.target.value); if (this.state.value === value) return; if (value.length < 2) { this.setState({value}); // timeout is to make sure that clearing happens after value is set // this is done beacause the setState callback was not triggering in react@15.2.4 setTimeout(() => { this.props.onChange(value); }, 0); } } focus() { this .input .focus(); } onFocus(e) { e.target.select(); this.setState({ focus: true }); } onBlur() { this.setState({ focus: false }); } validate(value) { if(this.props.validate) { return this.props.validate(value); } if(this.props.type === 'numeric') { const numCode = value.charCodeAt(0); const isInteger = numCode >= '0'.charCodeAt(0) && numCode <= '9'.charCodeAt(0); return isInteger ? value : ''; } return value.toUpperCase(); } render() { const { focus, value } = this.state; const { type, inputMode, inputStyle, inputFocusStyle } = this.props; const inputType = this.props.type === 'numeric' ? 'tel' : (this.props.type || 'text'); return (<input className='pincode-input-text' onChange={ this.onChange } onKeyDown={ this.onKeyDown } maxLength='1' autoComplete='off' type={ this.props.secret ? 'password' : inputType } pattern={ this.props.type === 'numeric' ? '[0-9]*' : '[A-Z0-9]*' } ref={ n => (this.input = n) } onFocus={ this.onFocus } onBlur={ this.onBlur } style={ Object.assign( {}, styles.input, inputStyle, focus ? Object.assign({}, styles.inputFocus, inputFocusStyle) : {}, ) } value={ value } />); } } PinItem.propTypes = { onChange: PropTypes.func.isRequired, onBackspace: PropTypes.func.isRequired, secret: PropTypes.bool, type: PropTypes.string, inputMode: PropTypes.string, validate: PropTypes.func, inputStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types inputFocusStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types }; PinItem.defaultProps = { secret: false, type: 'numeric', inputMode: undefined, validate: undefined, }; export default PinItem;