-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Spacer: add custom units for height and width (#36186)
* Add width and height units and use the custom UnitControl * Refactor out the ResizableSpacer and fix resizing in the canvas * Correctly initialize width and height for horizontal spacer * Handle min and max values for px * Apply unit to the dimensions on the frontend * Refactor out the controls * Disable percentage units for Spacer * Only output width or height styles as needed for orientation * Correctly generate styles when width or height is set to 0 * Remove unnecessary parsing, interpolation * Remove separate unit attributes and update type of height and width attrs * Add block deprecation * Update and add fixtures for deprecation * Update snapshots * Ensure that the unit is updated to px when resizing by dragging the handle * Add mobile support for custom units
- Loading branch information
Showing
26 changed files
with
526 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { InspectorControls, useSetting } from '@wordpress/block-editor'; | ||
import { | ||
BaseControl, | ||
PanelBody, | ||
__experimentalUseCustomUnits as useCustomUnits, | ||
__experimentalUnitControl as UnitControl, | ||
} from '@wordpress/components'; | ||
import { useInstanceId } from '@wordpress/compose'; | ||
import { useState } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { MAX_SPACER_SIZE } from './edit'; | ||
|
||
function DimensionInput( { label, onChange, isResizing, value = '' } ) { | ||
const [ temporaryInput, setTemporaryInput ] = useState( null ); | ||
|
||
const inputId = useInstanceId( UnitControl, 'block-spacer-height-input' ); | ||
|
||
// In most contexts the spacer size cannot meaningfully be set to a | ||
// percentage, since this is relative to the parent container. This | ||
// unit is disabled from the UI. | ||
const availableUnitSettings = useSetting( 'spacing.units' ).filter( | ||
( availableUnit ) => availableUnit !== '%' | ||
); | ||
|
||
const units = useCustomUnits( { | ||
availableUnits: availableUnitSettings || [ | ||
'px', | ||
'em', | ||
'rem', | ||
'vw', | ||
'vh', | ||
], | ||
defaultValues: { px: '100', em: '10', rem: '10', vw: '10', vh: '25' }, | ||
} ); | ||
|
||
const handleOnChange = ( unprocessedValue ) => { | ||
setTemporaryInput( null ); | ||
onChange( unprocessedValue ); | ||
}; | ||
|
||
const handleOnBlur = () => { | ||
if ( temporaryInput !== null ) { | ||
setTemporaryInput( null ); | ||
} | ||
}; | ||
|
||
const inputValue = temporaryInput !== null ? temporaryInput : value; | ||
|
||
return ( | ||
<BaseControl label={ label } id={ inputId }> | ||
<UnitControl | ||
id={ inputId } | ||
isResetValueOnUnitChange | ||
min={ 0 } | ||
max={ MAX_SPACER_SIZE } | ||
onBlur={ handleOnBlur } | ||
onChange={ handleOnChange } | ||
style={ { maxWidth: 80 } } | ||
value={ inputValue } | ||
units={ units } | ||
// Force the unit to update to `px` when the Spacer is being resized. | ||
unit={ isResizing ? 'px' : undefined } | ||
/> | ||
</BaseControl> | ||
); | ||
} | ||
|
||
export default function SpacerControls( { | ||
setAttributes, | ||
orientation, | ||
height, | ||
width, | ||
isResizing, | ||
} ) { | ||
return ( | ||
<InspectorControls> | ||
<PanelBody title={ __( 'Spacer settings' ) }> | ||
{ orientation === 'horizontal' && ( | ||
<DimensionInput | ||
label={ __( 'Width' ) } | ||
value={ width } | ||
onChange={ ( nextWidth ) => | ||
setAttributes( { width: nextWidth } ) | ||
} | ||
isResizing={ isResizing } | ||
/> | ||
) } | ||
{ orientation !== 'horizontal' && ( | ||
<DimensionInput | ||
label={ __( 'Height' ) } | ||
value={ height } | ||
onChange={ ( nextHeight ) => | ||
setAttributes( { height: nextHeight } ) | ||
} | ||
isResizing={ isResizing } | ||
/> | ||
) } | ||
</PanelBody> | ||
</InspectorControls> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { | ||
PanelBody, | ||
UnitControl, | ||
getValueAndUnit, | ||
__experimentalUseCustomUnits as useCustomUnits, | ||
} from '@wordpress/components'; | ||
import { useCallback } from '@wordpress/element'; | ||
import { useSetting } from '@wordpress/block-editor'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import styles from './style.scss'; | ||
|
||
const DEFAULT_VALUES = { px: '100', em: '10', rem: '10', vw: '10', vh: '25' }; | ||
|
||
function Controls( { attributes, context, setAttributes } ) { | ||
const { orientation } = context; | ||
const label = orientation !== 'horizontal' ? __( 'Height' ) : __( 'Width' ); | ||
|
||
const { height, width } = attributes; | ||
const { valueToConvert, valueUnit: unit } = | ||
getValueAndUnit( orientation !== 'horizontal' ? height : width ) || {}; | ||
const value = Number( valueToConvert ); | ||
|
||
const setNewDimensions = ( nextValue, nextUnit ) => { | ||
const valueWithUnit = `${ nextValue }${ nextUnit }`; | ||
if ( orientation === 'horizontal' ) { | ||
setAttributes( { width: valueWithUnit } ); | ||
} else { | ||
setAttributes( { height: valueWithUnit } ); | ||
} | ||
}; | ||
|
||
const handleChange = useCallback( | ||
( nextValue ) => { | ||
setNewDimensions( nextValue, unit ); | ||
}, | ||
[ height, width ] | ||
); | ||
|
||
const handleUnitChange = useCallback( | ||
( nextUnit ) => { | ||
setNewDimensions( value, nextUnit ); | ||
}, | ||
[ height, width ] | ||
); | ||
|
||
const units = useCustomUnits( { | ||
availableUnits: useSetting( 'spacing.units' ) || [ | ||
'px', | ||
'em', | ||
'rem', | ||
'vw', | ||
'vh', | ||
], | ||
defaultValues: DEFAULT_VALUES, | ||
} ); | ||
|
||
return ( | ||
<> | ||
<PanelBody title={ __( 'Dimensions' ) }> | ||
<UnitControl | ||
label={ label } | ||
min={ 1 } | ||
value={ value } | ||
onChange={ handleChange } | ||
onUnitChange={ handleUnitChange } | ||
units={ units } | ||
unit={ unit } | ||
style={ styles.rangeCellContainer } | ||
/> | ||
</PanelBody> | ||
</> | ||
); | ||
} | ||
|
||
export default Controls; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { useBlockProps } from '@wordpress/block-editor'; | ||
|
||
const deprecated = [ | ||
{ | ||
attributes: { | ||
height: { | ||
type: 'number', | ||
default: 100, | ||
}, | ||
width: { | ||
type: 'number', | ||
}, | ||
}, | ||
migrate( attributes ) { | ||
const { height, width } = attributes; | ||
return { | ||
...attributes, | ||
width: width !== undefined ? `${ width }px` : undefined, | ||
height: height !== undefined ? `${ height }px` : undefined, | ||
}; | ||
}, | ||
save( { attributes } ) { | ||
return ( | ||
<div | ||
{ ...useBlockProps.save( { | ||
style: { | ||
height: attributes.height, | ||
width: attributes.width, | ||
}, | ||
'aria-hidden': true, | ||
} ) } | ||
/> | ||
); | ||
}, | ||
}, | ||
]; | ||
|
||
export default deprecated; |
Oops, something went wrong.