@@ -26,7 +26,7 @@ import { settings as stackableSettings } from 'stackable'
2626 * WordPress dependencies
2727 */
2828import {
29- memo , useState , useEffect ,
29+ memo , useState , useEffect , useRef ,
3030} from '@wordpress/element'
3131import { Button } from '@wordpress/components'
3232import { settings } from '@wordpress/icons'
@@ -117,6 +117,8 @@ const AdvancedRangeControl = props => {
117117 // at the start, or show custom
118118 // If no initial value, use the given default from the settings
119119 const [ isMarkMode , setIsMarkMode ] = useState ( false )
120+ // Ensure the convesion of value from preset to custom with regards to the unit is donce once.
121+ const isConversionDone = useRef ( false )
120122
121123 let isMarkValue = ! ! props . marks && isMarkModeDefault
122124 if ( props . marks && derivedValue ) {
@@ -203,8 +205,16 @@ const AdvancedRangeControl = props => {
203205 let rangeOnChange = _onChange
204206 if ( isMarkMode ) {
205207 rangeValue = props . marks . findIndex ( mark => {
206- const [ _value , _unit ] = extractNumbersAndUnits ( mark . value ) [ 0 ]
207- return _value === derivedValue
208+ let _unit , _value
209+ // If the derivedValue is a CSS variable, compare with mark's CSS variable.
210+ // Otherwise, the derivedValue is custom from the previous switch from custom to preset mode,
211+ // so compare with raw size and units to convert to preset.
212+ if ( typeof derivedValue === 'string' && derivedValue . startsWith ( 'var' ) ) {
213+ [ _value , _unit ] = extractNumbersAndUnits ( mark . value ) [ 0 ]
214+ } else {
215+ [ _value , _unit ] = extractNumbersAndUnits ( mark . size ) [ 0 ]
216+ }
217+ return _value === derivedValue && ( _unit === '' || _unit === unit )
208218 } )
209219 rangeOnChange = ( value , property = 'value' ) => {
210220 if ( value === '' ) {
@@ -230,6 +240,30 @@ const AdvancedRangeControl = props => {
230240 }
231241
232242 _onChange ( newValue )
243+ isConversionDone . current = false
244+ }
245+ } else if ( typeof derivedValue === 'string' && derivedValue . startsWith ( 'var' ) ) {
246+ // If the derivedValue is a preset and currently not in mark mode, the derivedValue is from
247+ // the previous switch from preset to custom mode. Convert to custom.
248+ const currentSize = props . marks . find ( mark => {
249+ return derivedValue === mark . value
250+ } ) ?. size
251+ const [ _newValue , _unit ] = extractNumbersAndUnits ( currentSize ) [ 0 ]
252+ rangeValue = _newValue
253+
254+ if ( _unit && ! isConversionDone . current ) {
255+ dispatch ( 'core/block-editor' ) . __unstableMarkNextChangeAsNotPersistent ( )
256+ setAttributes ( { [ unitAttrName ] : _unit } )
257+ if ( props . onChangeUnit ) {
258+ props . onChangeUnit ( _unit )
259+ }
260+ isConversionDone . current = true
261+ }
262+ // Since the actual previous value is a preset, force the new custom value
263+ // when changing unit
264+ controlProps . onChangeUnit = ( unit , unitAttrName ) => {
265+ setAttributes ( { [ unitAttrName ] : unit } )
266+ _onChange ( _newValue )
233267 }
234268 }
235269
@@ -254,23 +288,6 @@ const AdvancedRangeControl = props => {
254288 size = "small"
255289 variant = "tertiary"
256290 onClick = { ( ) => {
257- // Set the value when changing from mark mode to custom
258- if ( isMarkMode && rangeValue !== - 1 ) {
259- rangeOnChange ( rangeValue , 'size' )
260- } else {
261- const rangeValue = props . marks . findIndex ( mark => {
262- let _unit , _value
263-
264- [ _value , _unit ] = extractNumbersAndUnits ( mark . size ) [ 0 ]
265- const converted = convertToPxIfUnsupported ( props . units , _unit , _value )
266- _value = converted . value
267- _unit = converted . unit
268-
269- return _value === derivedValue && ( _unit === '' || _unit === unit )
270- } )
271- const markValue = props . marks [ rangeValue ] ?. value || '0'
272- _onChange ( markValue )
273- }
274291 setIsMarkMode ( ! isMarkMode )
275292 } }
276293 icon = { settings }
0 commit comments