Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 123 additions & 0 deletions packages/block-editor/src/components/height-control/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* WordPress dependencies
*/
import { useMemo } from '@wordpress/element';
import {
BaseControl,
RangeControl,
Flex,
FlexItem,
__experimentalSpacer as Spacer,
__experimentalUseCustomUnits as useCustomUnits,
__experimentalUnitControl as UnitControl,
__experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

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

const RANGE_CONTROL_CUSTOM_SETTINGS = {
px: { max: 1000, step: 1 },
'%': { max: 100, step: 1 },
vw: { max: 100, step: 1 },
vh: { max: 100, step: 1 },
em: { max: 50, step: 0.1 },
rem: { max: 50, step: 0.1 },
};

export default function HeightControl( {
onChange,
label = __( 'Height' ),
value,
} ) {
const customRangeValue = parseFloat( value );

const units = useCustomUnits( {
availableUnits: useSetting( 'spacing.units' ) || [
'%',
'px',
'em',
'rem',
'vh',
'vw',
],
} );

const selectedUnit =
useMemo(
() => parseQuantityAndUnitFromRawValue( value ),
[ value ]
)[ 1 ] ||
units[ 0 ]?.value ||
'px';

const handleSliderChange = ( next ) => {
onChange( [ next, selectedUnit ].join( '' ) );
};

const handleUnitChange = ( newUnit ) => {
// Attempt to smooth over differences between currentUnit and newUnit.
// This should slightly improve the experience of switching between unit types.
const [ currentValue, currentUnit ] =
parseQuantityAndUnitFromRawValue( value );

if ( [ 'em', 'rem' ].includes( newUnit ) && currentUnit === 'px' ) {
// Convert pixel value to an approximate of the new unit, assuming a root size of 16px.
onChange( ( currentValue / 16 ).toFixed( 2 ) + newUnit );
} else if (
[ 'em', 'rem' ].includes( currentUnit ) &&
newUnit === 'px'
) {
// Convert to pixel value assuming a root size of 16px.
onChange( Math.round( currentValue * 16 ) + newUnit );
} else if (
[ 'vh', 'vw', '%' ].includes( newUnit ) &&
currentValue > 100
) {
// When converting to `vh`, `vw`, or `%` units, cap the new value at 100.
onChange( 100 + newUnit );
}
};

return (
<fieldset className="block-editor-height-control">
<BaseControl.VisualLabel as="legend">
{ label }
</BaseControl.VisualLabel>
<Flex>
<FlexItem isBlock>
<UnitControl
value={ value }
units={ units }
onChange={ onChange }
onUnitChange={ handleUnitChange }
min={ 0 }
size={ '__unstable-large' }
/>
</FlexItem>
<FlexItem isBlock>
<Spacer marginX={ 2 } marginBottom={ 0 }>
<RangeControl
value={ customRangeValue }
min={ 0 }
max={
RANGE_CONTROL_CUSTOM_SETTINGS[ selectedUnit ]
?.max ?? 100
}
step={
RANGE_CONTROL_CUSTOM_SETTINGS[ selectedUnit ]
?.step ?? 0.1
}
withInputField={ false }
onChange={ handleSliderChange }
__nextHasNoMarginBottom
/>
</Spacer>
</FlexItem>
</Flex>
</fieldset>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';

/**
* Internal dependencies
*/
import HeightControl from '../';

export default {
component: HeightControl,
title: 'BlockEditor/HeightControl',
};

const Template = ( props ) => {
const [ value, setValue ] = useState();
return <HeightControl onChange={ setValue } value={ value } { ...props } />;
};

export const Default = Template.bind( {} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.block-editor-height-control {
border: 0;
margin: 0;
padding: 0;
}
1 change: 1 addition & 0 deletions packages/block-editor/src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export { default as __experimentalColorGradientControl } from './colors-gradient
export { default as __experimentalColorGradientSettingsDropdown } from './colors-gradients/dropdown';
export { default as __experimentalPanelColorGradientSettings } from './colors-gradients/panel-color-gradient-settings';
export { default as __experimentalUseMultipleOriginColorsAndGradients } from './colors-gradients/use-multiple-origin-colors-and-gradients';
export { default as __experimentalHeightControl } from './height-control';
export {
default as __experimentalImageEditor,
ImageEditingProvider as __experimentalImageEditingProvider,
Expand Down
1 change: 0 additions & 1 deletion packages/block-editor/src/hooks/dimensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ export function DimensionsPanel( props ) {
) }
{ ! isMinHeightDisabled && (
<ToolsPanelItem
className="single-column"
hasValue={ () => hasMinHeightValue( props ) }
label={ __( 'Min. height' ) }
onDeselect={ () => resetMinHeight( props ) }
Expand Down
21 changes: 2 additions & 19 deletions packages/block-editor/src/hooks/min-height.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@
* WordPress dependencies
*/
import { getBlockSupport } from '@wordpress/blocks';
import {
__experimentalUseCustomUnits as useCustomUnits,
__experimentalUnitControl as UnitControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import useSetting from '../components/use-setting';
import HeightControl from '../components/height-control';
import { DIMENSIONS_SUPPORT_KEY } from './dimensions';
import { cleanEmptyObject } from './utils';

Expand Down Expand Up @@ -81,17 +78,6 @@ export function MinHeightEdit( props ) {
setAttributes,
} = props;

const units = useCustomUnits( {
availableUnits: useSetting( 'dimensions.units' ) || [
'%',
'px',
'em',
'rem',
'vh',
'vw',
],
} );

if ( useIsMinHeightDisabled( props ) ) {
return null;
}
Expand All @@ -109,13 +95,10 @@ export function MinHeightEdit( props ) {
};

return (
<UnitControl
<HeightControl
label={ __( 'Min. height' ) }
value={ style?.dimensions?.minHeight }
units={ units }
onChange={ onChange }
min={ 0 }
size={ '__unstable-large' }
/>
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
@import "./components/date-format-picker/style.scss";
@import "./components/duotone-control/style.scss";
@import "./components/font-appearance-control/style.scss";
@import "./components/height-control/style.scss";
@import "./components/image-size-control/style.scss";
@import "./components/inner-blocks/style.scss";
@import "./components/inserter-list-item/style.scss";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
} from '@wordpress/components';
import {
__experimentalUseCustomSides as useCustomSides,
__experimentalHeightControl as HeightControl,
__experimentalSpacingSizesControl as SpacingSizesControl,
} from '@wordpress/block-editor';
import { Icon, positionCenter, stretchWide } from '@wordpress/icons';
Expand Down Expand Up @@ -556,19 +557,15 @@ export default function DimensionsPanel( { name } ) {
) }
{ showMinHeightControl && (
<ToolsPanelItem
className="single-column"
hasValue={ hasMinHeightValue }
label={ __( 'Min. height' ) }
onDeselect={ resetMinHeightValue }
isShownByDefault={ true }
>
<UnitControl
<HeightControl
label={ __( 'Min. height' ) }
value={ minHeightValue }
onChange={ setMinHeightValue }
units={ units }
min={ 0 }
size={ '__unstable-large' }
/>
</ToolsPanelItem>
) }
Expand Down