Skip to content

Commit

Permalink
Add flex layout to Buttons block and new layout type. (#35819)
Browse files Browse the repository at this point in the history
* Add flex layout to Buttons block and new layout type.

* Make orientation a property of flex layout

* Update save function and add deprecation

* Update fixtures

* Fix php lint warnings.

* Fix bad conflict resolution

* Set orientation in layout tools

* Improve orientation controls

* Change orientation to opt-out
  • Loading branch information
tellthemachines authored Nov 3, 2021
1 parent fbac29b commit 623829e
Show file tree
Hide file tree
Showing 24 changed files with 351 additions and 180 deletions.
37 changes: 24 additions & 13 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,18 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$style .= "$selector > * + * { margin-top: var( --wp--style--block-gap ); margin-bottom: 0; }";
}
} elseif ( 'flex' === $layout_type ) {
$layout_orientation = isset( $layout['orientation'] ) ? $layout['orientation'] : 'horizontal';

$justify_content_options = array(
'left' => 'flex-start',
'right' => 'flex-end',
'center' => 'center',
'space-between' => 'space-between',
'left' => 'flex-start',
'right' => 'flex-end',
'center' => 'center',
);

if ( 'horizontal' === $layout_orientation ) {
$justify_content_options += array( 'space-between' => 'space-between' );
}

$flex_wrap_options = array( 'wrap', 'nowrap' );
$flex_wrap = ! empty( $layout['flexWrap'] ) && in_array( $layout['flexWrap'], $flex_wrap_options, true ) ?
$layout['flexWrap'] :
Expand All @@ -89,14 +94,21 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$style .= 'gap: 0.5em;';
}
$style .= "flex-wrap: $flex_wrap;";
$style .= 'align-items: center;';
/**
* Add this style only if is not empty for backwards compatibility,
* since we intend to convert blocks that had flex layout implemented
* by custom css.
*/
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "justify-content: {$justify_content_options[ $layout['justifyContent'] ]};";
if ( 'horizontal' === $layout_orientation ) {
$style .= 'align-items: center;';
/**
* Add this style only if is not empty for backwards compatibility,
* since we intend to convert blocks that had flex layout implemented
* by custom css.
*/
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "justify-content: {$justify_content_options[ $layout['justifyContent'] ]};";
}
} else {
$style .= 'flex-direction: column;';
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "align-items: {$justify_content_options[ $layout['justifyContent'] ]};";
}
}
$style .= '}';

Expand Down Expand Up @@ -204,4 +216,3 @@ function( $matches ) {
remove_filter( 'render_block', 'wp_restore_group_inner_container', 10, 2 );
}
add_filter( 'render_block', 'gutenberg_restore_group_inner_container', 10, 2 );

3 changes: 2 additions & 1 deletion packages/block-editor/src/hooks/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
font-size: $helptext-font-size;
}

.block-editor-hooks__flex-layout-justification-controls {
.block-editor-hooks__flex-layout-justification-controls,
.block-editor-hooks__flex-layout-orientation-controls {
margin-bottom: $grid-unit-15;
legend {
margin-bottom: $grid-unit-10;
Expand Down
145 changes: 106 additions & 39 deletions packages/block-editor/src/layouts/flex.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
justifyCenter,
justifyRight,
justifySpaceBetween,
arrowRight,
arrowDown,
} from '@wordpress/icons';
import { Button, ToggleControl } from '@wordpress/components';
import { Button, ToggleControl, Flex, FlexItem } from '@wordpress/components';

/**
* Internal dependencies
Expand All @@ -17,13 +19,21 @@ import { appendSelectors } from './utils';
import useSetting from '../components/use-setting';
import { BlockControls, JustifyContentControl } from '../components';

// Used with the default, horizontal flex orientation.
const justifyContentMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
'space-between': 'space-between',
};

// Used with the vertical (column) flex orientation.
const alignItemsMap = {
left: 'flex-start',
right: 'flex-end',
center: 'center',
};

const flexWrapOptions = [ 'wrap', 'nowrap' ];

export default {
Expand All @@ -33,12 +43,25 @@ export default {
layout = {},
onChange,
} ) {
const { allowOrientation = true } = layout;
return (
<>
<FlexLayoutJustifyContentControl
layout={ layout }
onChange={ onChange }
/>
<Flex>
<FlexItem>
<FlexLayoutJustifyContentControl
layout={ layout }
onChange={ onChange }
/>
</FlexItem>
<FlexItem>
{ allowOrientation && (
<OrientationControl
layout={ layout }
onChange={ onChange }
/>
) }
</FlexItem>
</Flex>
<FlexWrapControl layout={ layout } onChange={ onChange } />
</>
);
Expand All @@ -62,6 +85,7 @@ export default {
);
},
save: function FlexLayoutStyle( { selector, layout } ) {
const { orientation = 'horizontal' } = layout;
const blockGapSupport = useSetting( 'spacing.blockGap' );
const hasBlockGapStylesSupport = blockGapSupport !== null;
const justifyContent =
Expand All @@ -70,6 +94,17 @@ export default {
const flexWrap = flexWrapOptions.includes( layout.flexWrap )
? layout.flexWrap
: 'wrap';
const rowOrientation = `
flex-direction: row;
align-items: center;
justify-content: ${ justifyContent };
`;
const alignItems =
alignItemsMap[ layout.justifyContent ] || alignItemsMap.left;
const columnOrientation = `
flex-direction: column;
align-items: ${ alignItems };
`;
return (
<style>{ `
${ appendSelectors( selector ) } {
Expand All @@ -80,9 +115,7 @@ export default {
: '0.5em'
};
flex-wrap: ${ flexWrap };
align-items: center;
flex-direction: row;
justify-content: ${ justifyContent };
${ orientation === 'horizontal' ? rowOrientation : columnOrientation }
}
${ appendSelectors( selector, '> *' ) } {
Expand All @@ -91,57 +124,35 @@ export default {
` }</style>
);
},
getOrientation() {
return 'horizontal';
getOrientation( layout ) {
const { orientation = 'horizontal' } = layout;
return orientation;
},
getAlignments() {
return [];
},
};

const justificationOptions = [
{
value: 'left',
icon: justifyLeft,
label: __( 'Justify items left' ),
},
{
value: 'center',
icon: justifyCenter,
label: __( 'Justify items center' ),
},
{
value: 'right',
icon: justifyRight,
label: __( 'Justify items right' ),
},
{
value: 'space-between',
icon: justifySpaceBetween,
label: __( 'Space between items' ),
},
];
function FlexLayoutJustifyContentControl( {
layout,
onChange,
isToolbar = false,
} ) {
const { justifyContent = 'left' } = layout;
const { justifyContent = 'left', orientation = 'horizontal' } = layout;
const onJustificationChange = ( value ) => {
onChange( {
...layout,
justifyContent: value,
} );
};
const allowedControls = [ 'left', 'center', 'right' ];
if ( orientation === 'horizontal' ) {
allowedControls.push( 'space-between' );
}
if ( isToolbar ) {
return (
<JustifyContentControl
allowedControls={ [
'left',
'center',
'right',
'space-between',
] }
allowedControls={ allowedControls }
value={ justifyContent }
onChange={ onJustificationChange }
popoverProps={ {
Expand All @@ -152,6 +163,31 @@ function FlexLayoutJustifyContentControl( {
);
}

const justificationOptions = [
{
value: 'left',
icon: justifyLeft,
label: __( 'Justify items left' ),
},
{
value: 'center',
icon: justifyCenter,
label: __( 'Justify items center' ),
},
{
value: 'right',
icon: justifyRight,
label: __( 'Justify items right' ),
},
];
if ( orientation === 'horizontal' ) {
justificationOptions.push( {
value: 'space-between',
icon: justifySpaceBetween,
label: __( 'Space between items' ),
} );
}

return (
<fieldset className="block-editor-hooks__flex-layout-justification-controls">
<legend>{ __( 'Justification' ) }</legend>
Expand Down Expand Up @@ -187,3 +223,34 @@ function FlexWrapControl( { layout, onChange } ) {
/>
);
}

function OrientationControl( { layout, onChange } ) {
const { orientation = 'horizontal' } = layout;
return (
<fieldset className="block-editor-hooks__flex-layout-orientation-controls">
<legend>{ __( 'Orientation' ) }</legend>
<Button
label={ 'horizontal' }
icon={ arrowRight }
isPressed={ orientation === 'horizontal' }
onClick={ () =>
onChange( {
...layout,
orientation: 'horizontal',
} )
}
/>
<Button
label={ 'vertical' }
icon={ arrowDown }
isPressed={ orientation === 'vertical' }
onClick={ () =>
onChange( {
...layout,
orientation: 'vertical',
} )
}
/>
</fieldset>
);
}
16 changes: 7 additions & 9 deletions packages/block-library/src/buttons/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,6 @@
"description": "Prompt visitors to take action with a group of button-style links.",
"keywords": [ "link" ],
"textdomain": "default",
"attributes": {
"contentJustification": {
"type": "string"
},
"orientation": {
"type": "string",
"default": "horizontal"
}
},
"supports": {
"anchor": true,
"align": [ "wide", "full" ],
Expand All @@ -25,6 +16,13 @@
"__experimentalDefaultControls": {
"blockGap": true
}
},
"__experimentalLayout": {
"allowSwitching": false,
"allowInheriting": false,
"default": {
"type": "flex"
}
}
},
"editorStyle": "wp-block-buttons-editor",
Expand Down
Loading

0 comments on commit 623829e

Please sign in to comment.