Issue by mmintel
_Tuesday Nov 08, 2016 at 10:04 GMT_
_Originally opened as https://github.com/storybooks/storybook-addon-knobs/issues/73_
Hi!
href={text('href', undefined)}
works perfectly until I enter some text and delete it again. instead of removing my href prop it fills in an empty string. Which I don't really understand because, normally, react will remove the prop if its empty (right?).
So initially my component looks like
<Button .. />
and after editing href and deleting again it looks like
<Button href="" />
Is this a bug or do I use it the wrong way?
My component passes the href prop immediately to the attribute like this here:
href={href}
Cheers!
Comment by renatorib
_Wednesday Jan 11, 2017 at 20:08 GMT_
I have this use case too. It's sucks.
My suggest is that could have something like .optional usage, like this example:
<Button href={text.optional('href', 'http://google.com')} />
When uses with .optional show a checkbox in front of textfield, to enable/disable knob.
When disabled, it pass undefined to value.
When enabled, it pass the textfield value.
Comment by Djspaceg
_Tuesday Feb 28, 2017 at 01:59 GMT_
@renatorib's proposal would work well for select as well, which could add an initial blank to the <select> which when chosen would exclude the prop from being sent to the component.
Comment by renatorib
_Tuesday Mar 07, 2017 at 18:09 GMT_
Unfortunately storybook's repos are almost abandoned. =(
Comment by Djspaceg
_Tuesday Mar 07, 2017 at 18:55 GMT_
For others interested in this problem (in the future), here's our solution:
/*
*
* Use for props that can take null value so that Storybook doesn't complain.
* example use:
* `nullify(select('propName', [null, 'value', 'two']))`
* `nullify(select('propName', ['', 'value', 'two']))`
*
*/
const nullify = (v) => v === '' ? null : v;
export default nullify;
This allows a story author to identify knobs that need to be treated differently than always-convert-to-empty-string, i.e. null support cases. Simply use it like this in a story:
import nullify from '../src/utils/nullify.js';
...
<Slider
orientation={nullify(select('orientation', [null, 'vertical', 'radial']))}
>
The prop will even be omitted in the storybook component info screen when the null option is selected, just like you'd expect. selects render the null as a blank (no text) in the dropdown for that item. Also, because the developer must intentionally add it, it's not going to break existing stories that expect empty strings.
Comment by Djspaceg
_Saturday Mar 18, 2017 at 00:27 GMT_
Just last week I realized it would be nice to incorporate strict equality to false, which would remove optional props from appearing in the "info" addon too. You could apply nullify to Boolean props:
Things like <Button round>Basic</Button> will not appear as <Button round={false}>Basic</Button> but instead as simply <Button>Basic</Button>.
const nullify = (v) => (v === '' || v === false) ? null : v;
or even smaller:
const nullify = (v) => !v ? null : v;
Great! Sounds like it would just take 1 brave soul to convert this into a easily mergeable PR!!
Who wants to do it? @Djspaceg @renatorib @mmintel
Let me know if you need help!
Well, so as our understanding of React and ES evolves, it turns out that the following method works a bit more reliably, returning an undefined rather than a null, which allows the defaultTypes to flow through.
const nullify = (v) => !v ? void 0 : v;
I'm not sure where in the source of Storybook this handy method should reside. Also, it now is more of a "nullify" concept, rather than _literally converting_ a falsy value to null.
Well for starters, we could document this in addon-knobs README!
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 60 days. Thanks!
Going to close this if no-one wants this badly enough to open a PR.
:\ It's not that nobody wants it. It's that it's not my project. I'm also not familiar with the direction of this project, or what the current state of it is, because, at the moment, I'm locked into an older version of Storybook.
I still _really_ want this feature, it's just not possible to open a PR on it at this time.
Does this approach solve your problem?
href={text('href', '') || undefined}
href={text('href', '') || undefined} is only a falsey check, which doesn't allow setting false, 0, or explicit setting of an intentional null. Also, in general, I was hoping for more of a compartmentalized solution, to isolate the logic, since the project I'm working on has hundreds of knobs across dozens of stories and story files.
text cannot output anything other than string. And !v ? void 0 : v is a falsyness check as well.
Isolating this logic is a good intention, but i think it should be solved in the scope of particular project. You may want to create some kind of utils module where you can export wrapped versions of knobs like that:
```
import * as knobs from '@storybook/addon-knobs'
const replaceFalsyWithUndefined = v => v || void 0
const wrapKnob = knob => (...args) => replaceFalsyWithUndefined(knob(...args))
export const text = wrapKnob(knobs.text)
export const select = wrapKnob(knobs.select)
...
@Hypnosphi that's a good idea. Then we can just refer to our own versions of knobs that have this altered functionality.
You're right about the falsey thing. My mistake. I was looking at and thinking about something else.
Most helpful comment
Does this approach solve your problem?