@@ -72,6 +72,9 @@ type State = {
7272
7373 /** User has opted for inline filters in the Select */
7474 hasInlineFilter ?: boolean
75+
76+ /** Current form state (if any) */
77+ form ?: Record < string , string >
7578}
7679
7780/**
@@ -88,9 +91,20 @@ export default class AskUI extends React.PureComponent<Props, State> {
8891 public static getDerivedStateFromProps ( props : Props , state : State ) {
8992 if ( state . userSelection && props . ask . prompt . choices . find ( ( _ ) => _ . name === state . userSelection ) ) {
9093 return state
94+ } else if ( state . form ) {
95+ // there has been an update to the form, nothing to do here
96+ return state
9197 } else {
9298 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 > )
93106 return {
107+ form,
94108 userSelection : ! suggested ? undefined : suggested . name ,
95109 }
96110 }
@@ -170,9 +184,9 @@ export default class AskUI extends React.PureComponent<Props, State> {
170184
171185 /** User has clicked to submit a form */
172186 private readonly _onFormSubmit = ( evt : React . SyntheticEvent ) => {
173- if ( this . props . ask ) {
187+ if ( this . props . ask && this . state . form ) {
174188 evt . preventDefault ( )
175- this . props . ask . onChoose ( Promise . resolve ( this . _form ) )
189+ this . props . ask . onChoose ( Promise . resolve ( this . state . form ) )
176190 }
177191 return false
178192 }
@@ -319,15 +333,18 @@ export default class AskUI extends React.PureComponent<Props, State> {
319333 return "multiselect"
320334 }
321335
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+ }
330345
346+ /** Render a form ui */
347+ private form ( ask : Ask < Prompts . Form > , form : Required < State > [ "form" ] ) {
331348 return this . card (
332349 ask ,
333350 < Form onSubmit = { this . _onFormSubmit } className = "top-pad" >
@@ -336,9 +353,10 @@ export default class AskUI extends React.PureComponent<Props, State> {
336353 < FormGroup isRequired key = { _ . name } label = { _ . name } >
337354 < TextInput
338355 aria-label = { `text-input-${ _ . name } ` }
356+ data-name = { _ . name }
339357 isRequired
340358 value = { form [ _ . name ] }
341- onChange = { ( value ) => ( form [ _ . name ] = value ) }
359+ onChange = { this . _onFormChange }
342360 />
343361 </ FormGroup >
344362 ) ) }
@@ -366,8 +384,8 @@ export default class AskUI extends React.PureComponent<Props, State> {
366384 return this . select ( ask )
367385 } else if ( this . isMultiSelect ( ask ) ) {
368386 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 )
371389 }
372390 }
373391
0 commit comments