Skip to content

Commit

Permalink
Spacing: Optimize & condense unlinked spacing controls (#50660)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw committed May 29, 2023
1 parent 4c60efe commit 4bdc581
Show file tree
Hide file tree
Showing 23 changed files with 936 additions and 373 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,6 @@ export default function DimensionsPanel( {
sides={ paddingSides }
units={ units }
allowReset={ false }
splitOnAxis={ isAxialPadding }
onMouseOver={ onMouseOverPadding }
onMouseOut={ onMouseLeaveControls }
/>
Expand Down Expand Up @@ -540,7 +539,6 @@ export default function DimensionsPanel( {
sides={ marginSides }
units={ units }
allowReset={ false }
splitOnAxis={ isAxialMargin }
onMouseOver={ onMouseOverMargin }
onMouseOut={ onMouseLeaveControls }
/>
Expand Down Expand Up @@ -587,10 +585,10 @@ export default function DimensionsPanel( {
label={ __( 'Block spacing' ) }
min={ 0 }
onChange={ setGapValues }
showSideInLabel={ false }
sides={ isAxialGap ? gapSides : [ 'top' ] } // Use 'top' as the shorthand property in non-axial configurations.
values={ gapValues }
allowReset={ false }
splitOnAxis={ isAxialGap }
/>
) }
</ToolsPanelItem>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import useSetting from '../../use-setting';

export default function useSpacingSizes() {
const spacingSizes = [
{ name: 0, slug: '0', side: 0 },
...( useSetting( 'spacing.spacingSizes' ) || [] ),
];

if ( spacingSizes.length > 8 ) {
spacingSizes.unshift( {
name: __( 'Default' ),
slug: 'default',
size: undefined,
} );
}

return spacingSizes;
}
156 changes: 85 additions & 71 deletions packages/block-editor/src/components/spacing-sizes-control/index.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,50 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
import {
BaseControl,
__experimentalHStack as HStack,
} from '@wordpress/components';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { BaseControl } from '@wordpress/components';
import { __, _x, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import AllInputControl from './all-input-control';
import InputControls from './input-controls';
import AxialInputControls from './axial-input-controls';
import LinkedButton from './linked-button';
import { DEFAULT_VALUES, isValuesMixed, isValuesDefined } from './utils';
import useSetting from '../use-setting';
import AxialInputControls from './input-controls/axial';
import SeparatedInputControls from './input-controls/separated';
import SingleInputControl from './input-controls/single';
import SidesDropdown from './sides-dropdown';
import useSpacingSizes from './hooks/use-spacing-sizes';
import {
ALL_SIDES,
DEFAULT_VALUES,
LABELS,
VIEWS,
getInitialView,
} from './utils';

export default function SpacingSizesControl( {
inputProps,
onChange,
label = __( 'Spacing Control' ),
values,
sides,
splitOnAxis = false,
useSelect,
label: labelProp,
minimumCustomValue = 0,
onMouseOver,
onChange,
onMouseOut,
onMouseOver,
showSideInLabel = true,
sides = ALL_SIDES,
useSelect,
values,
} ) {
const spacingSizes = [
{ name: 0, slug: '0', size: 0 },
...( useSetting( 'spacing.spacingSizes' ) || [] ),
];

if ( spacingSizes.length > 8 ) {
spacingSizes.unshift( {
name: __( 'Default' ),
slug: 'default',
size: undefined,
} );
}

const spacingSizes = useSpacingSizes();
const inputValues = values || DEFAULT_VALUES;
const hasInitialValue = isValuesDefined( values );
const hasOneSide = sides?.length === 1;
const hasOnlyAxialSides =
sides?.includes( 'horizontal' ) &&
sides?.includes( 'vertical' ) &&
sides?.length === 2;

const [ isLinked, setIsLinked ] = useState(
! hasInitialValue || ! isValuesMixed( inputValues, sides ) || hasOneSide
);

const toggleLinked = () => {
setIsLinked( ! isLinked );
};
const [ view, setView ] = useState( getInitialView( inputValues, sides ) );

const handleOnChange = ( nextValue ) => {
const newValues = { ...values, ...nextValue };
Expand All @@ -64,43 +53,68 @@ export default function SpacingSizesControl( {

const inputControlProps = {
...inputProps,
minimumCustomValue,
onChange: handleOnChange,
isLinked,
onMouseOut,
onMouseOver,
sides,
values: inputValues,
spacingSizes,
type: labelProp,
useSelect,
type: label,
minimumCustomValue,
onMouseOver,
onMouseOut,
values: inputValues,
};

return (
<fieldset
className={ classnames( 'component-spacing-sizes-control', {
'is-unlinked': ! isLinked,
} ) }
>
<BaseControl.VisualLabel as="legend">
{ label }
</BaseControl.VisualLabel>
{ ! hasOneSide && (
<LinkedButton onClick={ toggleLinked } isLinked={ isLinked } />
) }
{ isLinked && (
<AllInputControl
aria-label={ label }
{ ...inputControlProps }
/>
) }
const renderControls = () => {
if ( view === VIEWS.axial ) {
return <AxialInputControls { ...inputControlProps } />;
}
if ( view === VIEWS.custom ) {
return <SeparatedInputControls { ...inputControlProps } />;
}
return (
<SingleInputControl
side={ view }
{ ...inputControlProps }
showSideInLabel={ showSideInLabel }
/>
);
};

const sideLabel =
ALL_SIDES.includes( view ) && showSideInLabel ? LABELS[ view ] : '';

const label = sprintf(
// translators: 2. Type of spacing being modified (Padding, margin, etc). 1: The side of the block being modified (top, bottom, left etc.).
__( '%1$s %2$s' ),
labelProp,
sideLabel
).trim();

{ ! isLinked && splitOnAxis && (
<AxialInputControls { ...inputControlProps } />
) }
{ ! isLinked && ! splitOnAxis && (
<InputControls { ...inputControlProps } />
) }
const dropdownLabelText = sprintf(
// translators: %s: The current spacing property e.g. "Padding", "Margin".
_x( '%s options', 'Button label to reveal side configuration options' ),
labelProp
);

return (
<fieldset className="spacing-sizes-control">
<HStack className="spacing-sizes-control__header">
<BaseControl.VisualLabel
as="legend"
className="spacing-sizes-control__label"
>
{ label }
</BaseControl.VisualLabel>
{ ! hasOneSide && ! hasOnlyAxialSides && (
<SidesDropdown
label={ dropdownLabelText }
onChange={ setView }
sides={ sides }
value={ view }
/>
) }
</HStack>
{ renderControls() }
</fieldset>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@
* Internal dependencies
*/
import SpacingInputControl from './spacing-input-control';
import { LABELS } from './utils';
import { LABELS, ICONS, hasAxisSupport } from '../utils';

const groupedSides = [ 'vertical', 'horizontal' ];

export default function AxialInputControls( {
minimumCustomValue,
onChange,
values,
onMouseOut,
onMouseOver,
sides,
spacingSizes,
type,
minimumCustomValue,
onMouseOver,
onMouseOut,
values,
} ) {
const createHandleOnChange = ( side ) => ( next ) => {
if ( ! onChange ) {
Expand All @@ -37,7 +37,7 @@ export default function AxialInputControls( {

// Filter sides if custom configuration provided, maintaining default order.
const filteredSides = sides?.length
? groupedSides.filter( ( side ) => sides.includes( side ) )
? groupedSides.filter( ( side ) => hasAxisSupport( sides, side ) )
: groupedSides;

return (
Expand All @@ -47,17 +47,18 @@ export default function AxialInputControls( {
side === 'vertical' ? values.top : values.left;
return (
<SpacingInputControl
value={ axisValue }
onChange={ createHandleOnChange( side ) }
label={ LABELS[ side ] }
key={ `spacing-sizes-control-${ side }` }
withInputField={ false }
icon={ ICONS[ side ] }
label={ LABELS[ side ] }
minimumCustomValue={ minimumCustomValue }
onChange={ createHandleOnChange( side ) }
onMouseOut={ onMouseOut }
onMouseOver={ onMouseOver }
side={ side }
spacingSizes={ spacingSizes }
type={ type }
minimumCustomValue={ minimumCustomValue }
onMouseOver={ onMouseOver }
onMouseOut={ onMouseOut }
value={ axisValue }
withInputField={ false }
/>
);
} ) }
Expand Down
Loading

0 comments on commit 4bdc581

Please sign in to comment.