Skip to content

Commit

Permalink
Add an icon and visually hidden a11y text to links that open in a new…
Browse files Browse the repository at this point in the history
… tab (#7883)

Adds an icon and the visually hidden text '(Opens in a new window)' for improved a11y to two links that open in a new tab.

- Use `ExternalLink` component for the link editor toolbar option on the Paragraph block. It replaces an `a` tag. This adds an additional icon and the visibly hidden text to the url.
- Use the `ExternalLink` component for the permalink url when editing the post header

Furthermore a change has been made to the preview button in the top toolbar so that is a button element instead of an anchor.

* Use ExternalLink for link in editor toolbar for Paragraph block

Links added in Paragraph are opened in a new tab when using the editor toolbar.
This commit switches the anchor tag with an ExternalLink component. This makes
the link more accessible (it adds some hidden text) and provides an icon
indicating that the link is external.

* Specify PostPreviewButton as opening external links

* Fix overly specific selector preventing override of icon styles

* Fix incorrect default display property given to button

* Make post preview button render as a button instead of a link

For accessibility purposes the post preview button is now rendered as a button,
meaning it can be interacted with using the keyboard (space bar to open a
preview page).

* Make the post permalink link an ExternalLink instead of a Button

* Rename member variable used as ref to reflect that it's no longer a button

* Modify ExternalLink component to forwards its ref

* Adjust styling to work in a wider range of contexts
  • Loading branch information
talldan authored Jul 24, 2018
1 parent 04320fb commit 10e87a9
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 33 deletions.
2 changes: 1 addition & 1 deletion edit-post/components/header/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
display: none;

@include break-small {
display: inline-block;
display: inline-flex;
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions editor/components/post-permalink/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import classnames from 'classnames';
import { withDispatch, withSelect } from '@wordpress/data';
import { Component } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { ClipboardButton, Button } from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { ClipboardButton, Button, ExternalLink } from '@wordpress/components';

/**
* Internal Dependencies
Expand Down Expand Up @@ -48,7 +48,7 @@ class PostPermalink extends Component {
componentDidUpdate( prevProps, prevState ) {
// If we've just stopped editing the permalink, focus on the new permalink.
if ( prevState.isEditingPermalink && ! this.state.isEditingPermalink ) {
this.permalinkButton.focus();
this.linkElement.focus();
}
}

Expand Down Expand Up @@ -79,15 +79,15 @@ class PostPermalink extends Component {
<span className="editor-post-permalink__label">{ __( 'Permalink:' ) }</span>

{ ! isEditingPermalink &&
<Button
<ExternalLink
className="editor-post-permalink__link"
href={ ! isPublished ? postLink : samplePermalink }
target="_blank"
ref={ ( permalinkButton ) => this.permalinkButton = permalinkButton }
ref={ ( linkElement ) => this.linkElement = linkElement }
>
{ decodeURI( samplePermalink ) }
&lrm;
</Button>
</ExternalLink>
}

{ isEditingPermalink &&
Expand Down
12 changes: 7 additions & 5 deletions editor/components/post-preview-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,16 @@ export class PostPreviewButton extends Component {
* @param {MouseEvent} event Click event from preview button click.
*/
openPreviewWindow( event ) {
const { isAutosaveable, previewLink } = this.props;
const { isAutosaveable, previewLink, currentPostLink } = this.props;

// If there are no changes to autosave, we cannot perform the save, but
// if there is an existing preview link (e.g. previous published post
// autosave), it should be reused as the popup destination.
if ( ! isAutosaveable && ! previewLink ) {
if ( ! isAutosaveable && ! previewLink && currentPostLink ) {
this.previewWindow = window.open(
currentPostLink,
this.getWindowTarget()
);
return;
}

Expand Down Expand Up @@ -115,15 +119,13 @@ export class PostPreviewButton extends Component {
}

render() {
const { currentPostLink, isSaveable } = this.props;
const { isSaveable } = this.props;

return (
<Button
className="editor-post-preview"
isLarge
href={ currentPostLink }
onClick={ this.openPreviewWindow }
target={ this.getWindowTarget() }
disabled={ ! isSaveable }
>
{ _x( 'Preview', 'imperative verb' ) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PostPreviewButton render() should match the snapshot 1`] = `
<Button
className="editor-post-preview"
disabled={false}
isLarge={true}
onClick={[Function]}
>
Preview
<WithSafeTimeout(WithSelect(WithDispatch(DotTip)))
id="core/editor.preview"
>
Click ‘Preview’ to load a preview of this page, so you can make sure you’re happy with your blocks.
</WithSafeTimeout(WithSelect(WithDispatch(DotTip)))>
</Button>
`;
17 changes: 10 additions & 7 deletions editor/components/post-preview-button/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ describe( 'PostPreviewButton', () => {
wrapper.simulate( 'click', { preventDefault } );

if ( expectedPreviewURL ) {
expect( preventDefault ).toHaveBeenCalled();
if ( expectedPreviewURL !== props.currentPostLink ) {
expect( preventDefault ).toHaveBeenCalled();
}

expect( window.open ).toHaveBeenCalledWith( expectedPreviewURL, 'wp-preview-1' );
} else {
expect( preventDefault ).not.toHaveBeenCalled();
Expand All @@ -113,11 +116,13 @@ describe( 'PostPreviewButton', () => {
return wrapper;
}

it( 'should do nothing if neither autosaveable nor preview link available', () => {
it( 'should open the currentPostLink if not autosaveable nor preview link available', () => {
const currentPostLink = 'https://wordpress.org/?p=1';
assertForPreview( {
isAutosaveable: false,
previewLink: undefined,
}, null, false );
currentPostLink,
}, currentPostLink, false );
} );

it( 'should save for autosaveable post with preview link', () => {
Expand All @@ -143,17 +148,15 @@ describe( 'PostPreviewButton', () => {
} );

describe( 'render()', () => {
it( 'should render a link', () => {
it( 'should match the snapshot', () => {
const wrapper = shallow(
<PostPreviewButton
postId={ 1 }
isSaveable
currentPostLink="https://wordpress.org/?p=1" />
);

expect( wrapper.prop( 'href' ) ).toBe( 'https://wordpress.org/?p=1' );
expect( wrapper.prop( 'disabled' ) ).toBe( false );
expect( wrapper.prop( 'target' ) ).toBe( 'wp-preview-1' );
expect( wrapper ).toMatchSnapshot();
} );

it( 'should be disabled if post is not saveable', () => {
Expand Down
6 changes: 3 additions & 3 deletions editor/components/rich-text/format-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Toolbar,
withSpokenMessages,
Popover,
ExternalLink,
} from '@wordpress/components';
import { ESCAPE, LEFT, RIGHT, UP, DOWN, BACKSPACE, ENTER, displayShortcut } from '@wordpress/keycodes';
import { prependHTTP } from '@wordpress/url';
Expand Down Expand Up @@ -255,13 +256,12 @@ class FormatToolbar extends Component {
onKeyPress={ stopKeyPropagation }
>
<div className="editor-format-toolbar__link-modal-line">
<a
<ExternalLink
className="editor-format-toolbar__link-value"
href={ formats.link.value }
target="_blank"
>
{ formats.link.value && filterURLForDisplay( decodeURI( formats.link.value ) ) }
</a>
</ExternalLink>
<IconButton icon="edit" label={ __( 'Edit' ) } onClick={ this.editLink } />
<IconButton
className="editor-format-toolbar__link-settings-toggle"
Expand Down
5 changes: 5 additions & 0 deletions packages/components/src/button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import classnames from 'classnames';
*/
import { createElement, forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import './style.scss';

export function Button( props, ref ) {
const {
href,
Expand Down
9 changes: 5 additions & 4 deletions packages/components/src/external-link/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import { compact, uniq } from 'lodash';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { forwardRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import Dashicon from '../dashicon';

function ExternalLink( { href, children, className, rel = '', ...additionalProps } ) {
export function ExternalLink( { href, children, className, rel = '', ...additionalProps }, ref ) {
rel = uniq( compact( [
...rel.split( ' ' ),
'external',
Expand All @@ -23,17 +24,17 @@ function ExternalLink( { href, children, className, rel = '', ...additionalProps
] ) ).join( ' ' );
const classes = classnames( 'components-external-link', className );
return (
<a { ...additionalProps } className={ classes } href={ href } target="_blank" rel={ rel }>
<a { ...additionalProps } className={ classes } href={ href } target="_blank" rel={ rel } ref={ ref }>
{ children }
<span className="screen-reader-text">
{
/* translators: accessibility text */
__( '(opens in a new window)' )
}
</span>
<Dashicon icon="external" />
<Dashicon icon="external" className="components-external-link__icon" />
</a>
);
}

export default ExternalLink;
export default forwardRef( ExternalLink );
14 changes: 6 additions & 8 deletions packages/components/src/external-link/style.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
.components-external-link {
.dashicon {
width: 1.4em;
height: 1.4em;
margin: 0 .2em;
vertical-align: top;
}
}
.components-external-link__icon {
width: 1.4em;
height: 1.4em;
margin: -0.2em 0.1em 0;
vertical-align: middle;
}

0 comments on commit 10e87a9

Please sign in to comment.