-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Autocomplete: Skip work for unselected blocks via isEnabled flag #78304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,6 +101,7 @@ export function useAutocomplete( { | |
| onReplace, | ||
| completers, | ||
| contentRef, | ||
| isEnabled = true, | ||
| }: UseAutocompleteProps ) { | ||
| const instanceId = useInstanceId( AUTOCOMPLETE_HOOK_REFERENCE ); | ||
| const [ state, dispatch ] = useReducer( autocompleteReducer, initialState ); | ||
|
|
@@ -241,13 +242,19 @@ export function useAutocomplete( { | |
| // but this is a preemptive performance improvement, since the autocompleter | ||
| // is a potential bottleneck for the editor type metric. | ||
| const textContent = useMemo( () => { | ||
| if ( ! isEnabled ) { | ||
| return ''; | ||
| } | ||
| if ( isCollapsed( record ) ) { | ||
| return getTextContent( slice( record, 0 ) ); | ||
| } | ||
| return ''; | ||
| }, [ record ] ); | ||
| }, [ record, isEnabled ] ); | ||
|
|
||
| useEffect( () => { | ||
| if ( ! isEnabled ) { | ||
| return; | ||
| } | ||
|
Comment on lines
250
to
+257
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we dispatch useEffect( () => {
if ( ! isEnabled ) {
if ( autocompleter ) {
dispatch( { type: 'RESET' } );
}
lastCompletionRef.current = null;
// Keep prevRecordTextRef in sync so the cursor-only guard below
// works correctly on the next re-enable (no false "text change").
prevRecordTextRef.current = record.text;
return;
}
const isTextChange = record.text !== prevRecordTextRef.current;
prevRecordTextRef.current = record.text;
// ... rest unchanged
}, [ textContent, isEnabled ] );
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the check here isn't needed, the text and completers become empty, and then the effect should clean itself up. P.S. Sorry, I'm at WordCamp and can't do a proper review at the moment.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @ciampo that it's worth flushing |
||
| const isTextChange = record.text !== prevRecordTextRef.current; | ||
| prevRecordTextRef.current = record.text; | ||
|
|
||
|
|
@@ -302,7 +309,7 @@ export function useAutocomplete( { | |
| dispatch( { type: 'MATCH', completer, query } ); | ||
| // We want to avoid introducing unexpected side effects. | ||
| // See https://github.com/WordPress/gutenberg/pull/41820 | ||
| }, [ textContent ] ); | ||
| }, [ textContent, isEnabled ] ); | ||
|
|
||
| const { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {}; | ||
| const { className } = autocompleter || {}; | ||
|
|
@@ -376,6 +383,7 @@ export function useLastDifferentValue( | |
| } | ||
|
|
||
| export function useAutocompleteProps( options: UseAutocompleteProps ) { | ||
| const { isEnabled = true } = options; | ||
| const ref = useRef< HTMLElement >( null ); | ||
| const onKeyDownRef = | ||
| useRef< ( event: KeyboardEvent ) => void >( undefined ); | ||
|
|
@@ -389,19 +397,25 @@ export function useAutocompleteProps( options: UseAutocompleteProps ) { | |
|
|
||
| const mergedRefs = useMergeRefs( [ | ||
| ref, | ||
| useRefEffect( ( element: HTMLElement ) => { | ||
| function _onKeyDown( event: KeyboardEvent ) { | ||
| onKeyDownRef.current?.( event ); | ||
| } | ||
| element.addEventListener( 'keydown', _onKeyDown ); | ||
| return () => { | ||
| element.removeEventListener( 'keydown', _onKeyDown ); | ||
| }; | ||
| }, [] ), | ||
| useRefEffect( | ||
| ( element: HTMLElement ) => { | ||
| if ( ! isEnabled ) { | ||
| return; | ||
| } | ||
| function _onKeyDown( event: KeyboardEvent ) { | ||
| onKeyDownRef.current?.( event ); | ||
| } | ||
| element.addEventListener( 'keydown', _onKeyDown ); | ||
| return () => { | ||
| element.removeEventListener( 'keydown', _onKeyDown ); | ||
| }; | ||
| }, | ||
| [ isEnabled ] | ||
| ), | ||
| ] ); | ||
|
|
||
| // We only want to show the popover if the user has typed something. | ||
| const didUserInput = record.text !== previousRecord?.text; | ||
| const didUserInput = isEnabled && record.text !== previousRecord?.text; | ||
|
|
||
| if ( ! didUserInput ) { | ||
| return { ref: mergedRefs }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there no way to trigger autocomplete programmatically for an unselected block?