@@ -72,6 +72,9 @@ type State = {
72
72
73
73
/** User has opted for inline filters in the Select */
74
74
hasInlineFilter ?: boolean
75
+
76
+ /** Current form state (if any) */
77
+ form ?: Record < string , string >
75
78
}
76
79
77
80
/**
@@ -88,9 +91,20 @@ export default class AskUI extends React.PureComponent<Props, State> {
88
91
public static getDerivedStateFromProps ( props : Props , state : State ) {
89
92
if ( state . userSelection && props . ask . prompt . choices . find ( ( _ ) => _ . name === state . userSelection ) ) {
90
93
return state
94
+ } else if ( state . form ) {
95
+ // there has been an update to the form, nothing to do here
96
+ return state
91
97
} else {
92
98
const suggested = props . ask . prompt . choices . find ( ( _ ) => ( _ as any ) [ "isSuggested" ] )
99
+ const form =
100
+ ! props . ask || ! Prompts . isForm ( props . ask . prompt )
101
+ ? undefined
102
+ : props . ask . prompt . choices . reduce ( ( M , _ ) => {
103
+ M [ _ . name ] = ( _ as any ) [ "initial" ]
104
+ return M
105
+ } , { } as Record < string , string > )
93
106
return {
107
+ form,
94
108
userSelection : ! suggested ? undefined : suggested . name ,
95
109
}
96
110
}
@@ -170,9 +184,9 @@ export default class AskUI extends React.PureComponent<Props, State> {
170
184
171
185
/** User has clicked to submit a form */
172
186
private readonly _onFormSubmit = ( evt : React . SyntheticEvent ) => {
173
- if ( this . props . ask ) {
187
+ if ( this . props . ask && this . state . form ) {
174
188
evt . preventDefault ( )
175
- this . props . ask . onChoose ( Promise . resolve ( this . _form ) )
189
+ this . props . ask . onChoose ( Promise . resolve ( this . state . form ) )
176
190
}
177
191
return false
178
192
}
@@ -319,15 +333,18 @@ export default class AskUI extends React.PureComponent<Props, State> {
319
333
return "multiselect"
320
334
}
321
335
322
- private _form : Record < string , string > = { }
323
-
324
- private form ( ask : Ask < Prompts . Form > ) {
325
- const form = ask . prompt . choices . reduce ( ( M , _ ) => {
326
- M [ _ . name ] = ( _ as any ) [ "initial" ]
327
- return M
328
- } , { } as Record < string , string > )
329
- this . _form = form
336
+ /** User has edited the form */
337
+ private readonly _onFormChange = ( value : string , evt : React . FormEvent < HTMLInputElement > ) => {
338
+ const name = evt . currentTarget . getAttribute ( "data-name" )
339
+ if ( name && this . state . form ) {
340
+ this . setState ( ( curState ) =>
341
+ ! curState . form ? null : { form : Object . assign ( { } , curState . form , { [ name ] : value } ) }
342
+ )
343
+ }
344
+ }
330
345
346
+ /** Render a form ui */
347
+ private form ( ask : Ask < Prompts . Form > , form : Required < State > [ "form" ] ) {
331
348
return this . card (
332
349
ask ,
333
350
< Form onSubmit = { this . _onFormSubmit } className = "top-pad" >
@@ -336,9 +353,10 @@ export default class AskUI extends React.PureComponent<Props, State> {
336
353
< FormGroup isRequired key = { _ . name } label = { _ . name } >
337
354
< TextInput
338
355
aria-label = { `text-input-${ _ . name } ` }
356
+ data-name = { _ . name }
339
357
isRequired
340
358
value = { form [ _ . name ] }
341
- onChange = { ( value ) => ( form [ _ . name ] = value ) }
359
+ onChange = { this . _onFormChange }
342
360
/>
343
361
</ FormGroup >
344
362
) ) }
@@ -366,8 +384,8 @@ export default class AskUI extends React.PureComponent<Props, State> {
366
384
return this . select ( ask )
367
385
} else if ( this . isMultiSelect ( ask ) ) {
368
386
return this . checkboxes ( ask )
369
- } else {
370
- return this . form ( ask )
387
+ } else if ( this . state . form ) {
388
+ return this . form ( ask , this . state . form )
371
389
}
372
390
}
373
391
0 commit comments