1- import { AnyListener , ChildForm , ErrorMap , FormInput , FormSelect , FormTextArea , useForm } from "typed-react-form" ;
1+ import { AnyListener , ArrayForm , ChildForm , ErrorMap , FormInput , FormSelect , FormTextArea , useForm } from "typed-react-form" ;
22import tv , { SchemaType } from "typed-object-validator" ;
33import React from "react" ;
44import { VisualRender } from "./VisualRender" ;
@@ -14,7 +14,14 @@ const FormDataSchema = tv.object({
1414 object : tv . object ( {
1515 childText : tv . string ( ) ,
1616 childNumber : tv . number ( )
17- } )
17+ } ) ,
18+ array : tv . array ( tv . string ( ) ) ,
19+ objectArray : tv . array (
20+ tv . object ( {
21+ text : tv . string ( ) ,
22+ boolean : tv . boolean ( )
23+ } )
24+ )
1825} ) ;
1926type FormData = SchemaType < typeof FormDataSchema > ;
2027
@@ -25,7 +32,19 @@ function validate(data: FormData) {
2532export function ExampleForm ( ) {
2633 // Initial values as first argument
2734 const form = useForm (
28- { longText : "" , text : "" , number : 123 , enum : "option1" , boolean : false , object : { childText : "" , childNumber : 0 } } as FormData ,
35+ {
36+ longText : "" ,
37+ text : "" ,
38+ number : 123 ,
39+ enum : "option1" ,
40+ boolean : false ,
41+ object : { childText : "" , childNumber : 0 } ,
42+ array : [ "Item 1" , "Item 2" ] ,
43+ objectArray : [
44+ { boolean : true , text : "Item 1" } ,
45+ { boolean : false , text : "Item 2" }
46+ ]
47+ } as FormData ,
2948 validate
3049 ) ;
3150
@@ -118,10 +137,12 @@ export function ExampleForm() {
118137 < FormInput form = { form } type = "checkbox" name = "text" setUndefinedOnUncheck value = "" />
119138 < FormInput form = { form } name = "text" hideWhenNull />
120139 </ div >
121- < pre > { `
140+ < pre >
141+ { `
122142<FormInput form={form} type="checkbox" name="text" setUndefinedOnUncheck value="" />
123143<FormInput form={form} name="text" hideWhenNull />
124- ` } </ pre >
144+ ` }
145+ </ pre >
125146
126147 { /* Object field */ }
127148 < label > Object field</ label >
@@ -139,7 +160,8 @@ export function ExampleForm() {
139160 ) }
140161 />
141162 </ div >
142- < pre > { `
163+ < pre >
164+ { `
143165<ChildForm
144166 form={form}
145167 name="parentObjectFieldName"
@@ -149,19 +171,198 @@ export function ExampleForm() {
149171 </div>
150172)}
151173/>
152- ` } </ pre >
174+ ` }
175+ </ pre >
153176
154177 { /* Set object field to undefined on uncheck */ }
155178 < label > Toggle object</ label >
156179 < FormInput form = { form } type = "checkbox" name = "object" setUndefinedOnUncheck value = { { childNumber : 0 , childText : "" } } />
157- < pre > { `
180+ < pre >
181+ { `
158182<FormInput
159183 form={form}
160184 type="checkbox"
161185 name="fieldName"
162186 setUndefinedOnUncheck
163187 value={{ childDefaultFieldValue: "" }}
164- /> ` } </ pre >
188+ /> ` }
189+ </ pre >
190+
191+ { /* Simple string array */ }
192+ < label > String array</ label >
193+ < ArrayForm
194+ form = { form }
195+ name = "array"
196+ render = { ( { form } ) => (
197+ < ul >
198+ { form . values . map ( ( _ , i ) => (
199+ < li key = { i } >
200+ < FormInput form = { form } name = { i } />
201+ </ li >
202+ ) ) }
203+ </ ul >
204+ ) }
205+ />
206+ < pre >
207+ { `
208+ <ArrayForm
209+ form={form}
210+ name="array"
211+ render={({ form }) => (
212+ <ul>
213+ {form.values.map((_, i) => (
214+ <li key={i}>
215+ <FormInput form={form} name={i} />
216+ </li>
217+ ))}
218+ </ul>
219+ )}
220+ />` }
221+ </ pre >
222+
223+ { /* Dynamic string array */ }
224+ < label > Dynamic string array</ label >
225+ < ArrayForm
226+ form = { form }
227+ name = "array"
228+ render = { ( { form, append, remove } ) => (
229+ < ul >
230+ { form . values . map ( ( _ , i ) => (
231+ < li key = { i } >
232+ < FormInput form = { form } name = { i } />
233+ < button onClick = { ( ) => remove ( i ) } > Remove</ button >
234+ </ li >
235+ ) ) }
236+ < button type = "button" onClick = { ( ) => append ( "" ) } >
237+ Add
238+ </ button >
239+ </ ul >
240+ ) }
241+ />
242+ < pre >
243+ { `
244+ <ArrayForm
245+ form={form}
246+ name="arrayFieldName"
247+ render={({ form, append, remove }) => (
248+ <div>
249+ <ul>
250+ {form.values.map((_, i) => (
251+ <li key={i}>
252+ <FormInput form={form} name={i} />
253+ <button onClick={() => remove(i)}>Remove</button>
254+ </li>
255+ ))}
256+ </ul>
257+ <button type="button" onClick={() => append("")}>
258+ Add
259+ </button>
260+ </div>
261+ )}
262+ /> ` }
263+ </ pre >
264+
265+ { /* Object array */ }
266+ < label > Object array</ label >
267+ < ArrayForm
268+ form = { form }
269+ name = "objectArray"
270+ render = { ( { form } ) => (
271+ < ul >
272+ { form . values . map ( ( _ , i ) => (
273+ < ChildForm
274+ form = { form }
275+ name = { i }
276+ render = { ( form ) => (
277+ < div >
278+ < FormInput form = { form } name = "text" />
279+ < FormInput form = { form } name = "boolean" type = "checkbox" />
280+ </ div >
281+ ) }
282+ />
283+ ) ) }
284+ </ ul >
285+ ) }
286+ />
287+ < pre >
288+ { `
289+ <ArrayForm
290+ form={form}
291+ name="objectArrayField"
292+ render={({ form }) => (
293+ <ul>
294+ {form.values.map((_, i) => (
295+ <ChildForm
296+ form={form}
297+ name={i}
298+ render={(form) => (
299+ <div>
300+ <FormInput form={form} name="objectFieldName" />
301+ </div>
302+ )}
303+ />
304+ ))}
305+ </ul>
306+ )}
307+ /> ` }
308+ </ pre >
309+
310+ { /* Dynamic object array */ }
311+ < label > Dynamic object array</ label >
312+ < ArrayForm
313+ form = { form }
314+ name = "objectArray"
315+ render = { ( { form, append, remove } ) => (
316+ < ul >
317+ { form . values . map ( ( _ , i ) => (
318+ < ChildForm
319+ form = { form }
320+ name = { i }
321+ render = { ( form ) => (
322+ < div >
323+ < FormInput form = { form } name = "text" />
324+ < FormInput form = { form } name = "boolean" type = "checkbox" />
325+ < button type = "button" onClick = { ( ) => remove ( i ) } >
326+ Remove
327+ </ button >
328+ </ div >
329+ ) }
330+ />
331+ ) ) }
332+ < button type = "button" onClick = { ( ) => append ( { text : "" , boolean : false } ) } >
333+ Add item
334+ </ button >
335+ </ ul >
336+ ) }
337+ />
338+ < pre >
339+ { `
340+ <ArrayForm
341+ form={form}
342+ name="objectArrayField"
343+ render={({ form, append, remove }) => (
344+ <ul>
345+ {form.values.map((_, i) => (
346+ <ChildForm
347+ form={form}
348+ name={i}
349+ render={(form) => (
350+ <div>
351+ <FormInput form={form} name="objectFieldName" />
352+ <button type="button" onClick={() => remove(i)}>
353+ Remove
354+ </button>
355+ </div>
356+ )}
357+ />
358+ ))}
359+ <button type="button" onClick={() => append({ objectFieldName: "default value" })}>
360+ Add item
361+ </button>
362+ </ul>
363+ )}
364+ />` }
365+ </ pre >
165366 </ form >
166367 ) ;
167368}
0 commit comments