Skip to content

Commit 1f8808c

Browse files
committed
Fix FormInput usages & hideWhenNull prop
1 parent 8520e16 commit 1f8808c

File tree

4 files changed

+60
-54
lines changed

4 files changed

+60
-54
lines changed

src/Field.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,37 @@ export type FieldProps<T extends object, K extends keyof T, C> = {
1212
form: FormState<T>;
1313
name: K;
1414
as?: C;
15+
hideWhenNull?: boolean;
1516
serializer?: Serializer<T[K]>;
1617
deserializer?: Deserializer<T[K]>;
1718
};
1819

1920
export function Field<T extends object, K extends keyof T, C extends React.FunctionComponent<any> | keyof JSX.IntrinsicElements = "input">(
2021
props: FieldProps<T, K, C> & Omit<ElementProps<C>, "value" | "onChange" | keyof FieldProps<T, K, C> | keyof SerializeProps> & SerializeProps
2122
) {
22-
const { form, as = "input", serializer, dateAsNumber, setNullOnUncheck, setUndefinedOnUncheck, deserializer, ...rest } = props;
23+
const { form, as = "input", serializer, dateAsNumber, setNullOnUncheck, setUndefinedOnUncheck, deserializer, hideWhenNull, ...rest } = props;
2324
const serializeProps = {
2425
dateAsNumber,
2526
setNullOnUncheck,
2627
setUndefinedOnUncheck,
2728
type: props.type,
2829
value: props.value
2930
};
30-
const { value, setValue } = useListener(form, props.name);
31+
const { value, setValue, state } = useListener(form, props.name);
3132
const onChange = useCallback(
3233
(ev: any) => {
3334
let [v, c] = "target" in ev ? [ev.target.value, ev.target.checked] : [ev, typeof ev === "boolean" ? ev : undefined];
3435
setValue((deserializer ?? defaultDeserializer)(v, c, value, serializeProps));
3536
},
3637
[setValue]
3738
);
39+
if (hideWhenNull && (value === undefined || value === null)) return null;
3840
let v = (serializer ?? defaultSerializer)(value, serializeProps);
3941
return React.createElement(as, {
4042
...rest,
4143
checked: typeof v === "boolean" ? v : undefined,
4244
value: typeof v === "boolean" ? undefined : value,
45+
disabled: state.isSubmitting,
4346
onChange
4447
});
4548
}

testing/src/ExampleForm.tsx

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AnyListener, ArrayForm, ChildForm, ErrorMap, FormInput, FormSelect, FormTextArea, useForm } from "typed-react-form";
1+
import { AnyListener, ArrayForm, ChildForm, ErrorMap, Field, useForm } from "typed-react-form";
22
import tv, { SchemaType } from "typed-object-validator";
33
import React from "react";
44
import { VisualRender } from "./VisualRender";
@@ -37,15 +37,18 @@ export function ExampleForm() {
3737
{
3838
longText: "",
3939
text: "",
40+
customText: "nice",
4041
number: 123,
4142
enum: "option1",
4243
boolean: false,
4344
object: { childText: "", childNumber: 0 },
45+
date: new Date(),
4446
array: ["Item 1", "Item 2"],
4547
objectArray: [
4648
{ boolean: true, text: "Item 1" },
4749
{ boolean: false, text: "Item 2" }
48-
]
50+
],
51+
tags: ["food"]
4952
} as FormData,
5053
validate
5154
);
@@ -71,31 +74,31 @@ export function ExampleForm() {
7174

7275
{/* A simple text input */}
7376
<label>Text</label>
74-
<FormInput form={form} name="text" />
75-
<pre>{`<FormInput form={form} name="fieldName" />`}</pre>
77+
<Field form={form} name="text" />
78+
<pre>{`<Field form={form} name="fieldName" />`}</pre>
7679

7780
{/* A simple text input */}
7881
<label>Deserializer text</label>
79-
<FormInput form={form} name="customText" serializer={(e) => e?.toLowerCase()} deserializer={(e) => e.toUpperCase()} />
80-
<pre>{`<FormInput form={form} name="fieldName" />`}</pre>
82+
<Field form={form} name="customText" serializer={(e) => e?.toLowerCase()} deserializer={(e) => e.toUpperCase()} />
83+
<pre>{`<Field form={form} name="fieldName" />`}</pre>
8184

8285
{/* A textarea */}
8386
<label>Long text</label>
84-
<FormTextArea form={form} name="longText" />
87+
<Field form={form} name="longText" as="textarea" />
8588
<pre>{`<FormTextArea form={form} name="fieldName" />`}</pre>
8689

8790
{/* A number input */}
8891
<label>Number</label>
89-
<FormInput form={form} type="number" name="number" />
90-
<pre>{`<FormInput form={form} type="number" name="fieldName" />`}</pre>
92+
<Field form={form} type="number" name="number" />
93+
<pre>{`<Field form={form} type="number" name="fieldName" />`}</pre>
9194

9295
{/* A select input */}
9396
<label>Enum</label>
94-
<FormSelect form={form} name="enum">
97+
<Field form={form} as="select" name="enum">
9598
<option value="option1">Option 1</option>
9699
<option value="option2">Option 2</option>
97100
<option value="option3">Option 3</option>
98-
</FormSelect>
101+
</Field>
99102
<pre>{`
100103
<FormSelect form={form} name="fieldName">
101104
<option value="option1">Option 1</option>
@@ -106,65 +109,65 @@ export function ExampleForm() {
106109

107110
{/* A checkbox input */}
108111
<label>Boolean</label>
109-
<FormInput form={form} type="checkbox" name="boolean" />
110-
<pre>{`<FormInput form={form} type="checkbox" name="fieldName" />`}</pre>
112+
<Field form={form} type="checkbox" name="boolean" />
113+
<pre>{`<Field form={form} type="checkbox" name="fieldName" />`}</pre>
111114

112115
<label>Tags</label>
113116
<div>
114117
<label>
115118
Food
116-
<FormInput form={form} type="checkbox" name="tags" value="food" />
119+
<Field form={form} type="checkbox" name="tags" value="food" />
117120
</label>
118121
<label>
119122
Sports
120-
<FormInput form={form} type="checkbox" name="tags" value="sports" />
123+
<Field form={form} type="checkbox" name="tags" value="sports" />
121124
</label>
122125
<label>
123126
Tech
124-
<FormInput form={form} type="checkbox" name="tags" value="tech" />
127+
<Field form={form} type="checkbox" name="tags" value="tech" />
125128
</label>
126129
</div>
127-
<pre>{`<FormInput form={form} type="checkbox" name="fieldName" />`}</pre>
130+
<pre>{`<Field form={form} type="checkbox" name="fieldName" />`}</pre>
128131

129132
{/* A radio input */}
130133
<label>Enum</label>
131134
<div>
132135
<label>
133-
<FormInput form={form} type="radio" name="enum" value="option1" /> Option 1
136+
<Field form={form} type="radio" name="enum" value="option1" /> Option 1
134137
</label>
135138
<label>
136-
<FormInput form={form} type="radio" name="enum" value="option2" /> Option 2
139+
<Field form={form} type="radio" name="enum" value="option2" /> Option 2
137140
</label>
138141
<label>
139-
<FormInput form={form} type="radio" name="enum" value="option3" /> Option 3
142+
<Field form={form} type="radio" name="enum" value="option3" /> Option 3
140143
</label>
141144
</div>
142145
<pre>{`
143-
<FormInput form={form} type="radio" name="fieldName" value="option1" /> Option 1
144-
<FormInput form={form} type="radio" name="fieldName" value="option2" /> Option 2
145-
<FormInput form={form} type="radio" name="fieldName" value="option3" /> Option 3
146+
<Field form={form} type="radio" name="fieldName" value="option1" /> Option 1
147+
<Field form={form} type="radio" name="fieldName" value="option2" /> Option 2
148+
<Field form={form} type="radio" name="fieldName" value="option3" /> Option 3
146149
`}</pre>
147150

148151
{/* A date input */}
149152
<label>Date</label>
150-
<FormInput form={form} type="date" name="date" />
151-
<pre>{`<FormInput form={form} type="date" name="fieldName" />`}</pre>
153+
<Field form={form} type="date" name="date" />
154+
<pre>{`<Field form={form} type="date" name="fieldName" />`}</pre>
152155

153156
{/* A date timestamp input */}
154157
<label>Timestamp (number)</label>
155-
<FormInput form={form} type="date" name="number" dateAsNumber />
156-
<pre>{`<FormInput form={form} type="date" name="fieldName" dateAsNumber />`}</pre>
158+
<Field form={form} type="date" name="number" dateAsNumber />
159+
<pre>{`<Field form={form} type="date" name="fieldName" dateAsNumber />`}</pre>
157160

158161
{/* Toggle field */}
159162
<label>Toggle text</label>
160163
<div>
161-
<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
162-
<FormInput form={form} name="text" hideWhenNull />
164+
<Field form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
165+
<Field form={form} name="text" hideWhenNull />
163166
</div>
164167
<pre>
165168
{`
166-
<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
167-
<FormInput form={form} name="text" hideWhenNull />
169+
<Field form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
170+
<Field form={form} name="text" hideWhenNull />
168171
`}
169172
</pre>
170173

@@ -177,9 +180,9 @@ export function ExampleForm() {
177180
render={(form) => (
178181
<div style={{ background: "#0001" }}>
179182
<p>Text</p>
180-
<FormInput form={form} name="childText" />
183+
<Field form={form} name="childText" />
181184
<p>Number</p>
182-
<FormInput form={form} name="childNumber" type="number" />
185+
<Field form={form} name="childNumber" type="number" />
183186
</div>
184187
)}
185188
/>
@@ -191,7 +194,7 @@ export function ExampleForm() {
191194
name="parentObjectFieldName"
192195
render={(childForm) => (
193196
<div>
194-
<FormInput form={childForm} name="childFieldName" />
197+
<Field form={childForm} name="childFieldName" />
195198
</div>
196199
)}
197200
/>
@@ -200,10 +203,10 @@ export function ExampleForm() {
200203

201204
{/* Set object field to undefined on uncheck */}
202205
<label>Toggle object</label>
203-
<FormInput form={form} type="checkbox" name="object" setUndefinedOnUncheck value={{ childNumber: 0, childText: "" }} />
206+
<Field form={form} type="checkbox" name="object" setUndefinedOnUncheck value={{ childNumber: 0, childText: "" }} />
204207
<pre>
205208
{`
206-
<FormInput
209+
<Field
207210
form={form}
208211
type="checkbox"
209212
name="fieldName"
@@ -221,7 +224,7 @@ export function ExampleForm() {
221224
<ul>
222225
{form.values.map((_, i) => (
223226
<li key={i}>
224-
<FormInput form={form} name={i} />
227+
<Field form={form} name={i} />
225228
</li>
226229
))}
227230
</ul>
@@ -236,7 +239,7 @@ export function ExampleForm() {
236239
<ul>
237240
{form.values.map((_, i) => (
238241
<li key={i}>
239-
<FormInput form={form} name={i} />
242+
<Field form={form} name={i} />
240243
</li>
241244
))}
242245
</ul>
@@ -253,7 +256,7 @@ export function ExampleForm() {
253256
<ul>
254257
{form.values.map((_, i) => (
255258
<li key={i}>
256-
<FormInput form={form} name={i} />
259+
<Field form={form} name={i} />
257260
<button onClick={() => remove(i)}>Remove</button>
258261
</li>
259262
))}
@@ -273,7 +276,7 @@ export function ExampleForm() {
273276
<ul>
274277
{form.values.map((_, i) => (
275278
<li key={i}>
276-
<FormInput form={form} name={i} />
279+
<Field form={form} name={i} />
277280
<button onClick={() => remove(i)}>Remove</button>
278281
</li>
279282
))}
@@ -299,8 +302,8 @@ export function ExampleForm() {
299302
name={i}
300303
render={(form) => (
301304
<div>
302-
<FormInput form={form} name="text" />
303-
<FormInput form={form} name="boolean" type="checkbox" />
305+
<Field form={form} name="text" />
306+
<Field form={form} name="boolean" type="checkbox" />
304307
</div>
305308
)}
306309
/>
@@ -321,7 +324,7 @@ export function ExampleForm() {
321324
name={i}
322325
render={(form) => (
323326
<div>
324-
<FormInput form={form} name="objectFieldName" />
327+
<Field form={form} name="objectFieldName" />
325328
</div>
326329
)}
327330
/>
@@ -344,8 +347,8 @@ export function ExampleForm() {
344347
name={i}
345348
render={(form) => (
346349
<div>
347-
<FormInput form={form} name="text" />
348-
<FormInput form={form} name="boolean" type="checkbox" />
350+
<Field form={form} name="text" />
351+
<Field form={form} name="boolean" type="checkbox" />
349352
<button type="button" onClick={() => remove(i)}>
350353
Remove
351354
</button>
@@ -372,7 +375,7 @@ export function ExampleForm() {
372375
name={i}
373376
render={(form) => (
374377
<div>
375-
<FormInput form={form} name="objectFieldName" />
378+
<Field form={form} name="objectFieldName" />
376379
<button type="button" onClick={() => remove(i)}>
377380
Remove
378381
</button>

testing/src/OneOfObjectArrayForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { AnyListener, ArrayForm, FormInput, FormState, useChildForm, useForm, useListener } from "typed-react-form";
2+
import { AnyListener, ArrayForm, Field, FormState, useChildForm, useForm, useListener } from "typed-react-form";
33

44
interface Apple {
55
type: "apple";
@@ -116,7 +116,7 @@ function AppleForm({ form }: { form: FormState<Apple> }) {
116116
<div>
117117
<h4>Apple editor</h4>
118118
<p>Select the color of your apple</p>
119-
<FormInput form={form} type="color" name="color" />
119+
<Field form={form} type="color" name="color" />
120120
</div>
121121
);
122122
}
@@ -126,7 +126,7 @@ function BreadForm({ form }: { form: FormState<Bread> }) {
126126
<div>
127127
<h4>Bread editor</h4>
128128
<p>Select the size of your bread</p>
129-
<FormInput form={form} type="number" name="size" />
129+
<Field form={form} type="number" name="size" />
130130
</div>
131131
);
132132
}

testing/src/OneOfObjectForm.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from "react";
2-
import { AnyListener, FormInput, FormState, Listener, useChildForm, useForm } from "typed-react-form";
2+
import { AnyListener, Field, FormState, Listener, useChildForm, useForm } from "typed-react-form";
33

44
interface Apple {
55
type: "apple";
@@ -95,7 +95,7 @@ function AppleForm({ form }: { form: FormState<Apple> }) {
9595
<div>
9696
<h4>Apple editor</h4>
9797
<p>Select the color of your apple</p>
98-
<FormInput form={form} type="color" name="color" />
98+
<Field form={form} type="color" name="color" />
9999
</div>
100100
);
101101
}
@@ -105,7 +105,7 @@ function BreadForm({ form }: { form: FormState<Bread> }) {
105105
<div>
106106
<h4>Bread editor</h4>
107107
<p>Select the size of your bread</p>
108-
<FormInput form={form} type="number" name="size" />
108+
<Field form={form} type="number" name="size" />
109109
</div>
110110
);
111111
}

0 commit comments

Comments
 (0)