Skip to content

Commit

Permalink
Buttons block: overhaul alignment/justification controls.
Browse files Browse the repository at this point in the history
  • Loading branch information
ZebulanStanphill committed Jun 21, 2020
1 parent 01fab7e commit 9637656
Show file tree
Hide file tree
Showing 19 changed files with 347 additions and 40 deletions.
2 changes: 1 addition & 1 deletion lib/patterns/two-buttons.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

return array(
'title' => __( 'Two Buttons', 'gutenberg' ),
'content' => "<!-- wp:buttons {\"align\":\"center\"} -->\n<div class=\"wp-block-buttons aligncenter\"><!-- wp:button {\"backgroundColor\":\"very-dark-gray\",\"borderRadius\":0} -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-background has-very-dark-gray-background-color no-border-radius\">Button One</a></div>\n<!-- /wp:button -->\n\n<!-- wp:button {\"textColor\":\"very-dark-gray\",\"borderRadius\":0,\"className\":\"is-style-outline\"} -->\n<div class=\"wp-block-button is-style-outline\"><a class=\"wp-block-button__link has-text-color has-very-dark-gray-color no-border-radius\">Button Two</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->",
'content' => "<!-- wp:buttons {\"contentJustification\":\"center\"} -->\n<div class=\"wp-block-buttons is-content-justification-center\"><!-- wp:button {\"backgroundColor\":\"very-dark-gray\",\"borderRadius\":0} -->\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-background has-very-dark-gray-background-color no-border-radius\">Button One</a></div>\n<!-- /wp:button -->\n\n<!-- wp:button {\"textColor\":\"very-dark-gray\",\"borderRadius\":0,\"className\":\"is-style-outline\"} -->\n<div class=\"wp-block-button is-style-outline\"><a class=\"wp-block-button__link has-text-color has-very-dark-gray-color no-border-radius\">Button Two</a></div>\n<!-- /wp:button --></div>\n<!-- /wp:buttons -->",
'viewportWidth' => 500,
'categories' => array( 'buttons' ),
);
8 changes: 6 additions & 2 deletions packages/block-library/src/buttons/block.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
{
"name": "core/buttons",
"category": "design",
"attributes": {
"contentJustification": {
"type": "string"
}
},
"supports": {
"align": true,
"alignWide": false,
"align": [ "wide", "full" ],
"lightBlockWrapper": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* WordPress dependencies
*/
import { DropdownMenu } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { justifyCenterIcon, justifyLeftIcon, justifyRightIcon } from './icons';

const DEFAULT_ALLOWED_VALUES = [ 'left', 'center', 'right' ];

const CONTROLS = {
left: {
icon: justifyLeftIcon,
title: __( 'Justify items left' ),
},
center: {
icon: justifyCenterIcon,
title: __( 'Justify items center' ),
},
right: {
icon: justifyRightIcon,
title: __( 'Justify items right' ),
},
};

const DEFAULT_ICON = CONTROLS.center.icon;

/**
* Dropdown for selecting a content justification option.
*
* @param {Object} props Component props.
* @param {string[]} [props.allowedValues] List of options to include. Default:
* ['left', 'center', 'right'].
* @param {()=>void} props.onChange Callback to run when an option is
* selected in the dropdown.
* @param {string} props.value The current content justification
* value.
*
* @return {WPComponent} The component.
*/
export default function ContentJustificationDropdown( {
onChange,
allowedValues = DEFAULT_ALLOWED_VALUES,
value,
} ) {
function applyOrUnset( align ) {
return () => onChange( value === align ? undefined : align );
}

return (
<DropdownMenu
icon={ CONTROLS[ value ]?.icon ?? DEFAULT_ICON }
label={ __( 'Change content justification' ) }
controls={ allowedValues.map( ( allowedValue ) => {
return {
...CONTROLS[ allowedValue ],
isActive: value === allowedValue,
role: 'menuitemradio',
onClick: applyOrUnset( allowedValue ),
};
} ) }
/>
);
}
37 changes: 37 additions & 0 deletions packages/block-library/src/buttons/deprecated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { InnerBlocks } from '@wordpress/block-editor';

const deprecated = [
{
supports: {
align: [ 'center', 'left', 'right' ],
},
save() {
return (
<div>
<InnerBlocks.Content />
</div>
);
},
isEligible( { align } ) {
return align && [ 'center', 'left', 'right' ].includes( align );
},
migrate( attributes ) {
return {
...attributes,
align: undefined,
// Floating Buttons blocks shouldn't have been supported in the
// first place. Most users using them probably expected them to
// act like content justification controls, so these blocks are
// migrated to use content justification.
// As for center-aligned Buttons blocks, the content justification
// equivalent will create an identical end result in most cases.
contentJustification: attributes.align,
};
},
},
];

export default deprecated;
52 changes: 41 additions & 11 deletions packages/block-library/src/buttons/edit.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
__experimentalAlignmentHookSettingsProvider as AlignmentHookSettingsProvider,
BlockControls,
InnerBlocks,
__experimentalBlock as Block,
} from '@wordpress/block-editor';
import { ToolbarGroup } from '@wordpress/components';

/**
* Internal dependencies
*/
import { name as buttonBlockName } from '../button/';
import { name as buttonBlockName } from '../button';
import ContentJustificationDropdown from './content-justification-dropdown';

const ALLOWED_BLOCKS = [ buttonBlockName ];
const BUTTONS_TEMPLATE = [ [ 'core/button' ] ];
Expand All @@ -20,17 +28,39 @@ const alignmentHooksSetting = {
isEmbedButton: true,
};

function ButtonsEdit() {
function ButtonsEdit( {
attributes: { contentJustification },
className,
setAttributes,
} ) {
return (
<Block.div>
<AlignmentHookSettingsProvider value={ alignmentHooksSetting }>
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
template={ BUTTONS_TEMPLATE }
__experimentalMoverDirection="horizontal"
/>
</AlignmentHookSettingsProvider>
</Block.div>
<>
<BlockControls>
<ToolbarGroup>
<ContentJustificationDropdown
value={ contentJustification }
onChange={ ( updatedValue ) => {
setAttributes( {
contentJustification: updatedValue,
} );
} }
/>
</ToolbarGroup>
</BlockControls>
<Block.div
className={ classnames( className, {
[ `is-content-justification-${ contentJustification }` ]: contentJustification,
} ) }
>
<AlignmentHookSettingsProvider value={ alignmentHooksSetting }>
<InnerBlocks
allowedBlocks={ ALLOWED_BLOCKS }
template={ BUTTONS_TEMPLATE }
__experimentalMoverDirection="horizontal"
/>
</AlignmentHookSettingsProvider>
</Block.div>
</>
);
}

Expand Down
12 changes: 0 additions & 12 deletions packages/block-library/src/buttons/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,6 @@
width: auto;
}

.wp-block[data-align="center"] > .wp-block-buttons {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
}

.wp-block[data-align="right"] > .wp-block-buttons {
display: flex;
justify-content: flex-end;
}

.wp-block-buttons .block-list-appender {
display: inline-block;
}
37 changes: 37 additions & 0 deletions packages/block-library/src/buttons/icons.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* WordPress dependencies
*/
import { Path, SVG } from '@wordpress/components';

export const justifyLeftIcon = (
<SVG
width="20"
height="20"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<Path d="M11 16v-3h10v-2H11V8l-4 4 4 4zM5 4H3v16h2V4z" />
</SVG>
);

export const justifyCenterIcon = (
<SVG
width="20"
height="20"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<Path d="M5 8v3H1v2h4v3l4-4-4-4zm14 8v-3h4v-2h-4V8l-4 4 4 4zM13 4h-2v16h2V4z" />
</SVG>
);

export const justifyRightIcon = (
<SVG
width="20"
height="20"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<Path d="M13 8v3H3v2h10v3l4-4-4-4zm8-4h-2v16h2V4z" />
</SVG>
);
2 changes: 2 additions & 0 deletions packages/block-library/src/buttons/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { button as icon } from '@wordpress/icons';
/**
* Internal dependencies
*/
import deprecated from './deprecated';
import transforms from './transforms';
import edit from './edit';
import metadata from './block.json';
Expand All @@ -23,6 +24,7 @@ export const settings = {
),
icon,
keywords: [ __( 'link' ) ],
deprecated,
transforms,
edit,
save,
Expand Down
16 changes: 14 additions & 2 deletions packages/block-library/src/buttons/save.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import { InnerBlocks } from '@wordpress/block-editor';

export default function save() {
export default function save( {
attributes: { contentJustification },
className,
} ) {
return (
<div>
<div
className={ classnames( className, {
[ `is-content-justification-${ contentJustification }` ]: contentJustification,
} ) }
>
<InnerBlocks.Content />
</div>
);
Expand Down
28 changes: 27 additions & 1 deletion packages/block-library/src/buttons/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.wp-blocks-buttons {
display: flex;
flex-wrap: wrap;
}

// Increased specificity to override blocks default margin.
.wp-block-buttons .wp-block-button {
display: inline-block;
Expand All @@ -9,6 +14,28 @@
}
}

.wp-block-buttons.is-content-justification-left {
justify-content: flex-start;
}

.wp-block-buttons.is-content-justification-center {
justify-content: center;
}

.wp-block-buttons.is-content-justification-right {
justify-content: flex-end;
}

.wp-block-buttons.is-content-justification-right .wp-block-button {
margin-left: $grid-unit-10;
margin-right: 0;

&:first-child {
margin-left: 0;
}
}

// Kept for backward compatibiity.
.wp-block-buttons.alignright .wp-block-button {
margin-right: 0;
margin-left: $grid-unit-10;
Expand All @@ -17,7 +44,6 @@
margin-left: 0;
}
}

.wp-block-buttons.aligncenter {
text-align: center;
}
4 changes: 2 additions & 2 deletions packages/e2e-tests/fixtures/blocks/core__buttons.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!-- wp:buttons -->
<div class="wp-block-buttons">
<!-- wp:buttons {"align":"wide","contentJustification":"center"} -->
<div class="wp-block-buttons alignwide is-content-justification-center">
<!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link">My button 1</a></div>
<!-- /wp:button -->
Expand Down
7 changes: 5 additions & 2 deletions packages/e2e-tests/fixtures/blocks/core__buttons.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"clientId": "_clientId_0",
"name": "core/buttons",
"isValid": true,
"attributes": {},
"attributes": {
"contentJustification": "center",
"align": "wide"
},
"innerBlocks": [
{
"clientId": "_clientId_0",
Expand All @@ -26,6 +29,6 @@
"originalContent": "<div class=\"wp-block-button\"><a class=\"wp-block-button__link\">My button 2</a></div>"
}
],
"originalContent": "<div class=\"wp-block-buttons\">\n\t\n\n\t\n</div>"
"originalContent": "<div class=\"wp-block-buttons alignwide is-content-justification-center\">\n\t\n\n\t\n</div>"
}
]
Loading

0 comments on commit 9637656

Please sign in to comment.