├── .babelrc ├── .gitignore ├── .npmignore ├── .prettierrc ├── .travis.yml ├── Example ├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── DatePicker.js ├── Form.js ├── Switch.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── index.js ├── ios │ ├── Example-tvOS │ │ └── Info.plist │ ├── Example-tvOSTests │ │ └── Info.plist │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── Example-tvOS.xcscheme │ │ │ └── Example.xcscheme │ ├── Example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ └── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist ├── metro.config.js ├── package.json ├── test.md └── yarn.lock ├── LICENSE ├── README.md ├── doc ├── formik_step_by_step.md └── images │ └── bottomForm.gif ├── index.d.ts ├── index.js ├── jest.config.js ├── jest └── preamble.js ├── package.json ├── src ├── __tests__ │ ├── makeReactNativeField.js │ ├── setFormikInitialValue.js │ ├── withError.js │ ├── withErrorIfNeeded.js │ ├── withFocus.js │ ├── withInputTypeProps.js │ ├── withNextInputAutoFocus.js │ └── withTouched.js ├── handleTextInput.js ├── makeReactNativeField.js ├── setFormikInitialValue.js ├── testUtils │ └── withFormikMock.js ├── withError.js ├── withErrorIfNeeded.js ├── withFocus.js ├── withFormik.js ├── withFormikControl.js ├── withInputTypeProps.js ├── withNextInputAutoFocus.js ├── withPickerValues │ ├── DisableKeyboard.js │ ├── KeyboardModal.js │ ├── PickerModal.js │ ├── index.js │ └── withPickerValues.js └── withTouched.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | Example 4 | src/__tests__ 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: 3 | directories: 4 | - ~/.npm 5 | notifications: 6 | email: false 7 | node_js: 8 | - "10" 9 | after_success: 10 | - npm run travis-deploy-once "npm run coveralls && npm run semantic-release" 11 | branches: 12 | except: 13 | - /^v\d+\.\d+\.\d+$/ 14 | -------------------------------------------------------------------------------- /Example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["module:metro-react-native-babel-preset"] 3 | } 4 | -------------------------------------------------------------------------------- /Example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /Example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | esproposal.optional_chaining=enable 33 | esproposal.nullish_coalescing=enable 34 | 35 | module.system=haste 36 | module.system.haste.use_name_reducers=true 37 | # get basename 38 | module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' 39 | # strip .js or .js.flow suffix 40 | module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' 41 | # strip .ios suffix 42 | module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' 43 | module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' 44 | module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' 45 | module.system.haste.paths.blacklist=.*/__tests__/.* 46 | module.system.haste.paths.blacklist=.*/__mocks__/.* 47 | module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* 48 | module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* 49 | 50 | munge_underscores=true 51 | 52 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 53 | 54 | module.file_ext=.js 55 | module.file_ext=.jsx 56 | module.file_ext=.json 57 | module.file_ext=.native.js 58 | 59 | suppress_type=$FlowIssue 60 | suppress_type=$FlowFixMe 61 | suppress_type=$FlowFixMeProps 62 | suppress_type=$FlowFixMeState 63 | 64 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 65 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 66 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 67 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 68 | 69 | [version] 70 | ^0.85.0 71 | -------------------------------------------------------------------------------- /Example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Example/DatePicker.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import DisableKeyboard from "react-native-formik/src/withPickerValues/DisableKeyboard"; 3 | import DateTimePicker from "react-native-modal-datetime-picker"; 4 | import { TextField as MaterialTextInput } from "react-native-material-textfield"; 5 | import { format } from "date-fns"; 6 | 7 | class DatePicker extends React.PureComponent { 8 | state = { 9 | pickerOpened: false 10 | }; 11 | 12 | focus = () => this.openPicker(); 13 | 14 | openPicker = () => { 15 | this.setState({ pickerOpened: true }); 16 | }; 17 | 18 | closePicker = () => 19 | this.setState({ pickerOpened: false }, () => { 20 | this.props.setFieldTouched(); 21 | }); 22 | 23 | handleDatePicked = value => { 24 | this.props.setFieldValue(value); 25 | this.closePicker(); 26 | if (this.props.onSubmitEditing) this.props.onSubmitEditing(); 27 | }; 28 | 29 | render() { 30 | return ( 31 | 32 | 33 | 41 | 42 | 48 | 49 | ); 50 | } 51 | } 52 | 53 | export default DatePicker; 54 | -------------------------------------------------------------------------------- /Example/Form.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Button, Text, ScrollView } from "react-native"; 3 | import { Formik } from "formik"; 4 | import { compose } from "recompose"; 5 | import { 6 | handleTextInput, 7 | withNextInputAutoFocusForm, 8 | withNextInputAutoFocusInput, 9 | withFormikControl 10 | } from "react-native-formik"; 11 | import { TextField } from "react-native-material-textfield"; 12 | import * as Yup from "yup"; 13 | import DatePicker from "./DatePicker"; 14 | import Switch from "./Switch"; 15 | 16 | const MyInput = compose( 17 | handleTextInput, 18 | withNextInputAutoFocusInput 19 | )(TextField); 20 | const Form = withNextInputAutoFocusForm(ScrollView, { 21 | submitAfterLastInput: false 22 | }); 23 | const FocusedDatePicker = compose( 24 | withFormikControl, 25 | withNextInputAutoFocusInput 26 | )(DatePicker); 27 | 28 | const validationSchema = Yup.object().shape({ 29 | email: Yup.string() 30 | .required() 31 | .email(), 32 | password: Yup.string() 33 | .required() 34 | .min(6, "Too short"), 35 | star: Yup.boolean() 36 | .required() 37 | .oneOf([true]) 38 | }); 39 | 40 | export default () => ( 41 | alert(JSON.stringify(values, null, 2))} 43 | validationSchema={validationSchema} 44 | initialValues={{ star: true }} 45 | > 46 | {props => { 47 | return ( 48 |
49 | 50 | 51 | 55 | 56 | 57 |