11ty / webc

Single File Web Components
MIT License
1.3k stars 36 forks source link

Components don’t have access to props data within `webc:setup` script tags #196

Open patrulea opened 8 months ago

patrulea commented 8 months ago

I can’t figure out why I can’t reference component props when trying to set up data with <script webc:setup>, as it just crashes the build.

[11ty] Original error stack trace: TypeError: Cannot read properties of undefined (reading 'ext')

index.webc

<some-component @ext="mp4"><some-component>

some-component.webc

<script webc:setup>

  let pictureFormats = ["apng", "avif", "gif", "jpg", "jpeg", "png", "svg", "webp"];
  let videoFormats = ["mp4", "webm"];
  let ext = this.ext; // data.ext, $data.ext, ext wouldn’t work either

  let type;
  if (pictureFormats.includes(ext)) {
    type = "picture";
  } else if (videoFormats.includes(ext)) {
    type = "video";
  }

</script>

How should I approach this?

estherbrunner commented 4 months ago

I had the same problem. I was expecting that the webc:setup should have access to attributes and properties of the component as well as in webc:root.

Anyhow, I figured out, I can pass the variable from evaluated attributes like @text="value(color)" and work around like this:

<script webc:setup>
    // const [l, c, h] = color.split(' '); // does not work!
    const value = (color) => {
        const [l, c, h] = color.split(' ');
        return `${Math.round(l * 1000) / 10}%, ${c}, ${h}°`
    };
    const css = (color) => `oklch(${color})`;
    const lightness = (color) => `${Math.round(color.split(' ')[0] * 1000) / 10}%`;
    const chroma = (color) => `${color.split(' ')[1]}`;
    const hue = (color) => `${color.split(' ')[2]}°`;
</script>
alexnozer commented 4 months ago

I have the same issue. I created a component and wanted to do some props processing in webc:setup before using it in a template. But it didn't work. I had to create a custom JavaScript function using eleventyConfig.addJavaScriptFunction API and call it inside the template.

patrulea commented 4 months ago

@alexnozer can you provide some example code?

tobystokes commented 2 months ago

Oof, this got me too.

@patrulea in your example:

some-component.webc

You do have access to 'ext' in html, not setup: <span @text="ext"></span>
So pass it as an argument to a function: <span @text="type(ext)"></span>

<script webc:setup>

  let pictureFormats = ["apng", "avif", "gif", "jpg", "jpeg", "png", "svg", "webp"];
  let videoFormats = ["mp4", "webm"];

  const type = (ext) => {
    if (pictureFormats.includes(ext)) {
      type = "picture";
    } else if (videoFormats.includes(ext)) {
      type = "video";
    }
    return type;
  }

</script>