@@ -252,9 +252,51 @@ class GameSources extends React.Component {
252252 steamSearchQuery : '' ,
253253 steamSearchResults : [ ] ,
254254 steamSearchBusy : false ,
255+ // Pending (uncommitted) chip-field text, keyed by `${service}:${key}`.
256+ // Mobile keyboards send "Next"/Tab (a blur) instead of Enter, so the
257+ // Autocomplete never commits the typed value and focus tabs away with
258+ // the input lost. We track the in-progress text and commit it on blur.
259+ chipInputs : { } ,
255260 } ;
256261 }
257262
263+ chipInputKey ( service , key ) {
264+ return `${ service } :${ key } ` ;
265+ }
266+
267+ // Append whatever the user has typed but not yet committed (no Enter press,
268+ // e.g. mobile "Next" button) to the chip list. Splits on commas so a
269+ // comma-separated paste becomes multiple chips.
270+ commitPendingChip ( service , key , values ) {
271+ const inputKey = this . chipInputKey ( service , key ) ;
272+ const pending = ( this . state . chipInputs [ inputKey ] || '' ) . trim ( ) ;
273+
274+ if ( pending . length === 0 ) {
275+ return ;
276+ }
277+
278+ const additions = pending
279+ . split ( ',' )
280+ . map ( ( item ) => {
281+ return item . trim ( ) ;
282+ } )
283+ . filter ( Boolean ) ;
284+
285+ const current = Array . isArray ( values ) ? values : [ ] ;
286+
287+ this . setState ( ( state ) => {
288+ return {
289+ chipInputs : Object . assign ( { } , state . chipInputs , {
290+ [ inputKey ] : '' ,
291+ } ) ,
292+ } ;
293+ } ) ;
294+
295+ if ( additions . length > 0 ) {
296+ this . setSectionList ( service , key , current . concat ( additions ) ) ;
297+ }
298+ }
299+
258300 getCurrentService ( ) {
259301 const services = Object . keys ( this . props . sources ) ;
260302
@@ -576,7 +618,29 @@ class GameSources extends React.Component {
576618 < Autocomplete
577619 freeSolo
578620 multiple
621+ inputValue = { this . state . chipInputs [ this . chipInputKey ( service , key ) ] || '' }
622+ onInputChange = { ( event , newInputValue ) => {
623+ const inputKey = this . chipInputKey ( service , key ) ;
624+
625+ this . setState ( ( state ) => {
626+ return {
627+ chipInputs : Object . assign ( { } , state . chipInputs , {
628+ [ inputKey ] : newInputValue ,
629+ } ) ,
630+ } ;
631+ } ) ;
632+ } }
579633 onChange = { ( event , newValue ) => {
634+ // A chip was committed (Enter) or removed — clear pending text.
635+ const inputKey = this . chipInputKey ( service , key ) ;
636+
637+ this . setState ( ( state ) => {
638+ return {
639+ chipInputs : Object . assign ( { } , state . chipInputs , {
640+ [ inputKey ] : '' ,
641+ } ) ,
642+ } ;
643+ } ) ;
580644 this . setSectionList ( service , key , newValue ) ;
581645 } }
582646 options = { [ ] }
@@ -586,6 +650,11 @@ class GameSources extends React.Component {
586650 { ...params }
587651 helperText = { settings . helperText }
588652 label = { settings . label || key }
653+ onBlur = { ( ) => {
654+ // Mobile "Next"/Tab blurs without an Enter — commit
655+ // whatever's typed so the value isn't silently lost.
656+ this . commitPendingChip ( service , key , values ) ;
657+ } }
589658 placeholder = { 'Type and press Enter' }
590659 size = { 'small' }
591660 variant = { 'outlined' }
0 commit comments