diff --git a/packages/block-library/src/separator/block.json b/packages/block-library/src/separator/block.json index 784146a733fbde..784f34adeff602 100644 --- a/packages/block-library/src/separator/block.json +++ b/packages/block-library/src/separator/block.json @@ -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 }, diff --git a/packages/block-library/src/separator/edit.native.js b/packages/block-library/src/separator/edit.native.js new file mode 100644 index 00000000000000..33a7207a3bf7d9 --- /dev/null +++ b/packages/block-library/src/separator/edit.native.js @@ -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 ( + <> + + + + ); +} + +export default withColors( 'color', { textColor: 'color' } )( SeparatorEdit ); diff --git a/packages/block-library/src/separator/separator-settings.native.js b/packages/block-library/src/separator/separator-settings.native.js index d2bdd8ef6443a3..8c238b28648f54 100644 --- a/packages/block-library/src/separator/separator-settings.native.js +++ b/packages/block-library/src/separator/separator-settings.native.js @@ -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 ( + + + + + + + + ); +}; + export default SeparatorSettings; diff --git a/packages/block-library/src/separator/shared.js b/packages/block-library/src/separator/shared.js new file mode 100644 index 00000000000000..6deba13b6d86e6 --- /dev/null +++ b/packages/block-library/src/separator/shared.js @@ -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(); +}; diff --git a/packages/primitives/src/horizontal-rule/index.native.js b/packages/primitives/src/horizontal-rule/index.native.js index 853b57e76d0c1a..3d338ad7d4ba7f 100644 --- a/packages/primitives/src/horizontal-rule/index.native.js +++ b/packages/primitives/src/horizontal-rule/index.native.js @@ -2,6 +2,7 @@ * External dependencies */ import Hr from 'react-native-hr'; +import { View } from 'react-native'; /** * WordPress dependencies @@ -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 ( -
+ +
+
); };