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

Use the new Framework API? #8

Open
jonniebigodes opened this issue Jan 10, 2023 · 6 comments
Open

Use the new Framework API? #8

jonniebigodes opened this issue Jan 10, 2023 · 6 comments

Comments

@jonniebigodes
Copy link

Hey @prantlf !
I'm one of the Storybook maintainers. I focus primarily on documentation and community outreach. I'm opening up this issue and letting you know that the Storybook API for building addons is currently being updated to factor in the changes introduced by the upcoming 7.0 release. If you're interested in making the required changes to help the community from benefiting from using your addon, we've prepared an abridged guide for the required changes here, and if you have any questions or issues, please reach out to us in the #prerelease channel in our Discord Server.

Hope you have a great day!

Stay safe

@prantlf
Copy link
Owner

prantlf commented May 7, 2023

Thank you, @jonniebigodes, for your attention to my humble plugin! I'm sorry for the delay with the update.

I haven't been able to upgrade all my projects yet, because some parts of the ecosystem aren't ready yet (Stencil). But so far, I'm ready to adapt this addon.

Your documentation about the change of the storySort is very helpful. And also alarming :-) Because of this:

NOTE: v7-style sorting is statically analyzed by Storybook, which puts a variety of constraints versus v6:

  • Sorting must be specified in the user's .storybook/preview.js. It cannot be specified by an addon or preset.
  • The preview.js export should not be generated by a function.
  • storySort must be a self-contained function that does not reference external variables.

It appears, that you don't execute preview.js as a JavaScript module any more. It appears, that you parse it to extract the exported object only. This is a problem for external implementations of storySort, which cannot be self-contained, because thy are implemented in a shared NPM module, which needs to be imported. (The configuration can be usually inlined, because it's not usually used beyond one projects.)

I'm trying a workaround "smuggling" data to storySort via globalThis. I'm going to write more about it later tonight.

@prantlf
Copy link
Owner

prantlf commented May 7, 2023

The idea how to implement the custom sorting with Storybook 7:

  1. Move the sort function and configuration to main.js:
// the shared sort implementation
import sortStories from 'storybook-multilevel-sort'

// the sort configuration
const storyOrder = { ... }

// make both identifiers above usable from storySort
globalThis['storybook-multilevel-sort'] = { sortStories, storyOrder }
  1. Replace the storySort in preview.js with this code:
export const parameters = {
  options: {
    storySort: (story1, story2) => {
      const { sortStories, storyOrder } = globalThis['storybook-multilevel-sort']
      return sortStories(storyOrder, story1, story2)
    }
  }
}

It feels rather ugly, doesn't it? :-) I made the final interface a little nicer, which is described in the migration instructions. It can be tested with the package [email protected].

Alternatively, I could pass the configuration to globalThis using an otherwise empty add-on, for example in main.js:

export default {
  addons: [
    {
      name: 'storybook-multilevel-sort',
      options: {
        storyOrder: { ... }
      }
    }
  ]
}

If storySort had access to anything from the context of the Storybook execution, like add-ons, I wouldn't need the hack with globalThis. For example, an extra parameter could be passed to storySort, which could be filled by some API:

storySort(story1, story2, context)

What do you think, @jonniebigodes?

@prantlf
Copy link
Owner

prantlf commented May 13, 2023

I wasn't able to write an addon encapsulating the custom sort. Consuming the sort configuration and exposing the storySort implementation works, with a nice interface in ./storybook/main.js:

const storyOrder = { ... }

export default {
  addons: [
    { name: 'storybook-multilevel-sort', options: { storyOrder } }
  ]
}

However, I couldn't figure out how to supply the storySort parameter as a default from my preview.js. I'd have to copy & paste the same following code to each Storybook projects's ./storybook/preview.js:

export default {
  parameters: { 
    options: {
      storySort: (story1, story2) =>
        globalThis['storybook-multilevel-sort:storySort'](story1, story2)
    }
  }
}

If I can't figure it out, I'll abandon the idea of an addon interface (#11) and merge the pure functional interface to be called in ./storybook/main.js and ./storybook/preview.js explicitly (#10).

@prantlf
Copy link
Owner

prantlf commented May 14, 2023

I merged the #10 and released 2.0.0 to allow upgrading to Storybook 7 now. The interface remains functional as it was in versions 1.x. The new limitation of Storybook 7 needs modifying both ./storybook/main.js and ./storybook/preview.js, as mentioned in a comment above and documented in the article about configuration migration.

I'd still like to simplify the interface by converting this package to a Storybook addon. I've kept the half-way conversion in #11 to be able to explore the possibilities in the future.

@jrencz
Copy link

jrencz commented Jun 16, 2023

Hi, @prantlf can you plz share some update on this one?

@prantlf
Copy link
Owner

prantlf commented Jun 16, 2023

Yes, I can, @jrencz. My previous comment was probably not clear. So:

  • Storybook 7 is supported by the latest versions (2.x) of this addon.
  • Older Storybook versions remain supported by the versions 1.x of this addon.

I'm not happy with the Storybook 7 API, which makes writing addons like this more difficult than the Storybook 6 API, and users of this addon need to edit two configuration files instead of one. But it doesn't mean that the currently available solution doesn't work.

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

No branches or pull requests

3 participants