Skip to content

Commit

Permalink
LinkControl - adds search results label for initial suggestions (#19665)
Browse files Browse the repository at this point in the history
* Adds search results label for initial suggestions

* Conditional render visually hidden label for normal search results

* Tweak wording from “modified” to “updated”

Addresses #19665 (comment)

* Fixes unecessary boolean inversion.

* Refactor arial-labelled by and aria-label implementation to confirm to spec

https://www.w3.org/TR/wai-aria/#aria-label

* Use undefined instead of boolean false to avoid rendering of id and aria-labelledby
  • Loading branch information
getdave authored Jan 15, 2020
1 parent 931746b commit c53b94d
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
21 changes: 17 additions & 4 deletions packages/block-editor/src/components/link-control/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { noop, startsWith } from 'lodash';
/**
* WordPress dependencies
*/
import { Button, ExternalLink } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { Button, ExternalLink, VisuallyHidden } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { useCallback, useState, Fragment } from '@wordpress/element';

import {
Expand Down Expand Up @@ -131,16 +131,29 @@ export function LinkControl( {
}, [ handleDirectEntry, fetchSearchSuggestions ] );

// Render Components
const renderSearchResults = ( { suggestionsListProps, buildSuggestionItemProps, suggestions, selectedSuggestion, isLoading } ) => {
const renderSearchResults = ( { suggestionsListProps, buildSuggestionItemProps, suggestions, selectedSuggestion, isLoading, isInitialSuggestions } ) => {
const resultsListClasses = classnames( 'block-editor-link-control__search-results', {
'is-loading': isLoading,
} );

const manualLinkEntryTypes = [ 'url', 'mailto', 'tel', 'internal' ];
const searchResultsLabelId = isInitialSuggestions ? `block-editor-link-control-search-results-label-${ instanceId }` : undefined;
const labelText = isInitialSuggestions ? __( 'Recently updated' ) : sprintf( __( 'Search results for %s' ), inputValue );
// According to guidelines aria-label should be added if the label
// itself is not visible.
// See: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/listbox_role
const ariaLabel = isInitialSuggestions ? undefined : labelText;
const SearchResultsLabel = (
<span className="block-editor-link-control__search-results-label" id={ searchResultsLabelId } aria-label={ ariaLabel } >
{ labelText }
</span>
);

return (
<div className="block-editor-link-control__search-results-wrapper">
<div { ...suggestionsListProps } className={ resultsListClasses }>
{ isInitialSuggestions ? SearchResultsLabel : <VisuallyHidden>{ SearchResultsLabel }</VisuallyHidden> }

<div { ...suggestionsListProps } className={ resultsListClasses } aria-labelledby={ searchResultsLabelId }>
{ suggestions.map( ( suggestion, index ) => (
<LinkControlSearchItem
key={ `${ suggestion.id }-${ suggestion.type }` }
Expand Down
6 changes: 6 additions & 0 deletions packages/block-editor/src/components/link-control/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@
}
}

.block-editor-link-control__search-results-label {
padding: 15px 30px 0 30px;
display: block;
font-size: 1.1em;
}

.block-editor-link-control__search-results {
margin: 0;
padding: $grid-size-large/2 $grid-size-large $grid-size-large;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,10 @@ describe( 'Default search suggestions', () => {
const searchInput = container.querySelector( 'input[aria-label="URL"]' );

// TODO: select these by aria relationship to autocomplete rather than arbitary selector.
const initialSearchResultElements = container.querySelectorAll( '[role="listbox"] [role="option"]' );
const searchResultsWrapper = container.querySelector( '[role="listbox"]' );
const initialSearchResultElements = searchResultsWrapper.querySelectorAll( '[role="option"]' );

const searchResultsLabel = container.querySelector( `#${ searchResultsWrapper.getAttribute( 'aria-labelledby' ) }` );

// Verify input has no value has default suggestions should only show
// when this does not have a value
Expand All @@ -342,6 +345,8 @@ describe( 'Default search suggestions', () => {

// Verify the search results already display the initial suggestions
expect( initialSearchResultElements ).toHaveLength( expectedResultsLength );

expect( searchResultsLabel.innerHTML ).toEqual( 'Recently updated' );
} );

it( 'should not display initial suggestions when input value is present', async () => {
Expand Down
2 changes: 2 additions & 0 deletions packages/block-editor/src/components/url-input/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ class URLInput extends Component {
placeholder = __( 'Paste URL or type to search' ),
value = '',
autoFocus = true,
__experimentalShowInitialSuggestions = false,
} = this.props;

const {
Expand Down Expand Up @@ -365,6 +366,7 @@ class URLInput extends Component {
buildSuggestionItemProps,
isLoading: loading,
handleSuggestionClick: this.handleOnClick,
isInitialSuggestions: __experimentalShowInitialSuggestions && ! ( value && value.length ),
} ) }

{ ! isFunction( renderSuggestions ) && showSuggestions && !! suggestions.length &&
Expand Down

0 comments on commit c53b94d

Please sign in to comment.