diff --git a/README.md b/README.md index dd0a0b9..bbb5ffb 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,17 @@ export default () => ( ) ``` +You can set your own input component: + +```js +import { Form } from 'react-native-autofocus' + +export default () => ( +
+ + + +) +``` + Hit enter inside your first input, and the next field will be focused. The logic is all abstracted for you! diff --git a/form.js b/form.js index 73d1033..a12e9aa 100644 --- a/form.js +++ b/form.js @@ -1,30 +1,54 @@ import React from 'react'; import { View } from 'react-native'; +import TextInput from "./text-input"; + export default class Form extends React.Component { constructor() { super(); this.inputs = []; } - renderChildren(children, recursiveIndex = 0) { - return React.Children.map(children, (child, index) => { + renderChildren(children, recursive=false) { + if(!recursive) this.count = 0; + let inputTypes = this.props.inputTypes || [ TextInput ]; + let elements = React.Children.map(children, (child, index) => { if(!child) return; - if (child.props.children) - return React.cloneElement(child, { - ...child.props, - children: this.renderChildren(child.props.children, index) - }); - if (child.type.name !== 'TextInput') return child; - - let realIndex = index + recursiveIndex + + if (!inputTypes.some(input => input === child.type)) { + if (child.props && child.props.children) { + return React.cloneElement(child, { + ...child.props, + children: this.renderChildren(child.props.children, true) + }); + } + return child; + } + + const realIndex = this.count; + this.count++; + return React.cloneElement(child, { - onEnter: () => - this.inputs[realIndex + 1] ? this.inputs[realIndex + 1].focus() : null, - inputRef: ref => (this.inputs[realIndex] = ref), + onSubmitEditing: () => { + if(this.inputs[realIndex + 1] && this.inputs[realIndex + 1].focus) { + this.inputs[realIndex + 1].focus(); + } + }, + inputRef: ref => { + this.inputs[realIndex] = ref; + if(child.props.inputRef) { + child.props.inputRef(ref); + } + }, }); }); + + if(children && !Array.isArray(children) && elements.length == 1) { + return elements[0]; + } + + return elements; } render() { diff --git a/text-input.js b/text-input.js index 0b60e06..7a6a0e3 100644 --- a/text-input.js +++ b/text-input.js @@ -1,15 +1,18 @@ import React from 'react'; import { TextInput as Input } from 'react-native'; -const TextInput = ({ onSubmitEditing, onEnter, inputRef, ...props }) => ( - inputRef(ref)} - onSubmitEditing={() => { - if (onEnter) onEnter(); - if (onSubmitEditing) onSubmitEditing(); - }} - {...props} - /> -); +const TextInput = ({ onSubmitEditing, onEnter, inputRef, component=null, ...props }) => { + const InputComponent = component || Input; + return ( + inputRef && inputRef(ref)} + onSubmitEditing={() => { + if (onEnter) onEnter(); + if (onSubmitEditing) onSubmitEditing(); + }} + {...props} + /> + ); +}; -export default TextInput; +export default TextInput; \ No newline at end of file