-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Refactor transitional decorator from addon-notes #3559
Conversation
This should make it easy to transitional other addons to a parameter-based style
|
||
const hoc = deprecate( | ||
options => story => context => decorator(options)(story, context), | ||
`Passing stories directly into ${name}() is deprecated, instead use addDecorator(${name}) and pass options with the '${parameterName}' parameter` |
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.
Are we sure that we want to deprecate the old way? Honestly, it looks a lot more explicit to me
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.
Oh, I thought we did?
I think the strongest argument in favour is if you want to pass parameters to more than one decorator for the same story:
.add('story', withNotes('foo')(backgrounds(['red', 'white'])(() => <Story />)))
vs
.add('story', () => <Story />, { notes: 'foo', backgrounds: ['red', 'white'] })
I was planning on changing all the documentation to not mention the old way at least, so deprecating made sense to me, but I'm open to whatever.
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 think we could afford supporting both
@ndelangen WDYT
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.
What is a benefit of having the old API supported?
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.
You may want to supply the same parameters (e.g. backgrounds) to multiple stories
And even extract it into variable or module, like here:
https://github.com/storybooks/storybook/tree/master/addons/backgrounds#usage
("Of course it's easy to create a library module")
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 mean my idea is that you would just add addDecorators(backgrounds) once in your .storybook/config.js once (like you need to add it to .storybook/addons.js), and then you would add the parameters to turn the addon on wherever you needed it.
That's perfect I think.
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.
@tmeasday I just realised that those are two different usecases
// here withSomething is params => (storyFn, context) => output
.addDecorator(withSomething(params))
// here it is params => storyFn => () => output
.add('story', withSomething(params)(storyFn))
Actually addons that support both do some checks to figure out which usage is it.
Can we maybe just deprecate the latter but keep the former, because it's quite useful in cases like backgrounds?
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.
Oh, now I see that the latter is the thing we're actually deprecating here, good
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.
But the former would probably need to be supported when migrating other addons
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.
Ok, I see what you are saying here. Let me take another pass at this.
Looks like tests are failing because of this: |
Codecov Report
@@ Coverage Diff @@
## master #3559 +/- ##
==========================================
- Coverage 37.08% 36.99% -0.09%
==========================================
Files 511 512 +1
Lines 10851 10857 +6
Branches 975 1002 +27
==========================================
- Hits 4024 4017 -7
- Misses 6227 6232 +5
- Partials 600 608 +8
Continue to review full report at Codecov.
|
Ok, did another pass. Let me know what you think @Hypnosphi. I suspect we may have to tweak it as we apply the pattern to the various addons. Right now, you can use the // 1. Pass parameters per-story, ala notes:
// We do this once
addDecorator(withNotes)
// Then, on every story, we do:
add('story', () => <Story />, { notes: 'Note' });
// In this case, wrapper is called with:
wrapper(story, context, { parameters: 'Note' });
// If a story does *not* set the parameters, the wrapper *IS STILL CALLED* but without options:
// It is the responsibility of the wrapper to ignore this story [A]:
wrapper(story, context, {});
// 2. Adding global parameters at "decoration-time", ala backgrounds:
// This is it:
addDecorator(withBackgrounds(['blue', 'red']));
// In this case, wrapper is called (per-story) with the options set [B]:
wrapper(story, context, { options: ['blue', 'red'] });
// 2a. [equivalent, C] Also, you can achieve the above with `addDecorator` + `addParameters`:
addDecorator(withBackgrounds)
addParameters({ backgrounds: ['blue', 'red'] });
// In this case, wrapper is called with parameters set [B]:
wrapper(story, context, { parameters: ['blue', 'red'] });
// 3. Per-story via wrapping directly (notes, deprecated):
.add('story', withNotes('Note')(() => <Story />));
// This will call the wrapper with options set:
// *BUT* will trigger deprecation warnings.
wrapper(story, context, { options: 'Note' }); Notes from above: [B] We could reconcile the two here? (i.e. make it [C] Although 2a. is a bit more verbose it is also more powerful (e.g. you can set background parameters for the whole app, for a specific chapter, and for a specific story, and the parameters mechanism handles reconciliation automatically). |
// .addDecorator(decorator) | ||
// .add('story', () => <Story />, { name: { parameters } }); | ||
|
||
export const makeTransitionalDecorator = ({ name, parameterName, wrapper }) => { |
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.
Should we rename it to something like makePolymorphicDecorator
?
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.
Sure! Or just makeDecorator()
?
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.
just makeDecorator
sounds good
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 like the makeDecorator name too
[A] In viewport addon, parameters are optional, so we should allow addons to handle stories without parameters [B] I'm Ok with both [C] I see. I still think that it wouldn't be too hard to support both versions |
|
||
return (...innerArgs) => { | ||
// Used as [.]addDecorator(decorator(options)) | ||
if (typeof innerArgs.length > 1) { |
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.
typeof?
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.
wow :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.
I need to add a test for this modality, it just doesn't really make sense for notes
. I'll do another PR for backgrounds
and we'll definitely have one.
Ok cool. We could also add an argument to the creator
👍
Oh, yeah, that is the plan. Sorry if I was confusing. I was saying we support both, even though there is some overlap. |
…ransitional-decorator
Not sure what's happening with the UI change to the angular CLI. I'll add a unit test to the |
@Hypnosphi do you want to re-review this, I added an extra API and some tests |
(Or just merge away) |
Released as |
This should make it easy to transitional other addons to a parameter-based style