Skip to content

Commit d1f783f

Browse files
committed
docs: add docs
1 parent 8413ca0 commit d1f783f

1 file changed

Lines changed: 321 additions & 1 deletion

File tree

README.md

Lines changed: 321 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,321 @@
1-
# react-native-formik
1+
# React Native Formik [![Coverage Status](https://coveralls.io/repos/bamlab/react-native-formik/badge.svg?branch=master)](https://coveralls.io/r/bamlab/react-native-formik?branch=master) [![license](https://img.shields.io/github/license/mashape/apistatus.svg)]()
2+
3+
Forms are very verbose in React, and a lot of the time, you end up copy pasting a lot of boilerplate.
4+
5+
This repository is a set of high order components designed to help you take control again of your forms with React Native and [Formik](https://github.com/jaredpalmer/formik)
6+
7+
**Features**
8+
9+
- Easily composable set of helpers
10+
- Connects your React Native input to Formik with no boilerplate (See `makeReactNativeField`)
11+
- Add a `type` prop on your TextInput to take care of the input options based on the type (See `withInputTypeProps`)
12+
- Automatically focus the next input (See `withNextInputAutoFocus`)
13+
- Awesome Test coverage [![Coverage Status](https://coveralls.io/repos/bamlab/react-native-formik/badge.svg?branch=master)](https://coveralls.io/r/bamlab/react-native-formik?branch=master)
14+
15+
**Table of contents**
16+
17+
- [Installation]()
18+
- [Advanced Example]()
19+
- [API]()
20+
- [makeReactNativeField]()
21+
- [withError]()
22+
- [withFocus]()
23+
- [withFormik]()
24+
- [withInputTypeProps]()
25+
- [withNextInputAutoFocus]()
26+
- [withTouched]()
27+
28+
## Installation
29+
30+
```shell
31+
yarn add react-native-formik
32+
```
33+
34+
## Advanced Example
35+
36+
Say we want to create a form with Material design inputs.
37+
38+
### Create a custom input
39+
Let's create our custom text input design, called `MaterialTextInput`:
40+
41+
We can use [react-native-material-textfield](https://github.com/n4kz/react-native-material-textfield) for the material design.
42+
43+
Our component takes `error` and `touched` in addition to the usual `TextInput` props.
44+
Notice our component also implement a `focus` function, for `withNextInputAutoFocus` to work.
45+
46+
```javascript
47+
// MaterialTextInput.js
48+
import React from "react";
49+
import { Text, View } from "react-native";
50+
import { TextField } from "react-native-material-textfield";
51+
52+
export default class MaterialTextInput extends React.PureComponent {
53+
// Your custom input needs a focus function for `withNextInputAutoFocus` to work
54+
focus() {
55+
this.input.focus();
56+
}
57+
58+
render() {
59+
const { error, touched, ...props } = this.props;
60+
61+
const displayError = !!error && touched;
62+
const errorColor = "rgb(239, 51, 64)";
63+
64+
return (
65+
<View>
66+
<TextField
67+
ref={input => this.input = input}
68+
labelHeight={12}
69+
baseColor={displayError ? errorColor : "#1976D2"}
70+
tintColor="#2196F3"
71+
textColor="#212121"
72+
{...props}
73+
/>
74+
<Text style={{ textAlign: "right", color: displayError ? errorColor : "transparent", height: 20 }}>
75+
{error}
76+
</Text>
77+
</View>
78+
);
79+
}
80+
}
81+
```
82+
83+
### Create our form logic
84+
85+
Compose our input with high order components to make it awesome.
86+
`react-native-formik` exports as default `compose(withInputTypeProps, withError, withTouched, makeReactNativeField);`.
87+
88+
Let's add in `withNextInputAutoFocusInput`:
89+
90+
```javascript
91+
import { compose } from "recompose";
92+
import makeInputGreatAgain, { withNextInputAutoFocusInput } from "react-native-formik";
93+
import MaterialTextInput from "./MaterialTextInput";
94+
95+
const MyInput = compose(makeInputGreatAgain, withNextInputAutoFocusInput)(MaterialTextInput);
96+
```
97+
98+
To complement `withNextInputAutoFocusInput`, we need to create a `Form` component, for instance:
99+
100+
```javascript
101+
import { View } from "react-native";
102+
import { withNextInputAutoFocusForm } from "react-native-formik";
103+
104+
const Form = withNextInputAutoFocusForm(View);
105+
```
106+
107+
We can also create a validation schema, with `yup`. It's of course possible to use other validation possibilities provided by Formik, but `yup` makes validation and error messaging painless.
108+
109+
```javascript
110+
import Yup from "yup";
111+
112+
const validationSchema = Yup.object().shape({
113+
email: Yup.string()
114+
.required()
115+
.email("well that's not an email"),
116+
password: Yup.string()
117+
.required()
118+
.min(2, "pretty sure this will be hacked")
119+
});
120+
```
121+
122+
Then the form in itself becomes simple:
123+
124+
```javascript
125+
export default props => (
126+
<Formik
127+
onSubmit={(values) => console.log(values)}
128+
validationSchema={validationSchema}
129+
render={props => {
130+
return (
131+
<Form>
132+
<MyInput label="Email" name="email" type="email" />
133+
<MyInput label="Password" name="password" type="password" />
134+
<MyInput label="First Name" name="firstName" type="name" />
135+
<MyInput label="Last Name" name="lastName" type="name" />
136+
<Button onPress={props.handleSubmit} title="SUBMIT" />
137+
</Form>
138+
);
139+
}}
140+
/>
141+
);
142+
```
143+
144+
Full code:
145+
146+
```javascript
147+
import React from "react";
148+
import { Button, TextInput, View } from "react-native";
149+
import { compose } from "recompose"
150+
import { Formik } from "formik";
151+
import Yup from "yup";
152+
import makeInputGreatAgain, { withNextInputAutoFocusForm, withNextInputAutoFocusInput } from "react-native-formik";
153+
import MaterialTextInput from "./MaterialTextInput";
154+
155+
const MyInput = compose(makeInputGreatAgain, withNextInputAutoFocusInput)(MaterialTextInput);
156+
const Form = withNextInputAutoFocusForm(View);
157+
158+
const validationSchema = Yup.object().shape({
159+
email: Yup.string()
160+
.required("please! email?")
161+
.email("well that's not an email"),
162+
password: Yup.string()
163+
.required()
164+
.min(2, "pretty sure this will be hacked")
165+
});
166+
167+
168+
export default props => (
169+
<Formik
170+
onSubmit={(values) => console.log(values)}
171+
validationSchema={validationSchema}
172+
render={props => {
173+
return (
174+
<Form>
175+
<MyInput label="Email" name="email" type="email" />
176+
<MyInput label="Password" name="password" type="password" />
177+
<MyInput label="First Name" name="firstName" type="name" />
178+
<MyInput label="Last Name" name="lastName" type="name" />
179+
<Button onPress={props.handleSubmit} title="SUBMIT" />
180+
</Form>
181+
);
182+
}}
183+
/>
184+
);
185+
```
186+
187+
## API
188+
189+
### makeReactNativeField
190+
191+
Connects your React Native component to the Formik context:
192+
- its value will be set
193+
- it will send `onChangeText` and `onBlur` events to Formik
194+
195+
Now you only need this code:
196+
```javascript
197+
import React from "react";
198+
import { TextInput, View } from "react-native";
199+
import { Formik } from "formik";
200+
import { makeReactNativeField } from "react-native-formik";
201+
202+
const MyInput = makeReactNativeField(TextInput);
203+
204+
export default props => {
205+
return (
206+
<Formik
207+
onSubmit={(values) => console.log(values)}
208+
render={props => {
209+
return (
210+
<View>
211+
<MyInput name="email" />
212+
<MyInput name="password" />
213+
</View>
214+
);
215+
}}
216+
/>
217+
);
218+
};
219+
```
220+
221+
instead of:
222+
```javascript
223+
import React from "react";
224+
import { TextInput, View } from "react-native";
225+
import { Formik } from "formik";
226+
import { makeReactNativeField } from "react-native-formik";
227+
228+
const MyInput = makeReactNativeField(TextInput);
229+
230+
export default props => {
231+
return (
232+
<Formik
233+
onSubmit={(values) => console.log(values)}
234+
render={props => {
235+
return (
236+
<View>
237+
<MyInput
238+
name="email"
239+
value={props.value.email}
240+
onChangeText={(text) => props.setFieldValue("email", text)}
241+
onBlur={() => setFieldTouched("email")}
242+
/>
243+
<MyInput
244+
name="password"
245+
value={props.value.email}
246+
onChangeText={(text) => props.setFieldValue("password", text)}
247+
onBlur={() => setFieldTouched("password")}
248+
/>
249+
</View>
250+
);
251+
}}
252+
/>
253+
);
254+
};
255+
```
256+
257+
### withError
258+
259+
Pass in the Formik error for the input as a prop.
260+
261+
### withFocus
262+
263+
Add a `focused` prop to the input depending on its focus state.
264+
265+
### withFormik
266+
267+
Pass Formik context as a prop to any component.
268+
269+
### withInputTypeProps
270+
271+
Let's face it, you'll always want to remove auto-capitalization for email inputs and use the email keyboard.
272+
273+
Using `withInputTypeProps` and passing a `type`, you'll always get the correct props for you input.
274+
275+
```javascript
276+
import { TextInput } from "react-native";
277+
import { withInputTypeProps } from "react-native-formik";
278+
279+
const MyInput = withInputTypeProps(TextInput);
280+
281+
const emailInput = () => <MyInput type="email" />;
282+
```
283+
284+
Authorized types as of now are `email`, `password`, `digits` and `name`. Setting another type has no consequence.
285+
286+
Check [the props set by the type](./src/withInputTypeProps) in the source!
287+
288+
### withNextInputAutoFocus
289+
290+
- when an input is submitted, it will automatically focuses on the next or submit the form if it's the last one
291+
- sets return key to "next" or "done" if input is the last one or not
292+
- :warning: your input component needs to be a class and needs to implement a `focus` function
293+
- :warning: Inputs need to be wrapped by `withNextInputAutoFocusInput` and the container of the inputs need to be wrapped in `withNextInputAutoFocusForm`.
294+
295+
```javascript
296+
import { TextInput, View } from "react-native";
297+
import { withNextInputAutoFocusForm, withNextInputAutoFocusInput } from "react-native-formik";
298+
299+
const MyInput = withNextInputAutoFocusInput(TextInput);
300+
const Form = withNextInputAutoFocusForm(View);
301+
302+
export default props => (
303+
<Formik
304+
onSubmit={(values) => console.log(values)}
305+
validationSchema={validationSchema}
306+
render={props => {
307+
return (
308+
<Form>
309+
<MyInput label="Email" name="email" type="email" />
310+
<MyInput label="Password" name="password" type="password" />
311+
<MyInput label="First Name" name="firstName" type="name" />
312+
</Form>
313+
);
314+
}}
315+
/>
316+
);
317+
```
318+
319+
### withTouched
320+
321+
Pass in the Formik touched value for the input as a prop.

0 commit comments

Comments
 (0)