Storybook: Framework support - Stencil.js

Created on 29 Oct 2018  ·  119Comments  ·  Source: storybookjs/storybook

Describe the solution you'd like
I'd like to see Stencil.js support, as I see Storybook to be very component focused, and Stencil being a very component focus framework - these tools would compliment each other very well.

Are you able to assist bring the feature to reality?
yes, I can...

P1 html web-components feature request todo

Most helpful comment

I spent the last 2 weeks playing with StencilJS and Storybook and did a livestream where I cover my solution. I feel there is a much better way, but I was able to get HMR, and most plugins to work with little issue. Would love any feedback you guys have on how to improve or import the loaders from the distribution stencil bundle.

https://www.youtube.com/watch?v=XwHtPw3izLE

And here is the repo! ^_^
https://github.com/MadnessLabs/enjin-components

All 119 comments

Duplicate to #1870 and #3423. Let's continue a discussion there

New Starter build for Current stencil and SB 5 to be created

@Edd-Strickland want to work on a stencl support version 🎉

I've upgraded the polymer starter with stencil to the latest version of SB need some help in removing polymer and adding in stencil complier now

Hi,

@Edd-Strickland just for information, i have implemented Stencil inside Storybook like you did in your starter, in this project : https://github.com/vogloblinsky/nutrition-web-components

I have used the HTML starter of Storybook.

For now with Storybook & Stencil, i just had to :

  • add a custom header pointing to each root JavaScript file generated by Stencil
  • add static files generated by Stencil in Storybook

The main problem i think is the usage of Webpack by Storybook to handle JavaScript files imported inside a story. The ideal workflow is to only imported the JS file of the Web Component.

Yeah this is what have done previously but with the polymer version however what this means is that by importing as plain static W/C implementations is you need to update each time into your story's which feels limiting.

Hi All, I have created a wrapper that can be installed on a stencil component type project. Hope it helps. https://github.com/nisheed2440/stencil-storybook-wrapper

looks really good I'll test on Monday. Good work :)

Will this be made into an official part of Storybook? I have a desperate need for this!

@o-t-w We're trying, would you be able to help us?

@ndelangen I would be happy to test things and provide feedback/bug reports.

Would this work with LitElement (and web components in general) or just Stencil?

@nisheed2440 your wrapper seems promising, I will test this soon! But it could be great to have a "native" integration documented by Storybook 👌

@nisheed2440 I have been very busy(sorry everyone) but have had a very small window today to test a very vanilla version of this locally and it's really good. works really well.

going to spend some time on this next week trying to incorporate it into an existing project to see how this might work for existing stencil users / projects.

I have tested it this morning and it works pretty well too! GJ it's really easy to setup. I have installed and tested some addons:

import '@storybook/addon-backgrounds/register';
import '@storybook/addon-knobs/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-notes/register';

Everything works fine, just found one issue with addon-knobs https://github.com/storybooks/storybook/issues/5017 But there is a workaround and this should be fixed pretty soon I think.

I spent the last 2 weeks playing with StencilJS and Storybook and did a livestream where I cover my solution. I feel there is a much better way, but I was able to get HMR, and most plugins to work with little issue. Would love any feedback you guys have on how to improve or import the loaders from the distribution stencil bundle.

https://www.youtube.com/watch?v=XwHtPw3izLE

And here is the repo! ^_^
https://github.com/MadnessLabs/enjin-components

@nisheed2440 Hello, i m using an approach very similar to yours and everything is working expect chromatic. were you able to make chromatic work with stencil/storybook?
when i run, it does discover all my stories but all the screenshots are empty. it s probably missing the stencil when trying to render the component screenshot on chromatic server

@nisheed2440 Thank you so much for this really great effort. Hopefully this gives the team here a head start in the right direction. Stencil and Storybooks are ideal for each other.

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Anybody want to pick this up?

My team is using StencilJS + Storybook for our common component library and I'd love to contribute. Maybe a few of us can get this thing back on track...

Seems like there's a lot of interest, e.g. https://twitter.com/dboskovic/status/1120336958008348672

One easy win would be publishing a @storybook/preset-stencil package which packages @popcorn245 's config into a storybook preset. I still need to finish off the docs for that, but I'm using it for the upcoming Storybook Docs release and it's straightforward & how most SB config will work in the future.

I'd be happy to guide anybody who wants to pick that up.

Hey @shilman, stoked so many people are psyched to pickup on this and implement Stencil with Storybook. That thread has some good things that I have found, but there are many more little bugs like having to return a string of the element in order to use knobs.

A much better implementation would piggy-back off of the Stencil compiler and allow for use of JSX like with React components, but that is MHO.

Also, Stencil One is about to drop with some huge changes so it may be good to put peepers on this Changelog to make sure whoever is working on this is aware of what is coming down the pipeline.

https://github.com/ionic-team/stencil/blob/core-refactor/BREAKING_CHANGES.md

This thread was immensely helpful to me, especially @popcorn245’s config. Personally I was using @stencil/state-tunnel, which broke that config. Fortunately I was able to get it to work with some minor ~hacks~ tweaks by running:

npm i -D [email protected]

And adding this to .storybook/webpack.config.js:

const { existsSync, readdirSync } = require('fs');
const { resolve } = require('path');
const CopyPlugin = require('copy-webpack-plugin');

module.exports = ({ config }) => {
  // 1. Transpile @stencil modules with Babel
  const babelLoader = config.module.rules.find(
    ({ use }) => use && use[0].loader === 'babel-loader'
  );
  babelLoader.exclude = [/node_modules\/(?!\@stencil).*/];
  if (babelLoader.use[0].options) {
    babelLoader.use[0].options.plugins = ['@babel/plugin-syntax-dynamic-import'];
  }

  // 2. Load JS & CSS from our components
  config.entry.push(resolve(__dirname, '..', 'dist', 'MYCOMPONENTNAME.js'));
  config.entry.push(resolve(__dirname, '..', 'dist', 'MYCOMPONENTNAME.css'));

  const components = resolve(__dirname, '..', 'dist', 'collection', 'components');
  readdirSync(components).map(file => {
    jsFilePath = resolve(components, file, `${file}.js`);
    try {
      if (existsSync(jsFilePath)) config.entry.push(jsFilePath);
    } catch (err) {
      console.error(err);
    }

    cssFilePath = resolve(components, file, `${file}.css`);
    try {
      if (existsSync(cssFilePath)) config.entry.push(cssFilePath);
    } catch (err) {
      console.error(err);
    }
  });

  // 3. Fix dynamic imports for Storybook
  // IMPORTANT: webpack must be at 4.28 due to a bug. See here: https://github.com/webpack/webpack/issues/8656
  config.plugins.push(
    new CopyPlugin([
      {
        from: resolve(__dirname, '..', 'dist'),
        to: resolve(__dirname, '..', 'node_modules', '@storybook', 'core', 'dist', 'public'),
      },
    ])
  );

  return config;
};

Starting to experiment with this also and (as mentioned somewhere else) using concurrently seems to work just fine for me (for now). I created a quick starter project that includes everything you need to get up and running with both stencil and storybook. Already using the latest stencil release.

Check it out here: stencil-storybook-starter

@fvaldes33 Nice! Starred it. I actually just updated to Stencil One beta and my config looks similar—I basically could use the stock webpack setup entirely.

The only difference for me was using stencil build --watch (prod, not dev) because the build times are so fast and it’s easier to consume the prod version in Stencil (especially with global styles and other imports).

@fvaldes33 how are you able to reference the build/components.js in your preview-head.html like that? I have to supply the full path e.g. http://localhost:3333/build/components.js. But I would like to not have to do that.

(I'm not using your starter, but i'm using the stencil component starter with a fresh storybook/html install)

EDIT:
realized i was starting storybook on port 6006 instead of in the www folder. problem solved!

Looks like lots of us have similar solutions out there (including me https://github.com/jagreehal/stencil-boilerplate), but I'd really like hot/live updates when I edit a Stencil component. Currently I have to manually refresh the browser to reload Storybook.

Is there a bullet list of requirements to complete this? I'd be happy to pitch in if I knew what needed to be built.

What is the current state? Can we contribute? I would love to see this!

I suggested contributing a preset above.

If somebody wanted to put together a preset based on the patterns above, I'd be happ to help on the Storybook side. I'm not familiar with the Stencil side.

I just posted my project out there for anybody who wants it. Here are the features:

  • automatic generation of stories

    • automatic knobs generation for all @Props on your components

    • ability to customize which knobs are used for each prop (though the code does a good job of guessing for strings, numbers, booleans, objects, dates, and colors).

    • ability to define multiple states which are rendered on a single page, each with a title, description, and copyable code snippet (kind of a lightweight chapters implementation)

    • ability to define notes for each component (usually you want the generated readme)

  • live rebuild/reload of stencil components (it's still a little wonky - sometimes you have to refresh the browser)
  • comes with the viewport add-on

Let me know what you think: https://github.com/DesignByOnyx/stencil-storybook-starter

@DesignByOnyx This looks great. Tweet about this and mention @storybookjs and I'll RT from the storybook account. And if you want to write a post about it, I'd be happy to work with you to get it publicized. I think there's a pretty large demand here.

Amazing job @DesignByOnyx ! It seems that this fits perfectly to be a preset :tada:

OK, I've tweeted (I don't twitter much). Furthermore I don't have a blog :/, but I'm glad to put something together if someone wants to publish it.

While the project works, I threw it together in a hurry and did not really make it easy to customize. Some of the code in there is really brittle as I am having to load and merge multiple files in order to render each individual component. I'm hoping for some feedback before I spend any time to make this more consumable.

I'm curious to see what a preset would look like. The biggest thing that would be nice is a JSX preset which is not react. This would enable a little bit easier rendering and template generation on top of the storybook-html variety, and it doesn't have much to do with stencil. Several addons would also need to be updated to make this usable, and I'm not sure I'm the best to coordinate that effort. Either way, let me know what I can do to help.

@DesignByOnyx Any chance you can hop on our Discord? https://discordapp.com/invite/UUt2PJb

I'd love to chat more about getting this work out there on the Storybook blog as well as promoting in the stencil community.

I've been playing with @storybook/html for Stencil and the experience pretty much "just works". You essentially do the following:

  1. Use concurrently to start the Storybook server and stencil build --watch "in parallel"
  2. Start storybook with the -s dist flag, so that your Stencil dist is served as static files.
  3. Configure .storybook/preview-head.html to include a script tag like:

    <script type="module" src="/$PACKAGE_NAME/$PACKAGE_NAME.esm.js"></script>
    <script nomodule="" src="/$PACKAGE_NAME/$PACKAGE_NAME.js"></script>
    

And... that's it! The out-of-the-box html support works for all your web component needs.

What I'd like to see is something like @storybook/stencil that has the same experience (and code) as the html package on the story authoring side, but

  1. Abstracts away running the Stencil build process as part of Storybook, so that configuring concurrently is not required
  2. Adds those script tags for you
  3. Hooks up auto-refresh when your Stencil components re-build

Is there interest in something like that? I'm in the process of selling my company on Stencil and Storybook, and assuming that gains traction, I'll have "work time" to make that story (excuse the pun) really nice around Storybook + Stencil playing together.

The work that @DesignByOnyx has done is really great, but you kind of have to _start_ your Stencil components with that kit and ignore the "normal" documentation for Stencil. If Storybook can provide a package that can be layered on top of the "normal" Stencil starter kit, you can easily add a Storybook config to an existing set of Stencil components.

Thanks for the great summary @alexlafroscia. I think your proposal makes a lot of sense. Does HMR not kick in automatically when Stencil rebuilds? If so, any idea why not?

@igor-dv Is it possible to add to preview-head.html in a preset?

@Hypnosphi Maybe this is an interesting example for your multi-framework efforts. In this case no decorator is needed (apparently) but an entire compiler is needed.

@alexlafroscia how does an example of story look like in your case?

In the company where I work, we've been playing with Storybook HTML and StencilJS packages for a while. I would be happy to contribute!

@alexlafroscia Very great ideas, indeed it would be nice to have a complete support for this compiler. Here are some other ideas:

  • Use StencilJS JSX capabilities (based on Preact at the moment) to write stories in a more maintainable way. Using plain old JS or even template literals might be cumbersome...
  • Have a Smart Knobs addon for Web Components. @DesignByOnyx provided a nice basis for this.

This article covers the on-going roadmap in StencilJS: Fall 2019 Stencil Roadmap. Notably:

Public Compiler APIs

Another area we’re also focusing on is ensuring the compiler can work within a browser and used by other tools. We’ve already been working with a few awesome teams such as Stackblitz, CodeSandbox, and WebComponents.dev. At the lowest levels, the compiler already works without running atop a NodeJS environment, so technically this isn’t a major refactor, but more-so just exposing the correct APIs.

We’re also seeing many areas for improvement to ensure the compiler is easy to consume by other NodeJS tools, including Rollup, Parcel, WebPack, and Bazel. If you’re a maintainer of any tooling, whether an online tool or a NodeJS environment, and you’re looking to implement the Stencil compiler, please feel free to reach out and we’ll be happy to help!

May be useful!

Does HMR not kick in automatically when Stencil rebuilds? If so, any idea why not?

@shilman It doesn't kick in because there's no "real" connection, in the setup that I have, between Storybook and Stencil. It's just a simple <script> tag pointing to the built assets.

how does an example of story look like in your case?

@Hypnosphi They look something like this (a story for the default my-component that Stencil generates in the initial package they create when you npm init stencil

import { document, console } from 'global';
import { storiesOf } from '@storybook/html';

storiesOf('My Component', module)
  .add('without a middle name', () => `
    <my-component
      first="Alex"
      last="LaFroscia"
    ></my-component>
  `)
  .add('with a middle name', () => `
    <my-component
      first="Alex"
      middle="Robert"
      last="LaFroscia"
    ></my-component>
  `);

Use StencilJS JSX capabilities (based on Preact at the moment) to write stories in a more maintainable way. Using plain old JS or even template literals might be cumbersome...

@darondel I totally agree with the concerns around the developer experience of not having JSX in the Story authoring files. I've used that approach in the past, before @storybook/html was available, and used the React experience which was OK.

Part of wanting to keep things as close to the "default" html experience is so that the stories act as documentation on how to actually use them from the HTML perspective -- otherwise they are tied to something like Preact, which at least in my organization, is not being used anywhere else (we are primarily an Ember.js shop).

You mentioned that template tags wouldn't be a great experience, but I think that something like htm could be a nice option. It also keeps the build process nice and simple, because there is no required build step, but might make it easier to interact with something like Knobs.

I was also thinking that trying to integrate with something like the upcoming DocsPage might be interesting! I'll bet that some of the work that's already been done by @DesignByOnyx could be useful here, so that there's a pathway to reading a Stencil component's "metadata" to generate the documentation information automatically. Probably not a "v1" concern, but something that would be really cool to see for a "v1.1"! I really like your idea of making something like that auto-knobs addon too, that would be really handy!

With DocsPages released today with Storybook 5.2, I did some research into whether it would be possible to get the information about props and such out of Stencil and rendered into Storybook. I think it should be possible, but definitely highlights how it would be useful to have an addon or preset tailored to using Storybook with Stencil to house a bunch of the "glue" needed for that.

I'm going to mess around with things a bit more this week and see if I can put something together.

@alexlafroscia would love to standardize how different frameworks communicate this data. Have seen something interesting from Jetbrains (web_types? Cc @elevatebart ) and also @atanasster is also doing work in this area for caching prop types in JSON files for performance. I think we should unify all of this in 6.0

I'm not familiar with the Jetbrains work -- I'll have to check that out! If you have any specific information that would be helpful to review, I'd love if you could send it my way!

In the case of Stencil, what I think the "best bet" will be is to have the Stencil build process output the JSON docs into either a location that's well-known by a Stencil Storybook addon or is configurable. That object contains all of the information on props expected, events emitted, and even the contents of the readme file for each component (without the auto-generated props documentation). I think we could build a really compelling story for populating the Storybook DocsPage with the information from that JSON file.


An example of the output from that file

{
  "timestamp": "2019-09-18T14:30:38",
  "compiler": {
    "name": "@stencil/core",
    "version": "1.3.2",
    "typescriptVersion": "3.5.3"
  },
  "components": [
    {
      "tag": "fluid-banner",
      "encapsulation": "shadow",
      "readme": "# fluid-banner\n\nThis is the contents of the README!\n",
      "docs": "This is the contents of the README!",
      "docsTags": [],
      "usage": {},
      "props": [],
      "methods": [],
      "events": [],
      "styles": [],
      "slots": []
    },
    {
      "tag": "fluid-button",
      "encapsulation": "shadow",
      "readme": "# fluid-button\n\n\n",
      "docs": "",
      "docsTags": [],
      "usage": {},
      "props": [
        {
          "name": "destructive",
          "type": "boolean",
          "mutable": false,
          "attr": "destructive",
          "reflectToAttr": false,
          "docs": "Whether to display in the `destructive` style",
          "docsTags": [],
          "default": "false",
          "optional": false,
          "required": false
        },
        {
          "name": "disabled",
          "type": "boolean",
          "mutable": false,
          "attr": "disabled",
          "reflectToAttr": false,
          "docs": "Whether the button should be treated as `disabled`",
          "docsTags": [],
          "default": "false",
          "optional": false,
          "required": false
        },
        {
          "name": "plain",
          "type": "boolean",
          "mutable": false,
          "attr": "plain",
          "reflectToAttr": false,
          "docs": "Whether to display in the `plain` style",
          "docsTags": [],
          "default": "false",
          "optional": false,
          "required": false
        },
        {
          "name": "primary",
          "type": "boolean",
          "mutable": false,
          "attr": "primary",
          "reflectToAttr": false,
          "docs": "Whether to display in the `primary` style",
          "docsTags": [],
          "default": "false",
          "optional": false,
          "required": false
        },
        {
          "name": "size",
          "type": "\"large\" | \"medium\" | \"small\"",
          "mutable": false,
          "attr": "size",
          "reflectToAttr": true,
          "docs": "The size to display the button",
          "docsTags": [],
          "default": "\"medium\"",
          "optional": false,
          "required": false
        }
      ],
      "methods": [],
      "events": [],
      "styles": [],
      "slots": []
    }
  ]
}

It's kind of a hack (I have it writing the JSON output into dist/output.json and then use fetch to grab the file) but I was able to get the DocsPage rendering for a Storybook component by just overriding the slot props that the DocsPage component can take.

Screen Shot 2019-09-18 at 11 35 40 AM

The Props table isn't perfect, but it's pretty good; the Stencil output provides all the props that the table expects, and then some. Whatever is in the readme.md for the component will be rendered at the top of the file.


If you want to play with it yourself, this is the replacement page component I wrote.

import React, { useContext, useEffect, useState } from "react";
import { DocsPage, DocsContext } from "@storybook/addon-docs/blocks";

export const StorybookDocsPage = () => {
  const docsContext = useContext(DocsContext);
  const [payload, setPayload] = useState(null);

  useEffect(function() {
    fetch("./output.json")
      .then(res => res.json())
      .then(res => setPayload(res));
  });

  if (!payload) {
    return null;
  }

  const component = payload.components.find(component =>
    docsContext.selectedKind.includes(component.tag)
  );

  // Empty because we will use the whole component README
  const titleSlot = () => "";
  const subtitleSlot = () => "";

  const descriptionSlot = () => component.readme;
  const propsSlot = () => ({
    rows: component.props.map(prop => ({
      name: prop.name,
      type: prop.type,
      description: prop.docs,
      required: prop.required,
      defaultValue: prop.default
    }))
  });

  return React.createElement(
    DocsPage,
    { titleSlot, subtitleSlot, descriptionSlot, propsSlot },
    null
  );
};

Update: Going a step further, I defined a whole custom DocsPage (rather than just overriding the slots) to get a second table with documentation of any custom styles.

Screen Shot 2019-09-18 at 12 27 33 PM


Code for custom DocsPage

import { createElement as e, useContext, useEffect, useState } from "react";
import { DocsPage, PropsTable } from "@storybook/components";
import { H2, H3 } from "@storybook/components/html";
import {
  Anchor,
  Description,
  DocsContext,
  Preview,
  Story
} from "@storybook/addon-docs/blocks";

function useStencilComponent() {
  const docsContext = useContext(DocsContext);
  const [payload, setPayload] = useState(null);

  useEffect(function() {
    fetch("./output.json")
      .then(res => res.json())
      .then(res => setPayload(res));
  });

  if (!payload) {
    return undefined;
  }

  return payload.components.find(component =>
    docsContext.selectedKind.includes(component.tag)
  );
}

const DocsStory = ({
  id,
  name,
  expanded = true,
  withToolbar = false,
  parameters
}) =>
  e(
    Anchor,
    { storyId: id },
    expanded && e(H3, null, (parameters && parameters.displayName) || name),
    expanded &&
      parameters &&
      parameters.docs &&
      parameters.docs.storyDescription &&
      e(Description, { markdown: parameters.docs.storyDescription }, null),
    e(Preview, { withToolbar }, e(Story, { id, height: "auto" }, null))
  );

export const CustomDocsPage = () => {
  const docsContext = useContext(DocsContext);
  const component = useStencilComponent();
  if (!component) {
    return null;
  }

  const { selectedKind, storyStore } = docsContext;
  const stories = storyStore.getStoriesForKind(selectedKind);
  const [primary, ...otherStories] = stories;

  const propDocs = component.props.length
    ? [
        e(H2, null, "Props"),
        e(
          PropsTable,
          {
            rows: component.props.map(prop => ({
              name: prop.name,
              type: prop.type,
              description: prop.docs,
              required: prop.required,
              defaultValue: JSON.parse(prop.default)
            }))
          },
          null
        )
      ]
    : [];

  const styleDocs = component.styles.length
    ? [
        e(H2, null, "Styles"),
        e(
          PropsTable,
          {
            rows: component.styles.map(style => ({
              name: style.name,
              description: style.docs
            }))
          },
          null
        )
      ]
    : [];

  const additionalStories = otherStories.length
    ? [
        e(H2, null, "Stories"),
        ...otherStories.map(story =>
          e(
            DocsStory,
            { key: story.id, ...story, expanded: true, withToolbar: false },
            null
          )
        )
      ]
    : [];

  return e(
    DocsPage,
    null,
    e(Description, { markdown: component.readme }, null),
    e(
      DocsStory,
      { key: primary.id, ...primary, expanded: false, withToolbar: true },
      null
    ),
    ...propDocs,
    ...styleDocs,
    ...additionalStories
  );
};

The custom page also fixes the fact that each story defaults to 500px in height, which is waaay too tall 😅

@alexlafroscia This is amazing, tremendous work!

FYI, we're going to generalize the prop table stuff in 5.3. Specifically, frameworks like Vue have the concept of slots & events, so those should be split out into their own tables. Maybe your styles work could use the same mechanism. https://github.com/storybookjs/storybook/issues/8123

The Jetbrains project I was referring to is this one (cc @piotrtomiak): https://github.com/JetBrains/web-types

I haven't looked at it in detail, and don't know that it's right for us. However, if it does meet our use cases and doesn't add too much extra cruft, I'd rather use an existing standard rather than invent our own.

@shilman Thanks for looking at our (JetBrains) effort on bringing some standard for metadata information exchange to web component libraries! Our initial drive was to simply provide good code completion for Vue components in HTML files, but we found out that there is much more to achieve with such a standard, so we designed it having a generic information exchange format in mind (IDEs, tooling, documenation). So far, our focus was on Vue framework, however we've always kept in mind support for Web Components or other frameworks. The web-types standard is pretty fresh, but we've already heard some positive feedback from Vue community and users. I am actively promoting the specification in Vue community, but it's so great to get some interest from other community!

I think there might be some things missing in the web-types JSON schema, which would be specific to your framework and those can be added to the spec. Vue specific items are for instance prefixed with vue. There is also missing whole section for documenting CSS support, which we could work on to include. So, if you feel it's worth giving web-types a chance feel free to file issues or create PRs for missing features.

The side-effect of documenting your components in web-types format will be a good code completion when developers would include your library in their project. We are planning to implement such a generic support based on common web-types features for all frameworks in a very near future. I am pretty sure that with a larger community acceptance of the format other IDEs will follow with support for the format, which would benefit everyone :)

@alexlafroscia fantastic work! The Stencil and Storybook integration (along with https://github.com/storybookjs/storybook/issues/7644) is looking good

Thanks for linking to that issue! I originally went down a similar path (trying to somehow use the existing README files and pull them directly into the DocsPage) but ultimately found it easier just to use the data that Stencil puts in the docs JSON file, since it _does not_ include the table of props and everything (since that data is elsewhere in the JSON file and the structured data is perfect for creating a custom table from).

@alexlafroscia Thanks for sharing your findings. Can I ask how can I debug the CustomDocsPage?

I've tried adding it with addParameters and it doesn't seem to be using the custom but the default instead.


.storybook/config.js setup

import { configure, addParameters } from '@storybook/react';
import { themes } from '@storybook/theming';

import { CustomDocsPage } from './docs.jsx';

addParameters({
  options: { theme: themes.dark },
  docs: { page: CustomDocsPage }
});

configure(require.context('../src', true, /\.(story|stories)\.(mdx)$/), module);


component.story.mdx

### Web Component
<Story name="WC">
    <component-name name="test"></component-name>
</Story>

The WC itself is loaded in the storybook docs page, even without using the CustomDocsPage.
Is there a way I can debug the component? I tried adding some logs, but I can't see any.

Thanks in advance.

I ran into that issue as well -- I had to override the DocsPage component at the "component" level

https://github.com/storybookjs/storybook/blob/next/addons/docs/docs/docspage.md#replacing-docspage

is it at all possible to get @storybook/html to work with jsx? would make writing my stories for stencil components much easier. would get typing, auto-complete, and don't have to use document.createElement or large template strings. tried to trick typescript with a // @jsx at the top using the react package, but that didn't work.

@vidarc what was the error when you did that? Do you have a custom babel config?

not much customizing. a few things added to the webpack. first typescript complains about Cannot find name 'h'. my tsconfig has jsx = react and jsxFactory = h. i can get those warnings to go away using the // @jsx h pragma setting at the top, but then i get a storybook error due to it not returning a DOM node or string.

going to try out: https://github.com/developit/vhtml next

EDIT: works great with jsx. can't figure out how to get it to work with typescript though :/

@vidarc if h stands for hyperscript, it returns a custom object which is neither string nor DOM element

vhtml seems the way to go

FYI, we have an incoming PR for a web-components app: https://github.com/storybookjs/storybook/pull/8400

Can somebody here comment on how that intersects with this issue? @vidarc @DesignByOnyx @Edd-Strickland @alexlafroscia @daKmoR

I haven't test #8400 yet, but prior to testing that I have been able to get "live" Stencil working via:

  1. Run start-storybook -s ./www in one window.
  2. Run stencil build --dev --watch in another.
  3. Update .storybook/config.ts to reload the window on HMR:
const req = require.context('../src/components', true, /.stories.tsx$/);

function loadStories() {
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);

if (module.hot) {
  module.hot.accept(req.id, () => {
    const currentLocationHref = window.location.href;
    window.history.pushState(null, null, currentLocationHref);
    window.location.reload();
  });
}

It's a little kludgy.

The reason why I couldn't investigate alternatives like https://github.com/CleverCloud/clever-components/blob/master/stories/atoms/cc-button.stories.js is that import "./my-component" fails since import { Component } from "@stencil/core" isn't a valid export, and in fact stripped as part of the build process:

https://github.com/ionic-team/stencil/blob/master/src/compiler/transformers/validate-types-transform.ts

Does anyone actually have a stencil and storybook implementation/configuration that works in IE11? I've tried each implementation mentioned in this thread with no luck.
always run into Unhandled promise rejection TypeError: Invalid Scheme with stencil versions 1.2.4 -> 1.7.4.

@shilman I was able to get stencil components up on the web-components app but it seems to me that it's just reading them in the same way everyone is doing with the html one, and HMR doesn't react to updates to the stencil components themselves.

It would really be better if there was a way to get the stencil compiler built into the storybook run sequence like it is for React, Angular, etc.

I'll continue trying out ways of getting Stencil components "live", but the architectural problem I've been running into is that, unless I'm mistaken, _Stencil components require a custom build step to work_ (stencil build --dev --watch), and there's not a run-time equivalent.

I attempted to do import { MyComponent} from "./MyComponent", but that fails since @Component isn't actually exported from @stencil/core. In fact, it's stripped as part of the build step:

https://github.com/ionic-team/stencil/blob/master/src/compiler/transformers/validate-types-transform.ts

Knowing this, my next test is to keep the build step with React bindings (https://github.com/ionic-team/stencil-ds-plugins), but instead replace the HMR logic to use React (instead of HTML) stories.

Hopefully this will let the storybook UX match the React one, leaving Stencil to just the component implementation.

I don't think it's the end of the world to require stencil build to be running in parallel in dev mode:

  • We could instruct the user how to run this with concurrently in their package.json
  • A stencil preset could spawn this process on startup, and then kill it on shutdown if we wanted to hide that from the user

A solution with fewer moving parts is preferable, but let's not let good be the enemy of great here. AFAIK for now everybody's still rolling their own stencil support right now, and there's a nice opportunity to help simplify things for a lot of people here...

Using concurrently is what's working for me currently.

There are incremental steps for sure.

The main thing that got me as a user was "why" stencil didn't work the same
as my react stories, which can't be resolved without stencil-specific
changes.

On Thu, Oct 31, 2019, 5:02 PM Michael Shilman notifications@github.com
wrote:

I don't think it's the end of the world to require stencil build to be
running in parallel in dev mode:

  • We could instruct the user how to run this with concurrently
    https://www.npmjs.com/package/concurrently in their package.json
  • A stencil preset could spawn this process on startup, and then kill
    it on shutdown if we wanted to hide that from the user

A solution with fewer moving parts is preferable, but let's not let good
be the enemy of great here. AFAIK for now everybody's still rolling their
own stencil support right now, and there's a nice opportunity to help
simplify things for a lot of people here...


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/storybookjs/storybook/issues/4600?email_source=notifications&email_token=AAADWTSIACMC4XSZHQWMAFTQRNW2DA5CNFSM4F7Y7BGKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECZTMEQ#issuecomment-548615698,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AAADWTWS5RITQW46NXEJHZLQRNW2DANCNFSM4F7Y7BGA
.

one other approach to this would be to clearly separate the UI (storybook) from the Preview (stencil). With storybook standalone, this should be already possible.
That way you could even prebuild storybook 💪 which would mean way faster bootup times.

And then you sort of would only use stencil build while developing (but still using storybooks UI). Which would mean you will get all the goodies the stencil dev server supports without a need to think about interopt with storybooks webpack setup.

We already investigated this by using es-dev-server to power the preview for web-components. We sort of have a POC... but there are still quite some rough edges.
However, I assume the exact same approach should work for stencil as well.

If someone has any questions or would be interested to investigate this for stencil or help with making a reference project by using es-dev-server then I'm sure @LarsDenBakker is happy to share some more details 🤗

PS: all of this is only possible because of storybook having this awesome iframe setup with channel messages to keep the UI separate from the preview 🤗

Hey all

After some time and a great deal of fiddling around this is my repo for a stencil integrated storybook implementation https://github.com/Edd-Strickland/stencilbook.

Happy to discuss further hopefully most things are obvious from the readme and from looking at the package.json for the scripts.

This is built using the vanilla stencil starter component and the vanilla storybook HTML implementation.

Please look and review...

StencilBook - A Stencil Storybook Starter

This is a starter project for building a standalone Web Component using Stencil and Storybook.

Stencil

Stencil is a compiler for building fast web apps using Web Components.

Stencil combines the best concepts of the most popular frontend frameworks into a compile-time rather than run-time tool. Stencil takes TypeScript, JSX, a tiny virtual DOM layer, efficient one-way data binding, an asynchronous rendering pipeline (similar to React Fiber), and lazy-loading out of the box, and generates 100% standards-based Web Components that run in any browser supporting the Custom Elements v1 spec.

Stencil components are just Web Components, so they work in any major framework or with no framework at all.

Getting Started

Clone the repo

git clone https://github.com/Edd-Strickland/stencilbook.git

Change into the base directory:

cd stencilbook

Install the modules:

npm install

and run a build for the entire repo:

npm run build:all

After this run storybook:

npm run storybook

Other commands for this repo include:

Build stencil:

npm run stencil

Start stencil directly in serve/watch mode; Useful for ameneding stencil components directly:

npm run stencil:start

Run storybook and a stencil build with watch and serve, deleting any previous versions built and will serve locally:

npm run storybook:build:all

Serve storybook Locally:

npm run storybook:serve

Reset modules; Deletes and reinstalls node modules:

npm run reset:modules

To run the unit tests for the components, run:

npm test

Test

To run tests in watch mode:

npm run test.watch

Generate new components

To generate new Stencil components automagically:

npm run generate

@Edd-Strickland This is a great start! If I could suggest that maybe you add a start script for easier bootup, I did "start": "npm-run-all -p stencil:start storybook" and it works pretty well, except there's no hot reloading as storybook doesn't seem to recognize when stencil has built.

...that is unless I'm missing something?

@shilman there seems to be a @storybook/web-components package already in master in alpha, but I don't see Stencil referenced in the README.md: https://github.com/storybookjs/storybook/tree/next/app/web-components

Is this parallel effort? If not, would you happen to know the corresponding issue? Could not find when searching for web-components in issues. Found the app: web-components tag, but has just been added to the release and a bug.

@robaxelsen https://github.com/storybookjs/storybook/pulls?utf8=%E2%9C%93&q=is%3Apr+sort%3Aupdated-desc+is%3Aclosed+label%3A%22app%3A+web-components%22+

I don't understand what is necessary to add proper stencil support above and beyond what is provided by @storybook/web-components. I'm sure somebody on this thread knows though!

@Edd-Strickland This is a great start! If I could suggest that maybe you add a start script for easier bootup, I did "start": "npm-run-all -p stencil:start storybook" and it works pretty well, except there's no hot reloading as storybook doesn't seem to recognize when stencil has built.

...that is unless I'm missing something?

Hmm Apologies been busy and at conferences at the end of last week.

I'm confused as to the issue you're having, could you raise this via the repo issues rather than on this thread for more detail.

However if you do an install, and then run the storybook command it will launch the watch server accordingly. Stencil will auto HMR whenever you change or add or update a component whilst this is running.

@robaxelsen https://github.com/storybookjs/storybook/pulls?utf8=%E2%9C%93&q=is%3Apr+sort%3Aupdated-desc+is%3Aclosed+label%3A%22app%3A+web-components%22+

I don't understand what is necessary to add proper stencil support above and beyond what is provided by @storybook/web-components. I'm sure somebody on this thread knows though!

depends, the web components works with vanilla instances I've not compared the differences between them however stencil outputs web components but runs as a complier for W/C rather than being W/C by default.

So arguably there's need for both. One native JS W/C and one for the stencil compiler if you want to fast prototype Stencil based W/C's in side of storybook as you could with say a react or angular component.

I've not have time to catch up with @daKmoR to discuss if this is duplication or redundant given their work however for the time being we're maintaining this version.

I recently stumbled upon Bulmil due to their work on the Stencil integration with nuxt-stencil and their nuxt examples.

I also figured out that there is a decent Storybook support. Maybe it's worth a look too. I don't know the internals / how they differ from the current state of this thread but it works out of the box within Bulmil once you run storybook.

@storybook/addon-actions does not yet seem to work or I was not yet able to get this working.

Maybe we can get @Gomah in this thread and hear his ideas for collaboration on making stencil support better for storybook?

Recently I stumbled upon Bulmil due to their work on the Stencil integration with nuxt-stencil and their nuxt examples.

I also figured out that there is a decent Storybook support. Maybe it's worth a look too. I don't know the internals / how they differ from the current state of this thread but it works out of the box within Bulmil once you run storybook.

@storybook/addon-actions does not yet seem to work or I was not yet able to get this working.
Certainly within the repo above add on-actions will work, as a standard storybook addon

E2A: the stencil book not the @Gomah variant.

The object with the basic stencil / SB integration above was simply to create a base which allowed storybook to storybook and stencil to stencil and then both of them to integrate together to allow you to have web components made via stencil out put into a storybook frame.

I’ve stuck a spike in with my teams sprint for the next two weeks to see if the W/C version will run as well as this iteration and if we could convert our existing version we’re using to the W/C version.

Ideally it would all work so there would be no fragmentation of the W/C variants however unlike native W/C implementations Stencil isn’t really a framework it’s. compiler. So it might still be worth while having the distinction to allow you to write JSX components which will output as W/C after.

Or it might be really simple.

Will let you know once we’ve completed the spike.

not much customizing. a few things added to the webpack. first typescript complains about Cannot find name 'h'. my tsconfig has jsx = react and jsxFactory = h. i can get those warnings to go away using the // @jsx h pragma setting at the top, but then i get a storybook error due to it not returning a DOM node or string.

going to try out: https://github.com/developit/vhtml next

EDIT: works great with jsx. can't figure out how to get it to work with typescript though :/

Hi @vidarc. Were you able to make this work with storiesOf() syntax? If so, I would be really curious to see how you did it. Do you have a code example or code base to share?

While we have storybook and stencil integrated and working well in our project, the biggest pain point we have is having to resort to creating stories with document.createElement() for components with object props etc. If vhtml can solve this, that would be awesome!

@robaxelsen https://github.com/storybookjs/storybook/pulls?utf8=%E2%9C%93&q=is%3Apr+sort%3Aupdated-desc+is%3Aclosed+label%3A%22app%3A+web-components%22+

I don't understand what is necessary to add proper stencil support above and beyond what is provided by @storybook/web-components. I'm sure somebody on this thread knows though!

You're right, and I agree. I noticed in the README.md the folders included, and saw other web-components frameworks, but not stencil:

By default the following folders are included

src/*.js
packages/*/src/*.js
node_modules/lit-html/*.js
node_modules/lit-element/*.js
node_modules/@open-wc/*.js
node_modules/@polymer/*.js
node_modules/@vaadin/*.js

I therefore thought stencil was not included for a reason. But if this works well without anything added, that's perfectly fine with me.

Btw, can this this issue now be closed, as it's solved by aforementioned web-components preset?

not much customizing. a few things added to the webpack. first typescript complains about Cannot find name 'h'. my tsconfig has jsx = react and jsxFactory = h. i can get those warnings to go away using the // @jsx h pragma setting at the top, but then i get a storybook error due to it not returning a DOM node or string.
going to try out: https://github.com/developit/vhtml next
EDIT: works great with jsx. can't figure out how to get it to work with typescript though :/

Hi @vidarc. Were you able to make this work with storiesOf() syntax? If so, I would be really curious to see how you did it. Do you have a code example or code base to share?

While we have storybook and stencil integrated and working well in our project, the biggest pain point we have is having to resort to creating stories with document.createElement() for components with object props etc. If vhtml can solve this, that would be awesome!

you can make them as CSF stories directly with the latest and swap your stories to that format it works well. Also if you import some data factories to populate the data objects then you can just use these to hydrate your props....

@robaxelsen https://github.com/storybookjs/storybook/pulls?utf8=%E2%9C%93&q=is%3Apr+sort%3Aupdated-desc+is%3Aclosed+label%3A%22app%3A+web-components%22+
I don't understand what is necessary to add proper stencil support above and beyond what is provided by @storybook/web-components. I'm sure somebody on this thread knows though!

You're right, and I agree. I noticed in the README.md the folders included, and saw other web-components frameworks, but not stencil:

By default the following folders are included

src/*.js
packages/*/src/*.js
node_modules/lit-html/*.js
node_modules/lit-element/*.js
node_modules/@open-wc/*.js
node_modules/@polymer/*.js
node_modules/@vaadin/*.js

I therefore thought stencil was not included for a reason. But if this works well without anything added, that's perfectly fine with me.

Btw, can this this issue now be closed, as it's solved by aforementioned web-components preset?

I'm going to test if it works with stencil and will report back then we can close. No point in closing if it doesn't actually work with stencil...

...

Hi @vidarc. Were you able to make this work with storiesOf() syntax? If so, I would be really curious to see how you did it. Do you have a code example or code base to share?
While we have storybook and stencil integrated and working well in our project, the biggest pain point we have is having to resort to creating stories with document.createElement() for components with object props etc. If vhtml can solve this, that would be awesome!

you can make them as CSF stories directly with the latest and swap your stories to that format it works well. Also if you import some data factories to populate the data objects then you can just use these to hydrate your props....

Thanks. Hadn't realized that CSF now is the recommended way to write stories. Have you managed to make the jsx addon to work with vhtml btw, or is that not possible?

...

Hi @vidarc. Were you able to make this work with storiesOf() syntax? If so, I would be really curious to see how you did it. Do you have a code example or code base to share?
While we have storybook and stencil integrated and working well in our project, the biggest pain point we have is having to resort to creating stories with document.createElement() for components with object props etc. If vhtml can solve this, that would be awesome!

you can make them as CSF stories directly with the latest and swap your stories to that format it works well. Also if you import some data factories to populate the data objects then you can just use these to hydrate your props....

Thanks. Hadn't realized that CSF now is the recommended way to write stories. Have you managed to make the jsx addon to work with vhtml btw, or is that not possible?

So the JSX is parsed directly via the stencil compiler into the shadow dom. So as long as you're using the integration of the complier into storybook you write your standard stencil component and then include it in the CSF story and then import in your data factory to populate the prop's.

The vanilla repo I posted with do this out of the box no need for VHTML plugins or any thing else no need even for a wrapper you can write directly as stencil and just output.

you can use the storyOf syntax but then you're locked into the classic document.createElement Pattern.
For example this old storysOf Syntax for our icon

import { storiesOf } from '@storybook/html';
/** 
  * Import readme from component into the story 
  */
import markdown from './readme.md';

storiesOf('1-Atoms/icon', module)
    .addParameters({ viewport: { defaultViewport: 'responsive' } })
    .add('knobs', () => {
        /**
         * Add Knobs to component panel
         * Set within Each knob as the third parameter
         */
        let icon = document.createElement('namespace-icon');
        icon.classList.add('namespace-action-plan');
        icon.size = 'medium';
        return icon;
    }, { notes: { markdown } });

VS

import centered from '@storybook/addon-centered/html';
import markdown from './readme.md';

export default {
  title: 'Atoms|Icon',
  decorators: [centered],
  parameters: {
    notes: { markdown },
    viewport: { defaultViewport: 'responsive' }
  }
};

export const knobs = (): HTMLNamespaceIconElement => {
  const icon: HTMLYooIconElement = document.createElement('namespace-icon');

  icon.classList.add('namespace-action-plan');
  icon.size = 'medium';

  return icon;
};

not much customizing. a few things added to the webpack. first typescript complains about Cannot find name 'h'. my tsconfig has jsx = react and jsxFactory = h. i can get those warnings to go away using the // @jsx h pragma setting at the top, but then i get a storybook error due to it not returning a DOM node or string.
going to try out: https://github.com/developit/vhtml next
EDIT: works great with jsx. can't figure out how to get it to work with typescript though :/

Hi @vidarc. Were you able to make this work with storiesOf() syntax? If so, I would be really curious to see how you did it. Do you have a code example or code base to share?

While we have storybook and stencil integrated and working well in our project, the biggest pain point we have is having to resort to creating stories with document.createElement() for components with object props etc. If vhtml can solve this, that would be awesome!

@robaxelsen
I ended up just using @storybook/react and modifying the webpack config to transform MD files along with MDX files. Then just a small bit of code to create knobs based on the json doc output stencil provides. For the stencil code, we use storybook's copy from their CLI and link those files in the preview-head.html file. Suits my purposes pretty well.

@Edd-Strickland Thanks a lot for the example and explanation. With your last example, I still end up having to pass attributes programmatically though, as props on the element. My hope was that I could, either with vhtml or plain stencil compiler write my stories as JSX.

So instead of:

export const knobs = (): HTMLNamespaceIconElement => {
  const icon: HTMLYooIconElement = document.createElement('namespace-icon');

  icon.classList.add('namespace-action-plan');
  icon.size = 'medium';

  return icon;
};

...I would write:

export const knobs = (): HTMLNamespaceIconElement => {
    return (
        <namespace-icon class="namespace-action-plan" size="medium">
        </namespace-icon>
    );
};

Both for readability, and ease of creating stories. This is not possible, then? If it is possible, could you provide a quick example?

We can also talk in discord chat if that is easier. I am Rob Axelsen#1373.

EDIT: To add to the above, I've also looked at the CSF documentation, and tried with JSX syntax importing h, but throws error "Expecting an HTML snippet or DOM node from the story: "Simple Story" of "Component".":

export const simpleStory = () => <namespace-icon class="namespace-action-plan" size="medium"></name-spaceicon>;

If this is about writing stories that need to set properties for web components then you can take a look at @storybook/web-components. It is using lit-html to declaratively create html with properties.

This should work when running storybook and stencil side by side :)

Except stencil doesn't use lit html. That's a Vue thing...

@shilman there seems to be a @storybook/web-components package already in master in alpha, but I don't see Stencil referenced in the README.md: https://github.com/storybookjs/storybook/tree/next/app/web-components

How do we download and test the web-components package the repo linked here has no clone actions etc?

@Edd-Strickland that's just a directory in the main storybook monorepo

Except stencil doesn't use lit html. That's a Vue thing...

it's a lit thing 🤔

however, that is the beauty of web components - it does not matter what stencil uses under the hood. You can use lit-html or any other way of defining your stories. All you probably need is a way of writing "html" with properties.

For lit-html it would look like this

export myStory = () => {
  const dataArray = [{ name: 'john', age: 21 }, { name: 'maria', age: 28 }];
  return html`
    <my-lit-component .title=${'some title'} power="unlimited">
      <p> some light dom</p>
    </my-lit-component>
    <my-stencil-component super-mode .data=${dataArray}></my-stencil-component>
  `;
}

So if you would go into the DevTools in Chrome in the story you could select the lit-component and you could read the following details

  • property title e.g. console.log($0.title) // some title
  • attribute power e.g. console.log($0.getAttribute('power')) // unlimited

for the stencil component it would be "the same"

  • property data e.g. console.log($0.data) // [{ name: 'john', age: 21 }, { name: 'maria', age: 28 }];
  • attribute super-mode e.g. console.log($0.hasAttribute('super-mode')) // true

lit-html only renders the dom... where/how the dom elements are registered lit-html doesn't know/care about - so which technology is used for each component can be completely different... e.g. you can have component who are lit-element, stencil, vanilla HTMLElement or it could be even a web component wrapper for a full react/vue/angular application... 😱

stencil may be a compiler but once it's compiled to web component it can be used as just dom 🤗

PS: @storybook/web-components uses lit-html

The Stencil team are refactoring the compiler which I think will change the Stencil/Storybook integration.

If anyone is just going to use Stencil and Storybook via React checkout https://github.com/the-road-to-learn-react/use-custom-element which allow you to pass arrays and objects. I'll have a try myself later but this could help some people.

For those interested, I've published a starter for combining Storybook/react and Stencil: https://github.com/bbellmyers/stencil-storybook-starter. Note that with this configuration, changes to components require a hard refresh in the browser, but changes to stories do not.

Seems like storybook is developing storybook for web components. I tried it out with stencil and it is working pretty good.

https://github.com/storybookjs/storybook/tree/next/app/web-components

@sem4phor can you share you configuration ?

I'm getting errors about lit-html on a fresh storybook install for web-components

ERROR in ./node_modules/@storybook/web-components/dist/client/preview/render.js
Module not found: Error: Can't resolve 'lit-html' in '/Users/david/www/stencil-starter/node_modules/@storybook/web-components/dist/client/preview'
 @ ./node_modules/@storybook/web-components/dist/client/preview/render.js 20:15-34
 @ ./node_modules/@storybook/web-components/dist/client/preview/index.js
 @ ./node_modules/@storybook/web-components/dist/client/index.js
 @ ./.storybook/preview.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/preview.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

@dmartinjs you do need to install 'lit-html' yourself it's being used to render components in the default examples.

@Edd-Strickland we added storybook for web-components & in 6.0.0 storybook for polymer will be deprecated / not updated anymore.

Is there anything there needs to be done to make storybook for web-components work for stencil components?

The web components storybook can render stencil web components components, but stencil isn't able to run in the browser as is and needs to be compiled. Therefore it still needs some special handling, unless you compile the stencil components before running storybook.

@LarsDenBakker is it a matter of adding a webpack plugin / loader to get the above to work. ( I imagine it's desired to make stencil component HMR & compile dynamically )

Yes, although stencil itself uses rollup. If the compile step can be used as a separate project, you could make it into a webpack plugin perhaps. I don't know enough about the internals for that.

Stencil doesn't use Webpack. It uses Rollup instead.

It's possible using the repo I set up to have both working accordingly and enable HMR equivalent in Stencil with the -watch call. So that stencil reloads when stencils updated and that Storybook reloads when it's updated.

So no need to build out each time as this will cover it.

Whilst I'v e not had time recently to update the repo with the latest SB or Stencil this process will still work and you can then upgrade the repo with the latest versions.

Thanks

@Edd-Strickland we added storybook for web-components & in 6.0.0 storybook for polymer will be deprecated / not updated anymore.

Is there anything there needs to be done to make storybook for web-components work for stencil components?

yes it still doesn't really account for live reload/ HMR because as detailed above the differences between webpack use and roll up use so at present if you want to use the SB WC version then it requires a full build of stencil in order to render then all the goodness of HMR is lost to stencil.

This version is currently based on the HTML version not the polymer version so this shouldn't impact on the longer term aim to retire that version.

@LarsDenBakker is it a matter of adding a webpack plugin / loader to get the above to work. ( I imagine it's desired to make stencil component HMR & compile dynamically )

I wouldn't advise it, the webpack version of Stencil is a significantly more difficult development path and increases the dependancies footprint without any need, As show in the repo I produced it's perfectly possible to have stencil running in watch most which recompiles live on every change of the WC or the SB instance. It's about configuring it to allow both.

Yes, although stencil itself uses rollup. If the compile step can be used as a separate project, you could make it into a webpack plugin perhaps. I don't know enough about the internals for that.

There is already a stencil WP plugin however this isn't a supported or community approved dependancy.

cc @jthoms1 @adamdbradley

@dmartinjs you do need to install 'lit-html' yourself it's being used to render components in the default examples.

@sem4phor can you share you configuration ?

I'm getting errors about lit-html on a fresh storybook install for web-components

ERROR in ./node_modules/@storybook/web-components/dist/client/preview/render.js
Module not found: Error: Can't resolve 'lit-html' in '/Users/david/www/stencil-starter/node_modules/@storybook/web-components/dist/client/preview'
 @ ./node_modules/@storybook/web-components/dist/client/preview/render.js 20:15-34
 @ ./node_modules/@storybook/web-components/dist/client/preview/index.js
 @ ./node_modules/@storybook/web-components/dist/client/index.js
 @ ./.storybook/preview.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/preview.js ./.storybook/generated-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=true

Any feedback on this? I am having to install this dependency myself. If it is used by @storybook/web-components, then it should be automatically installed as a dependency...?

@LeeBurton not if it's a peer dependency? (Not sure whether it is, if it's not perhaps it should be) cc @daKmoR

@LeeBurton at the time i was testing it lit-html was a peer dependency. It is normal that you have to install peer dependencies by yourself. https://nodejs.org/es/blog/npm/peer-dependencies/

For what it's worth, I got stencil working with this config in .storybook/preview.js

import { defineCustomElements } from "../dist/esm/loader.mjs"
defineCustomElements()

configure(require.context('../src', true, /.*\.stories\.(js|mdx)$/), module);

@idmyn I tried that and while it compiles, any change made to any src file still doesn't get loaded into browser without a manual hard reload.

I got it to work by running Stencil's build locally with watch enabled in one npm run script while running start-storybook in parallel with npm-run-all package.

I configured storybook's webpack config to watch Stencil's dist files using the following in my main.js:

const path = require('path');
const glob = require('glob');

module.exports = {
  webpackFinal: (config) => {
    // watch all revelant files in dist folder
    const distDir = path.resolve(__dirname, '../dist');
    const files = glob.sync(`${distDir}/**/*.entry.js`, { absolute: true, ignore: ['**/*.system.entry.js'] });
    config.entry.push(...files);
    return config;
  },
};

You may have to change the paths/files a bit for your project, but this worked for me.

Just wondering, did @DesignByOnyx or @Edd-Strickland ever look at turning their solutions into a preset for 6? I've used both repo's and - as is usually the way - I like bits of each :-)

I've moved my copy of @Edd-Strickland's to 6.0.0-beta reasonably successfully, although I find it doesn't always rebuild everything when it spots a change (eg readme.md).

Is this publicly available @paulfelton?

It is now, help yourself :-)

I've forked Edd's project. @Edd-Strickland, shall I pop in a PR? It'll need good review, I'm no expert in this.

I've bumped the packages, refactored the config to the new format. I had to add a typings and refer to it in tsconfig to get the story to import the stencil readme, and add a config to translate 'notes' to 'docs'.

Wishlist:

  • Well, I'd like see the integration generate a basic story from the stencil component. Ideally, both mdx and CSF.
  • I'd like to move from Storybook HTML to Storybook Webcomponent flavour, although I'm not sure if there's benefits of doing so. It just feels more natural.
  • I'd like the stencil docs to import more naturally to the new addon-docs, rather than going 'via' notes.
  • All this via a preset :-)

@paulfelton do you need anything from me?

@ndelangen I'm not sure. As you may have gathered, I'm pretty new to both Stencil and Storybook, so just munged together what I can drag up from various issues discussions, google, etc.

I had a go at a starter repo as well, heavily inspired but all the great efforts in this issue (thanks all!).

https://github.com/elwynelwyn/stencilbook-ding

Uses @storybook/web-components, working with the essentials addons (e.g. Controls, Actions). Latest versions of everything at this stage..

Some extra integration between Stencil dev server and the Storybook preview frame (so the Stencil error overlay shows up inline in Storybook - better DX!) (check ./storybook/preview-body.html and ./src/index.html for the deets).

~Mashed the Stencil devserver into start-storybook so you just run a single command and it spins up stencil behind the scenes.~
EDIT: simplified this with concurrently + wait-on - wait for Stencil to spin up, then go ahead with Storybook

Code changes (to Stencil components or Storybook stories) will reload the preview frame (not the entire storybook app). It's not proper HMR but it's reasonably nice to dev with!

Nice. The link doesn't work.

Whoops, repo is public now ^

I've put together a boilerplate repo using stencil v2 and @storybook/web-components v6 here: https://github.com/bjankord/stencil-storybook-boilerplate

There's also a repo at https://github.com/miriamgonp/stencil-web-components-boilerplate built by @miriamgonp from the Storybook/Stencil discord channel. Anyone fancy combining these emerging boilerplates? ;-)

These two repos look great. If they were consolidated into one with would be a good addition. And if anyone would be willing to contribute with a tutorial in Intro to Storybook based on these two repos we would really appreciate. Let me know if anyone is willing to help us with it and i would gladly go over to help out members of the community that use Stencil.

i got a proper hmr solution ;) coming soon!

i got a proper hmr solution ;) coming soon!

here it is!
Stencil 2+ & Storybook 6+ (Old Stencil version should also works ;))
https://github.com/dutscher/stencil-storybook
have fun and cheers

edit: with storybook on gh-pages https://dutscher.github.io/stencil-storybook/index.html

Swapped this ^^ in to our project last week and after stripping out the bits not relevant to us (Bootstrap, scss, chromatic etc) and fixing a couple minor things (e.g. package.json name not working everywhere it's imported due to being in @myorg/my-proj format) it's been working really well.

Have been using it for a day or so now and the HMR is excellent!

@elwynelwyn anything we need to do on storybook's side do you think?

@ndelangen the important things are:

  1. the proxy https://github.com/dutscher/stencil-storybook/blob/master/scripts/proxy.js
  2. the stencil production injection via main.js https://github.com/dutscher/stencil-storybook/blob/master/.storybook/main.js#L30
  3. and simple and minimal npm scripts for dev and prod https://github.com/dutscher/stencil-storybook/blob/master/package.json

cheers

Was this page helpful?
0 / 5 - 0 ratings