Skip to content

Commit

Permalink
Add range control
Browse files Browse the repository at this point in the history
  • Loading branch information
tellthemachines committed Mar 22, 2023
1 parent 99a52f5 commit b338b73
Showing 1 changed file with 76 additions and 22 deletions.
98 changes: 76 additions & 22 deletions packages/block-editor/src/layouts/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { __ } from '@wordpress/i18n';
import {
Flex,
FlexItem,
RangeControl,
__experimentalUnitControl as UnitControl,
__experimentalParseQuantityAndUnitFromRawValue as parseQuantityAndUnitFromRawValue,
} from '@wordpress/components';

/**
Expand All @@ -16,6 +18,15 @@ import { appendSelectors, getBlockGapCSS } from './utils';
import { getGapCSSValue } from '../hooks/gap';
import { shouldSkipSerialization } from '../hooks/utils';

const RANGE_CONTROL_MAX_VALUES = {
px: 600,
'%': 100,
vw: 100,
vh: 100,
em: 38,
rem: 38,
};

export default {
name: 'grid',
label: __( 'Grid' ),
Expand All @@ -24,16 +35,10 @@ export default {
onChange,
} ) {
return (
<>
<Flex direction="column">
<FlexItem>
<GridLayoutMinimumWidthControl
layout={ layout }
onChange={ onChange }
/>
</FlexItem>
</Flex>
</>
<GridLayoutMinimumWidthControl
layout={ layout }
onChange={ onChange }
/>
);
},
toolBarControls: function DefaultLayoutToolbarControls() {
Expand Down Expand Up @@ -93,19 +98,68 @@ export default {

// Enables setting minimum width of grid items.
function GridLayoutMinimumWidthControl( { layout, onChange } ) {
const { minimumColumnWidth = '20rem' } = layout;
const { minimumColumnWidth: value = '12rem' } = layout;
const [ quantity, unit ] = parseQuantityAndUnitFromRawValue( value );

const handleSliderChange = ( next ) => {
onChange( {
...layout,
minimumColumnWidth: [ next, unit ].join( '' ),
} );
};

// Mostly copied from HeightControl.
const handleUnitChange = ( newUnit ) => {
// Attempt to smooth over differences between currentUnit and newUnit.
// This should slightly improve the experience of switching between unit types.
let newValue;

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

onChange( {
...layout,
minimumColumnWidth: newValue,
} );
};

return (
<UnitControl
size={ '__unstable-large' }
label={ __( 'Minimum column width ' ) }
onChange={ ( value ) => {
onChange( {
...layout,
minimumColumnWidth: value,
} );
} }
value={ minimumColumnWidth }
/>
<Flex>
<FlexItem isBlock>
<UnitControl
label={ __( 'Minimum column width' ) }
size={ '__unstable-large' }
onChange={ ( newValue ) => {
onChange( {
...layout,
minimumColumnWidth: newValue,
} );
} }
onUnitChange={ handleUnitChange }
value={ value }
min={ 0 }
/>
</FlexItem>
<FlexItem isBlock>
<RangeControl
onChange={ handleSliderChange }
value={ quantity }
min={ 0 }
max={ RANGE_CONTROL_MAX_VALUES[ unit ] || 600 }
withInputField={ false }
/>
</FlexItem>
</Flex>
);
}

0 comments on commit b338b73

Please sign in to comment.