gutenberg icon indicating copy to clipboard operation
gutenberg copied to clipboard

Box Control range slider doesn't set a unit initially

Open albanyacademy opened this issue 1 year ago • 7 comments

Description

When using the __experimentalBoxControl with all values as null, the unit for each side is only set when the UnitControl itself is changed. When one uses the RangeControl first and drags to a number, the value received is just the number itself without a unit attached.

Step-by-step reproduction instructions

  1. Use a box control with a default value empty/null;
  2. set the onChange to console log the value;
  3. observe that when only dragging the range slider the value returned is only a number
  4. observe that unit only gets added when unitcontrol is used

Screenshots, screen recording, code snippet

https://www.screencast.com/t/I3RDlCL9ht2

Environment info

wp 6.5.2

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

albanyacademy avatar May 06 '24 18:05 albanyacademy

Thanks for the report. I don't know if this specification was intended or a bug, but I was able to reproduce the problem on Storybook.

https://github.com/WordPress/gutenberg/assets/54422211/77943da7-d413-4adb-b7e6-b78343056060

t-hamano avatar May 07 '24 05:05 t-hamano

Interesting. It might be debatable, but I think we can say this is a bug.

mirka avatar May 20 '24 22:05 mirka

Any news on this?

Tropicalista avatar Aug 17 '24 18:08 Tropicalista

Interesting. It might be debatable, but I think we can say this is a bug.

I mean, a number without a unit isn't usable, so I'd say without a doubt it's a bug 😛

albanyacademy avatar Sep 03 '24 15:09 albanyacademy

I've been having the same issue for the past couple of months, still not fix. My workaround was to create a function that checks if the unit exists, if not then i append it on the value

giannis-koulouris-bb avatar Nov 01 '24 13:11 giannis-koulouris-bb

Hi @t-hamano , I tried debugging and investigating the root cause of this issue and can say this as per my observations

  1. The input box on the left works well, As soon as we input a value it has both the value and the unit.

I backtracked it and could say that the UnitControl passes the correct value to the onChangeProp() which has both the unit and value and this in return comes to this and gets executed perfectly as expected in this onChange handler in the BoxInputControl

https://github.com/WordPress/gutenberg/blob/523c2bab2dfdf84b980f4abde75848050a88ec52/packages/components/src/box-control/input-control.tsx#L111-L114

  1. The case is different in the range control slider, here we have something like this defined as the onChange handler

https://github.com/WordPress/gutenberg/blob/523c2bab2dfdf84b980f4abde75848050a88ec52/packages/components/src/box-control/input-control.tsx#L224-L230

In this i observed that the root cause is computedUnit not assigned any value and is undefined thus we just get numbers only passed onto the handleOnValueChange of the BoxInputControl.

After a bit of more backtracking ...

https://github.com/WordPress/gutenberg/blob/523c2bab2dfdf84b980f4abde75848050a88ec52/packages/components/src/box-control/input-control.tsx#L146-L156

I linked computedUnit depends on parsedUnit depends on mergedValue which depends on values this is being passed to BoxInputControl component as a prop, after this I lost track 😅 .

I am not quite sure of how to handle this bug in the most correct way possible. I have a temporary fix. This is not scaleable IMO.

I would appreciate your thoughts on this Issue. Thank you in advance 🙇

Code sample with possible fix
  <FlexedRangeControl
        __nextHasNoMarginBottom
        __next40pxDefaultSize={ __next40pxDefaultSize }
        __shouldNotWarnDeprecated36pxSize
        aria-controls={ inputId }
        label={ LABELS[ side ] }
        hideLabelFromVision
        onChange={ ( newValue ) => {
        	handleOnValueChange(
        		newValue !== undefined
        			? [ newValue, computedUnit ].join( '' ) // Here we can do something like this computedUnit ?? 'px' same patterns as below 
        			: undefined
        	);
        } }
        min={ isFinite( min ) ? min : 0 }
        max={
        	CUSTOM_VALUE_SETTINGS[ computedUnit ?? 'px' ]
        		?.max ?? 10
        }
        step={
        	CUSTOM_VALUE_SETTINGS[ computedUnit ?? 'px' ]
        		?.step ?? 0.1
        }
        value={ parsedQuantity ?? 0 }
        withInputField={ false }
  />

im3dabasia avatar May 30 '25 14:05 im3dabasia

I think the reason the input box works correctly is because it uses the first available unit as a fallback if the unit is not yet defined:

https://github.com/WordPress/gutenberg/blob/44dba3879e54f904a6c6ddf326b70ca5160e38ea/packages/components/src/unit-control/utils.ts#L360-L365

In this i observed that the root cause is computedUnit not assigned any value and is undefined thus we just get numbers only passed onto the handleOnValueChange of the BoxInputControl.

Maybe the fallback logic is needed for the slider as well. In other words, if we provide a fallback unit here, selectedUnits will not be undefined, and as a result, computedUnit will not be undefined either.

t-hamano avatar May 31 '25 10:05 t-hamano