Skip to content

Commit 48a62c0

Browse files
committed
Fix mobile chip fields losing typed value on Next/Tab
The allowed/disallowed sections Autocomplete only committed a chip on Enter. Mobile keyboards send Next/Tab (a blur) instead, so the typed value was dropped and focus tabbed to the next field. Track the pending input and commit it on blur (splitting on commas for multi-entry).
1 parent 5db2518 commit 48a62c0

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

src/GameSources.jsx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)