diff --git a/packages/block-library/src/separator/block.json b/packages/block-library/src/separator/block.json
index 2983a93a86190a..0fbb45a2930127 100644
--- a/packages/block-library/src/separator/block.json
+++ b/packages/block-library/src/separator/block.json
@@ -8,6 +8,13 @@
},
"customColor": {
"type": "string"
+ },
+ "height": {
+ "type": "number"
+ },
+ "heightUnit": {
+ "type": "string",
+ "default": "px"
}
},
"supports": {
diff --git a/packages/block-library/src/separator/edit.js b/packages/block-library/src/separator/edit.js
index f611abde42a62b..e5c881b949a959 100644
--- a/packages/block-library/src/separator/edit.js
+++ b/packages/block-library/src/separator/edit.js
@@ -2,33 +2,121 @@
* External dependencies
*/
import classnames from 'classnames';
+import { clamp } from 'lodash';
/**
* WordPress dependencies
*/
-import { HorizontalRule } from '@wordpress/components';
+import { HorizontalRule, ResizableBox } from '@wordpress/components';
+import { useState } from '@wordpress/element';
import { withColors, useBlockProps } from '@wordpress/block-editor';
+import { View } from '@wordpress/primitives';
+
/**
* Internal dependencies
*/
import SeparatorSettings from './separator-settings';
+import { HEIGHT_CONSTRAINTS } from './shared';
+
+function SeparatorEdit( props ) {
+ const { attributes, setAttributes, color, setColor, isSelected } = props;
+ const { height, heightUnit } = attributes;
+ const [ isResizing, setIsResizing ] = useState( false );
+
+ const currentMinHeight = HEIGHT_CONSTRAINTS[ heightUnit ].min;
+ const currentMaxHeight = HEIGHT_CONSTRAINTS[ heightUnit ].max;
+
+ // Resize handler for when user is drag resizing block via ResizableBlock.
+ const onResize = ( _event, _direction, elt ) => {
+ setAttributes( {
+ height: clamp(
+ parseInt( elt.clientHeight, 10 ),
+ HEIGHT_CONSTRAINTS.px.min,
+ HEIGHT_CONSTRAINTS.px.max
+ ),
+ heightUnit: 'px',
+ } );
+ };
+
+ const cssHeight = `${ height }${ heightUnit }`;
+ const blockProps = useBlockProps();
+ const margin = height
+ ? `${ height / 2 }${ heightUnit }`
+ : `${ currentMinHeight / 2 }${ heightUnit }`;
-function SeparatorEdit( { color, setColor, className } ) {
+ // The block's className and styles are moved to the inner
to retain
+ // the different styling approaches between themes. The use of bottom
+ // borders and background colors prevents using padding internally on the
+ // edit component. Adjusting margins leads to losing visual indicators for
+ // block selection.
return (
<>
-
+
+ setIsResizing( true ) }
+ onResize={ onResize }
+ onResizeStop={ ( ...args ) => {
+ onResize( ...args );
+ setIsResizing( false );
+ } }
+ showHandle={ isSelected }
+ __experimentalShowTooltip={ true }
+ __experimentalTooltipProps={ {
+ axis: 'y',
+ position: 'bottom',
+ isVisible: isResizing,
+ } }
+ />
+
+
-
>
);
}
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..b6a1bf95fa120f
--- /dev/null
+++ b/packages/block-library/src/separator/edit.native.js
@@ -0,0 +1,79 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
+/**
+ * WordPress dependencies
+ */
+import { HorizontalRule, useConvertUnitToMobile } from '@wordpress/components';
+import { withColors, useBlockProps } from '@wordpress/block-editor';
+import { View } from '@wordpress/primitives';
+
+/**
+ * Internal dependencies
+ */
+import SeparatorSettings from './separator-settings';
+import { HEIGHT_CONSTRAINTS } from './shared';
+
+function SeparatorEdit( props ) {
+ const {
+ attributes: { height, heightUnit },
+ setAttributes,
+ color,
+ setColor,
+ } = props;
+
+ const currentMinHeight = HEIGHT_CONSTRAINTS[ heightUnit ].min;
+ const currentMaxHeight = HEIGHT_CONSTRAINTS[ heightUnit ].max;
+
+ const convertedHeightValue = useConvertUnitToMobile(
+ height || currentMinHeight,
+ heightUnit
+ );
+
+ const margin = convertedHeightValue / 2;
+ const blockProps = useBlockProps();
+
+ // The block's className and styles are moved to the inner
to retain
+ // the different styling approaches between themes. The use of bottom
+ // borders and background colors prevents using padding internally on the
+ // edit component. Adjusting margins leads to losing visual indicators for
+ // block selection.
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
+
+export default withColors( 'color', { textColor: 'color' } )( SeparatorEdit );
diff --git a/packages/block-library/src/separator/editor.scss b/packages/block-library/src/separator/editor.scss
index 24e940684279e8..18a056860465fe 100644
--- a/packages/block-library/src/separator/editor.scss
+++ b/packages/block-library/src/separator/editor.scss
@@ -3,3 +3,29 @@
padding-top: 0.1px;
padding-bottom: 0.1px;
}
+
+.block-library-separator__wrapper {
+ position: relative;
+}
+
+.editor-styles-wrapper {
+ .wp-block.wp-block-separator__wrapper {
+ margin: 0 auto;
+ }
+}
+
+// Duplicate selector to overcome theme specificity.
+.editor-styles-wrapper .wp-block .wp-block-separator.wp-block-separator {
+ margin: 0;
+ position: absolute;
+ width: 100%;
+
+ &.is-style-dots {
+ border-top: none;
+ }
+}
+
+// Counter the added height of the dots style's pseudo after element
+.wp-block-separator__wrapper.is-style-dots .is-style-dots {
+ transform: translateY(-0.75em);
+}
diff --git a/packages/block-library/src/separator/save.js b/packages/block-library/src/separator/save.js
index 67d489bd611c3c..6ce2c7a342af98 100644
--- a/packages/block-library/src/separator/save.js
+++ b/packages/block-library/src/separator/save.js
@@ -9,7 +9,8 @@ import classnames from 'classnames';
import { getColorClassName, useBlockProps } from '@wordpress/block-editor';
export default function separatorSave( { attributes } ) {
- const { color, customColor } = attributes;
+ const { color, customColor, height, heightUnit } = attributes;
+ const margin = height ? `${ height / 2 }${ heightUnit }` : undefined;
// the hr support changing color using border-color, since border-color
// is not yet supported in the color palette, we use background-color
@@ -27,6 +28,8 @@ export default function separatorSave( { attributes } ) {
const style = {
backgroundColor: backgroundClass ? undefined : customColor,
color: colorClass ? undefined : customColor,
+ marginBottom: margin,
+ marginTop: margin,
};
return
;
diff --git a/packages/block-library/src/separator/separator-settings.js b/packages/block-library/src/separator/separator-settings.js
index 320cfc862b93bd..561b12adaebb64 100644
--- a/packages/block-library/src/separator/separator-settings.js
+++ b/packages/block-library/src/separator/separator-settings.js
@@ -1,22 +1,69 @@
+/**
+ * External dependencies
+ */
+import { clamp } from 'lodash';
+
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
+import {
+ PanelBody,
+ __experimentalUnitControl as UnitControl,
+} from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { HEIGHT_CONSTRAINTS, HEIGHT_CSS_UNITS } from './shared';
+
+const SeparatorSettings = ( props ) => {
+ const { color, setColor, height, heightUnit, setAttributes } = props;
+ const minHeight = HEIGHT_CONSTRAINTS[ heightUnit ].min;
+ const maxHeight = HEIGHT_CONSTRAINTS[ heightUnit ].max;
+
+ const updateHeight = ( value ) => {
+ setAttributes( {
+ height: clamp( parseFloat( value ), minHeight, maxHeight ),
+ heightUnit,
+ } );
+ };
+
+ const updateHeightUnit = ( value ) => {
+ setAttributes( {
+ height: HEIGHT_CONSTRAINTS[ value ].default,
+ heightUnit: value,
+ } );
+ };
-const SeparatorSettings = ( { color, setColor } ) => (
-
-
-
-);
+ return (
+
+
+
+
+
+
+ );
+};
export default SeparatorSettings;
diff --git a/packages/block-library/src/separator/separator-settings.native.js b/packages/block-library/src/separator/separator-settings.native.js
index d2bdd8ef6443a3..77c6526bd900df 100644
--- a/packages/block-library/src/separator/separator-settings.native.js
+++ b/packages/block-library/src/separator/separator-settings.native.js
@@ -1,3 +1,68 @@
-// Mobile has no separator settings at this time, so render nothing
-const SeparatorSettings = () => null;
+/**
+ * External dependencies
+ */
+import { clamp } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { __ } from '@wordpress/i18n';
+import { InspectorControls, PanelColorSettings } from '@wordpress/block-editor';
+import { PanelBody, UnitControl } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { HEIGHT_CONSTRAINTS, HEIGHT_CSS_UNITS } from './shared';
+
+const SeparatorSettings = ( props ) => {
+ const { color, setColor, height, heightUnit, setAttributes } = props;
+ const minHeight = HEIGHT_CONSTRAINTS[ heightUnit ].min;
+ const maxHeight = HEIGHT_CONSTRAINTS[ heightUnit ].max;
+
+ const updateHeight = ( value ) => {
+ setAttributes( {
+ height: clamp( parseFloat( value ), minHeight, maxHeight ),
+ heightUnit,
+ } );
+ };
+
+ const updateHeightUnit = ( value ) => {
+ setAttributes( {
+ height: HEIGHT_CONSTRAINTS[ value ].default,
+ heightUnit: value,
+ } );
+ };
+
+ 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..46755a90d4a219
--- /dev/null
+++ b/packages/block-library/src/separator/shared.js
@@ -0,0 +1,53 @@
+/**
+ * WordPress dependencies
+ */
+import { Platform } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+//Separator height related constants.
+export const MIN_PX_HEIGHT = 30;
+export const MIN_EM_HEIGHT = 1.5;
+export const MIN_REM_HEIGHT = 1.5;
+export const MAX_PX_HEIGHT = 500;
+export const MAX_EM_HEIGHT = 30;
+export const MAX_REM_HEIGHT = 30;
+
+const isWeb = Platform.OS === 'web';
+
+/**
+ * Available CSS units for specifying Separator height.
+ */
+export const HEIGHT_CSS_UNITS = [
+ { value: 'px', label: isWeb ? 'px' : __( 'Pixels (px)' ), default: 0 },
+ {
+ value: 'em',
+ label: isWeb ? 'em' : __( 'Relative to parent font size (em)' ),
+ default: 0,
+ },
+ {
+ value: 'rem',
+ label: isWeb ? 'rem' : __( 'Relative to root font size (rem)' ),
+ default: 0,
+ },
+];
+
+/**
+ * Separator height constraints for available CSS units.
+ */
+export const HEIGHT_CONSTRAINTS = {
+ px: {
+ min: MIN_PX_HEIGHT,
+ max: MAX_PX_HEIGHT,
+ default: MIN_PX_HEIGHT,
+ },
+ em: {
+ min: MIN_EM_HEIGHT,
+ max: MAX_EM_HEIGHT,
+ default: 1.5,
+ },
+ rem: {
+ min: MIN_REM_HEIGHT,
+ max: MAX_REM_HEIGHT,
+ default: 1.5,
+ },
+};
diff --git a/packages/primitives/src/horizontal-rule/index.native.js b/packages/primitives/src/horizontal-rule/index.native.js
index 853b57e76d0c1a..6046411cbbe82f 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,25 @@ 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 (
-
+
+
+
);
};
diff --git a/packages/primitives/src/horizontal-rule/styles.native.scss b/packages/primitives/src/horizontal-rule/styles.native.scss
index dabb62a8336542..7ec1e49e85d2c2 100644
--- a/packages/primitives/src/horizontal-rule/styles.native.scss
+++ b/packages/primitives/src/horizontal-rule/styles.native.scss
@@ -1,3 +1,13 @@
+.container {
+ align-items: center;
+ bottom: 0;
+ justify-content: center;
+ left: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+}
+
.line {
background-color: $gray-lighten-20;
height: 2;