@reactables/react-forms 1.0.3 → 1.1.0
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 +7 -189
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,197 +1,15 @@
|
|
|
1
|
-
|
|
2
1
|
# Reactables React
|
|
3
2
|
|
|
4
3
|
## Description
|
|
5
4
|
|
|
6
5
|
React components for binding [`@reactables/forms`](https://github.com/reactables/reactables/tree/main/packages/forms) reactables.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
1. [Installation](#installation)
|
|
11
|
-
1. [API](#api)
|
|
12
|
-
1. [`Form`](#form)
|
|
13
|
-
1. [`Field`](#field)
|
|
14
|
-
1. [`FormArray`](#form-array)
|
|
15
|
-
|
|
16
|
-
## Installation <a name="installation"></a>
|
|
17
|
-
|
|
18
|
-
`npm i @reactables/react-forms`
|
|
19
|
-
|
|
20
|
-
## API<a name="api"></a>
|
|
21
|
-
|
|
22
|
-
### `Form`<a name="form"></a>
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
type HookedRxForm = HookedReactable<ControlModels.Form<unknown>, RxFormActions>;
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`Form` is the provider component giving child `Field` and `FormArray` child components access to a `HookedRxForm`.
|
|
29
|
-
|
|
30
|
-
[See full example on StackBlitz](https://stackblitz.com/edit/vitejs-vite-6lzq4i?file=src%2FMyForm.tsx)
|
|
31
|
-
|
|
32
|
-
```typescript
|
|
33
|
-
import { build, group, control } from '@reactables/forms';
|
|
34
|
-
import { useReactable } from '@reactables/react';
|
|
35
|
-
import { Form, Field } from '@reactables/react-forms';
|
|
36
|
-
import Input from './Input';
|
|
37
|
-
|
|
38
|
-
const userConfig = group({
|
|
39
|
-
controls: {
|
|
40
|
-
name: control(['', 'required']),
|
|
41
|
-
email: control(['', ['required', 'email']]),
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const MyForm = () => {
|
|
46
|
-
const rxForm = useReactable(() => build(userConfig));
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<Form rxForm={rxForm}>
|
|
50
|
-
<Field name="name" label="Name:" component={Input} />
|
|
51
|
-
<Field name="email" label="Email: " component={Input} />
|
|
52
|
-
</Form>
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export default MyForm;
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### `Field`<a name="field"></a>
|
|
60
|
-
|
|
61
|
-
A wrapper component that connects a component to the reactable form.
|
|
62
|
-
|
|
63
|
-
Below is an `Input` component that will be wrapped by `Field` and provided the `FormControl<T>` via the `meta` prop.
|
|
64
|
-
|
|
65
|
-
`WrappedFieldInputProps` are passed in by the `input` prop which contains the input value and event handlers.
|
|
66
|
-
|
|
67
|
-
[See full example on StackBlitz](https://stackblitz.com/edit/vitejs-vite-6lzq4i?file=src%2FMyForm.tsx)
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
import { WrappedFieldProps } from '@reactables/react-forms';
|
|
71
|
-
|
|
72
|
-
const Input = ({
|
|
73
|
-
input,
|
|
74
|
-
label,
|
|
75
|
-
meta: { touched, errors, pending, valid },
|
|
76
|
-
}: { label?: string } & WrappedFieldProps) => {
|
|
77
|
-
return (
|
|
78
|
-
<div className="mb-3">
|
|
79
|
-
{label && (
|
|
80
|
-
<label className={`form-label ${touched && !valid ? 'text-danger' : ''}`}>{label}</label>
|
|
81
|
-
)}
|
|
82
|
-
<input
|
|
83
|
-
{...input}
|
|
84
|
-
type="text"
|
|
85
|
-
className={`form-control ${touched && !valid ? 'is-invalid' : ''}`}
|
|
86
|
-
/>
|
|
87
|
-
{touched && errors.required && (
|
|
88
|
-
<div>
|
|
89
|
-
<small className="text-danger">Field is required</small>
|
|
90
|
-
</div>
|
|
91
|
-
)}
|
|
92
|
-
{touched && errors.email && (
|
|
93
|
-
<div>
|
|
94
|
-
<small className="text-danger">Not a valid email address</small>
|
|
95
|
-
</div>
|
|
96
|
-
)}
|
|
97
|
-
</div>
|
|
98
|
-
);
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export default Input;
|
|
102
|
-
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
Continuing from our `Form` example we can wrap the `Input` component above as follows:
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
import { build, group, control } from '@reactables/forms';
|
|
109
|
-
import { useReactable } from '@reactables/react-helpers';
|
|
110
|
-
import { Form, Field } from '@reactables/react-forms';
|
|
111
|
-
import Input from './Input';
|
|
112
|
-
|
|
113
|
-
const userConfig = group({
|
|
114
|
-
controls: {
|
|
115
|
-
name: control(['', 'required']),
|
|
116
|
-
email: control(['', ['required', 'email']]),
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const MyForm = () => {
|
|
121
|
-
const rxForm = useReactable(() => build(userConfig));
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<Form rxForm={rxForm}>
|
|
125
|
-
<Field name="name" label="Name:" component={Input} />
|
|
126
|
-
<Field name="email" label="Email: " component={Input} />
|
|
127
|
-
</Form>
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
export default MyForm;
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### `FormArray`<a name="form-array"></a>
|
|
136
|
-
|
|
137
|
-
`FormArray` uses the function as children pattern and makes available the `array` items as well as `pushControl` and `removeControl` action methods.
|
|
138
|
-
|
|
139
|
-
[See full example on StackBlitz](https://stackblitz.com/edit/vitejs-vite-fmst4h?file=src%2FMyForm.tsx)
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
import { build, group, control, array } from '@reactables/forms';
|
|
143
|
-
import { useReactable } from '@reactables/react';
|
|
144
|
-
import { Form, Field, FormArray } from '@reactables/react-forms';
|
|
145
|
-
import Input from './Input';
|
|
146
|
-
|
|
147
|
-
const userConfig = group({
|
|
148
|
-
controls: {
|
|
149
|
-
name: control(['', 'required']),
|
|
150
|
-
email: control(['', ['required', 'email']]),
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const MyForm = () => {
|
|
155
|
-
const rxForm = useReactable(() =>
|
|
156
|
-
build(
|
|
157
|
-
group({
|
|
158
|
-
controls: {
|
|
159
|
-
contacts: array({
|
|
160
|
-
controls: [userConfig],
|
|
161
|
-
}),
|
|
162
|
-
},
|
|
163
|
-
})
|
|
164
|
-
)
|
|
165
|
-
);
|
|
166
|
-
|
|
167
|
-
return (
|
|
168
|
-
<Form rxForm={rxForm}>
|
|
169
|
-
<FormArray name="contacts">
|
|
170
|
-
{({ items, pushControl, removeControl }) => {
|
|
171
|
-
return (
|
|
172
|
-
<>
|
|
173
|
-
{items.map((control, index) => {
|
|
174
|
-
return (
|
|
175
|
-
<div key={control.key}>
|
|
176
|
-
<Field name={`contacts.${index}.name`} label="Name:" component={Input} />
|
|
177
|
-
<Field name={`contacts.${index}.email`} label="Email: " component={Input} />
|
|
178
|
-
<button type="button" onClick={() => removeControl(index)}>
|
|
179
|
-
Remove contact
|
|
180
|
-
</button>
|
|
181
|
-
</div>
|
|
182
|
-
);
|
|
183
|
-
})}
|
|
184
|
-
<button type="button" onClick={() => pushControl(userConfig)}>
|
|
185
|
-
Add User
|
|
186
|
-
</button>
|
|
187
|
-
</>
|
|
188
|
-
);
|
|
189
|
-
}}
|
|
190
|
-
</FormArray>
|
|
191
|
-
</Form>
|
|
192
|
-
);
|
|
193
|
-
};
|
|
7
|
+
[See docs at https://reactables.github.io/reactables/react/react-form-components/](https://reactables.github.io/reactables/react/react-form-components/)
|
|
194
8
|
|
|
195
|
-
|
|
9
|
+
### Contact
|
|
196
10
|
|
|
197
|
-
|
|
11
|
+
Dave Lai
|
|
12
|
+
email: <a href="dlai@dave-lai.com">dlai@dave-lai.com</a>
|
|
13
|
+
<br>
|
|
14
|
+
<br>
|
|
15
|
+
Github: https://github.com/laidav
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"license": "ISC",
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@reactables/core": "*",
|
|
20
|
-
"@reactables/forms": "^1.0
|
|
20
|
+
"@reactables/forms": "^1.1.0",
|
|
21
21
|
"@reactables/react": "*"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
26
26
|
"rxjs": "^6.0.0 || ^7.0.0"
|
|
27
27
|
},
|
|
28
|
-
"version": "1.0
|
|
28
|
+
"version": "1.1.0"
|
|
29
29
|
}
|