Skip to content
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

Refactoring of withX wrappers withNotes and withInfo #1538

Merged
merged 4 commits into from
Jul 31, 2017

Conversation

shilman
Copy link
Member

@shilman shilman commented Jul 28, 2017

Issue: #1452

What I did

  • make withX signatures consistent
  • make string-only variant of withNotes/withInfo
  • simplify withInfo code

I have documented the rationale behind this change here:

https://gist.github.com/shilman/792dc25550daa9c2bf37238f4ef7a398#options-types

Will obviously put this into a more permanent place in the docs if we converge on this convention and migrate things over to it.

How to test

yarn && yarn boostrap
cd examples cra-kitchen-sink
yarn storybook

- make signatures consistent
- make string-only variant of withNotes/withInfo
- simplify withInfo code
const channel = addons.getChannel();

const text = typeof textOrOptions === 'string' ? textOrOptions : textOrOptions.text;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extract into a function

@@ -135,8 +135,8 @@ storiesOf('Button', module)
)
.add(
'addons composition',
withInfo('see Notes panel for composition info')(
withNotes({ notes: 'Composition: Info(Notes())' })(context =>
withInfo({ text: 'see Notes panel for composition info' })(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the example we show to users, do you think it makes sense like this?
I think the less verbose syntax:
withInfo('see Notes panel for composition info')
makes more sense tbh.

We should document these options somewhere, but the example should showcase the common use case here, I think.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree

addWithInfo: deprecate(function addWithInfo(storyName, info, storyFn, _options) {
return this.add(storyName, withInfo(info, _options)(storyFn));
addWithInfo: deprecate(function addWithInfo(storyName, text, storyFn, options) {
if (typeof storyFn !== 'function') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use a bit of refactoring,
in some cases the const text is actually the storyFn. I find this confusing.

I'd prefer using abstract names or simply an argument array to do detection, and only assign to a const when we are sure what it is.

const options = {
...defaultOptions,
..._options,
...infoOptions,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also merge in:

if (!options.propTables) {
  options.propTables = null;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how would you merge this in? see the comment above in the code.

@ndelangen
Copy link
Member

This will be backwards compatible? or not?

@tmeasday
Copy link
Member

tmeasday commented Jul 28, 2017

I think both withX functions are new in 3.2 -- It's only incompatible in sense that the old way is deprecated. But @shilman can answer for sure.

export const withInfo = (info, _options) =>
addonCompose((storyFn, context) => addInfo(storyFn, context, info, _options));
export const withInfo = textOrOptions => {
if (typeof textOrOptions === 'string') {
Copy link
Member

@tmeasday tmeasday Jul 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just:

const options = (typeof textOrOptions === 'string') ?
  { text: textOrOptions } :
  textOrOptions;

@codecov
Copy link

codecov bot commented Jul 28, 2017

Codecov Report

Merging #1538 into master will increase coverage by 0.02%.
The diff coverage is 69.23%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1538      +/-   ##
==========================================
+ Coverage   20.52%   20.55%   +0.02%     
==========================================
  Files         241      241              
  Lines        5222     5220       -2     
  Branches      643      657      +14     
==========================================
+ Hits         1072     1073       +1     
+ Misses       3667     3639      -28     
- Partials      483      508      +25
Impacted Files Coverage Δ
addons/notes/src/index.js 0% <0%> (ø) ⬆️
addons/info/src/index.js 90.9% <90%> (-0.4%) ⬇️
lib/ui/src/modules/ui/libs/hierarchy.js 45.45% <0%> (ø) ⬆️
addons/events/src/components/Event.js 0% <0%> (ø) ⬆️
addons/knobs/src/react/WrapStory.js 12% <0%> (ø) ⬆️
app/react/src/client/preview/element_check.js 41.17% <0%> (ø) ⬆️
addons/info/src/components/Props.js 37.2% <0%> (ø) ⬆️
addons/knobs/src/KnobManager.js 35.41% <0%> (ø) ⬆️
lib/ui/src/modules/ui/configs/init_panels.js 25% <0%> (ø) ⬆️
addons/knobs/src/components/types/Color.js 8% <0%> (ø) ⬆️
... and 26 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b02fec0...ee6204e. Read the comment docs.

Copy link
Member

@ndelangen ndelangen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

Copy link
Member

@usulpro usulpro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!


return getStory => context => {
// send the notes to the channel before the story is rendered
channel.emit('storybook/notes/add_notes', notes);
channel.emit('storybook/notes/add_notes', options.text);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we mean that this addon could have other options in the future (or even if we want to keep it as an addon example) why don't pass all 'options' object here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can emit those options once we handle them on the other end.

There may be "preview-side" options, so I don't think it's necessarily the case that we'd want to emit them all.

@@ -34,20 +28,10 @@ const defaultMarksyConf = {
ul: UL,
};

export function addInfo(storyFn, context, info, _options) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to not export this function to users? Maybe our documentation shouldn't encourage people to use it, but there could be some "advanced" use cases when this form is more convenient! Especially it makes sense after #1501

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, we should never export a function to users if we don't need to, because then we are stuck supporting it unless we want to break the API.

@@ -83,12 +67,25 @@ export function addInfo(storyFn, context, info, _options) {
);
}

export const withInfo = (info, _options) =>
addonCompose((storyFn, context) => addInfo(storyFn, context, info, _options));
export const withInfo = textOrOptions => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, it would be nice to provide here such an option as well:

withInfo('text info', { options })

There are two reasons for that:

1.1. We might want to use different text info with the same other options:

.add('Button', withInfo('Default Button', widgetInfoOptions)(() => <Button />))

1.2. We might want to use multiline template string for `text info` and such syntax would be less verbose

  1. It's relevant to the previous behavior of .addWithInfo when we could pass (or not) text info as a separate argument

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@usulpro the reason @tmeasday wanted to keep it to a single argument is for this API:

https://gist.github.com/shilman/792dc25550daa9c2bf37238f4ef7a398#options-types

The API described in the gist is obviously just a proposal, but we think having a single argument makes stuff like this simple to implement. If we have two arguments it gets complicated fast.

Copy link
Member

@tmeasday tmeasday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@shilman shilman merged commit f98a950 into master Jul 31, 2017
@shilman shilman deleted the 1147-addon-info-refactor branch July 31, 2017 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants