react-pin-input
Version:
React component for PIN like input
119 lines (103 loc) • 2.83 kB
JSX
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import PinItem from './PinItem';
/**
*/
class PinInput extends Component {
constructor(props) {
super(props);
// this.props.secret = this.props.secret || false;
// TODO: better way to create array
this.values = new Array(props.length)
.join('0')
.split('0');
this.elements = [];
this.currentIndex = 0;
}
componentDidMount() {
// Setting focus on the first element
if(this.props.focus && this.props.length) this.elements[0].focus();
}
clear() {
this.elements.forEach(e => e.clear());
this.values = this.values.map(() => undefined)
this.elements[0].focus();
}
focus() {
if(this.props.length) this.elements[0].focus();
}
/**
*/
onItemChange(value, index) {
const { length, onComplete, onChange } = this.props;
let currentIndex = index;
this.values[index] = value;
// Set focus on next
if (value.length === 1 && index < length - 1) {
currentIndex += 1;
this
.elements[currentIndex]
.focus();
}
// Notify the parent
const pin = this
.values
.join('');
onChange(pin, currentIndex);
if (pin.length === length) {
onComplete(pin, currentIndex);
}
}
onBackspace(index) {
if (index > 0) {
this.elements[index - 1].focus();
}
}
render() {
return (
<div style={this.props.style} className='pincode-input-container'>
{this
.values
.map((e, i) => <PinItem
ref={ n => (this.elements[i] = n) }
key={ i }
onBackspace={ () => this.onBackspace(i) }
secret={ this.props.secret || false }
onChange={ v => this.onItemChange(v, i) }
type={ this.props.type }
inputMode={ this.props.inputMode }
validate={ this.props.validate }
inputStyle={ this.props.inputStyle }
inputFocusStyle={ this.props.inputFocusStyle }
/>)
}
</div>
);
}
}
PinInput.propTypes = {
length: PropTypes.number.isRequired,
type: PropTypes.string,
onComplete: PropTypes.func,
validate: PropTypes.func,
secret: PropTypes.bool,
focus: PropTypes.bool,
onChange: PropTypes.func,
inputMode: PropTypes.string,
style: PropTypes.object, // eslint-disable-line react/forbid-prop-types
inputStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types
inputFocusStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types
};
PinInput.defaultProps = {
type: 'numeric',
secret: false,
validate: null,
focus: false,
onChange: () => {},
onComplete: () => {},
inputMode: undefined,
style: {},
inputStyle: {},
inputFocusStyle: {},
};
export default PinInput;