Skip to content

Commit 7f70eaa

Browse files
committed
Fixed typos
1 parent cc61aad commit 7f70eaa

File tree

7 files changed

+192
-57
lines changed

7 files changed

+192
-57
lines changed

articles/Array-fields.md

Lines changed: 9 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,12 @@ function NotesList() {
2626
}}
2727
>
2828
<ArrayForm
29-
parent={form}
29+
form={form}
3030
name="notes"
3131
render={({ form, values, append, remove }) => (
3232
<>
33-
{values.map((
34-
_,
35-
i // You SHOULD use index as key. See top for info.
36-
) => (
33+
{/* You SHOULD use index as key. See top for info. */}
34+
{values.map((_, i) => (
3735
<div key={i}>
3836
<FormInput form={form} name={i} />
3937
<button type="button" onClick={() => remove(i)}>
@@ -74,18 +72,20 @@ function ShoppingListForm() {
7472
<h2>Title</h2>
7573
<FormInput form={form} type="text" name="title" />
7674

75+
{/* Create an array child form for the 'items' field */}
7776
<h2>Items</h2>
78-
<ArrayForm // Create an array child form for the 'items' field
79-
parent={form}
77+
<ArrayForm
78+
form={form}
8079
name="items"
8180
render={({ form, values, append, remove }) => (
8281
<>
8382
{/* This only rerenders when the whole array changes. */}
8483

8584
{values.map((_, i) => (
86-
<ChildForm // Create a child form for each item in the array, because each array item is an object.
85+
// Create a child form for each item in the array, because each array item is an object.
86+
<ChildForm
8787
key={i} // You should index as key
88-
parent={form} // Pass the parent form
88+
form={form} // Pass the parent form
8989
name={i} // Pass the current index as the name
9090
render={(form) => (
9191
<div>
@@ -221,45 +221,3 @@ function AnswerForm() {
221221
);
222222
}
223223
```
224-
225-
✔️ **Fixed array field containing objects**
226-
227-
```tsx
228-
function SettingsForm() {
229-
const form = useForm({
230-
settings: [
231-
{ name: "Enable email", value: true },
232-
{ name: "Enable notifications", value: false },
233-
],
234-
});
235-
return (
236-
<form
237-
onSubmit={(ev) => {
238-
ev.preventDefault();
239-
console.log("submit", form.values);
240-
}}
241-
>
242-
<ChildForm // First child form is array
243-
parent={form}
244-
name="settings"
245-
render={(form) =>
246-
form.values.map((_, i) => (
247-
<ChildForm // Second child form is object in array
248-
key={i}
249-
parent={form}
250-
name={i}
251-
render={(form) => (
252-
<div>
253-
<p>{form.values.name}</p>
254-
<FormInput form={form} name="value" type="checkbox" />
255-
</div>
256-
)}
257-
/>
258-
))
259-
}
260-
/>
261-
<button>Submit</button>
262-
</form>
263-
);
264-
}
265-
```

articles/Custom-input.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ If the default input types (FormInput, FormSelect ...) do not provide enough fun
66

77
The following code resembles a custom input component that shows an error when needed, paints gray background when modified, gets disabled when submitting and shows its defaultValue as a placeholder. You can tweak this custom input further by implementing transformations for different input types, allowing `HTMLInputAttributes` etc.
88

9+
The builtin inputs are also just abstractions around the useListener hook.
10+
911
```tsx
1012
function CustomInput<T>(props: { form: FormState<T>; name: keyof T; children?: React.ReactNode }) {
1113
const { value, error, dirty, setValue, state, defaultValue } = useListener(props.form, props.name);

articles/FormInput.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,4 @@ Make sure you pass along a `value` too, this is the value that will be set when
152152

153153
---
154154

155-
All of the input components are wrappers and abstractions around the [`useListener`](/docs/useListener) hook. Using this hook, you can create your own [custom inputs](/docs/Custom-inputs).
155+
All of the input components are wrappers and abstractions around the [`useListener`](/docs/useListener) hook. Using this hook, you can create your own [custom inputs](/docs/Custom-input).

articles/Getting-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ Tweak the above example to your desire by...
115115

116116
- [Reading more about `FormInput`](/docs/FormInput)
117117
- [Implementing validation](/docs/Validation)
118-
- [Adding object fields](/docs/Object-fields)
119-
- [Adding array fields](/docs/Array-fields)
118+
- [Using object fields](/docs/Object-fields)
119+
- [Using array fields](/docs/Array-fields)
120120
- [Toggling a field using a checkbox](/docs/Toggling-a-field)
121121
- [Creating a component which shows the current form values in JSON](/docs/Live-json-component)
122122
- [Creating a custom input like FormInput, FormSelect ...](/docs/Custom-input)

articles/Object-fields.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function PersonForm() {
2828
{/* Input on root form */}
2929
<FormInput form={form} type="text" name="name" />
3030
<ChildForm
31-
parent={form}
31+
form={form}
3232
name="info"
3333
render={(form) => (
3434
<>

articles/Toggling-a-field.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function ToggleForm() {
5151
<FormInput form={form} name="location" type="checkbox" setNullOnUncheck />
5252
{/* ChildForm hides its contents when null/undefined by default */}
5353
<ChildForm
54-
parent={form}
54+
form={form}
5555
name="location"
5656
render={(form) => (
5757
<>

pages/docs/test.tsx

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import React from "react";
2-
import { AnyListener, FormInput, useForm } from "typed-react-form";
2+
import {
3+
AnyListener,
4+
FormInput,
5+
useForm,
6+
ArrayForm,
7+
ChildForm,
8+
FormState,
9+
useAnyListener,
10+
ErrorMap,
11+
FormError,
12+
} from "typed-react-form";
313

414
function MyForm() {
515
const form = useForm({ email: "" });
@@ -38,12 +48,177 @@ function MyForm2() {
3848
);
3949
}
4050

51+
function ShoppingListForm() {
52+
const form = useForm({
53+
title: "My shopping list",
54+
items: [{ name: "Coffee", amount: 1 }],
55+
});
56+
57+
return (
58+
<form
59+
onSubmit={(ev) => {
60+
ev.preventDefault();
61+
console.log("submit", form.values);
62+
}}
63+
>
64+
<h2>Title</h2>
65+
<FormInput form={form} type="text" name="title" />
66+
67+
{/* Create an array child form for the 'items' field */}
68+
<h2>Items</h2>
69+
<ArrayForm
70+
form={form}
71+
name="items"
72+
render={({ form, values, append, remove }) => (
73+
<>
74+
{/* This only rerenders when the whole array changes. */}
75+
76+
{values.map((_, i) => (
77+
// Create a child form for each item in the array, because each array item is an object.
78+
<ChildForm
79+
key={i} // You should index as key
80+
form={form} // Pass the parent form
81+
name={i} // Pass the current index as the name
82+
render={(form) => (
83+
<div>
84+
{/* Everything here is type-checked! */}
85+
<FormInput form={form} type="text" name="name" />
86+
<FormInput form={form} type="number" name="amount" />
87+
<button type="button" onClick={() => remove(i)}>
88+
Remove
89+
</button>
90+
</div>
91+
)}
92+
/>
93+
))}
94+
95+
{/* Use the append helper function to add an item to the array */}
96+
<button type="button" onClick={() => append({ name: "", amount: 1 })}>
97+
Add item
98+
</button>
99+
</>
100+
)}
101+
/>
102+
<button>Submit</button>
103+
</form>
104+
);
105+
}
106+
107+
function ToggleForm() {
108+
const form = useForm({
109+
name: "codestix",
110+
location: { long: 123, lat: 456 }, // Object field
111+
});
112+
return (
113+
<form
114+
onSubmit={(ev) => {
115+
ev.preventDefault();
116+
console.log("submit", form.values);
117+
}}
118+
>
119+
<FormInput form={form} name="name" type="text" />
120+
121+
{/* Use the setNullOnUncheck prop. The value prop contains the value that is set when the box gets checked again, you can omit it to use the default value */}
122+
<FormInput form={form} name="location" type="checkbox" setNullOnUncheck />
123+
{/* ChildForm hides its contents when null/undefined by default */}
124+
<ChildForm
125+
form={form}
126+
name="location"
127+
render={(form) => (
128+
<>
129+
<p>Location lat/long</p>
130+
<FormInput form={form} name="lat" type="number" />
131+
<FormInput form={form} name="long" type="number" />
132+
</>
133+
)}
134+
/>
135+
<button>Submit</button>
136+
</form>
137+
);
138+
}
139+
140+
// Take a form containing any values
141+
function FormJson(props: { form: FormState<any> }) {
142+
// Listen for all changes on the form
143+
const { values } = useAnyListener(props.form);
144+
// Show the json representation of the values in the form
145+
return <pre>{JSON.stringify(values, null, 2)}</pre>;
146+
}
147+
148+
// Usage
149+
function ExampleForm() {
150+
const form = useForm({ name: "John", age: 19 });
151+
return (
152+
<form
153+
style={{ margin: "1em" }}
154+
onSubmit={async (ev) => {
155+
ev.preventDefault();
156+
console.log("submit", form.values);
157+
}}
158+
>
159+
<FormInput form={form} name="name" />
160+
<FormInput type="number" form={form} name="age" />
161+
{/* Use your component, pass the form */}
162+
<FormJson form={form} />
163+
{/* Using AnyListener, provides the same functionality */}
164+
<AnyListener form={form} render={({ values }) => <pre>{JSON.stringify(values, null, 2)}</pre>} />
165+
<button>Submit</button>
166+
</form>
167+
);
168+
}
169+
170+
interface LoginRequest {
171+
email: string;
172+
password: string;
173+
}
174+
175+
// May be async if needed
176+
function loginValidator(values: LoginRequest): ErrorMap<LoginRequest, string> {
177+
// Example validator logic, the returned error object should follow the same structure as the values object.
178+
return {
179+
email: values.email.length < 10 ? "Email must be longer" : undefined,
180+
password: values.password.length < 5 ? "Password must be longer" : undefined,
181+
};
182+
}
183+
184+
function FormExample() {
185+
const form = useForm<LoginRequest>(
186+
{ email: "", password: "" },
187+
loginValidator, // Pass loginValidator to useForm
188+
true, // Validate on change (false by default)
189+
false // Validate on mount (false by default)
190+
);
191+
return (
192+
<form
193+
onSubmit={(ev) => {
194+
ev.preventDefault();
195+
console.log("submit", form.values);
196+
}}
197+
>
198+
<FormInput form={form} name="email" type="email" />
199+
<FormError form={form} name="email" />
200+
<FormInput form={form} name="password" type="password" />
201+
<FormError form={form} name="password" />
202+
{/* Listen for any change on the form, and disable the submit button when there is an error */}
203+
<AnyListener form={form} render={(form) => <button disabled={form.error}>Submit</button>} />
204+
</form>
205+
);
206+
}
207+
41208
export default function Testing() {
42209
return (
43210
<>
44211
<MyForm />
45212
<hr />
46213
<MyForm2 />
214+
<hr />
215+
<ShoppingListForm />
216+
<hr />
217+
<ToggleForm />
218+
<hr />
219+
<ExampleForm />
220+
<hr />
221+
<FormExample />
47222
</>
48223
);
49224
}

0 commit comments

Comments
 (0)