Skip to content

Commit c107143

Browse files
committed
OneOfObjectForm example
1 parent 7f69074 commit c107143

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

example/src/OneOfObjectForm.tsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import React from "react";
2+
import { AnyListener, FormInput, FormState, Listener, useChildForm, useForm } from "typed-react-form";
3+
4+
interface Apple {
5+
type: "apple";
6+
color: string;
7+
}
8+
9+
interface Bread {
10+
type: "bread";
11+
size: number;
12+
}
13+
14+
interface FormData {
15+
object: Apple | Bread;
16+
}
17+
18+
export default function OneOfObjectArrayForm() {
19+
const form = useForm<FormData>({
20+
object: { type: "apple", color: "#ff0000" } // or { type: "bread", size: 200 }
21+
});
22+
return (
23+
<form
24+
style={{ margin: "0.5em" }}
25+
onReset={() => form.resetAll()}
26+
onSubmit={async (ev) => {
27+
ev.preventDefault();
28+
form.setState({ isSubmitting: true });
29+
await new Promise((res) => setTimeout(res, 500));
30+
form.setState({ isSubmitting: false });
31+
console.log(form.values);
32+
form.setDefaultValues(form.values);
33+
}}
34+
>
35+
<AppleOrBreadForm parent={form} />
36+
<AnyListener
37+
form={form}
38+
render={({ values, dirty }) => (
39+
<pre>
40+
{dirty ? "MODIFIED" : "UNMODIFIED"}
41+
<br />
42+
{JSON.stringify(values, null, 2)}
43+
</pre>
44+
)}
45+
/>
46+
<button>Submit!</button>
47+
<button type="reset">Reset</button>
48+
</form>
49+
);
50+
}
51+
52+
function AppleOrBreadForm(props: { parent: FormState<FormData> }) {
53+
const form = useChildForm(props.parent, "object");
54+
return (
55+
<div style={{ background: "#0001", padding: "1em", margin: "1em" }}>
56+
<label>Object type: </label>
57+
{/* You can also use the useListener hook instead */}
58+
<Listener
59+
form={form}
60+
name="type"
61+
render={({ value }) => (
62+
<>
63+
<select
64+
value={value}
65+
onChange={(ev) => {
66+
if (ev.target.value === "apple") form.setValues({ type: "apple", color: "#ff0000" });
67+
else if (ev.target.value === "bread") form.setValues({ type: "bread", size: 200 });
68+
}}
69+
>
70+
<option value="apple">Apple</option>
71+
<option value="bread">Bread</option>
72+
</select>
73+
74+
{/* Render AppleForm when the type is 'apple'. When type is 'bread', render BreadForm */}
75+
{value === "apple" ? <AppleForm form={form as FormState<Apple>} /> : <BreadForm form={form as FormState<Bread>} />}
76+
</>
77+
)}
78+
/>
79+
</div>
80+
);
81+
}
82+
83+
function AppleForm({ form }: { form: FormState<Apple> }) {
84+
return (
85+
<div>
86+
<h4>Apple editor</h4>
87+
<p>Select the color of your apple</p>
88+
<FormInput form={form} type="color" name="color" />
89+
</div>
90+
);
91+
}
92+
93+
function BreadForm({ form }: { form: FormState<Bread> }) {
94+
return (
95+
<div>
96+
<h4>Bread editor</h4>
97+
<p>Select the size of your bread</p>
98+
<FormInput form={form} type="number" name="size" />
99+
</div>
100+
);
101+
}

0 commit comments

Comments
 (0)