From 3f08bf6b339c4321ebc6d036989197ad6c404dce Mon Sep 17 00:00:00 2001 From: Alexandre Stapenhorst Date: Wed, 24 Aug 2022 00:49:12 -0300 Subject: [PATCH 1/2] fix: fix deprecated ViewPropTypes message --- components/ConfirmationCodeInput.js | 3 ++- package.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/components/ConfirmationCodeInput.js b/components/ConfirmationCodeInput.js index 1d9f9b2..a43d944 100644 --- a/components/ConfirmationCodeInput.js +++ b/components/ConfirmationCodeInput.js @@ -1,6 +1,7 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import { View, TextInput, StyleSheet, Dimensions, ViewPropTypes } from 'react-native'; +import { View, TextInput, StyleSheet, Dimensions } from 'react-native'; +import { ViewPropTypes } from 'deprecated-react-native-prop-types' import _ from 'lodash'; // if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) diff --git a/package.json b/package.json index d7b2aa8..997c5ca 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ ], "dependencies": { "lodash": "^4.17.4", - "prop-types": "^15.5.10" + "prop-types": "^15.5.10", + "deprecated-react-native-prop-types": "^2.3.0" }, "homepage": "https://github.com/ttdung11t2/react-native-confirmation-code-input.git", "bugs": { From afb0afd35dc847cc1b4ddcd2310535c929ba94ed Mon Sep 17 00:00:00 2001 From: Alexandre Stapenhorst Date: Wed, 21 Sep 2022 22:53:54 -0300 Subject: [PATCH 2/2] fix: fixes textinput proptypes --- components/ConfirmationCodeInput.js | 246 +++++++++-------- .../src/components/ConfirmationCodeInput.js | 254 ++++++++++-------- 2 files changed, 280 insertions(+), 220 deletions(-) diff --git a/components/ConfirmationCodeInput.js b/components/ConfirmationCodeInput.js index a43d944..3c84611 100644 --- a/components/ConfirmationCodeInput.js +++ b/components/ConfirmationCodeInput.js @@ -1,11 +1,15 @@ -import React, {Component} from 'react'; -import PropTypes from 'prop-types'; -import { View, TextInput, StyleSheet, Dimensions } from 'react-native'; -import { ViewPropTypes } from 'deprecated-react-native-prop-types' -import _ from 'lodash'; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { View, TextInput, StyleSheet, Dimensions } from "react-native"; +import { + ViewPropTypes, + TextInputPropTypes, +} from "deprecated-react-native-prop-types"; +import _ from "lodash"; // if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) const viewPropTypes = ViewPropTypes || View.propTypes; +const textInputPropTypes = TextInputPropTypes || TextInput.propTypes; export default class ConfirmationCodeInput extends Component { static propTypes = { @@ -20,206 +24,217 @@ export default class ConfirmationCodeInput extends Component { inactiveColor: PropTypes.string, ignoreCase: PropTypes.bool, autoFocus: PropTypes.bool, - codeInputStyle: TextInput.propTypes.style, + codeInputStyle: textInputPropTypes.style, containerStyle: viewPropTypes.style, onFulfill: PropTypes.func, onCodeChange: PropTypes.func, }; - + static defaultProps = { codeLength: 5, - inputPosition: 'center', + inputPosition: "center", autoFocus: true, size: 40, - className: 'border-box', + className: "border-box", cellBorderWidth: 1, - activeColor: 'rgba(255, 255, 255, 1)', - inactiveColor: 'rgba(255, 255, 255, 0.2)', + activeColor: "rgba(255, 255, 255, 1)", + inactiveColor: "rgba(255, 255, 255, 0.2)", space: 8, - compareWithCode: '', + compareWithCode: "", ignoreCase: false, }; - + constructor(props) { super(props); - + this.state = { - codeArr: new Array(this.props.codeLength).fill(''), - currentIndex: 0 + codeArr: new Array(this.props.codeLength).fill(""), + currentIndex: 0, }; - + this.codeInputRefs = []; } - + componentDidMount() { const { compareWithCode, codeLength, inputPosition } = this.props; if (compareWithCode && compareWithCode.length !== codeLength) { - console.error("Invalid props: compareWith length is not equal to codeLength"); + console.error( + "Invalid props: compareWith length is not equal to codeLength" + ); } - - if (_.indexOf(['center', 'left', 'right', 'full-width'], inputPosition) === -1) { - console.error('Invalid input position. Must be in: center, left, right, full'); + + if ( + _.indexOf(["center", "left", "right", "full-width"], inputPosition) === -1 + ) { + console.error( + "Invalid input position. Must be in: center, left, right, full" + ); } } - + clear() { this.setState({ - codeArr: new Array(this.props.codeLength).fill(''), - currentIndex: 0 + codeArr: new Array(this.props.codeLength).fill(""), + currentIndex: 0, }); this._setFocus(0); } - + _setFocus(index) { this.codeInputRefs[index].focus(); } - + _blur(index) { this.codeInputRefs[index].blur(); } - + _onFocus(index) { let newCodeArr = _.clone(this.state.codeArr); - const currentEmptyIndex = _.findIndex(newCodeArr, c => !c); + const currentEmptyIndex = _.findIndex(newCodeArr, (c) => !c); if (currentEmptyIndex !== -1 && currentEmptyIndex < index) { return this._setFocus(currentEmptyIndex); } for (const i in newCodeArr) { if (i >= index) { - newCodeArr[i] = ''; + newCodeArr[i] = ""; } } - + this.setState({ codeArr: newCodeArr, - currentIndex: index - }) + currentIndex: index, + }); } - + _isMatchingCode(code, compareWithCode, ignoreCase = false) { if (ignoreCase) { return code.toLowerCase() == compareWithCode.toLowerCase(); } return code == compareWithCode; } - + _getContainerStyle(size, position) { switch (position) { - case 'left': + case "left": return { - justifyContent: 'flex-start', - height: size + justifyContent: "flex-start", + height: size, }; - case 'center': + case "center": return { - justifyContent: 'center', - height: size + justifyContent: "center", + height: size, }; - case 'right': + case "right": return { - justifyContent: 'flex-end', - height: size + justifyContent: "flex-end", + height: size, }; default: return { - justifyContent: 'space-between', - height: size - } + justifyContent: "space-between", + height: size, + }; } } - + _getInputSpaceStyle(space) { const { inputPosition } = this.props; switch (inputPosition) { - case 'left': + case "left": return { - marginRight: space + marginRight: space, }; - case 'center': + case "center": return { - marginRight: space/2, - marginLeft: space/2 + marginRight: space / 2, + marginLeft: space / 2, }; - case 'right': + case "right": return { - marginLeft: space + marginLeft: space, }; default: return { marginRight: 0, - marginLeft: 0 + marginLeft: 0, }; } } - + _getClassStyle(className, active) { const { cellBorderWidth, activeColor, inactiveColor, space } = this.props; let classStyle = { ...this._getInputSpaceStyle(space), - color: activeColor + color: activeColor, }; - + switch (className) { - case 'clear': + case "clear": return _.merge(classStyle, { borderWidth: 0 }); - case 'border-box': + case "border-box": return _.merge(classStyle, { borderWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-circle': + case "border-circle": return _.merge(classStyle, { borderWidth: cellBorderWidth, borderRadius: 50, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-b': + case "border-b": return _.merge(classStyle, { borderBottomWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor), + borderColor: active ? activeColor : inactiveColor, }); - case 'border-b-t': + case "border-b-t": return _.merge(classStyle, { borderTopWidth: cellBorderWidth, borderBottomWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-l-r': + case "border-l-r": return _.merge(classStyle, { borderLeftWidth: cellBorderWidth, borderRightWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); default: return className; } } - + _onKeyPress(e) { - if (e.nativeEvent.key === 'Backspace') { + if (e.nativeEvent.key === "Backspace") { const { currentIndex } = this.state; let newCodeArr = _.clone(this.state.codeArr); const nextIndex = currentIndex > 0 ? currentIndex - 1 : 0; for (const i in newCodeArr) { if (i >= nextIndex) { - newCodeArr[i] = ''; + newCodeArr[i] = ""; } } - this.props.onCodeChange(newCodeArr.join('')) + this.props.onCodeChange(newCodeArr.join("")); this._setFocus(nextIndex); } } - + _onInputCode(character, index) { - const { codeLength, onFulfill, compareWithCode, ignoreCase, onCodeChange } = this.props; + const { codeLength, onFulfill, compareWithCode, ignoreCase, onCodeChange } = + this.props; let newCodeArr = _.clone(this.state.codeArr); newCodeArr[index] = character; - + if (index == codeLength - 1) { - const code = newCodeArr.join(''); - + const code = newCodeArr.join(""); + if (compareWithCode) { - const isMatching = this._isMatchingCode(code, compareWithCode, ignoreCase); + const isMatching = this._isMatchingCode( + code, + compareWithCode, + ignoreCase + ); onFulfill(isMatching, code); !isMatching && this.clear(); } else { @@ -229,15 +244,20 @@ export default class ConfirmationCodeInput extends Component { } else { this._setFocus(this.state.currentIndex + 1); } - - this.setState(prevState => { - return { - codeArr: newCodeArr, - currentIndex: prevState.currentIndex + 1 - }; - }, () => { onCodeChange(newCodeArr.join('')) }); + + this.setState( + (prevState) => { + return { + codeArr: newCodeArr, + currentIndex: prevState.currentIndex + 1, + }; + }, + () => { + onCodeChange(newCodeArr.join("")); + } + ); } - + render() { const { codeLength, @@ -247,44 +267,52 @@ export default class ConfirmationCodeInput extends Component { autoFocus, className, size, - activeColor + activeColor, } = this.props; - + const initialCodeInputStyle = { width: size, - height: size + height: size, }; - + let codeInputs = []; for (let i = 0; i < codeLength; i++) { const id = i; codeInputs.push( (this.codeInputRefs[id] = ref)} + ref={(ref) => (this.codeInputRefs[id] = ref)} style={[ - styles.codeInput, - initialCodeInputStyle, + styles.codeInput, + initialCodeInputStyle, this._getClassStyle(className, this.state.currentIndex == id), - codeInputStyle + codeInputStyle, ]} underlineColorAndroid="transparent" selectionColor={activeColor} - keyboardType={'name-phone-pad'} - returnKeyType={'done'} + keyboardType={"name-phone-pad"} + returnKeyType={"done"} {...this.props} autoFocus={autoFocus && id == 0} onFocus={() => this._onFocus(id)} - value={this.state.codeArr[id] ? this.state.codeArr[id].toString() : ''} - onChangeText={text => this._onInputCode(text, id)} + value={ + this.state.codeArr[id] ? this.state.codeArr[id].toString() : "" + } + onChangeText={(text) => this._onInputCode(text, id)} onKeyPress={(e) => this._onKeyPress(e)} maxLength={1} /> - ) + ); } - + return ( - + {codeInputs} ); @@ -294,12 +322,12 @@ export default class ConfirmationCodeInput extends Component { const styles = StyleSheet.create({ container: { flex: 1, - flexDirection: 'row', - marginTop: 20 + flexDirection: "row", + marginTop: 20, }, codeInput: { - backgroundColor: 'transparent', - textAlign: 'center', - padding: 0 - } + backgroundColor: "transparent", + textAlign: "center", + padding: 0, + }, }); diff --git a/example/src/components/ConfirmationCodeInput.js b/example/src/components/ConfirmationCodeInput.js index 682caaf..68c0b97 100644 --- a/example/src/components/ConfirmationCodeInput.js +++ b/example/src/components/ConfirmationCodeInput.js @@ -1,7 +1,15 @@ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { View, TextInput, StyleSheet, Dimensions } from 'react-native'; -import _ from 'lodash'; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { View, TextInput, StyleSheet, Dimensions } from "react-native"; +import { + ViewPropTypes, + TextInputPropTypes, +} from "deprecated-react-native-prop-types"; +import _ from "lodash"; + +// if ViewPropTypes is not defined fall back to View.propType (to support RN < 0.44) +const viewPropTypes = ViewPropTypes || View.propTypes; +const textInputPropTypes = TextInputPropTypes || TextInput.propTypes; export default class ConfirmationCodeInput extends Component { static propTypes = { @@ -16,207 +24,218 @@ export default class ConfirmationCodeInput extends Component { inactiveColor: PropTypes.string, ignoreCase: PropTypes.bool, autoFocus: PropTypes.bool, - codeInputStyle: TextInput.propTypes.style, - containerStyle: View.propTypes.style, + codeInputStyle: textInputPropTypes.style, + containerStyle: viewPropTypes.style, onFulfill: PropTypes.func, onCodeChange: PropTypes.func, }; - + static defaultProps = { codeLength: 5, - inputPosition: 'center', + inputPosition: "center", autoFocus: true, size: 40, - className: 'border-box', + className: "border-box", cellBorderWidth: 1, - activeColor: 'rgba(255, 255, 255, 1)', - inactiveColor: 'rgba(255, 255, 255, 0.2)', + activeColor: "rgba(255, 255, 255, 1)", + inactiveColor: "rgba(255, 255, 255, 0.2)", space: 8, - compareWithCode: '', + compareWithCode: "", ignoreCase: false, - onCodeChange: (code) => null + onCodeChange: (code) => null, }; - + constructor(props) { super(props); - + this.state = { - codeArr: new Array(this.props.codeLength).fill(''), - currentIndex: 0 + codeArr: new Array(this.props.codeLength).fill(""), + currentIndex: 0, }; - + this.codeInputRefs = []; } - + componentDidMount() { const { compareWithCode, codeLength, inputPosition } = this.props; if (compareWithCode && compareWithCode.length !== codeLength) { - console.error("Invalid props: compareWith length is not equal to codeLength"); + console.error( + "Invalid props: compareWith length is not equal to codeLength" + ); } - - if (_.indexOf(['center', 'left', 'right', 'full-width'], inputPosition) === -1) { - console.error('Invalid input position. Must be in: center, left, right, full'); + + if ( + _.indexOf(["center", "left", "right", "full-width"], inputPosition) === -1 + ) { + console.error( + "Invalid input position. Must be in: center, left, right, full" + ); } } - + clear() { this.setState({ - codeArr: new Array(this.props.codeLength).fill(''), - currentIndex: 0 + codeArr: new Array(this.props.codeLength).fill(""), + currentIndex: 0, }); this._setFocus(0); } - + _setFocus(index) { this.codeInputRefs[index].focus(); } - + _blur(index) { this.codeInputRefs[index].blur(); } - + _onFocus(index) { let newCodeArr = _.clone(this.state.codeArr); - const currentEmptyIndex = _.findIndex(newCodeArr, c => !c); + const currentEmptyIndex = _.findIndex(newCodeArr, (c) => !c); if (currentEmptyIndex !== -1 && currentEmptyIndex < index) { return this._setFocus(currentEmptyIndex); } for (const i in newCodeArr) { if (i >= index) { - newCodeArr[i] = ''; + newCodeArr[i] = ""; } } - + this.setState({ codeArr: newCodeArr, - currentIndex: index - }) + currentIndex: index, + }); } - + _isMatchingCode(code, compareWithCode, ignoreCase = false) { if (ignoreCase) { return code.toLowerCase() == compareWithCode.toLowerCase(); } return code == compareWithCode; } - + _getContainerStyle(size, position) { switch (position) { - case 'left': + case "left": return { - justifyContent: 'flex-start', - height: size + justifyContent: "flex-start", + height: size, }; - case 'center': + case "center": return { - justifyContent: 'center', - height: size + justifyContent: "center", + height: size, }; - case 'right': + case "right": return { - justifyContent: 'flex-end', - height: size + justifyContent: "flex-end", + height: size, }; default: return { - justifyContent: 'space-between', - height: size - } + justifyContent: "space-between", + height: size, + }; } } - + _getInputSpaceStyle(space) { const { inputPosition } = this.props; switch (inputPosition) { - case 'left': + case "left": return { - marginRight: space + marginRight: space, }; - case 'center': + case "center": return { - marginRight: space/2, - marginLeft: space/2 + marginRight: space / 2, + marginLeft: space / 2, }; - case 'right': + case "right": return { - marginLeft: space + marginLeft: space, }; default: return { marginRight: 0, - marginLeft: 0 + marginLeft: 0, }; } } - + _getClassStyle(className, active) { const { cellBorderWidth, activeColor, inactiveColor, space } = this.props; let classStyle = { ...this._getInputSpaceStyle(space), - color: activeColor + color: activeColor, }; - + switch (className) { - case 'clear': + case "clear": return _.merge(classStyle, { borderWidth: 0 }); - case 'border-box': + case "border-box": return _.merge(classStyle, { borderWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-circle': + case "border-circle": return _.merge(classStyle, { borderWidth: cellBorderWidth, borderRadius: 50, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-b': + case "border-b": return _.merge(classStyle, { borderBottomWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor), + borderColor: active ? activeColor : inactiveColor, }); - case 'border-b-t': + case "border-b-t": return _.merge(classStyle, { borderTopWidth: cellBorderWidth, borderBottomWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); - case 'border-l-r': + case "border-l-r": return _.merge(classStyle, { borderLeftWidth: cellBorderWidth, borderRightWidth: cellBorderWidth, - borderColor: (active ? activeColor : inactiveColor) + borderColor: active ? activeColor : inactiveColor, }); default: return className; } } - + _onKeyPress(e) { - if (e.nativeEvent.key === 'Backspace') { + if (e.nativeEvent.key === "Backspace") { const { currentIndex } = this.state; let newCodeArr = _.clone(this.state.codeArr); const nextIndex = currentIndex > 0 ? currentIndex - 1 : 0; for (const i in newCodeArr) { if (i >= nextIndex) { - newCodeArr[i] = ''; + newCodeArr[i] = ""; } } - this.props.onCodeChange(newCodeArr.join('')) + this.props.onCodeChange(newCodeArr.join("")); this._setFocus(nextIndex); } } - + _onInputCode(character, index) { - const { codeLength, onFulfill, compareWithCode, ignoreCase, onCodeChange } = this.props; + const { codeLength, onFulfill, compareWithCode, ignoreCase, onCodeChange } = + this.props; let newCodeArr = _.clone(this.state.codeArr); newCodeArr[index] = character; - + if (index == codeLength - 1) { - const code = newCodeArr.join(''); - + const code = newCodeArr.join(""); + if (compareWithCode) { - const isMatching = this._isMatchingCode(code, compareWithCode, ignoreCase); + const isMatching = this._isMatchingCode( + code, + compareWithCode, + ignoreCase + ); onFulfill(isMatching, code); !isMatching && this.clear(); } else { @@ -226,15 +245,20 @@ export default class ConfirmationCodeInput extends Component { } else { this._setFocus(this.state.currentIndex + 1); } - - this.setState(prevState => { - return { - codeArr: newCodeArr, - currentIndex: prevState.currentIndex + 1 - }; - }, () => { onCodeChange(newCodeArr.join('')) }); + + this.setState( + (prevState) => { + return { + codeArr: newCodeArr, + currentIndex: prevState.currentIndex + 1, + }; + }, + () => { + onCodeChange(newCodeArr.join("")); + } + ); } - + render() { const { codeLength, @@ -244,44 +268,52 @@ export default class ConfirmationCodeInput extends Component { autoFocus, className, size, - activeColor + activeColor, } = this.props; - + const initialCodeInputStyle = { width: size, - height: size + height: size, }; - + let codeInputs = []; for (let i = 0; i < codeLength; i++) { const id = i; codeInputs.push( (this.codeInputRefs[id] = ref)} + ref={(ref) => (this.codeInputRefs[id] = ref)} style={[ - styles.codeInput, - initialCodeInputStyle, + styles.codeInput, + initialCodeInputStyle, this._getClassStyle(className, this.state.currentIndex == id), - codeInputStyle + codeInputStyle, ]} underlineColorAndroid="transparent" selectionColor={activeColor} - keyboardType={'name-phone-pad'} - returnKeyType={'done'} + keyboardType={"name-phone-pad"} + returnKeyType={"done"} {...this.props} autoFocus={autoFocus && id == 0} onFocus={() => this._onFocus(id)} - value={this.state.codeArr[id] ? this.state.codeArr[id].toString() : ''} - onChangeText={text => this._onInputCode(text, id)} + value={ + this.state.codeArr[id] ? this.state.codeArr[id].toString() : "" + } + onChangeText={(text) => this._onInputCode(text, id)} onKeyPress={(e) => this._onKeyPress(e)} maxLength={1} /> - ) + ); } - + return ( - + {codeInputs} ); @@ -291,12 +323,12 @@ export default class ConfirmationCodeInput extends Component { const styles = StyleSheet.create({ container: { flex: 1, - flexDirection: 'row', - marginTop: 20 + flexDirection: "row", + marginTop: 20, }, codeInput: { - backgroundColor: 'transparent', - textAlign: 'center', - padding: 0 - } -}); \ No newline at end of file + backgroundColor: "transparent", + textAlign: "center", + padding: 0, + }, +});