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

Separator Block: Add top/bottom margins via block support and modified BoxControl #30609

Closed
wants to merge 1 commit into from
Closed
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
5 changes: 4 additions & 1 deletion packages/block-library/src/separator/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
},
"supports": {
"anchor": true,
"align": [ "center", "wide", "full" ]
"align": [ "center", "wide", "full" ],
"spacing": {
"margin": [ "top", "bottom" ]
}
},
"styles": [
{ "name": "default", "label": "Default", "isDefault": true },
Expand Down
48 changes: 48 additions & 0 deletions packages/block-library/src/separator/edit.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* WordPress dependencies
*/
import { withColors, useBlockProps } from '@wordpress/block-editor';
import { HorizontalRule, useConvertUnitToMobile } from '@wordpress/components';

/**
* Internal dependencies
*/
import SeparatorSettings from './separator-settings';
import { MARGIN_CONSTRAINTS, parseUnit } from './shared';

function SeparatorEdit( props ) {
const {
color,
attributes: { style },
} = props;

const { top, bottom } = style?.spacing?.margin || {};
const marginUnit = parseUnit( top || bottom );

const convertedMarginTop = useConvertUnitToMobile(
parseFloat( top || 0 ) || MARGIN_CONSTRAINTS[ marginUnit ].min,
marginUnit
);

const convertedMarginBottom = useConvertUnitToMobile(
parseFloat( bottom || 0 ) || MARGIN_CONSTRAINTS[ marginUnit ].min,
marginUnit
);

return (
<>
<HorizontalRule
{ ...useBlockProps() }
style={ {
backgroundColor: color.color,
color: color.color,
marginBottom: convertedMarginBottom,
marginTop: convertedMarginTop,
} }
/>
<SeparatorSettings { ...props } />
</>
);
}

export default withColors( 'color', { textColor: 'color' } )( SeparatorEdit );
114 changes: 112 additions & 2 deletions packages/block-library/src/separator/separator-settings.native.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,113 @@
// Mobile has no separator settings at this time, so render nothing
const SeparatorSettings = () => null;
/**
* WordPress dependencies
*/
import { InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
import {
PanelBody,
UnitControl,
__experimentalUseCustomUnits as useCustomUnits,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import { MARGIN_CONSTRAINTS, parseUnit } from './shared';

const SeparatorSettings = ( {
color,
setColor,
attributes: { style },
setAttributes,
} ) => {
const units = useCustomUnits( {
availableUnits: [ 'px', 'em', 'rem' ],
defaultValues: { px: '0', em: '0', rem: '0' },
} );

const { top, bottom } = style?.spacing?.margin || {};
const topUnit = parseUnit( top );
const bottomUnit = parseUnit( bottom );
const topValue = top
? parseFloat( top )
: MARGIN_CONSTRAINTS[ topUnit ].min;
const bottomValue = bottom
? parseFloat( bottom )
: MARGIN_CONSTRAINTS[ bottomUnit ].min;

const updateMargins = ( margins ) => {
setAttributes( {
style: {
...style,
spacing: {
...style?.spacing,
margin: margins,
},
},
} );
};

const createHandleMarginChange = ( side, unit ) => ( value ) => {
updateMargins( {
...style?.spacing?.margin,
[ side ]: `${ value }${ unit }`,
} );
};

const onUnitChange = ( unit ) => {
updateMargins( {
top: MARGIN_CONSTRAINTS[ unit ].default,
bottom: MARGIN_CONSTRAINTS[ unit ].default,
} );
};

return (
<InspectorControls>
<PanelColorSettings
title={ __( 'Color settings' ) }
colorSettings={ [
{
value: color.color,
onChange: setColor,
label: __( 'Color' ),
},
] }
/>
<PanelBody title={ __( 'Separator settings' ) }>
<UnitControl
label={ __( 'Top margin' ) }
key={ `separator-top-margin-${ bottomUnit }` }
min={ MARGIN_CONSTRAINTS[ topUnit ].min }
max={ MARGIN_CONSTRAINTS[ topUnit ].max }
value={ topValue || MARGIN_CONSTRAINTS[ topUnit ].min }
unit={ topUnit }
units={ units }
onChange={ createHandleMarginChange( 'top', topUnit ) }
onUnitChange={ onUnitChange }
decimalNum={ 1 }
step={ topUnit === 'px' ? 1 : 0.1 }
/>
<UnitControl
label={ __( 'Bottom margin' ) }
key={ `separator-bottom-margin-${ bottomUnit }` }
min={ MARGIN_CONSTRAINTS[ bottomUnit ].min }
max={ MARGIN_CONSTRAINTS[ bottomUnit ].max }
value={
bottomValue || MARGIN_CONSTRAINTS[ bottomUnit ].min
}
unit={ bottomUnit }
units={ units }
onChange={ createHandleMarginChange(
'bottom',
bottomUnit
) }
onUnitChange={ onUnitChange }
decimalNum={ 1 }
step={ bottomUnit === 'px' ? 1 : 0.1 }
/>
</PanelBody>
</InspectorControls>
);
};

export default SeparatorSettings;
47 changes: 47 additions & 0 deletions packages/block-library/src/separator/shared.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Separator margin related constants.
export const MIN_PX_MARGIN = 15;
export const MIN_EM_MARGIN = 0.75;
export const MIN_REM_MARGIN = 0.7;
export const MAX_PX_MARGIN = 300;
export const MAX_EM_MARGIN = 20;
export const MAX_REM_MARGIN = 20;

/**
* Separator margin constraints for available CSS units.
*/
export const MARGIN_CONSTRAINTS = {
px: {
min: MIN_PX_MARGIN,
max: MAX_PX_MARGIN,
default: `${ MIN_PX_MARGIN }px`,
},
em: {
min: MIN_EM_MARGIN,
max: MAX_EM_MARGIN,
default: '1em',
},
rem: {
min: MIN_REM_MARGIN,
max: MAX_REM_MARGIN,
default: '1rem',
},
};

/**
* Extracts CSS unit from string.
*
* @param { string } cssValue CSS string containing unit and value.
* @return { string } CSS unit. Defaults to 'px'.
*/
export const parseUnit = ( cssValue ) => {
if ( ! cssValue ) {
return 'px';
}

const matches = cssValue.trim().match( /[\d.\-+]*\s*([a-zA-Z]*)$/ );
if ( ! matches ) {
return 'px';
}
const [ , unit ] = matches;
return ( unit || 'px' ).toLowerCase();
};
29 changes: 22 additions & 7 deletions packages/primitives/src/horizontal-rule/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import Hr from 'react-native-hr';
import { View } from 'react-native';

/**
* WordPress dependencies
Expand All @@ -13,16 +14,30 @@ import { withPreferredColorScheme } from '@wordpress/compose';
*/
import styles from './styles.scss';

const HR = ( { getStylesFromColorScheme, ...props } ) => {
const HR = ( { getStylesFromColorScheme, style, ...props } ) => {
const lineStyle = getStylesFromColorScheme( styles.line, styles.lineDark );
const customBackground = style?.backgroundColor
? { backgroundColor: style.backgroundColor }
: {};

return (
<Hr
{ ...props }
lineStyle={ [ lineStyle, props.lineStyle ] }
marginLeft={ 0 }
marginRight={ 0 }
/>
<View
style={ {
marginTop: style?.marginTop,
marginBottom: style?.marginBottom,
} }
>
<Hr
{ ...props }
lineStyle={ {
...lineStyle,
...props.lineStyle,
...customBackground,
} }
marginLeft={ 0 }
marginRight={ 0 }
/>
</View>
);
};

Expand Down