diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index b5d6beabb4f60..d995ccb31bbf5 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -4,6 +4,7 @@ $z-layers: ( ".block-editor-block-list__block::before": 0, + ".block-editor-block-list__block.is-selected": 20, ".block-editor-block-switcher__arrow": 1, ".block-editor-block-list__block {core/image aligned wide or fullwide}": 20, ".block-library-classic__toolbar": 31, // When scrolled to top this toolbar needs to sit over block-editor-block-toolbar diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index 2bf9d47d3385d..3971df611c277 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -183,6 +183,14 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b user-select: none; } + &.has-negative-margin { + &.is-selected, + &.has-child-selected { + // Bring the selected block forward so we can see it. + z-index: z-index(".block-editor-block-list__block.is-selected"); + } + } + .reusable-block-edit-panel * { z-index: z-index(".block-editor-block-list__block .reusable-block-edit-panel *"); } diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index af98f24b98785..b91b9d32f52ac 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -144,6 +144,16 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { ); } + let hasNegativeMargin = false; + if ( + wrapperProps?.style?.marginTop?.charAt( 0 ) === '-' || + wrapperProps?.style?.marginBottom?.charAt( 0 ) === '-' || + wrapperProps?.style?.marginLeft?.charAt( 0 ) === '-' || + wrapperProps?.style?.marginRight?.charAt( 0 ) === '-' + ) { + hasNegativeMargin = true; + } + return { tabIndex: blockEditingMode === 'disabled' ? -1 : 0, ...wrapperProps, @@ -174,6 +184,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { 'can-insert-moving-block': canInsertMovingBlock, 'is-editing-disabled': isEditingDisabled, 'has-editable-outline': hasEditableOutline, + 'has-negative-margin': hasNegativeMargin, 'is-content-locked-temporarily-editing-as-blocks': isTemporarilyEditingAsBlocks, }, diff --git a/packages/block-editor/src/components/global-styles/dimensions-panel.js b/packages/block-editor/src/components/global-styles/dimensions-panel.js index 94e53eec16372..3ba726b1a6613 100644 --- a/packages/block-editor/src/components/global-styles/dimensions-panel.js +++ b/packages/block-editor/src/components/global-styles/dimensions-panel.js @@ -561,6 +561,7 @@ export default function DimensionsPanel( { { + if ( value?.charAt( 0 ) === '-' ) { + setMinValue( 0 ); + } + } } + onDrag={ () => { + if ( value?.charAt( 0 ) === '-' ) { + setMinValue( 0 ); + } + } } + onDragEnd={ () => { + setMinValue( minimumCustomValue ); + } } /> {}; function useUniqueId( idProp?: string ) { @@ -74,7 +70,6 @@ function useUniqueId( idProp?: string ) { function BoxControl( { __next40pxDefaultSize = false, id: idProp, - inputProps = defaultInputProps, onChange = noop, label = __( 'Box Control' ), values: valuesProp, @@ -85,6 +80,7 @@ function BoxControl( { resetValues = DEFAULT_VALUES, onMouseOver, onMouseOut, + ...inputProps }: BoxControlProps ) { const [ values, setValues ] = useControlledState( valuesProp, { fallback: DEFAULT_VALUES, @@ -140,8 +136,11 @@ function BoxControl( { setIsDirty( false ); }; + const min = 'min' in inputProps ? inputProps.min : 0; + const newInputProps = { ...inputProps, min }; + const inputControlProps = { - ...inputProps, + newInputProps, onChange: handleOnChange, onFocus: handleOnFocus, isLinked, diff --git a/packages/components/src/box-control/input-controls.tsx b/packages/components/src/box-control/input-controls.tsx index 553f547abf9b0..2c10c0510ad3e 100644 --- a/packages/components/src/box-control/input-controls.tsx +++ b/packages/components/src/box-control/input-controls.tsx @@ -2,6 +2,7 @@ * WordPress dependencies */ import { useInstanceId } from '@wordpress/compose'; +import { useState } from '@wordpress/element'; /** * Internal dependencies */ @@ -28,6 +29,8 @@ export default function BoxInputControls( { sides, ...props }: BoxControlInputControlProps ) { + const minimumCustomValue = props.min; + const [ minValue, setMinValue ] = useState( minimumCustomValue ); const generatedId = useInstanceId( BoxInputControls, 'box-control-input' ); const createHandleOnFocus = @@ -100,6 +103,9 @@ export default function BoxInputControls( { ? parsedUnit : selectedUnits[ side ]; + const isNegativeValue = + parsedQuantity !== undefined && parsedQuantity < 0; + const inputId = [ generatedId, side ].join( '-' ); return ( @@ -115,6 +121,7 @@ export default function BoxInputControls( { value={ [ parsedQuantity, computedUnit ].join( '' ) } + min={ minValue } onChange={ ( nextValue, extra ) => handleOnValueChange( side, @@ -126,6 +133,19 @@ export default function BoxInputControls( { side ) } onFocus={ createHandleOnFocus( side ) } + onDragStart={ () => { + if ( isNegativeValue ) { + setMinValue( 0 ); + } + } } + onDrag={ () => { + if ( isNegativeValue ) { + setMinValue( 0 ); + } + } } + onDragEnd={ () => { + setMinValue( minimumCustomValue ); + } } label={ LABELS[ side ] } hideLabelFromVision />