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

Make accessible toolbar stable and deprecate old usage #23316

Merged
merged 28 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fc54ccd
Deprecate legacy toolbar usage
diegohaz Jun 19, 2020
e29ae96
Update e2e tests
diegohaz Jun 19, 2020
867543d
Merge branch 'master' into try/accessible-toolbar
diegohaz Jul 13, 2020
b40177f
Merge branch 'master' into try/accessible-toolbar
diegohaz Jul 16, 2020
d5201eb
Remove __experimental flag from Toolbar accessibilityLabel prop
diegohaz Jul 16, 2020
ac60181
Merge branch 'master' into try/accessible-toolbar
diegohaz Jul 20, 2020
fde5aa1
Merge branch 'master' into try/accessible-toolbar
diegohaz Jul 23, 2020
7aecd5e
Use label instead of accessibilityLabel
diegohaz Jul 23, 2020
94d5ca2
Deprecate <Toolbar> without label prop
diegohaz Jul 23, 2020
26dda7e
Make ToolbarItem component stable
diegohaz Jul 23, 2020
5efe0db
Deprecate ToolbarButton usage without a parent Toolbar
diegohaz Jul 23, 2020
f48467e
Simplify jsdocs
diegohaz Jul 23, 2020
b464950
data-experimental-toolbar-item to data-toolbar-item
diegohaz Jul 23, 2020
1813a7d
Remove deprecation warning from ToolbarButton
diegohaz Jul 23, 2020
e16144a
Update unit test
diegohaz Jul 23, 2020
e387239
Update Toolbar README
diegohaz Jul 23, 2020
696279d
Update tests
diegohaz Jul 23, 2020
cf740b4
Remove ToolbarGroup test from Toolbar
diegohaz Jul 23, 2020
c184881
Merge branch 'master' into try/accessible-toolbar
diegohaz Jul 28, 2020
dff1660
Replace Toolbar by ToolbarGroup on the Classic Editor
diegohaz Jul 28, 2020
dbc4da3
Merge branch 'master' into try/accessible-toolbar
diegohaz Aug 6, 2020
2b5d232
Add Toolbar, ToolbarButton, ToolbarGroup and ToolbarItem docs
diegohaz Aug 6, 2020
5931985
Add links to depreaction notices and warnings
diegohaz Aug 6, 2020
cf8483d
Update ToolbarButton docs
diegohaz Aug 6, 2020
df663c6
Improve documentation around BlockControls usage
diegohaz Aug 10, 2020
dd7ead5
Update deprecation warning link on Navigable Toolbar
diegohaz Aug 10, 2020
e177fb1
Update ToolbarItem README
diegohaz Aug 10, 2020
c0acb82
Update ToolbarItem README
diegohaz Aug 10, 2020
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/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,18 @@
"markdown_source": "../packages/components/src/toolbar-button/README.md",
"parent": "components"
},
{
"title": "ToolbarGroup",
"slug": "toolbar-group",
"markdown_source": "../packages/components/src/toolbar-group/README.md",
"parent": "components"
},
{
"title": "ToolbarItem",
"slug": "toolbar-item",
"markdown_source": "../packages/components/src/toolbar-item/README.md",
"parent": "components"
},
{
"title": "Toolbar",
"slug": "toolbar",
Expand Down
5 changes: 1 addition & 4 deletions packages/block-editor/src/components/block-mover/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import classnames from 'classnames';
/**
* WordPress dependencies
*/
import {
ToolbarGroup,
__experimentalToolbarItem as ToolbarItem,
} from '@wordpress/components';
import { ToolbarGroup, ToolbarItem } from '@wordpress/components';
import { getBlockType } from '@wordpress/blocks';
import { Component } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/**
* WordPress dependencies
*/
import {
ToolbarGroup,
__experimentalToolbarItem as ToolbarItem,
} from '@wordpress/components';
import { ToolbarGroup, ToolbarItem } from '@wordpress/components';

/**
* Internal dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
DropdownMenu,
ToolbarButton,
ToolbarGroup,
__experimentalToolbarItem as ToolbarItem,
ToolbarItem,
MenuGroup,
Popover,
} from '@wordpress/components';
Expand Down
15 changes: 12 additions & 3 deletions packages/block-editor/src/components/navigable-toolbar/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
useEffect,
useCallback,
} from '@wordpress/element';
import deprecated from '@wordpress/deprecated';
import { focus } from '@wordpress/dom';
import { useShortcut } from '@wordpress/keyboard-shortcuts';

Expand All @@ -23,7 +24,7 @@ function useUpdateLayoutEffect( effect, deps ) {
}

function hasOnlyToolbarItem( elements ) {
const dataProp = 'experimentalToolbarItem';
const dataProp = 'toolbarItem';
return ! elements.some( ( element ) => ! ( dataProp in element.dataset ) );
}

Expand Down Expand Up @@ -59,7 +60,15 @@ function useIsAccessibleToolbar( ref ) {

const determineIsAccessibleToolbar = useCallback( () => {
const tabbables = focus.tabbable.find( ref.current );
setIsAccessibleToolbar( hasOnlyToolbarItem( tabbables ) );
const onlyToolbarItem = hasOnlyToolbarItem( tabbables );
if ( ! onlyToolbarItem ) {
deprecated( 'Using custom components as toolbar controls', {
diegohaz marked this conversation as resolved.
Show resolved Hide resolved
alternative: 'ToolbarItem or ToolbarButton components',
link:
'https://developer.wordpress.org/block-editor/components/toolbar-button/#inside-blockcontrols',
} );
}
setIsAccessibleToolbar( onlyToolbarItem );
}, [] );

useLayoutEffect( determineIsAccessibleToolbar, [] );
Expand Down Expand Up @@ -106,7 +115,7 @@ function NavigableToolbar( { children, focusOnMount, ...props } ) {
if ( isAccessibleToolbar ) {
return (
<Toolbar
__experimentalAccessibilityLabel={ props[ 'aria-label' ] }
label={ props[ 'aria-label' ] }
ref={ wrapper }
{ ...props }
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { orderBy } from 'lodash';

import { __ } from '@wordpress/i18n';
import {
__experimentalToolbarItem as ToolbarItem,
ToolbarItem,
ToolbarGroup,
DropdownMenu,
Slot,
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/classic/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { debounce } from 'lodash';
* WordPress dependencies
*/
import { BlockControls } from '@wordpress/block-editor';
import { Toolbar } from '@wordpress/components';
import { ToolbarGroup } from '@wordpress/components';
import { Component } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import { BACKSPACE, DELETE, F10, isKeyboardEvent } from '@wordpress/keycodes';
Expand Down Expand Up @@ -248,9 +248,9 @@ export default class ClassicEdit extends Component {
return (
<>
<BlockControls>
<Toolbar>
<ToolbarGroup>
<ConvertToBlocksButton clientId={ clientId } />
</Toolbar>
</ToolbarGroup>
</BlockControls>
<div
key="toolbar"
Expand Down
4 changes: 1 addition & 3 deletions packages/block-library/src/heading/heading-level-dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ export default function HeadingLevelDropdown( { selectedLevel, onChange } ) {
renderContent={ () => (
<Toolbar
className="block-library-heading-level-toolbar"
__experimentalAccessibilityLabel={ __(
'Change heading level'
) }
label={ __( 'Change heading level' ) }
>
<ToolbarGroup
isCollapsed={ false }
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/image/image-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import {
ToolbarGroup,
ToolbarButton,
__experimentalToolbarItem as ToolbarItem,
ToolbarItem,
Spinner,
RangeControl,
DropdownMenu,
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/table/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
TextControl,
ToggleControl,
ToolbarGroup,
__experimentalToolbarItem as ToolbarItem,
ToolbarItem,
} from '@wordpress/components';
import {
alignLeft,
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export { default as Toolbar } from './toolbar';
export { default as ToolbarButton } from './toolbar-button';
export { default as __experimentalToolbarContext } from './toolbar-context';
export { default as ToolbarGroup } from './toolbar-group';
export { default as __experimentalToolbarItem } from './toolbar-item';
export { default as ToolbarItem } from './toolbar-item';
export { default as Tooltip } from './tooltip';
export {
default as __experimentalTreeGrid,
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export { default as Toolbar } from './toolbar';
export { default as ToolbarButton } from './toolbar-button';
export { default as __experimentalToolbarContext } from './toolbar-context';
export { default as ToolbarGroup } from './toolbar-group';
export { default as __experimentalToolbarItem } from './toolbar-item';
export { default as ToolbarItem } from './toolbar-item';
export { default as Icon } from './icon';
export { default as IconButton } from './button/deprecated';
export { default as Spinner } from './spinner';
Expand Down
53 changes: 43 additions & 10 deletions packages/components/src/toolbar-button/README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
# ToolbarButton

A ToolbarButton can be used to add actions to your block control, usually inside a ToolbarGroup. It has similar features to the [Button](/packages/components/src/button/README.md) component. Using `ToolbarButton` will ensure the correct styling for a button in a toolbar, and also that keyboard interactions in a toolbar are consistent with the [WAI ARIA toolbar pattern](https://www.w3.org/TR/wai-aria-practices/#toolbar).
ToolbarButton can be used to add actions to a toolbar, usually inside a [Toolbar](/packages/components/src/toolbar/README.md) or [ToolbarGroup](/packages/components/src/toolbar-group/README.md) when used to create general interfaces. If you're using it to add controls to your custom block, you should consider using [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md).

It has similar features to the [Button](/packages/components/src/button/README.md) component. Using `ToolbarButton` will ensure the correct styling for a button in a toolbar, and also that keyboard interactions in a toolbar are consistent with the [WAI-ARIA toolbar pattern](https://www.w3.org/TR/wai-aria-practices/#toolbar).

## Usage

To create general interfaces, you'll want to render ToolbarButton in a [Toolbar](/packages/components/src/toolbar/README.md) component.

```jsx
import { ToolbarButton } from "@wordpress/components";
import { edit } from "@wordpress/icons";

const MyToolbarButton = () => (
<MyToolbarButton
title="Edit"
icon={ edit }
onClick={ onEdit } />
);
import { Toolbar, ToolbarButton } from '@wordpress/components';
import { edit } from '@wordpress/icons';

function MyToolbar() {
return (
<Toolbar label="Options">
<ToolbarButton
icon={ edit }
label="Edit"
onClick={ () => alert( 'Editing' ) }
/>
</Toolbar>
);
}
```

### Inside BlockControls

If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optinally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md).

```jsx
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { edit } from '@wordpress/icons';

function Edit() {
return (
<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon={ edit }
label="Edit"
onClick={ () => alert( 'Editing' ) }
/>
</ToolbarGroup>
</BlockControls>
);
}
```

## Props
Expand Down
4 changes: 1 addition & 3 deletions packages/components/src/toolbar-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ function ToolbarButton(
const accessibleToolbarState = useContext( ToolbarContext );

if ( ! accessibleToolbarState ) {
// This should be deprecated when <Toolbar __experimentalAccessibilityLabel="label">
// becomes stable.
return (
<ToolbarButtonContainer className={ containerClassName }>
<Button
Expand All @@ -52,7 +50,7 @@ function ToolbarButton(
) }
isPressed={ isActive }
disabled={ isDisabled }
data-experimental-toolbar-item
data-toolbar-item
{ ...extraProps }
{ ...props }
>
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/toolbar-button/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const _default = () => {
const icon = text( 'Icon', 'wordpress' );

return (
<Toolbar __experimentalAccessibilityLabel="Example Toolbar">
<Toolbar label="Example Toolbar">
<ToolbarButton icon={ icon } label={ label } />
</Toolbar>
);
Expand Down
33 changes: 33 additions & 0 deletions packages/components/src/toolbar-group/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# ToolbarGroup

A ToolbarGroup can be used to create subgroups of controls inside a [Toolbar](/packages/components/src/toolbar/README.md).

## Usage

```jsx
import { Toolbar, ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { paragraph, formatBold, formatItalic, link } from '@wordpress/icons';

function MyToolbar() {
return (
<Toolbar label="Options">
<ToolbarGroup>
<ToolbarButton icon={ paragraph } label="Paragraph" />
</ToolbarGroup>
<ToolbarGroup>
<ToolbarButton icon={ formatBold } label="Bold" />
<ToolbarButton icon={ formatItalic } label="Italic" />
<ToolbarButton icon={ link } label="Link" />
</ToolbarGroup>
</Toolbar>
);
}
```

### Props

ToolbarGroup will pass all HTML props to the underlying element.

## Related components

* ToolbarGroup may contain [ToolbarButton](/packages/components/src/toolbar-button/README.md) and [ToolbarItem](/packages/components/src/toolbar-Item/README.md) as children.
2 changes: 1 addition & 1 deletion packages/components/src/toolbar-group/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ function ToolbarGroup( {
...props
} ) {
// It'll contain state if `ToolbarGroup` is being used within
// `<Toolbar accessibilityLabel="label" />`
// `<Toolbar label="label" />`
const accessibleToolbarState = useContext( ToolbarContext );

if ( ( ! controls || ! controls.length ) && ! children ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import ToolbarItem from '../toolbar-item';

function ToolbarGroupCollapsed( { controls = [], ...props } ) {
// It'll contain state if `ToolbarGroup` is being used within
// `<Toolbar __experimentalAccessibilityLabel="label" />`
// `<Toolbar label="label" />`
const accessibleToolbarState = useContext( ToolbarContext );

const renderDropdownMenu = ( toggleProps ) => (
<DropdownMenu
controls={ controls }
toggleProps={ {
...toggleProps,
'data-experimental-toolbar-item': true,
'data-toolbar-item': true,
} }
{ ...props }
/>
Expand Down
72 changes: 72 additions & 0 deletions packages/components/src/toolbar-item/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# ToolbarItem

A ToolbarItem is a generic headless component that can be used to make any custom component a [Toolbar](/packages/components/src/toolbar/README.md) item. It should be inside a [Toolbar](/packages/components/src/toolbar/README.md) or [ToolbarGroup](/packages/components/src/toolbar-group/README.md) when used to create general interfaces. If you're using it to add controls to your custom block, you should consider using [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md).

## Usage

### `as` prop

You can use the `as` prop with a custom component or any HTML element.

```jsx
import { Toolbar, ToolbarItem, Button } from '@wordpress/components';

function MyToolbar() {
return (
<Toolbar label="Options">
<ToolbarItem as={ Button }>I am a toolbar button</ToolbarItem>
<ToolbarItem as="button">I am another toolbar button</ToolbarItem>
</Toolbar>
);
}
```

### render prop

You can pass children as function to get the ToolbarItem props and pass them to another component.

```jsx
import { Toolbar, ToolbarItem, DropdownMenu } from '@wordpress/components';
import { table } from '@wordpress/icons';

function MyToolbar() {
return (
<Toolbar label="Options">
<ToolbarItem>
{ ( toolbarItemHTMLProps ) => (
<DropdownMenu
icon={ table }
toggleProps={ toolbarItemHTMLProps }
label={ 'Edit table' }
controls={ [] }
/>
) }
</ToolbarItem>
</Toolbar>
);
}
```

### Inside BlockControls

If you're working on a custom block and you want to add controls to the block toolbar, you should use [BlockControls](/docs/designers-developers/developers/tutorials/block-tutorial/block-controls-toolbar-and-sidebar.md) instead. Optinally wrapping it with [ToolbarGroup](/packages/components/src/toolbar-group/README.md).

```jsx
import { BlockControls } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarItem, Button } from '@wordpress/components';

function Edit() {
return (
<BlockControls>
<ToolbarGroup>
<ToolbarItem as={ Button }>I am a toolbar button</ToolbarItem>
</ToolbarGroup>
</BlockControls>
);
}
```

## Related components

* ToolbarItem should be used inside [Toolbar](/packages/components/src/toolbar/README.md) or [ToolbarGroup](/packages/components/src/toolbar-group/README.md).
* If you want a simple toolbar button, consider using [ToolbarButton](/packages/components/src/toolbar-button/README.md) instead.
Loading