diff --git a/lib/block-supports/layout.php b/lib/block-supports/layout.php index 1abc69c7362da5..d2fe978c20e581 100644 --- a/lib/block-supports/layout.php +++ b/lib/block-supports/layout.php @@ -65,8 +65,8 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) { ?> > * { max-width: ; - margin-left: auto; - margin-right: auto; + margin-left: auto !important; + margin-right: auto !important; } > .alignwide { diff --git a/lib/class-wp-theme-json.php b/lib/class-wp-theme-json.php index e422d58778da0f..dc86e724db4722 100644 --- a/lib/class-wp-theme-json.php +++ b/lib/class-wp-theme-json.php @@ -106,6 +106,12 @@ class WP_Theme_JSON { 'bottom' => null, 'left' => null, ), + 'margin' => array( + 'top' => null, + 'right' => null, + 'bottom' => null, + 'left' => null, + ), ), 'typography' => array( 'fontFamily' => null, @@ -133,6 +139,7 @@ class WP_Theme_JSON { ), 'spacing' => array( 'customPadding' => null, + 'customMargin' => null, 'units' => null, ), 'typography' => array( @@ -281,6 +288,10 @@ class WP_Theme_JSON { 'value' => array( 'spacing', 'padding' ), 'properties' => array( 'top', 'right', 'bottom', 'left' ), ), + 'margin' => array( + 'value' => array( 'spacing', 'margin' ), + 'properties' => array( 'top', 'right', 'bottom', 'left' ), + ), 'text-decoration' => array( 'value' => array( 'typography', 'textDecoration' ), ), diff --git a/lib/experimental-default-theme.json b/lib/experimental-default-theme.json index da910ca84747a7..1145b711580eb0 100644 --- a/lib/experimental-default-theme.json +++ b/lib/experimental-default-theme.json @@ -168,6 +168,7 @@ }, "spacing": { "customPadding": false, + "customMargin": false, "units": [ "px", "em", "rem", "vh", "vw" ] }, "border": { diff --git a/packages/block-editor/src/components/block-list/layout.js b/packages/block-editor/src/components/block-list/layout.js index 3f898ae12c02fe..d5c2d31c7efd1b 100644 --- a/packages/block-editor/src/components/block-list/layout.js +++ b/packages/block-editor/src/components/block-list/layout.js @@ -43,8 +43,8 @@ export function LayoutStyle( { selector, layout = {} } ) { ? ` ${ appendSelectors( selector, '> *' ) } { max-width: ${ contentSize ?? wideSize }; - margin-left: auto; - margin-right: auto; + margin-left: auto !important; + margin-right: auto !important; } ${ appendSelectors( selector, '> [data-align="wide"]' ) } { diff --git a/packages/block-editor/src/components/spacing-panel-control/index.js b/packages/block-editor/src/components/spacing-panel-control/index.js index aafdbb94151d27..d7db9c6f73c8a1 100644 --- a/packages/block-editor/src/components/spacing-panel-control/index.js +++ b/packages/block-editor/src/components/spacing-panel-control/index.js @@ -11,9 +11,10 @@ import InspectorControls from '../inspector-controls'; import useEditorFeature from '../use-editor-feature'; export default function SpacingPanelControl( { children, ...props } ) { - const isSpacingEnabled = useEditorFeature( 'spacing.customPadding' ); + const supportsPadding = useEditorFeature( 'spacing.customPadding' ); + const supportsMargin = useEditorFeature( 'spacing.customMargin' ); - if ( ! isSpacingEnabled ) return null; + if ( ! supportsMargin && ! supportsPadding ) return null; return ( diff --git a/packages/block-editor/src/hooks/margin.js b/packages/block-editor/src/hooks/margin.js new file mode 100644 index 00000000000000..00efa5233b566f --- /dev/null +++ b/packages/block-editor/src/hooks/margin.js @@ -0,0 +1,86 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Platform } from '@wordpress/element'; +import { getBlockSupport } from '@wordpress/blocks'; +import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import { cleanEmptyObject } from './utils'; +import { useCustomUnits } from '../components/unit-control'; +import useEditorFeature from '../components/use-editor-feature'; + +const SPACING_SUPPORT_KEY = 'spacing'; + +const hasMarginSupport = ( blockName ) => { + const spacingSupport = getBlockSupport( blockName, SPACING_SUPPORT_KEY ); + return spacingSupport && spacingSupport.margin !== false; +}; + +/** + * Inspector control panel containing the margin related configuration + * + * @param {Object} props + * + * @return {WPElement} Margin edit element. + */ +export function MarginEdit( props ) { + const { + name: blockName, + attributes: { style }, + setAttributes, + } = props; + + const supportsMargin = useEditorFeature( 'spacing.customMargin' ); + const units = useCustomUnits(); + + if ( ! supportsMargin || ! hasMarginSupport( blockName ) ) { + return null; + } + + const onChange = ( next ) => { + const newStyle = { + ...style, + spacing: { + ...style?.spacing, + margin: next, + }, + }; + + setAttributes( { + style: cleanEmptyObject( newStyle ), + } ); + }; + + const onChangeShowVisualizer = ( next ) => { + const newStyle = { + ...style, + visualizers: { + ...style?.visualizers, + margin: next, + }, + }; + + setAttributes( { + style: cleanEmptyObject( newStyle ), + } ); + }; + + return Platform.select( { + web: ( + <> + + + ), + native: null, + } ); +} diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js index 7253ee0629b66d..aef6afc29bc521 100644 --- a/packages/block-editor/src/hooks/padding.js +++ b/packages/block-editor/src/hooks/padding.js @@ -11,6 +11,7 @@ import { __experimentalBoxControl as BoxControl } from '@wordpress/components'; */ import { cleanEmptyObject } from './utils'; import { useCustomUnits } from '../components/unit-control'; +import useEditorFeature from '../components/use-editor-feature'; export const SPACING_SUPPORT_KEY = 'spacing'; @@ -33,9 +34,10 @@ export function PaddingEdit( props ) { setAttributes, } = props; + const supportsPadding = useEditorFeature( 'spacing.customPadding' ); const units = useCustomUnits(); - if ( ! hasPaddingSupport( blockName ) ) { + if ( ! supportsPadding || ! hasPaddingSupport( blockName ) ) { return null; } @@ -43,6 +45,7 @@ export function PaddingEdit( props ) { const newStyle = { ...style, spacing: { + ...style?.spacing, padding: next, }, }; @@ -56,6 +59,7 @@ export function PaddingEdit( props ) { const newStyle = { ...style, visualizers: { + ...style?.visualizers, padding: next, }, }; diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js index b1c7239b2d791d..61445b9317e8e3 100644 --- a/packages/block-editor/src/hooks/style.js +++ b/packages/block-editor/src/hooks/style.js @@ -21,6 +21,7 @@ import { BORDER_SUPPORT_KEY, BorderPanel } from './border'; import { COLOR_SUPPORT_KEY, ColorEdit } from './color'; import { TypographyPanel, TYPOGRAPHY_SUPPORT_KEYS } from './typography'; import { SPACING_SUPPORT_KEY, PaddingEdit } from './padding'; +import { MarginEdit } from './margin'; import SpacingPanelControl from '../components/spacing-panel-control'; const styleSupportKeys = [ @@ -188,6 +189,7 @@ export const withBlockControls = createHigherOrderComponent( hasSpacingSupport && ( + ), ]; diff --git a/packages/block-library/src/group/block.json b/packages/block-library/src/group/block.json index ad4cc62fc68a73..716c2bdaf33a09 100644 --- a/packages/block-library/src/group/block.json +++ b/packages/block-library/src/group/block.json @@ -20,7 +20,8 @@ "link": true }, "spacing": { - "padding": true + "padding": true, + "margin": true }, "__experimentalBorder": { "color": true, diff --git a/packages/blocks/src/api/constants.js b/packages/blocks/src/api/constants.js index 4215022da66594..71da48eb75ba59 100644 --- a/packages/blocks/src/api/constants.js +++ b/packages/blocks/src/api/constants.js @@ -70,6 +70,11 @@ export const __EXPERIMENTAL_STYLE_PROPERTY = { support: [ 'spacing', 'padding' ], properties: [ 'top', 'right', 'bottom', 'left' ], }, + margin: { + value: [ 'spacing', 'margin' ], + support: [ 'spacing', 'margin' ], + properties: [ 'top', 'right', 'bottom', 'left' ], + }, textDecoration: { value: [ 'typography', 'textDecoration' ], support: [ '__experimentalTextDecoration' ],