From ebafb854c29b956c43be3057240824e4c9d095e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Tue, 28 Feb 2023 10:37:22 +0200 Subject: [PATCH] Rewrite by deriving from record --- packages/components/src/autocomplete/index.js | 44 ++++++++----------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/packages/components/src/autocomplete/index.js b/packages/components/src/autocomplete/index.js index be96839a2dd57..5903e2cf53f1f 100644 --- a/packages/components/src/autocomplete/index.js +++ b/packages/components/src/autocomplete/index.js @@ -418,53 +418,47 @@ function useAutocomplete( { }; } +function useLastDifferentValue( value ) { + const history = useRef( new Set() ); + + history.current.add( value ); + + // Keep the history size to 2. + if ( history.current.size > 2 ) { + history.current.delete( Array.from( history.current )[ 0 ] ); + } + + return Array.from( history.current )[ 0 ]; +} + export function useAutocompleteProps( options ) { - const [ isVisible, setIsVisible ] = useState( false ); const ref = useRef(); - const recordAfterInput = useRef(); const onKeyDownRef = useRef(); + const { record } = options; + const previousRecord = useLastDifferentValue( record ); const { popover, listBoxId, activeId, onKeyDown } = useAutocomplete( { ...options, contentRef: ref, } ); onKeyDownRef.current = onKeyDown; - useEffect( () => { - if ( isVisible ) { - if ( ! recordAfterInput.current ) { - recordAfterInput.current = options.record; - } else if ( - recordAfterInput.current.start !== options.record.start || - recordAfterInput.current.end !== options.record.end - ) { - setIsVisible( false ); - recordAfterInput.current = null; - } - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ options.record ] ); - const mergedRefs = useMergeRefs( [ ref, useRefEffect( ( element ) => { function _onKeyDown( event ) { onKeyDownRef.current( event ); } - function _onInput() { - // Only show auto complete UI if the user is inputting text. - setIsVisible( true ); - recordAfterInput.current = null; - } element.addEventListener( 'keydown', _onKeyDown ); - element.addEventListener( 'input', _onInput ); return () => { element.removeEventListener( 'keydown', _onKeyDown ); - element.removeEventListener( 'input', _onInput ); }; }, [] ), ] ); - if ( ! isVisible ) { + // We only want to show the popover if the user has typed something. + const didUserInput = record.text !== previousRecord?.text; + + if ( ! didUserInput ) { return { ref: mergedRefs }; }