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

[Feature Request]: Truly portable stories: decouple @storybook/web-components and Lit, make storyResult return void #20357

Open
justinfagnani opened this issue Dec 21, 2022 · 0 comments

Comments

@justinfagnani
Copy link
Contributor

Is your feature request related to a problem? Please describe

@storybook/web-components expects that stories can return Lit-specific return types like TemplateResult. This coupling is unfortunate because not every web component developer uses Lit. It also means that CSF renders need to have Lit support built-in. It would be great if instead CSF modules were completely self-contained by bringing their own renderer.

Describe the solution you'd like

It seems like we could have much more portable stories that don't require detecting the return type of story render functions and don't even require Storybook or alternate story renders to have any dependencies on the framework used to render stories by making the storyResult type be void.

This way stories would be entirely self-contained, and instead of returning a lit-html template from render(), render() would just be responsible for rendering to the canvas element.

So the metadata export would go from:

import {html} from 'lit';

const meta: Meta<MyElement> = {
  title: 'Example/MyElement',
  tags: ['docsPage'],
  render: ({count}) => html`<my-element .count=${count}></my-element>`;
};
export default meta;

to:

import {html, render} from 'lit';

const meta: Meta<MyElement> = {
  title: 'Example/MyElement',
  tags: ['docsPage'],
  render: ({count}, {canvasElement}) => {
    render(html`<my-element .count=${count}></my-element>`, canvasElement);
  },
};
export default meta;

Then to render a story module, one only needs to fetch it and call the render function:

const mod = await import(storyUrl);
const render = mod.default.render;

for (const [name, story] of Object.entries(mod)) {
  const canvasElement = document.createElement('div');
  document.body.append(canvasElement);
  render(story.args, {canvasElement})  
}

This solution should actually work with any framework so that even Storybook wouldn't need any specific framework support built-in.

Describe alternatives you've considered

No response

Are you able to assist to bring the feature to reality?

yes, I can

Additional context

I am working on a web components catalog and am considering using CSF as the story format, but don't want to build Lit support directly into the catalog. If we use CSF, we might say that we only support CSF modules that are self-contained in this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant