-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Controls/Knobs: Set input to empty string when value is null #14457
Controls/Knobs: Set input to empty string when value is null #14457
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should instead handle this in the story store, so that any other "consumers" of these args will gracefully handle null as well. I'm thinking mapArgsToTypes
but applied to any arg, not just URL args.
@@ -135,7 +135,7 @@ const RangeInput = styled.input(({ theme }) => ({ | |||
}, | |||
'&:focus::-ms-fill-lower': { background: '#dddddd' }, | |||
'&:focus::-ms-fill-upper': { background: '#e0e0e0' }, | |||
'@supports (-ms-ime-align:auto)': { 'input[type=range]': { margin: '0' } }, | |||
'@supports (msImeAlign:auto)': { 'input[type=range]': { margin: '0' } }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, not sure how this snuck in there.
@@ -164,13 +164,16 @@ export const RangeControl: FC<RangeProps> = ({ | |||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => { | |||
onChange(parse(event.target.value)); | |||
}; | |||
const inputValue = value === null ? '' : value; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just inline this variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I can do that. I was on the fence about whether or not to inline it.
In 6.3 we are going to update all the controls to allow an "unset" value -- i.e. With that in mind, it shouldn't be possible to have So I am not sure if this PR is a step towards that or not, WDYT @kmurgic? |
I'm not sure if I am interpreting this comment correctly. When a control or knob is cleared, I would think null - or possibly undefined - makes the most sense for the value of the knob/control. We only want the empty string value passed to the actual input in the knobs panel or controls panel to avoid the input inside the panel changing between controlled and uncontrolled. This way we avoid making a breaking change here. I personally like having the value of a knob be undefined when the last character in the input for a number knob/control is deleted. For example, in an InputField component I have an optional maxLength property that I am using a number control for. It would make sense to me that when the control panel input is cleared, the maxLength property would be undefined. In my code now I am doing |
It should be safe to do |
Apologies for taking such a long break from this PR. |
Hi @kmurgic thanks for coming back! Your timing is actually great, we are working on the solution I mentioned this week: #14899 So to address your points:
In that PR we show a button rather than the control if the value of the arg is
We are tossing up with this and setting it 0. There are a few controls where this is relevant:
There are couple reasons that setting the arg to We don't love setting it to a "random" value in 2-3 either, arguably that's an inconsistent UI too. We were thinking that if you blurred the control we might surface the new value (i.e. you clear the control, tab away, and it changes to "0"). [1] I'm actually unsure what happens if you mis-type an arg; for instance if you set a number-value arg to an object; what gets passed to the control? What should we do? We should probably address that now. |
I was having trouble deciphering the changes to figure out how this works. Can I "unset" a number input after I set it? For example if I set a control for my maxLength property, is there a way to remove the maxLength property entirely so that I'm passing maxLength: undefined to the component? What would I click to do that?
As long as there is a reasonable way to unset the number control I think this solution seems good to me. The thing I would want to avoid is not giving users any way to set a value for a number control to undefined. It's nice right now in SB that I can delete the contents of a number input and have the prop become null. For some optional props a value of undefined or null is very different from a value of 0. Examples Really though in a way this discussion is out of the scope of the issue/bug. In terms of the bug the important thing is that if we are ever showing an input in the controls section when the value of a knob is null or undefined we should be setting the value of the input that is inside the control panel to an empty string in order to avoid React's warning about a component switching between controlled and uncontrolled. Although if we are sure that if the knob value is null or undefined we won't even be showing an input component, then I suppose that solves this as well. |
I'm not an expert here by any means, but as a user my preference would be to have an error in the console and probably set the control as either unset or whatever it's default empty value would be. It also doesn't seem that unreasonable to me if the story failed to build in this case - as long as we could make it very clear to the user why the build failed. |
As of the latest alphas you can unset a control via resetting all the controls for the story. @domyen and I discussed this a couple times, and decide that the inconsistency (for a number control you can unset it by clearing, for a text control you cannot) was probably worse than the inconvenience of not being able to unset a control without clearing all. Perhaps users will feel differently once they have a chance to play with this.
I think that probably makes sense. I suspect what we'll do is pass the arg through (the arg type could be wrong too), but the control will either not work or be unset as you say. In any case, if you want to discuss if further we have a specific issue for this:
I think we are good here; if you can still repro this issue in the latest alphas, let us know. |
Issue: #13826
What I did
React is adding errors to the console:
value prop on 'input' should not be null
andA component is changing a controlled input of type number to be uncontrolled
whenever the contents of a number control or knob are deleted.In this PR, I set the input value to an empty string when the value of the knob or control is null. This prevents React from throwing errors about input values being null and inputs changing from controlled to uncontrolled.
How to test
In the current official storybook and kitchen sink examples if you delete the text inside a number knob or control there will be errors in the console. Examples of this issue can be found in the stories for examples/official-storybook in
controls/number
andaddons/knobs/withKnobs/tweaks static values
.In this branch there are no longer any errors in the console when you delete the text in a number control or number knob.
Is this testable with Jest or Chromatic screenshots?
No
Does this need a new example in the kitchen sink apps?
No
Does this need an update to the documentation?
No
If your answer is yes to any of these, please make sure to include it in your PR.