storybook icon indicating copy to clipboard operation
storybook copied to clipboard

Svelte: Work with Custom Elements API

Open jweston491 opened this issue 2 years ago • 3 comments

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

jweston491 avatar Jun 28 '22 23:06 jweston491

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

Brandon-Ritchie avatar Feb 07 '23 14:02 Brandon-Ritchie

@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

JacobWeinbren avatar Feb 17 '24 01:02 JacobWeinbren

cc @JReinhold

shilman avatar Feb 18 '24 15:02 shilman