storybookjs / storybook

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

Svelte: Work with Custom Elements API #18593

Open jweston491 opened 2 years ago

jweston491 commented 2 years ago

Is your feature request related to a problem? Please describe Related to https://github.com/storybookjs/storybook/issues/14381

Setting customElement: true in "svelteOptions" (like below) breaks the built-in <HOC>, <PreviewRender>, and <SlotDecorator> components since they are not configured to work with as Custom Elements. (See "Illegal Constructor" in screenshot)

Screen Shot 2022-06-28 at 4 31 40 PM

Example config (not working):

...
"svelteOptions": {
    "preprocess": require("svelte-preprocess")(),
    "loader": {
      compilerOptions: {
        customElement: true
      }
    }
  },
...

Describe the solution you'd like Setting customElement: true in main.js should result in Storybook being able to render custom web components.

Describe alternatives you've considered I've tried the following custom webpack config, but it's not working (see error below). Perhaps someone can point me in the right direction

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx|svelte)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions"
  ],
  "framework": "@storybook/svelte",
  "svelteOptions": {
    "preprocess": require("svelte-preprocess")()
    }
  },
  webpackFinal: async (config, { configType }) => {

    // Custom loader for .svelte files at project root
    config.module.rules.push({
      test: /(src|stories).*\.svelte$/,
      loader: require.resolve('svelte-loader'),
      options: {
        preprocess: require("svelte-preprocess")(),
        loader: {
          compilerOptions: { customElement: true }
        }
      }
    });

    // Return the altered config
    return config;
  },
}

Which results in the following error:

ERROR in ./src/components/forms/MultiSelect.svelte
Module build failed (from ./node_modules/svelte-loader/index.js):
Error: ParseError: Expected } (32:1241)
30: 
31: function add_css(target) {
32:   append_styles(target, "svelte-1t7dfnx", "input.svelte-1t7dfnx.svelte-1t7dfnx{cursor:pointer}label.svelte-1t7dfnx.svelte-1t7dfnx{display:block;cursor:pointer}label[for=\"dropdown-content\"].svelte-1t7dfnx.svelte-1t7dfnx{margin-bottom:.5rem}span.svelte-1t7dfnx.svelte-1t7dfnx{max-width:100%;cursor:pointer;width:100%;box-sizing:border-box}.dropdown.svelte-1t7dfnx.svelte-1t7dfnx{font-size:var(--font-size, .75rem);position:relative;display:inline-block;min-width:max-content;box-sizing:border-box;width:100%}.dropdown.svelte-1t7dfnx>span.svelte-1t7dfnx{display:block;padding:10px;border:2px solid black}.dropdown-content.svelte-1t7dfnx.svelte-1t7dfnx{white-space:nowrap;box-sizing:border-box;color:#414142;line-height:1.5;top:100%;left:0;z-index:1000;float:left;font-size:14px;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:4px;box-shadow:0 6px 12px rgba(0,0,0,.175);position:absolute;list-style-type:none;font-family:inherit;text-align:left;margin:0;padding:1em;display:none;width:fit-content}.dropdown.svelte-1t7dfnx:hover .dropdown-content.svelte-1t7dfnx{display:block}label.required.svelte-1t7dfnx.svelte-1t7dfnx::before{content:'* ';color:var( --alert-color, #bf0000 )}");
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ^
33: }
34: 
    at /Users/my.user/Development/abc-components-svelte/node_modules/svelte-loader/index.js:89:12
 @ ./stories/component.stories.ts 102:0-69 153:15-26 165:15-26
 @ ./stories sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx|svelte))$
 @ ./generated-stories-entry.js
 @ multi ./node_modules/@storybook/core-client/dist/esm/globals/polyfills.js ./node_modules/@storybook/core-client/dist/esm/globals/globals.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./storybook-init-framework-entry.js ./node_modules/@storybook/svelte/dist/esm/client/preview/config-generated-config-entry.js ./node_modules/@storybook/svelte/dist/esm/client/docs/config-generated-config-entry.js ./node_modules/@storybook/addon-links/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-docs/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-actions/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-backgrounds/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-measure/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-outline/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-interactions/preview.js-generated-config-entry.js ./.storybook/preview.js-generated-config-entry.js ./generated-stories-entry.js

ERROR in ./stories/decorators/MaxWidthDecorator.svelte
Module build failed (from ./node_modules/svelte-loader/index.js):
Error: ParseError: The keyword 'let' is reserved (18:1)
16: 
17: function create_fragment(ctx) {
18:   let div;
      ^
19:   let current;
20:   const default_slot_template = /*#slots*/ ctx[1].default;
    at /Users/my.user/Development/abc-components-svelte/node_modules/svelte-loader/index.js:89:12
 @ ./stories/component.stories.ts 103:0-70 158:13-30
 @ ./stories sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx|svelte))$
 @ ./generated-stories-entry.js
 @ multi ./node_modules/@storybook/core-client/dist/esm/globals/polyfills.js ./node_modules/@storybook/core-client/dist/esm/globals/globals.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./storybook-init-framework-entry.js ./node_modules/@storybook/svelte/dist/esm/client/preview/config-generated-config-entry.js ./node_modules/@storybook/svelte/dist/esm/client/docs/config-generated-config-entry.js ./node_modules/@storybook/addon-links/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-docs/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-actions/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-backgrounds/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-measure/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-outline/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-interactions/preview.js-generated-config-entry.js ./.storybook/preview.js-generated-config-entry.js ./generated-stories-entry.js

ERROR in ./src/components/forms/Input.svelte
Module build failed (from ./node_modules/svelte-loader/index.js):
Error: ParseError: The keyword 'let' is reserved (29:1)
27: 
28: function create_else_block(ctx) {
29:   let input;
      ^
30:   let mounted;
31:   let dispose;
    at /Users/my.user/Development/abc-components-svelte/node_modules/svelte-loader/index.js:89:12
 @ ./stories/component.stories.ts 101:0-57 120:15-20 130:15-20 141:15-20
 @ ./stories sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx|svelte))$
 @ ./generated-stories-entry.js
 @ multi ./node_modules/@storybook/core-client/dist/esm/globals/polyfills.js ./node_modules/@storybook/core-client/dist/esm/globals/globals.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./storybook-init-framework-entry.js ./node_modules/@storybook/svelte/dist/esm/client/preview/config-generated-config-entry.js ./node_modules/@storybook/svelte/dist/esm/client/docs/config-generated-config-entry.js ./node_modules/@storybook/addon-links/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-docs/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-actions/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-backgrounds/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-measure/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-outline/preview.js-generated-config-entry.js ./node_modules/@storybook/addon-interactions/preview.js-generated-config-entry.js ./.storybook/preview.js-generated-config-entry.js ./generated-stories-entry.js

Are you able to assist to bring the feature to reality? Probably not, which is why I opened this ticket, but willing to try to learn

Brandon-Ritchie commented 1 year ago

Did you end up finding any workarounds to this? I am running into similar issues.

JacobWeinbren commented 4 months ago

@shilman would you be able to provide any advice on this? I am experiencing the same problem. Is some setup using webpack needed?

<svelte:options customElement={{ tag: "primer-icon" }} />

This is my source - https://github.com/JacobWeinbren/Primer-Components

shilman commented 4 months ago

cc @JReinhold