Skip to content

Commit

Permalink
Add top/bottom margins to separator block
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed Nov 5, 2021
1 parent f01e9c5 commit f4be82a
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 10 deletions.
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

0 comments on commit f4be82a

Please sign in to comment.