react-f0rm 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/dist/index.cjs.js +667 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.esm.js +482 -340
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +529 -344
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +2 -2
- package/dist/index.umd.min.js.map +1 -1
- package/dist/resolvers/yup.cjs.js +15 -0
- package/dist/resolvers/yup.cjs.js.map +1 -0
- package/dist/resolvers/yup.esm.js +13 -0
- package/dist/resolvers/yup.esm.js.map +1 -0
- package/dist/resolvers/zod.cjs.js +12 -0
- package/dist/resolvers/zod.cjs.js.map +1 -0
- package/dist/resolvers/zod.esm.js +10 -0
- package/dist/resolvers/zod.esm.js.map +1 -0
- package/package.json +82 -45
- package/index.d.ts +0 -22
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# react-f0rm
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
|
|
5
|
+
- Drive by event.
|
|
6
|
+
- Refined tree-shaking support. Needn't have to pay for features not used.
|
|
7
|
+
- Theoretically more efficient(need a benchmark).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm i react-f0rm
|
|
13
|
+
```
|
|
14
|
+
or
|
|
15
|
+
```
|
|
16
|
+
yarn add react-f0rm
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```jsx
|
|
22
|
+
import React from 'react';
|
|
23
|
+
import {Form, Field} from 'react-f0rm';
|
|
24
|
+
|
|
25
|
+
export default function Register() {
|
|
26
|
+
return (
|
|
27
|
+
<Form
|
|
28
|
+
initialValues={{name: 'wmzy', email: '1256573276@qq.com'}}
|
|
29
|
+
onValidSubmit={values => console.log(values)}
|
|
30
|
+
>
|
|
31
|
+
<Field name="name" />
|
|
32
|
+
<Field name="email" />
|
|
33
|
+
<button>SUBMIT</button>
|
|
34
|
+
</Form>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Hooks
|
|
40
|
+
|
|
41
|
+
### `useField`
|
|
42
|
+
|
|
43
|
+
For full control over field rendering:
|
|
44
|
+
|
|
45
|
+
```jsx
|
|
46
|
+
import {useField} from 'react-f0rm';
|
|
47
|
+
|
|
48
|
+
function CustomField({name}) {
|
|
49
|
+
const {value, onChange, onBlur, error} = useField({name});
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
<input value={value} onChange={e => onChange(e.target.value)} onBlur={onBlur} />
|
|
53
|
+
{error && <span>{error}</span>}
|
|
54
|
+
</div>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### `useFieldArray`
|
|
60
|
+
|
|
61
|
+
Manage dynamic lists of fields:
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
import {useFieldArray} from 'react-f0rm';
|
|
65
|
+
|
|
66
|
+
function Tags() {
|
|
67
|
+
const {fields, append, remove} = useFieldArray({name: 'tags'});
|
|
68
|
+
return (
|
|
69
|
+
<div>
|
|
70
|
+
{fields.map((field, index) => (
|
|
71
|
+
<div key={field.id}>
|
|
72
|
+
<Field name={['tags', index]} />
|
|
73
|
+
<button type="button" onClick={() => remove(index)}>Remove</button>
|
|
74
|
+
</div>
|
|
75
|
+
))}
|
|
76
|
+
<button type="button" onClick={() => append('')}>Add Tag</button>
|
|
77
|
+
</div>
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Submit Handlers
|
|
83
|
+
|
|
84
|
+
```jsx
|
|
85
|
+
<Form
|
|
86
|
+
initialValues={{email: ''}}
|
|
87
|
+
onValidSubmit={(values, e) => {
|
|
88
|
+
// Called after successful validation
|
|
89
|
+
saveToServer(values);
|
|
90
|
+
}}
|
|
91
|
+
onInvalidSubmit={(errors, values) => {
|
|
92
|
+
// Called when validation fails
|
|
93
|
+
console.error(errors);
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Field name="email" />
|
|
97
|
+
<button>Submit</button>
|
|
98
|
+
</Form>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Validation
|
|
102
|
+
|
|
103
|
+
### Field-level validation
|
|
104
|
+
|
|
105
|
+
Pass a `validate` function to `Field` or `useField`. Return an error string or `undefined`:
|
|
106
|
+
|
|
107
|
+
```jsx
|
|
108
|
+
<Field
|
|
109
|
+
name="email"
|
|
110
|
+
validate={value => {
|
|
111
|
+
if (!value.includes('@')) return 'Invalid email';
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Form-level validation
|
|
117
|
+
|
|
118
|
+
Pass a `validate` function to `createForm`. It receives all values and returns an object of errors:
|
|
119
|
+
|
|
120
|
+
```jsx
|
|
121
|
+
import {createForm} from 'react-f0rm';
|
|
122
|
+
|
|
123
|
+
const form = createForm({
|
|
124
|
+
initialValues: {password: '', confirm: ''},
|
|
125
|
+
validate: values => {
|
|
126
|
+
const errors = {};
|
|
127
|
+
if (values.password !== values.confirm) {
|
|
128
|
+
errors.confirm = 'Passwords do not match';
|
|
129
|
+
}
|
|
130
|
+
return errors;
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Custom Components
|
|
136
|
+
|
|
137
|
+
Use the `as` prop to render a custom component instead of `<input>`:
|
|
138
|
+
|
|
139
|
+
```jsx
|
|
140
|
+
function TextArea({value, onChange, ...props}) {
|
|
141
|
+
return <textarea {...props} value={value} onChange={e => onChange(e.target.value)} />;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
<Field name="bio" as={TextArea} />
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## TypeScript
|
|
148
|
+
|
|
149
|
+
```tsx
|
|
150
|
+
import {Form, Field, useForm, createForm} from 'react-f0rm';
|
|
151
|
+
|
|
152
|
+
interface UserForm {
|
|
153
|
+
name: string;
|
|
154
|
+
email: string;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const form = createForm<UserForm>();
|
|
158
|
+
|
|
159
|
+
function MyForm() {
|
|
160
|
+
return (
|
|
161
|
+
<Form<UserForm>
|
|
162
|
+
form={form}
|
|
163
|
+
onValidSubmit={values => {
|
|
164
|
+
// values is typed as UserForm
|
|
165
|
+
console.log(values.name);
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<Field name="name" />
|
|
169
|
+
<Field name="email" />
|
|
170
|
+
<button>Submit</button>
|
|
171
|
+
</Form>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
```
|