Skip to content

Commit 2e54a21

Browse files
committed
Example form
1 parent f49e7f1 commit 2e54a21

File tree

2 files changed

+169
-2
lines changed

2 files changed

+169
-2
lines changed

example/src/ExampleForm.tsx

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
import { AnyListener, ChildForm, ErrorMap, FormInput, FormSelect, FormTextArea, useForm } from "typed-react-form";
2+
import tv, { SchemaType } from "typed-object-validator";
3+
import React from "react";
4+
import { VisualRender } from "./VisualRender";
5+
6+
// Example validation schema using typed-object-validator
7+
const FormDataSchema = tv.object({
8+
text: tv.string().min(1).max(30),
9+
longText: tv.string(),
10+
enum: tv.value("option1").or(tv.value("option2")).or(tv.value("option3")),
11+
number: tv.number(),
12+
boolean: tv.boolean(),
13+
date: tv.date(),
14+
object: tv.object({
15+
childText: tv.string(),
16+
childNumber: tv.number()
17+
})
18+
});
19+
type FormData = SchemaType<typeof FormDataSchema>;
20+
21+
function validate(data: FormData) {
22+
return (FormDataSchema.validate(data) as ErrorMap<FormData, string>) ?? {};
23+
}
24+
25+
export function ExampleForm() {
26+
// Initial values as first argument
27+
const form = useForm(
28+
{ longText: "", text: "", number: 123, enum: "option1", boolean: false, object: { childText: "", childNumber: 0 } } as FormData,
29+
validate
30+
);
31+
32+
function submit() {
33+
console.log(form.values);
34+
}
35+
36+
return (
37+
<form
38+
onSubmit={form.handleSubmit(submit)}
39+
style={{ display: "grid", gridTemplateColumns: "125px 300px 1fr", width: "300px", margin: "2em", gap: "1em 2em", alignItems: "center" }}
40+
>
41+
{/* Show JSON representation */}
42+
<AnyListener
43+
form={form}
44+
render={() => (
45+
<pre style={{ gridColumn: "span 3" }}>
46+
<VisualRender>{JSON.stringify(form.values, null, 2)}</VisualRender>
47+
</pre>
48+
)}
49+
/>
50+
51+
{/* A simple text input */}
52+
<label>Text</label>
53+
<FormInput form={form} name="text" />
54+
<pre>{`<FormInput form={form} name="fieldName" />`}</pre>
55+
56+
{/* A textarea */}
57+
<label>Long text</label>
58+
<FormTextArea form={form} name="longText" />
59+
<pre>{`<FormTextArea form={form} name="fieldName" />`}</pre>
60+
61+
{/* A number input */}
62+
<label>Number</label>
63+
<FormInput form={form} type="number" name="number" />
64+
<pre>{`<FormInput form={form} type="number" name="fieldName" />`}</pre>
65+
66+
{/* A select input */}
67+
<label>Enum</label>
68+
<FormSelect form={form} name="enum">
69+
<option value="option1">Option 1</option>
70+
<option value="option2">Option 2</option>
71+
<option value="option3">Option 3</option>
72+
</FormSelect>
73+
<pre>{`
74+
<FormSelect form={form} name="fieldName">
75+
<option value="option1">Option 1</option>
76+
<option value="option2">Option 2</option>
77+
<option value="option3">Option 3</option>
78+
</FormSelect>
79+
`}</pre>
80+
81+
{/* A checkbox input */}
82+
<label>Boolean</label>
83+
<FormInput form={form} type="checkbox" name="boolean" />
84+
<pre>{`<FormInput form={form} type="checkbox" name="fieldName" />`}</pre>
85+
86+
{/* A radio input */}
87+
<label>Enum</label>
88+
<div>
89+
<label>
90+
<FormInput form={form} type="radio" name="enum" value="option1" /> Option 1
91+
</label>
92+
<label>
93+
<FormInput form={form} type="radio" name="enum" value="option2" /> Option 2
94+
</label>
95+
<label>
96+
<FormInput form={form} type="radio" name="enum" value="option3" /> Option 3
97+
</label>
98+
</div>
99+
<pre>{`
100+
<FormInput form={form} type="radio" name="fieldName" value="option1" /> Option 1
101+
<FormInput form={form} type="radio" name="fieldName" value="option2" /> Option 2
102+
<FormInput form={form} type="radio" name="fieldName" value="option3" /> Option 3
103+
`}</pre>
104+
105+
{/* A date input */}
106+
<label>Date</label>
107+
<FormInput form={form} type="date" name="date" />
108+
<pre>{`<FormInput form={form} type="date" name="fieldName" />`}</pre>
109+
110+
{/* A date timestamp input */}
111+
<label>Timestamp (number)</label>
112+
<FormInput form={form} type="date" name="number" dateAsNumber />
113+
<pre>{`<FormInput form={form} type="date" name="fieldName" dateAsNumber />`}</pre>
114+
115+
{/* Toggle field */}
116+
<label>Toggle text</label>
117+
<div>
118+
<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
119+
<FormInput form={form} name="text" hideWhenNull />
120+
</div>
121+
<pre>{`
122+
<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
123+
<FormInput form={form} name="text" hideWhenNull />
124+
`}</pre>
125+
126+
{/* Object field */}
127+
<label>Object field</label>
128+
<div>
129+
<ChildForm
130+
form={form}
131+
name="object"
132+
render={(form) => (
133+
<div style={{ background: "#0001" }}>
134+
<p>Text</p>
135+
<FormInput form={form} name="childText" />
136+
<p>Number</p>
137+
<FormInput form={form} name="childNumber" type="number" />
138+
</div>
139+
)}
140+
/>
141+
</div>
142+
<pre>{`
143+
<ChildForm
144+
form={form}
145+
name="parentObjectFieldName"
146+
render={(childForm) => (
147+
<div>
148+
<FormInput form={childForm} name="childFieldName" />
149+
</div>
150+
)}
151+
/>
152+
`}</pre>
153+
154+
{/* Set object field to undefined on uncheck */}
155+
<label>Toggle object</label>
156+
<FormInput form={form} type="checkbox" name="object" setUndefinedOnUncheck value={{ childNumber: 0, childText: "" }} />
157+
<pre>{`
158+
<FormInput
159+
form={form}
160+
type="checkbox"
161+
name="fieldName"
162+
setUndefinedOnUncheck
163+
value={{ childDefaultFieldValue: "" }}
164+
/> `}</pre>
165+
</form>
166+
);
167+
}

example/src/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import "./index.css";
22

33
import React from "react";
44
import ReactDOM from "react-dom";
5-
import App from "./App";
65
import OneOfObjectForm from "./OneOfObjectForm";
76
import OneOfObjectArrayForm from "./OneOfObjectArrayForm";
87
import { BrowserRouter, Route, Switch } from "react-router-dom";
98
import { StyledForm } from "./StyledForm";
9+
import { ExampleForm } from "./ExampleForm";
1010

1111
function Router() {
1212
return (
@@ -15,7 +15,7 @@ function Router() {
1515
<Route path="/object-types" component={OneOfObjectForm} />
1616
<Route path="/object-types-array" component={OneOfObjectArrayForm} />
1717
<Route path="/styled-form" component={StyledForm} />
18-
<Route path="/" component={App} />
18+
<Route path="/" component={ExampleForm} />
1919
</Switch>
2020
</BrowserRouter>
2121
);

0 commit comments

Comments
 (0)