Box Control range slider doesn't set a unit initially
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
- Use a box control with a default value empty/null;
- set the onChange to console log the value;
- observe that when only dragging the range slider the value returned is only a number
- 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
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
Interesting. It might be debatable, but I think we can say this is a bug.
Any news on this?
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 😛
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
Hi @t-hamano , I tried debugging and investigating the root cause of this issue and can say this as per my observations
- 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
- 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 }
/>
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
computedUnitnot assigned any value and is undefined thus we just get numbers only passed onto thehandleOnValueChangeof theBoxInputControl.
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.