Skip to content

Commit

Permalink
RichText: remove Autocomplete wrappers (#17580)
Browse files Browse the repository at this point in the history
  • Loading branch information
ellatrix authored Sep 26, 2019
1 parent 5e854c2 commit fd7f27b
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 271 deletions.
104 changes: 16 additions & 88 deletions packages/block-editor/src/components/autocomplete/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { clone } from 'lodash';
* WordPress dependencies
*/
import { applyFilters, hasFilter } from '@wordpress/hooks';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { Autocomplete as OriginalAutocomplete } from '@wordpress/components';

Expand All @@ -16,112 +15,41 @@ import { Autocomplete as OriginalAutocomplete } from '@wordpress/components';
*/
import { withBlockEditContext } from '../block-edit/context';

/*
* Use one array instance for fallback rather than inline array literals
* because the latter may cause rerender due to failed prop equality checks.
*/
const completersFallback = [];

/**
* Wrap the default Autocomplete component with one that
* supports a filter hook for customizing its list of autocompleters.
*
* Since there may be many Autocomplete instances at one time, this component
* applies the filter on demand, when the component is first focused after
* receiving a new list of completers.
*
* This function is exported for unit test.
*
* @param {Function} Autocomplete Original component.
* @return {Function} Wrapped component
*/
export function withFilteredAutocompleters( Autocomplete ) {
return class FilteredAutocomplete extends Component {
constructor() {
super();

this.state = { completers: completersFallback };

this.saveParentRef = this.saveParentRef.bind( this );
this.onFocus = this.onFocus.bind( this );
}

componentDidUpdate() {
const hasFocus = this.parentNode.contains( document.activeElement );

/*
* It's possible for props to be updated when the component has focus,
* so here, we ensure new completers are immediately applied while we
* have the focus.
*
* NOTE: This may trigger another render but only when the component has focus.
*/
if ( hasFocus && this.hasStaleCompleters() ) {
this.updateCompletersState();
}
}

onFocus() {
if ( this.hasStaleCompleters() ) {
this.updateCompletersState();
}
}

hasStaleCompleters() {
return (
! ( 'lastFilteredCompletersProp' in this.state ) ||
this.state.lastFilteredCompletersProp !== this.props.completers
return ( props ) => {
let { completers = [] } = props;

if ( hasFilter( 'editor.Autocomplete.completers' ) ) {
completers = applyFilters(
'editor.Autocomplete.completers',
// Provide copies so filters may directly modify them.
completers.map( clone ),
props.blockName,
);
}

updateCompletersState() {
const { blockName, completers } = this.props;
let nextCompleters = completers;
const lastFilteredCompletersProp = nextCompleters;

if ( hasFilter( 'editor.Autocomplete.completers' ) ) {
nextCompleters = applyFilters(
'editor.Autocomplete.completers',
// Provide copies so filters may directly modify them.
nextCompleters && nextCompleters.map( clone ),
blockName,
);
}

this.setState( {
lastFilteredCompletersProp,
completers: nextCompleters || completersFallback,
} );
}

saveParentRef( parentNode ) {
this.parentNode = parentNode;
}

render() {
const { completers } = this.state;
const autocompleteProps = {
...this.props,
completers,
};

return (
<div onFocus={ this.onFocus } ref={ this.saveParentRef }>
<Autocomplete onFocus={ this.onFocus } { ...autocompleteProps } />
</div>
);
}
return (
<Autocomplete
{ ...props }
completers={ completers }
/>
);
};
}

/**
* @see https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/autocomplete/README.md
*/
export default compose( [
withBlockEditContext( ( { name } ) => {
return {
blockName: name,
};
} ),
withBlockEditContext( ( { name } ) => ( { blockName: name } ) ),
withFilteredAutocompleters,
] )( OriginalAutocomplete );
122 changes: 0 additions & 122 deletions packages/block-editor/src/components/autocomplete/test/index.js

This file was deleted.

4 changes: 3 additions & 1 deletion packages/block-editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,14 +414,16 @@ class RichTextWrapper extends Component {
completers={ autocompleters }
record={ value }
onChange={ onChange }
isSelected={ isSelected }
>
{ ( { listBoxId, activeId } ) =>
{ ( { listBoxId, activeId, onKeyDown } ) =>
<Editable
aria-autocomplete={ listBoxId ? 'list' : undefined }
aria-owns={ listBoxId }
aria-activedescendant={ activeId }
start={ start }
reversed={ reversed }
onKeyDown={ onKeyDown }
/>
}
</Autocomplete>
Expand Down
Loading

0 comments on commit fd7f27b

Please sign in to comment.