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

Normalize the block toolbar for more blocks: button, buttons, list, heading, paragraph and quote #29863

Merged
merged 2 commits into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions packages/block-editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ registerCoreBlocks();

<!-- START TOKEN(Autogenerated API docs) -->

<a name="AlignmentControl" href="#AlignmentControl">#</a> **AlignmentControl**
gziolo marked this conversation as resolved.
Show resolved Hide resolved

Undocumented declaration.

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

Undocumented declaration.
Expand Down Expand Up @@ -406,6 +410,10 @@ _Related_

- <https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inspector-controls/README.md>

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

Undocumented declaration.

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

Undocumented declaration.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Alignment Toolbar
## Alignment Control

The `AlignmentToolbar` component renders a toolbar that displays alignment options for the selected block.
The `AlignmentControl` component renders a dropdown mmmenu that displays alignment options for the selected block.

This component is mostly used for blocks that display text, such as Heading, Paragraph, Post Author, Post Comments, Verse, Quote, Post Title, etc... And the available alignment options are `left`, `center` or `right` alignment.

Expand All @@ -18,11 +18,11 @@ This component is mostly used for blocks that display text, such as Heading, Par
Renders an alignment toolbar with alignments options.

```jsx
import { AlignmentToolbar } from '@wordpress/block-editor';
import { AlignmentControl } from '@wordpress/block-editor';

const MyAlignmentToolbar = () => (
<BlockControls>
<AlignmentToolbar
<BlockControls group="block">
<AlignmentControl
value={ textAlign }
onChange={ ( nextAlign ) => {
setAttributes( { textAlign: nextAlign } );
Expand All @@ -31,7 +31,7 @@ const MyAlignmentToolbar = () => (
</BlockControls>
);
```
_Note:_ In this example that we render `AlignmentToolbar` as a child of the `BlockControls` component.
_Note:_ In this example that we render `AlignmentControl` as a child of the `BlockControls` component.

### Props

Expand Down
12 changes: 12 additions & 0 deletions packages/block-editor/src/components/alignment-control/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Internal dependencies
*/
import AlignmentUI from './ui';

export function AlignmentControl( props ) {
return <AlignmentUI { ...props } isToolbar={ false } />;
}

export function AlignmentToolbar( props ) {
return <AlignmentUI { ...props } isToolbar />;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AlignmentToolbar should allow custom alignment controls to be specified 1`] = `
exports[`AlignmentUI should allow custom alignment controls to be specified 1`] = `
<ToolbarGroup
controls={
Array [
Expand Down Expand Up @@ -62,7 +62,7 @@ exports[`AlignmentToolbar should allow custom alignment controls to be specified
/>
`;

exports[`AlignmentToolbar should match snapshot 1`] = `
exports[`AlignmentUI should match snapshot 1`] = `
<ToolbarGroup
controls={
Array [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import { alignLeft, alignCenter } from '@wordpress/icons';
/**
* Internal dependencies
*/
import { AlignmentToolbar } from '../';
import AlignmentUI from '../ui';

describe( 'AlignmentToolbar', () => {
describe( 'AlignmentUI', () => {
const alignment = 'left';
const onChangeSpy = jest.fn();

const wrapper = shallow(
<AlignmentToolbar value={ alignment } onChange={ onChangeSpy } />
<AlignmentUI isToolbar value={ alignment } onChange={ onChangeSpy } />
);

const controls = wrapper.props().controls;
Expand Down Expand Up @@ -53,7 +53,8 @@ describe( 'AlignmentToolbar', () => {

test( 'should allow custom alignment controls to be specified', () => {
const wrapperCustomControls = shallow(
<AlignmentToolbar
<AlignmentUI
isToolbar
value={ 'custom-right' }
onChange={ onChangeSpy }
alignmentControls={ [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { find } from 'lodash';
* WordPress dependencies
*/
import { __, isRTL } from '@wordpress/i18n';
import { ToolbarGroup } from '@wordpress/components';
import { DropdownMenu, ToolbarGroup } from '@wordpress/components';
import { alignLeft, alignRight, alignCenter } from '@wordpress/icons';

const DEFAULT_ALIGNMENT_CONTROLS = [
Expand All @@ -33,16 +33,16 @@ const POPOVER_PROPS = {
isAlternate: true,
};

export function AlignmentToolbar( props ) {
const {
value,
onChange,
alignmentControls = DEFAULT_ALIGNMENT_CONTROLS,
label = __( 'Align' ),
describedBy = __( 'Change text alignment' ),
isCollapsed = true,
} = props;

function AlignmentUI( {
value,
onChange,
alignmentControls = DEFAULT_ALIGNMENT_CONTROLS,
label = __( 'Align' ),
describedBy = __( 'Change text alignment' ),
isCollapsed = true,
isToolbar,
isToolbarButton = true,
} ) {
function applyOrUnset( align ) {
return () => onChange( value === align ? undefined : align );
}
Expand All @@ -57,9 +57,11 @@ export function AlignmentToolbar( props ) {
return isRTL() ? alignRight : alignLeft;
}

const UIComponent = isToolbar ? ToolbarGroup : DropdownMenu;
const extraProps = isToolbar ? { isCollapsed } : { isToolbarButton };

return (
<ToolbarGroup
isCollapsed={ isCollapsed }
<UIComponent
icon={ setIcon() }
label={ label }
toggleProps={ { describedBy } }
Expand All @@ -75,8 +77,9 @@ export function AlignmentToolbar( props ) {
onClick: applyOrUnset( align ),
};
} ) }
{ ...extraProps }
/>
);
}

export default AlignmentToolbar;
export default AlignmentUI;
7 changes: 5 additions & 2 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
export * from './colors';
export * from './gradients';
export * from './font-sizes';
export { default as AlignmentToolbar } from './alignment-toolbar';
export { AlignmentControl, AlignmentToolbar } from './alignment-control';
export { default as Autocomplete } from './autocomplete';
export {
BlockAlignmentControl,
Expand Down Expand Up @@ -47,7 +47,10 @@ export {
} from './inner-blocks';
export { default as InspectorAdvancedControls } from './inspector-advanced-controls';
export { default as InspectorControls } from './inspector-controls';
export { default as JustifyToolbar } from './justify-toolbar';
export {
JustifyToolbar,
JustifyContentControl,
} from './justify-content-control';
export { default as __experimentalLinkControl } from './link-control';
export { default as __experimentalLinkControlSearchInput } from './link-control/search-input';
export { default as __experimentalLinkControlSearchResults } from './link-control/search-results';
Expand Down
7 changes: 5 additions & 2 deletions packages/block-editor/src/components/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ export { default as BlockVerticalAlignmentToolbar } from './block-vertical-align
export * from './colors';
export * from './gradients';
export * from './font-sizes';
export { default as AlignmentToolbar } from './alignment-toolbar';
export { AlignmentControl, AlignmentToolbar } from './alignment-control';
export { default as InnerBlocks } from './inner-blocks';
export { default as InspectorAdvancedControls } from './inspector-advanced-controls';
export { default as InspectorControls } from './inspector-controls';
export { default as JustifyToolbar } from './justify-toolbar';
export {
JustifyToolbar,
JustifyContentControl,
} from './justify-content-control';
export { default as LineHeightControl } from './line-height-control';
export { default as PlainText } from './plain-text';
export {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Justify Toolbar

The `JustifyToolbar` component renders a toolbar that displays justify options for the selected block.
The `JustifyContentControl` component renders a toolbar that displays justify options for the selected block.

This component is used to set the flex justification for the elements in the block, allowing to justify `left`, `center`, `right`, and `space-between`. In comparison, the alignment options are for the block itself.

Expand All @@ -10,14 +10,14 @@ See the Navigation block for an example usage.

### Usage

Renders an justification toolbar with options.
Renders an justification control with options.

```jsx
import { JustifyToolbar } from '@wordpress/block-editor';
import { JustifyContentControl } from '@wordpress/block-editor';

const MyJustifyToolbar = ( { attributes, setAttributes } ) => (
<BlockControls>
<JustifyToolbar
<BlockControls group="block">
<JustifyContentControl
value={ attributes.justification }
onChange={ ( next ) => {
setAttributes( { justfication: next } );
Expand All @@ -35,7 +35,7 @@ const MyJustifyToolbar = ( { attributes, setAttributes } ) => (
items-justified-space-between


_Note:_ In this example that we render `JustifyToolbar` as a child of the `BlockControls` component.
_Note:_ In this example that we render `JustifyContentControl` as a child of the `BlockControls` component.


### Props
Expand All @@ -46,14 +46,6 @@ _Note:_ In this example that we render `JustifyToolbar` as a child of the `Block

An array of strings for what controls to show, by default it shows all.


#### `isCollapsed`
* **Type:** `boolean`
* **Default:** `true`

Whether to display toolbar options in the dropdown menu.


#### `onChange`
* **Type:** `Function`
* **Required:** Yes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Internal dependencies
*/
import JustifyContentUI from './ui';

export function JustifyContentControl( props ) {
return <JustifyContentUI { ...props } isToolbar={ false } />;
}

export function JustifyToolbar( props ) {
return <JustifyContentUI { ...props } isToolbar />;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { ToolbarGroup } from '@wordpress/components';
import { DropdownMenu, ToolbarGroup } from '@wordpress/components';
import {
justifyLeft,
justifyCenter,
Expand All @@ -17,12 +17,14 @@ const icons = {
'space-between': justifySpaceBetween,
};

export function JustifyToolbar( {
function JustifyContentUI( {
allowedControls = [ 'left', 'center', 'right', 'space-between' ],
isCollapsed = true,
onChange,
value,
popoverProps,
isToolbar,
isToolbarButton = true,
Copy link
Member

@gziolo gziolo Mar 18, 2021

Choose a reason for hiding this comment

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

Is it necessary here – isToolbarButton? What would be a use case to set it as false? The same question applies to AlignmentUI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the reason for this is if this control is rendered outside the block toolbar (which is not the case now), but if we want these controls to be generic, that's something we need to consider.

Copy link
Member

Choose a reason for hiding this comment

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

Right, should it consume the toolbar context instead to detect if it should be a toolbar button or not? @diegohaz might have an idea how to do it.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's possible to consume the toolbar context, yes. But I'd try a more untangled approach like this:

<JustifyContentUI as={ToolbarGroup} />
<JustifyContentUI as={DropdownMenu} toggleAs={ToolbarButton} />
<DropdownMenu toggleAs={ToolbarButton} />

} ) {
// If the control is already selected we want a click
// again on the control to deselect the item, so we
Expand Down Expand Up @@ -67,17 +69,20 @@ export function JustifyToolbar( {
},
];

const UIComponent = isToolbar ? ToolbarGroup : DropdownMenu;
const extraProps = isToolbar ? { isCollapsed } : { isToolbarButton };

return (
<ToolbarGroup
<UIComponent
icon={ icon }
popoverProps={ popoverProps }
label={ __( 'Change items justification' ) }
isCollapsed={ isCollapsed }
controls={ allControls.filter( ( elem ) =>
allowedControls.includes( elem.name )
) }
{ ...extraProps }
/>
);
}

export default JustifyToolbar;
export default JustifyContentUI;
2 changes: 1 addition & 1 deletion packages/block-editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
@import "./components/contrast-checker/style.scss";
@import "./components/default-block-appender/style.scss";
@import "./components/font-appearance-control/style.scss";
@import "./components/justify-toolbar/style.scss";
@import "./components/justify-content-control/style.scss";
@import "./components/link-control/style.scss";
@import "./components/line-height-control/style.scss";
@import "./components/image-size-control/style.scss";
Expand Down
43 changes: 20 additions & 23 deletions packages/block-library/src/button/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import {
RangeControl,
TextControl,
ToolbarButton,
ToolbarGroup,
Popover,
} from '@wordpress/components';
import {
Expand Down Expand Up @@ -147,28 +146,26 @@ function URLPicker( {
);
return (
<>
<BlockControls>
<ToolbarGroup>
{ ! urlIsSet && (
<ToolbarButton
name="link"
icon={ link }
title={ __( 'Link' ) }
shortcut={ displayShortcut.primary( 'k' ) }
onClick={ openLinkControl }
/>
) }
{ urlIsSetandSelected && (
<ToolbarButton
name="link"
icon={ linkOff }
title={ __( 'Unlink' ) }
shortcut={ displayShortcut.primaryShift( 'k' ) }
onClick={ unlinkButton }
isActive={ true }
/>
) }
</ToolbarGroup>
<BlockControls group="block">
{ ! urlIsSet && (
<ToolbarButton
name="link"
icon={ link }
title={ __( 'Link' ) }
shortcut={ displayShortcut.primary( 'k' ) }
onClick={ openLinkControl }
/>
) }
{ urlIsSetandSelected && (
<ToolbarButton
name="link"
icon={ linkOff }
title={ __( 'Unlink' ) }
shortcut={ displayShortcut.primaryShift( 'k' ) }
onClick={ unlinkButton }
isActive={ true }
/>
) }
</BlockControls>
{ isSelected && (
<KeyboardShortcuts
Expand Down
Loading