diff --git a/plugins/woocommerce-admin/client/dashboard/components/settings/general/store-address.js b/plugins/woocommerce-admin/client/dashboard/components/settings/general/store-address.js index 8efb901c6cd..a40a8a4ba07 100644 --- a/plugins/woocommerce-admin/client/dashboard/components/settings/general/store-address.js +++ b/plugins/woocommerce-admin/client/dashboard/components/settings/general/store-address.js @@ -4,7 +4,9 @@ */ import { __ } from '@wordpress/i18n'; import { decodeEntities } from '@wordpress/html-entities'; -import { useMemo } from 'react'; +import { escapeRegExp } from 'lodash'; +import { Fragment } from '@wordpress/element'; +import { useEffect, useMemo, useState } from 'react'; import { getSetting } from '@woocommerce/wc-admin-settings'; /** @@ -69,6 +71,66 @@ export function getCountryStateOptions() { return countryStateOptions; } +/** + * Get the autofill countryState fields and set value from filtered options. + * + * @param {Array} options Array of filterable options. + * @param {String} countryState The value of the countryState field. + * @param {Function} setValue Set value of the countryState input. + * @return {Object} React component. + */ +export function getCountryStateAutofill( options, countryState, setValue ) { + const [ autofillCountry, setAutofillCountry ] = useState( '' ); + const [ autofillState, setAutofillState ] = useState( '' ); + + useEffect( + () => { + let filteredOptions = []; + if ( autofillState.length || autofillCountry.length ) { + const countrySearch = new RegExp( + escapeRegExp( autofillCountry.replace( /\s/g, '' ) ), + 'i' + ); + filteredOptions = options.filter( option => + countrySearch.test( option.label.replace( '-', '' ).replace( /\s/g, '' ) ) + ); + } + if ( autofillCountry.length && autofillState.length ) { + const stateSearch = new RegExp( escapeRegExp( autofillState.replace( /\s/g, '' ) ), 'i' ); + filteredOptions = filteredOptions.filter( option => + stateSearch.test( option.label.replace( '-', '' ).replace( /\s/g, '' ) ) + ); + } + if ( 1 === filteredOptions.length && countryState !== filteredOptions[ 0 ].key ) { + setValue( 'countryState', filteredOptions[ 0 ].key ); + } + }, + [ autofillCountry, autofillState ] + ); + + return ( + + setAutofillCountry( event.target.value ) } + value={ autofillCountry } + name="country" + type="text" + className="woocommerce-select-control__autofill-input" + tabIndex="-1" + /> + + setAutofillState( event.target.value ) } + value={ autofillState } + name="state" + type="text" + className="woocommerce-select-control__autofill-input" + tabIndex="-1" + /> + + ); +} + /** * Store address fields. * @@ -76,7 +138,7 @@ export function getCountryStateOptions() { * @return {Object} - */ export function StoreAddress( props ) { - const { getInputProps } = props; + const { getInputProps, setValue } = props; const countryStateOptions = useMemo( () => getCountryStateOptions(), [] ); return ( @@ -99,7 +161,13 @@ export function StoreAddress( props ) { options={ countryStateOptions } isSearchable { ...getInputProps( 'countryState' ) } - /> + > + { getCountryStateAutofill( + countryStateOptions, + getInputProps( 'countryState' ).value, + setValue + ) } + - { ( { getInputProps, handleSubmit, values, isValidForm } ) => ( + { ( { getInputProps, handleSubmit, values, isValidForm, setValue } ) => ( { showUsageModal && ( this.setState( { showUsageModal: false } ) } /> ) } - + - { ( { getInputProps, handleSubmit } ) => ( + { ( { getInputProps, handleSubmit, setValue } ) => ( - + diff --git a/plugins/woocommerce-admin/packages/components/src/select-control/control.js b/plugins/woocommerce-admin/packages/components/src/select-control/control.js index 7777db2413b..a0d61d0df9e 100644 --- a/plugins/woocommerce-admin/packages/components/src/select-control/control.js +++ b/plugins/woocommerce-admin/packages/components/src/select-control/control.js @@ -110,6 +110,7 @@ class Control extends Component { return ( { @@ -226,9 +228,26 @@ export class SelectControl extends Component { ) ); } + onAutofillChange( event ) { + const { options } = this.props; + const filteredOptions = this.getFilteredOptions( options, event.target.value ); + + if ( 1 === filteredOptions.length ) { + this.selectOption( filteredOptions[ 0 ] ); + } + } + render() { - const { className, inlineTags, instanceId, isSearchable, options } = this.props; - const { isExpanded, selectedIndex } = this.state; + const { + autofill, + children, + className, + inlineTags, + instanceId, + isSearchable, + options, + } = this.props; + const { isExpanded, isFocused, selectedIndex } = this.state; const hasTags = this.hasTags(); const { key: selectedKey = '' } = options[ selectedIndex ] || {}; @@ -241,10 +260,21 @@ export class SelectControl extends Component {
+ { autofill && ( + + ) } + { children }