Skip to content
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

Post author dropdown: add accessible-autocomplete #7385

Closed
wants to merge 143 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
ea01c26
Merge branch 'master' of github.com:WordPress/gutenberg
Jun 19, 2018
f84c371
accessible autocomplete, first pass
Jun 19, 2018
240c304
Add apiRequest author search
Jun 19, 2018
0d1991d
debounce search, only show autocomplete when more than 50 users
Jun 19, 2018
ea094fb
Add i18n
Jun 19, 2018
642ae6f
cleanup/whitespace
Jun 19, 2018
4ab2777
Only fetch 100 users in getAuthors
Jun 19, 2018
3ebc2c2
Remove the filter that enabled passing `-1` to get the first 10000 us…
Jun 19, 2018
a526c60
remove an old inline comment that is no longer relevant
Jun 19, 2018
a8e9bb1
Add the accessible-autocomplete npm package
Jun 19, 2018
aad6dcb
whitespace
Jun 19, 2018
16dd20c
manually limit search to strings of 2 or more characters
Jun 19, 2018
b056747
use backticks for template literals
Jun 19, 2018
6e69cf0
fixes for eslint
Jun 19, 2018
12e58b0
Revert "Remove the filter that enabled passing `-1` to get the first …
Jun 20, 2018
14edb8a
Merge branch 'master' into feature/accessible-autocomplete
Jul 4, 2018
6d555c7
use <Autocomplete /> component for more than 50 authors
Jul 4, 2018
853dfe6
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 5, 2018
83a7be4
Merge branch 'master' into feature/accessible-autocomplete
Jul 5, 2018
940f338
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 6, 2018
18290b2
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 6, 2018
42c6a60
accessible autocomplete, first pass
Jun 19, 2018
1e322aa
Add apiRequest author search
Jun 19, 2018
8da09fc
debounce search, only show autocomplete when more than 50 users
Jun 19, 2018
e31b540
Add i18n
Jun 19, 2018
7a70911
cleanup/whitespace
Jun 19, 2018
7e7696b
Only fetch 100 users in getAuthors
Jun 19, 2018
6c765c7
Remove the filter that enabled passing `-1` to get the first 10000 us…
Jun 19, 2018
1b10c63
remove an old inline comment that is no longer relevant
Jun 19, 2018
7aab164
Add the accessible-autocomplete npm package
Jun 19, 2018
4e47a3f
whitespace
Jun 19, 2018
03e0155
manually limit search to strings of 2 or more characters
Jun 19, 2018
3e33275
use backticks for template literals
Jun 19, 2018
6238e4c
fixes for eslint
Jun 19, 2018
9d1b490
Revert "Remove the filter that enabled passing `-1` to get the first …
Jun 20, 2018
efac333
use <Autocomplete /> component for more than 50 authors
Jul 4, 2018
7ec4b6c
Bail early if no postAuthor, add missing semicolon
Jul 9, 2018
8a9e711
Hello eslint!
Jul 9, 2018
5173a7a
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Jul 9, 2018
e4915b0
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 9, 2018
86b3d31
Merge branch 'master' into feature/accessible-autocomplete
Jul 9, 2018
d6e1deb
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 27, 2018
6bdba75
Merge branch 'master' into feature/accessible-autocomplete
Jul 27, 2018
a683a1c
update package-lock
Jul 27, 2018
46d27f9
add css
Jul 27, 2018
c3bf43d
Merge remote-tracking branch 'origin/master' into feature/accessible-…
notnownikki Oct 15, 2018
877032a
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Oct 18, 2018
9e42571
Merge branch 'master' of github.com:WordPress/gutenberg
Oct 18, 2018
43ccd6c
Merge branch 'master' into feature/accessible-autocomplete
Oct 18, 2018
79b6c66
include postAuthor data in PostAuthor test
Oct 18, 2018
708fd55
override some dropdown styles
Oct 18, 2018
aa5376f
Merge branch 'master' into feature/accessible-autocomplete
Oct 28, 2018
4f94442
Merge branch 'master' into feature/accessible-autocomplete
Nov 25, 2018
1ecfa05
Merge branch 'master' into feature/accessible-autocomplete
Dec 3, 2018
c6a9b18
update package lock
Dec 3, 2018
06b3cdd
Merge branch 'master' of github.com:WordPress/gutenberg
Dec 10, 2018
319c96c
Merge branch 'master' into feature/accessible-autocomplete
Dec 10, 2018
a97e293
Merge branch 'master' of github.com:WordPress/gutenberg
Dec 14, 2018
839a618
Merge branch 'master' into feature/accessible-autocomplete
Dec 14, 2018
550c63a
current author load on mount
Dec 17, 2018
d1731ec
Set or fetch the current author
Dec 17, 2018
6585f70
If the postAuthor is provided, use it directly. Fixes test, enables p…
Dec 17, 2018
ca3e4be
Merge branch 'master' of github.com:WordPress/gutenberg
Dec 17, 2018
66daf9f
Merge branch 'master' into feature/accessible-autocomplete
Dec 17, 2018
74e4083
Build docs
swissspidy Dec 18, 2018
c70e125
remove unused getAuthor resolver
Dec 18, 2018
cdf7bde
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Dec 18, 2018
4aded2f
lodash!
Dec 18, 2018
f1b5739
findWhere -> find
Dec 18, 2018
d227dfb
Merge branch 'master' of github.com:WordPress/gutenberg
Dec 19, 2018
205f07a
Merge branch 'master' into feature/accessible-autocomplete
Dec 19, 2018
790c2c2
add caching; only debounce remote requests
Dec 19, 2018
cb94e71
Merge branch 'master' of github.com:WordPress/gutenberg
Dec 21, 2018
729037d
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 4, 2019
849949c
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 10, 2019
91a891d
Merge branch 'master' into feature/accessible-autocomplete
Jan 10, 2019
2f1b5e2
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 12, 2019
76090f7
Merge branch 'master' into feature/accessible-autocomplete
Jan 12, 2019
e6a8713
remove autoprefixer
Jan 12, 2019
74e4f71
use string literals
Jan 12, 2019
ac7bedd
use sprintf
Jan 12, 2019
783655c
use _n
Jan 12, 2019
180cd54
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 18, 2019
e45ffe0
Merge branch 'master' into feature/accessible-autocomplete
Jan 18, 2019
525cf40
remove minified styles, unused
Jan 18, 2019
93b5396
imports in order of increasing locality
Jan 18, 2019
9a35172
remove un-needed bind
Jan 18, 2019
31d50b5
re-add disable reason
Jan 18, 2019
50400fc
Style updates
kjellr Jan 24, 2019
ac21e7b
Cleaning up size variables.
kjellr Jan 24, 2019
800787e
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 25, 2019
a021841
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Jan 25, 2019
3fdd917
Merge branch 'master' into feature/accessible-autocomplete
Jan 25, 2019
741a2a8
Remove some unused styles
kjellr Jan 25, 2019
9862909
Merge branch 'master' of github.com:WordPress/gutenberg
Jan 28, 2019
96ed175
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Jan 28, 2019
1980080
Merge branch 'master' into feature/accessible-autocomplete
Jan 28, 2019
624c49d
rearrange constructor calls
Jan 28, 2019
fcaf60d
getInitialPostAuthor to pull author from props
Jan 28, 2019
da3de52
Merge branch 'master' of github.com:WordPress/gutenberg
Feb 6, 2019
d3443e7
Merge branch 'master' of github.com:WordPress/gutenberg
Feb 10, 2019
1217076
Merge branch 'master' into feature/accessible-autocomplete
Feb 10, 2019
1d13ad8
improve tStatusResults string construction
Feb 10, 2019
8d3ae5b
remove unused postAuthor check
Feb 10, 2019
db3bea3
adjust z-index use & document
Feb 10, 2019
807b61e
prefix css classes
Feb 10, 2019
5ba93d1
remove autoselect
Feb 10, 2019
0c7d6b5
Merge branch 'master' of github.com:WordPress/gutenberg
Feb 20, 2019
03fc448
Merge branch 'master' of github.com:WordPress/gutenberg
Feb 28, 2019
aa4bbcc
Merge branch 'master' into feature/accessible-autocomplete
Feb 28, 2019
b3839b3
Merge branch 'master' of github.com:WordPress/gutenberg
May 16, 2019
e593595
Merge branch 'master' of github.com:WordPress/gutenberg
Jun 23, 2019
d528303
Merge branch 'master' of github.com:WordPress/gutenberg
Jun 25, 2019
27cedb3
move package.json dependency to editor
Jun 25, 2019
7e5d82d
Merge branch 'master' into feature/accessible-autocomplete
Jun 25, 2019
4c9fd8b
update package lock
Jun 25, 2019
4d8c249
increase author cutoff count to 99 and add inline doc explaining
Jun 25, 2019
b830022
correct translation string
Jun 25, 2019
2426493
ensure unique authors; check found before swetting
Jun 25, 2019
bd6ef21
Improve inline documentation
Jun 26, 2019
0b12bfd
helper for author slugs
Jun 26, 2019
28bf036
display a default list when the current selection is unchanged
Jun 26, 2019
2daaa8c
Post Author: add component tests to document when a select or autocom…
gwwar Jun 27, 2019
1e824ad
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 1, 2019
c89d301
Merge branch 'master' of github.com:WordPress/gutenberg
Jul 2, 2019
8d7db70
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Jul 2, 2019
43d4a59
Merge branch 'master' into feature/accessible-autocomplete
Jul 2, 2019
4c6a447
correct typo
Jul 16, 2019
83f6086
correct typo
Jul 16, 2019
3317851
Merge branch 'feature/accessible-autocomplete' of github.com:WordPres…
Aug 27, 2019
615e3d9
Merge branch 'master' into feature/accessible-autocomplete
Aug 27, 2019
cbea8ff
update packacge-lock
Aug 27, 2019
0066508
merge master
adamsilverstein Dec 20, 2019
ba26d03
Merge branch 'master' into feature/accessible-autocomplete
adamsilverstein Dec 23, 2019
eb64f3b
update package lock
adamsilverstein Dec 23, 2019
24ddea3
Upgrade accessible-autocomplete to version 2.0.1.
adamsilverstein Dec 23, 2019
92e4074
correct doc block typo
adamsilverstein Dec 23, 2019
71b7243
Add post author endpoint to preccache via `block_editor_preload_paths`
adamsilverstein Dec 23, 2019
73343ae
Improve auto-complete styling.
adamsilverstein Dec 23, 2019
e445aa7
Get post author object with a getPostAuthor selector
adamsilverstein Dec 23, 2019
6e129da
Show up to 10 items in menu.
adamsilverstein Dec 23, 2019
e545898
Correct construction of tStatusSelectedOption using sprintf.
adamsilverstein Dec 23, 2019
1c1fb89
Add expected_user_path to tests.
adamsilverstein Dec 23, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/designers-developers/developers/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@ _Returns_

- `?Object`: The entity record's save error.

<a name="getPostAuthor" href="#getPostAuthor">#</a> **getPostAuthor**

Returns post author.

_Parameters_

- _state_ `Object`: Data state.

_Returns_

- `Array`: Authors list.

<a name="getRawEntityRecord" href="#getRawEntityRecord">#</a> **getRawEntityRecord**

Returns the entity's record object by key,
Expand Down
8 changes: 8 additions & 0 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,14 @@ function gutenberg_extend_block_editor_preload_paths( $preload_paths, $post ) {
$preload_paths[] = $blocks_path;
}

/**
* Attach the current post author data.
*/
$author_path = '/wp/v2/users/' . $post->post_author;
if ( ! in_array( $author_path, $preload_paths, true ) ) {
$preload_paths[] = $author_path;
}

return $preload_paths;
}
add_filter( 'block_editor_preload_paths', 'gutenberg_extend_block_editor_preload_paths', 10, 2 );
22,760 changes: 9,235 additions & 13,525 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/base-styles/_z-index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ $z-layers: (
".components-drop-zone": 40,
".components-drop-zone__content": 50,

// Autocomplete dropdown shows over other sidebar elements.
".autocomplete__menu--overlay": 100,

// The block mover for floats should overlap the controls of adjacent blocks.
".block-editor-block-list__block {core/image aligned left or right}": 21,

Expand Down
12 changes: 12 additions & 0 deletions packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,18 @@ _Returns_

- `?Object`: The entity record's save error.

<a name="getPostAuthor" href="#getPostAuthor">#</a> **getPostAuthor**

Returns post author.

_Parameters_

- _state_ `Object`: Data state.

_Returns_

- `Array`: Authors list.

<a name="getRawEntityRecord" href="#getRawEntityRecord">#</a> **getRawEntityRecord**

Returns the entity's record object by key,
Expand Down
12 changes: 11 additions & 1 deletion packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ import { apiFetch, resolveSelect } from './controls';
* Requests authors from the REST API.
*/
export function* getAuthors() {
const users = yield apiFetch( { path: '/wp/v2/users/?who=authors&per_page=-1' } );
const users = yield apiFetch( { path: '/wp/v2/users/?who=authors&per_page=100' } );
yield receiveUserQuery( 'authors', users );
}

/**
adamsilverstein marked this conversation as resolved.
Show resolved Hide resolved
* Requests a post author by ID from the REST API.
*
* @param {string} id Author id.
*/
export function* getPostAuthor( id ) {
const postAuthor = yield apiFetch( { path: `/wp/v2/users/${ id }` } );
yield receiveUserQuery( 'postAuthor', postAuthor );
}

/**
* Requests the current user from the REST API.
*/
Expand Down
12 changes: 12 additions & 0 deletions packages/core-data/src/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ export function getAuthors( state ) {
return getUserQueryResults( state, 'authors' );
}

/**
* Returns post author.
*
* @param {Object} state Data state.
*
* @return {Array} Authors list.
*/

export function getPostAuthor( state ) {
return getUserQueryResults( state, 'postAuthor' )[ 0 ];
}

/**
* Returns the current user.
*
Expand Down
1 change: 1 addition & 0 deletions packages/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@wordpress/url": "file:../url",
"@wordpress/viewport": "file:../viewport",
"@wordpress/wordcount": "file:../wordcount",
"accessible-autocomplete": "2.0.1",
"classnames": "^2.2.5",
"equivalent-key-map": "^0.2.2",
"lodash": "^4.17.15",
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/components/autocompleters/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ export default {
options( search ) {
let payload = '';
if ( search ) {
payload = '?search=' + encodeURIComponent( search );
payload = `?search=${ encodeURIComponent( search ) }`;
}
return apiFetch( { path: '/wp/v2/users' + payload } );
return apiFetch( { path: `/wp/v2/users${ payload }` } );
},
isDebounced: true,
getOptionKeywords( user ) {
Expand Down
196 changes: 181 additions & 15 deletions packages/editor/src/components/post-author/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
/**
* External dependencies
*/
import Autocomplete from 'accessible-autocomplete/react';
import { debounce } from 'lodash';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { sprintf, __, _n } from '@wordpress/i18n';
import { withInstanceId, compose } from '@wordpress/compose';
import { Component } from '@wordpress/element';
import { withSelect, withDispatch } from '@wordpress/data';
import { decodeEntities } from '@wordpress/html-entities';
import apiFetch from '@wordpress/api-fetch';

/**
* Internal dependencies
Expand All @@ -17,34 +24,192 @@ export class PostAuthor extends Component {
super( ...arguments );

this.setAuthorId = this.setAuthorId.bind( this );
this.suggestAuthor = this.suggestAuthor.bind( this );
this.getCurrentAuthor = this.getCurrentAuthor.bind( this );
this.resolveResults = this.resolveResults.bind( this );
noisysocks marked this conversation as resolved.
Show resolved Hide resolved
this.requestResults = debounce( ( query, populateResults ) => {
const payload = '?search=' + encodeURIComponent( query );
apiFetch( { path: `/wp/v2/users${ payload }` } ).then( ( results ) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally a component should never be calling apiFetch directly, and rather use the core data resources as the canonical source for REST API entities. One issue with how this is implemented is we have nothing to cancel the behaviors from taking place if the component suddenly becomes unmounted, potentially leading to errors.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll switch this to using core/data adding whatever support we need there.

we have nothing to cancel the behaviors from taking place

will core/data account for that or should i be endeavouring to cancel these requests when the component unmounts? another option would be tracking mount state and doing ending silently for request when unmounted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will core/data account for that or should i be endeavouring to cancel these requests when the component unmounts?

It's a non-concern for you. In practice, it doesn't actually cancel it, but it doesn't really matter, and also helps if a future component mount also needs the same data (another reason why instance-specific fetches should be discouraged, since the data can / should be shared).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we also use apiFetch in the user autocompleter - https://github.com/WordPress/gutenberg/blob/master/packages/editor/src/components/autocompleters/user.js#L20 - i think to replace thse we'll need a new resolver, perhaps searchAuthors?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth Thinking about adding the capability to select both a single user by ID and to search users via the data component - currently this does not seem possible.

Do you think I should add this to the existing getAuthors selector, eg the ability to pass an id or search query to the selector? or create something new?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth any feedback on this question?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth Thinking about adding the capability to select both a single user by ID and to search users via the data component - currently this does not seem possible.

Do you think I should add this to the existing getAuthors selector, eg the ability to pass an id or search query to the selector? or create something new?

There's some precedent here with the existing "entities", currently post types, taxonomies, and media items. The entities implementation will auto-generate two selectors:

  • One for retrieving a singular data entry, accepting an ID as its sole argument
  • Another for querying data, accepting the REST API query as its argument

Considering getAuthors as a sort of partially-applied entities selector, I could see this being applied as either:

  • Following the above in spirit, accepting a query object for getAuthors and creating a new getAuthor selector
  • Implementing the users entity explicitly, where querying authors just becomes part of the query object passed to getUsers

And, in fact, it could be both, where the first is just an abstraction on the second.

I'm not sure if I've missed anything, but I'd rather not have getAuthors diverge as being its own special thing if it's possible for us to bring it in line with these other standard entities behaviors.

populateResults( this.resolveResults( results ) );
this.searchCache[ query ] = results;
} );
}, 300 );
this.searchCache = [];
this.state = {
postAuthor: false,
initialAuthors: [],
currentSelection: '',
};
}

// Get the initial author from props if available.
getInitialPostAuthor() {
return this.props.postAuthor;
}

componentDidMount() {
const { authors } = this.props;

// Store a set of authors for display as initial results when using an autocomplete.
this.setState( { initialAuthors: authors.slice( 0, 9 ) } );
}

/**
* Construct a unique author string from an author object in the form `${ author.name } (${ author.slug })`.
*
* @param {Object} author An author object.
*
* @return {string} An author name for display.
*/
authorUniqueName( author ) {
if ( ! author || ! author.name || ! author.slug ) {
return '';
}
return `${ author.name } (${ author.slug })`;
}

/**
* Search for authors that match the passed query, passing them to a callback function when resolved.
*
* @param {string} query The search query.
* @param {Function} populateResults A callback function which receives the results.
*/
suggestAuthor( query, populateResults ) {
// If the query is the current selection, return the first 10 users.
const {
initialAuthors,
currentSelection,
} = this.state;
if ( query === currentSelection ) {
populateResults( this.resolveResults( initialAuthors ) );
return;
}

if ( query.length < 2 ) {
populateResults( this.resolveResults( initialAuthors ) );
return;
}

if ( this.searchCache[ query ] ) {
populateResults( this.resolveResults( this.searchCache[ query ] ) );
return;
}

this.requestResults( query, populateResults );
}

/**
* Resolve the author objects into strings for display.
*
* @param {Array} results The array of authors that matched the search.
*
* @return {Array} an array of strings ready for displaying.
*/
resolveResults( results ) {
this.authors = results;
return results.map( ( author ) => ( this.authorUniqueName( author ) ) );
}

/**
* Retrieve the author object by id and set in state.
*
* @param {number} authorId The id of the author to fetch.
*/
getCurrentAuthor( authorId ) {
if ( ! authorId ) {
return;
}
// Note: This route is cached at load time.
apiFetch( { path: `/wp/v2/users/${ encodeURIComponent( authorId ) }` } ).then( ( results ) => {
this.setState( {
postAuthor: results,
currentSelection: this.authorUniqueName( results ),
} );
} );
}

setAuthorId( event ) {
/**
* Set the current author based on the selection. Handles strings passed from the HTML
* select element or strings passed from the auto-complete component.
*
* @param {number|string} selection The author id or name that was selected.
*/
setAuthorId( selection ) {
if ( ! selection ) {
return;
}
const { onUpdateAuthor } = this.props;
const { value } = event.target;
onUpdateAuthor( Number( value ) );
if ( typeof selection === 'string' ) {
// Author name from the auto-completer.
const author = this.authors.find( ( singleAuthor ) => {
return this.authorUniqueName( singleAuthor ) === selection;
} );
if ( author ) {
this.setState( { currentSelection: selection } );
onUpdateAuthor( Number( author.id ) );
}
} else {
// Author ID from the select.
onUpdateAuthor( Number( selection.target.value ) );
}
}

render() {
const { postAuthor, instanceId, authors } = this.props;
const selectId = 'post-author-selector-' + instanceId;

// Disable reason: A select with an onchange throws a warning
adamsilverstein marked this conversation as resolved.
Show resolved Hide resolved
const { postAuthorId, instanceId, authors, postAuthor } = this.props;
const selectId = `post-author-selector-${ instanceId }`;
let selector;
if ( ! postAuthor ) {
return null;
}

/* eslint-disable jsx-a11y/no-onchange */
return (
<PostAuthorCheck>
<label htmlFor={ selectId }>{ __( 'Author' ) }</label>
// If there are a small number of users, use a regular select element; once the list grows to a certain size, switch
// to an accessible auto-complete component.
if ( authors.length < 99 ) {
// Disable reason: A select with an onchange throws a warning.
/* eslint-disable jsx-a11y/no-onchange */
selector =
<select
id={ selectId }
value={ postAuthor }
value={ postAuthorId }
onChange={ this.setAuthorId }
className="editor-post-author__select"
>
{ authors.map( ( author ) => (
<option key={ author.id } value={ author.id }>{ decodeEntities( author.name ) }</option>
) ) }
</select>
</select>;
} else {
selector =
<Autocomplete
id={ selectId }
minLength={ 2 }
showAllValues={ true }
defaultValue={ postAuthor ? this.authorUniqueName( postAuthor ) : '' }
displayMenu="overlay"
onConfirm={ this.setAuthorId }
source={ this.suggestAuthor }
showNoOptionsFound={ false }
preserveNullOptions={ true }
tStatusQueryTooShort={ ( minQueryLength ) =>
// translators: %d: the number characters required to initiate an author search.
sprintf( __( 'Type in %d or more characters for results' ), minQueryLength )
}
tStatusNoResults={ () => __( 'No search results' ) }
// translators: 1: the index of thre selected result. 2: The total number of results.
tStatusSelectedOption={ ( selectedOption, length, index ) => sprintf( __( '%1$s (%2$s of %3$s) is selected' ), selectedOption, index + 1, length ) }
tStatusResults={ ( length, contentSelectedOption ) => {
const resultString = _n( '%d result is available.', '%d results are available.', length ) + ' ' + contentSelectedOption;
return sprintf( resultString, length );
} }
cssNamespace="components-post-author__autocomplete"

/>;
}

return (
<PostAuthorCheck>
<label htmlFor={ selectId }>{ __( 'Author' ) }</label>
{ selector }
</PostAuthorCheck>
);
/* eslint-enable jsx-a11y/no-onchange */
Expand All @@ -54,8 +219,9 @@ export class PostAuthor extends Component {
export default compose( [
withSelect( ( select ) => {
return {
postAuthor: select( 'core/editor' ).getEditedPostAttribute( 'author' ),
postAuthorId: select( 'core/editor' ).getEditedPostAttribute( 'author' ),
authors: select( 'core' ).getAuthors(),
postAuthor: select( 'core' ).getPostAuthor( select( 'core/editor' ).getEditedPostAttribute( 'author' ) ),
};
} ),
withDispatch( ( dispatch ) => ( {
Expand Down
Loading