storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
83.93k stars 9.21k forks source link

Add Blazor support #13731

Open ntindle opened 3 years ago

ntindle commented 3 years ago

Is your feature request related to a problem? Please describe I am frustrated when I cannot use Storybook for blazor development as it is a tool I am used to using and would like to keep using as we move to blazor. Without a tool like Storybook, my development workflow is more tedious and error prone.

Describe the solution you'd like I would like to be able to build components in blazor and use them in Storybook.

Describe alternatives you've considered Weโ€™ve investigated building our own framework in blazor to allow us to do this level of dev/testing however it was deemed not reasonable when such tools like Storybook exist. I would really prefer to not rebuild Storybook in blazor.

Are you able to assist to bring the feature to reality? yes, I can however I may need help.

Additional context

11380

shilman commented 3 years ago

@ntindle Blazor isn't currently on our dev roadmap. However, it's possible to add framework support yourself, and this is documented here: https://storybook.js.org/docs/react/api/new-frameworks

We also have a Discord community for interactive help if you get stuck: https://discord.gg/storybook

ntindle commented 3 years ago

Yeah, I've taken a look at those docs and unfortunately they are very JS heavy whereas blazor is intended to run in web assembly. I'll join the discord and chat if I have time.

elkaz commented 3 years ago

Has there been any progress made on this?

ntindle commented 3 years ago

Not yet, itโ€™s on our backlog to work on at work (I am not part of storybook) but itโ€™s not been prioritized yet.

elkaz commented 3 years ago

@ntindle do you have a (potentially) workable approach in mind? I assume it will be WASM not server.

ntindle commented 3 years ago

We've not even started analyzing the problem yet. We are working on other tooling support that takes priority first.

Goal on our end is for server side but our components should be able to run on both so we will see how that plays out.

This may involve waiting for more functionality added to blazor upstream. We will have to cross that bridge when we come to it.

If you have any thoughts on how to do this (through either method), I'd love to hear them.

elkaz commented 3 years ago

While I haven't spent a great deal of time thinking on this, my immediate thoughts/questions are:

Can JS interop be used to run an ES defined story, whereby parsing razor syntax through a WASM render function?

Alternatively, can Storybook be modified to run razor stories?

Also, what hook will Storybook use to trigger the WASM runtime?

ntindle commented 3 years ago

Note: there has been a channel created on the community discord called #blazor to help work on this

elkaz commented 3 years ago

Not able to access discord but thought this might be worth sharing: https://github.com/conficient/BlazorTemplater

MrDach commented 3 years ago

Has anyone managed to build a working solution with Storybook and Blazor yet?

dgcaron commented 2 years ago

yes, i have been able to this with the web-components support. I can't see it is production ready but I was able to see my components in storybook with .net 6. with the new version you can publish your blazor components as web components (experimental). you can then consume these in storybook and with the help of a proxy you can get them loaded. I'll create a gist of what I did and share it later today

dgcaron commented 2 years ago

in your blazor (WASM) app startup you call

builder.RootComponents.RegisterAsCustomElement<Counter>("my-blazor-counter");

this will expose a web component from your blazor app to be used elsewhere. in order to work with the component you need to add some files to the .storybook folder:

middleware.js

const {createProxyMiddleware }  = require('http-proxy-middleware')

module.exports = function expressMiddleware (router) {
    router.use('/_framework', createProxyMiddleware({
        target: 'https://localhost:5001',
        changeOrigin: true,
        secure: false 
    }));

    router.use('/_content', createProxyMiddleware({
        target: 'https://localhost:5001',
        changeOrigin: true,
        secure: false 
    }));

    router.use('/blazor', createProxyMiddleware({
        target: 'https://localhost:5001',
        changeOrigin: true,
        secure: false,
        pathRewrite: {
            '^/blazor': '/', // remove base path
      },
  }))
}

preview-head.html

<link href="blazor/BlazorAppProvidingCustomElements.styles.css" rel="stylesheet" />

<script src="_content/Microsoft.AspNetCore.Components.CustomElements/BlazorCustomElements.js"></script>
<script src="_framework/blazor.webassembly.js"></script>

in storybook the storie looks like this

export default {
  title: 'Components/Counter',
};

const Template = ({ title, increment }) => <my-blazor-counter title={title} increment-amount={increment}></my-blazor-counter>;

export const Primary = Template.bind({});

Primary.args = {
  title: 'in storybook',
  increment: 1
};
ilyvion commented 2 years ago

I'm using Blazor Server, and thought I'd document the changes I had to make to the above in case anyone else comes by who wants the same kind of setup. Here's what I had to do in addition to what was outlined above for Blazor WASM:

To get access to RegisterAsCustomElement I had to add the Microsoft.AspNetCore.Components.CustomElements package to my project. (dotnet add package Microsoft.AspNetCore.Components.CustomElements)

In preview-header.html I had to change _framework/blazor.webassembly.js to _framework/blazor.server.js.

In middleware.js I had to add this additional proxy configuration:

router.use(
    "/_blazor",
    createProxyMiddleware({
        target: "https://localhost:7127",
        changeOrigin: true,
        secure: false,
        ws: true,
    })
);

Also, just in case: if you're using http locally, you'll have to comment out app.UseHttpsRedirection(); in Program.cs or you'll run into automatic redirects.

I also had to add a dependency on lit-html to my package.json and write my template like this:

import { html } from "lit-html";

// ... other stuff ...

const Template = ({ bar }) =>
    html`<my-component foo="${bar}"></my-component>`;

otherwise I'd get errors like

Support for the experimental syntax 'jsx' isn't currently enabled

when attempting to load the story.

OskarKlintrot commented 2 years ago

In preview-header.html I had to change _framework/blazor.webassembly.js to _framework/blazor.server.js.

Sounds like you use Blazor server and not Blazor WASM?

ilyvion commented 2 years ago

Sounds like you use Blazor server and not Blazor WASM?

True. I suppose I didn't notice that discrepancy until you pointed it out. But I will edit my original comment to reflect this new information.

ilyvion commented 2 years ago

I also want to say that trying to use web component versions of Blazor components has been a lackluster experience so far. I might be missing some information, although the information on what you can do with BlazorCustomElements is lacking at best, and there's no obvious place to ask questions or report issues for it.

Some things I've been unable to do include being able to nest components (i.e. if you have a component that takes a

[Parameter]
public RenderFragment? ChildContent { get; set; }

and then try to do

<outer-component>
    <inner-component />
</outer-component>

using the web component versions, it doesn't work. Another one is events; I can't figure out how to go from

[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }

to an actual printout of an action in Storybook's actions addon. If anyone's had better success with this than I have, I'd be happy to hear some solutions to these problems I'm having.

dgcaron commented 2 years ago

The webcomponent library is far from perfect indeed. I haven't been able to add complex parameters and or child content either. However, that doesn't seem related to storybook but more to the experimental stage of the web component library.

adamk22 commented 2 years ago

I've recently joined a team that uses blazor and would like to have a storybook-like implementation. I've tried the workaround by @alexschrod but unfortunately it's just too tricky to get it working right. I'm unfamiliar with the dotnet ecospace and was wondering if people here are working with other alternatives? Because I don't think Blazor support is high up in storybook's priorities tbh.

ilyvion commented 2 years ago

It's not good news, @adamk22 but I thought I should say that for the time being, I've given up on trying to integrate blazor with storybook since the support isn't really there. I haven't found a suitable replacement either, so I'm just doing without for now. Maybe one day we'll have more native support. ๐Ÿ˜Š

shilman commented 2 years ago

i know next to nothing about blazor, but i'll share a couple pieces of info in case anybody finds it useful:

  1. we have no plans to support blazor in storybook, but we're happy to help anybody who wants to add support

  2. we're revamping framework support in SB7.0 so it should become a lot easier to roll your own. i'll try to remember to share here once that's documented & there are good examples available (ETA this fall)

  3. i heard mention about server support. storybook has a server-rendered framework implementation that's being used by github primer design system for rails view components and also laravel blade.

dgcaron commented 2 years ago

@shilman thanks for your feedback, and I get the point of view. One thing to make sure I get it completely. Are there no plans to support WebAssembly in it's entirety or just not specifically Blazor.

shilman commented 2 years ago

@dgcaron What would supporting WebAssembly entail? That sounds like something we'd want to do, but I'd need to learn more.

dgcaron commented 2 years ago

i am not entirely sure how low-level the integration should be for storybook but I can imagine there is a need for a generic way to load webassembly code (and possibly it's dependencies):

https://developer.mozilla.org/en-US/docs/WebAssembly/Loading_and_running

after loading the webassembly code, it could be displayed as webcomponent(s) and possibly leveraging the current implementation for webcomponents in storybook? like this attempt:

https://medium.com/coinmonks/develop-w3c-web-components-with-webassembly-d65938284255

CSBatchelor commented 2 years ago

+1 to this as I'd also like to use Storybook with Blazor.

While @dgcaron's trick is a step forward I don't think it warrants the "has workaround" tag as it doesn't support some of the fundamental Blazor Component features such as event callbacks and child components as others have mentioned.

DefinitelyADev commented 1 year ago

+1

luckyluggi commented 1 year ago

Any news on this since custom elements are now officially supported in .net7?

jsakamoto commented 1 year ago

[FYI] Today, I released the "Blazing Story" preview 1, the clone of "Storybook" for Blazor! ๐ŸŽ‰ https://github.com/jsakamoto/BlazingStory/ movie-001 It is the first preview, will not be stable, and lacks many features, but an important milestone for me.

OskarKlintrot commented 1 year ago

@jsakamoto you should have named it "Blazing Saddles" ๐Ÿ˜‰

Bustillox commented 1 year ago

hello everyone! - I was just wondering if you guys are planning to release a Blazor version anytime soon or if "Blazing Story" above will be an official blazor version of storybook. Cheers!

cc: @ntindle, @shilman

shilman commented 1 year ago

@jsakamoto Amazing job with Blazing Story!!! ๐ŸŽ‰ ๐Ÿ˜

@Bustillox According to Blazing Story's README:

The "Blazing Story" is just my hobby work and a personal technical exhibition, so it is not an officially derived product from the "Storybook".

Since it's not compatible with Storybook's ecosystem of addons & APIs I would say that it's not on official Blazor version of Storybook. However, since there is no official version and it's not currently on our roadmap, I'd encourage anybody who needs to do isolated component development in Blazor to give it a try!

That said, if anybody is interested in implementing an official Blazor version for Storybook, we'd be happy to provide guidance and support. Feel free to reach out here or in the Storybook Discord https://discord.gg/storybook