diff --git a/packages/block-editor/src/hooks/border-width.js b/packages/block-editor/src/hooks/border-width.js index 0876cc50a5f65b..ec584efde4bce8 100644 --- a/packages/block-editor/src/hooks/border-width.js +++ b/packages/block-editor/src/hooks/border-width.js @@ -26,7 +26,7 @@ export const BorderWidthEdit = ( props ) => { } = props; // Step value is maintained in state so step is appropriate for current unit - // even when current radius value is undefined. + // even when current width value is undefined. const initialStep = parseUnit( style?.border?.width ) === 'px' ? 1 : 0.25; const [ step, setStep ] = useState( initialStep ); diff --git a/packages/edit-site/src/components/sidebar/border-panel.js b/packages/edit-site/src/components/sidebar/border-panel.js index b37f9b8b33d5e2..b994c24d16dc06 100644 --- a/packages/edit-site/src/components/sidebar/border-panel.js +++ b/packages/edit-site/src/components/sidebar/border-panel.js @@ -2,10 +2,15 @@ * WordPress dependencies */ import { + __experimentalBorderRadiusControl as BorderRadiusControl, __experimentalBorderStyleControl as BorderStyleControl, __experimentalColorGradientControl as ColorGradientControl, } from '@wordpress/block-editor'; -import { PanelBody, RangeControl } from '@wordpress/components'; +import { + PanelBody, + __experimentalUnitControl as UnitControl, +} from '@wordpress/components'; +import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** @@ -13,14 +18,16 @@ import { __ } from '@wordpress/i18n'; */ import { useEditorFeature } from '../editor/utils'; -const MIN_BORDER_RADIUS_VALUE = 0; -const MAX_BORDER_RADIUS_VALUE = 50; const MIN_BORDER_WIDTH = 0; -const MAX_BORDER_WIDTH = 50; // Defining empty array here instead of inline avoids unnecessary re-renders of // color control. const EMPTY_ARRAY = []; +const CSS_UNITS = [ + { value: 'px', label: 'px', default: '' }, + { value: 'em', label: 'em', default: '' }, + { value: 'rem', label: 'rem', default: '' }, +]; export function useHasBorderPanel( { supports, name } ) { const controls = [ @@ -61,28 +68,32 @@ function useHasBorderWidthControl( { supports, name } ) { ); } +function parseUnit( cssValue ) { + const value = String( cssValue ).trim(); + const unitMatch = value.match( /[\d.\-\+]*\s*(.*)/ )[ 1 ]; + const unit = unitMatch !== undefined ? unitMatch.toLowerCase() : ''; + const currentUnit = CSS_UNITS.find( ( item ) => item.value === unit ); + + return currentUnit?.value || 'px'; +} + export default function BorderPanel( { context: { supports, name }, getStyle, setStyle, } ) { - // Border style. - const hasBorderStyle = useHasBorderStyleControl( { supports, name } ); - const borderStyle = getStyle( name, 'borderStyle' ); - // Border width. const hasBorderWidth = useHasBorderWidthControl( { supports, name } ); - const borderWidthValue = parseInt( - getStyle( name, 'borderWidth' ) || 0, - 10 - ); + const borderWidthValue = getStyle( name, 'borderWidth' ); - // Border radius. - const hasBorderRadius = useHasBorderRadiusControl( { supports, name } ); - const borderRadiusValue = parseInt( - getStyle( name, 'borderRadius' ) || 0, - 10 - ); + // Step value is maintained in state so step is appropriate for current unit + // even when current width value is undefined. + const initialStep = parseUnit( borderWidthValue ) === 'px' ? 1 : 0.25; + const [ step, setStep ] = useState( initialStep ); + + // Border style. + const hasBorderStyle = useHasBorderStyleControl( { supports, name } ); + const borderStyle = getStyle( name, 'borderStyle' ); // Border color. const colors = useEditorFeature( 'color.palette' ) || EMPTY_ARRAY; @@ -91,43 +102,42 @@ export default function BorderPanel( { const hasBorderColor = useHasBorderColorControl( { supports, name } ); const borderColor = getStyle( name, 'borderColor' ); + // Border radius. + const hasBorderRadius = useHasBorderRadiusControl( { supports, name } ); + const borderRadiusValues = getStyle( name, 'borderRadius' ); + return ( - { hasBorderStyle && ( - - setStyle( name, 'borderStyle', value ) - } - /> - ) } - { hasBorderWidth && ( - { - const widthStyle = value ? `${ value }px` : undefined; - setStyle( name, 'borderWidth', widthStyle ); - } } - /> - ) } - { hasBorderRadius && ( - { - const radiusStyle = value ? `${ value }px` : undefined; - setStyle( name, 'borderRadius', radiusStyle ); - } } - /> + { ( hasBorderWidth || hasBorderStyle ) && ( +
+ { hasBorderWidth && ( + { + setStyle( + name, + 'borderWidth', + value || undefined + ); + } } + onUnitChange={ ( newUnit ) => { + setStep( newUnit === 'px' ? 1 : 0.25 ); + } } + step={ step } + units={ CSS_UNITS } + /> + ) } + { hasBorderStyle && ( + + setStyle( name, 'borderStyle', value ) + } + /> + ) } +
) } { hasBorderColor && ( ) } + { hasBorderRadius && ( + + setStyle( name, 'borderRadius', value ) + } + /> + ) }
); } diff --git a/packages/edit-site/src/components/sidebar/style.scss b/packages/edit-site/src/components/sidebar/style.scss index bc75cfb88ec401..712db7bed14a0a 100644 --- a/packages/edit-site/src/components/sidebar/style.scss +++ b/packages/edit-site/src/components/sidebar/style.scss @@ -24,3 +24,17 @@ .edit-site-global-styles-sidebar__reset-button.components-button { margin-left: auto; } + +.edit-site-global-styles-sidebar__border-controls-row { + display: flex; + justify-content: space-between; + margin-bottom: $grid-unit-15; + + > * { + width: calc(50% - #{ $grid-unit-10 }); + } + + .components-border-style-control__buttons { + margin-bottom: 0; + } +}