11ty / webc

Single File Web Components
MIT License
1.32k stars 38 forks source link

Get a public attributes object for programatic use (`webc.filterPublicAttributes`) #132

Closed solution-loisir closed 1 year ago

solution-loisir commented 1 year ago

I'm building an image-process component which use the eleventy-img plugin and it would be useful to have access to an object of public attributes only to feed to the generateHTML method. When using webc.attributes directly I get all the attributes including webc:*, @attributes, :@my-private-attribute, etc. I came with my own (maybe naive) workaround which is filtering webc.attributes. It works, but it is very brittle.

const attributes = () => Object.keys(webc.attributes)
    .filter((key) => !key.startsWith("webc:"))
    .filter((key) => key !== "src")
    .filter((key) => key !== "uid")
    .filter((key) => key !== "options")
    .filter((key) => key !== "attributes")
    .reduce((newObject, key) => {
      newObject[key] = _attributes[key];
      return newObject;
    }, {});

Something like webc.attributes.public or getPublic(webc.attributes) would do. Here's the full component for context.

<script webc:type="js" webc:root="override">
  const Image = require("@11ty/eleventy-img");
  const _attributes = webc.attributes;
  const src = _attributes.src;
  const options = _attributes.options || {};
  const attributes = () => Object.keys(_attributes)
    .filter((key) => !key.startsWith("webc:"))
    .filter((key) => key !== "src")
    .filter((key) => key !== "uid")
    .filter((key) => key !== "options")
    .filter((key) => key !== "attributes")
    .reduce((newObject, key) => {
      newObject[key] = _attributes[key];
      return newObject;
    }, {});

  Image(src, options)
    .then((imgMeta) => Image.generateHTML(imgMeta, attributes(), {
      whitespaceMode: "inline"
    }))
    .catch((error) => console.error(error));
</script>

So far, I'm having a lot of fun writing WebC! Thank you so much!

zachleat commented 1 year ago

webc.renderAttributes does this for you, but it does give a string back—and it looks like generateHTML does not accept a string. Good point!

solution-loisir commented 1 year ago

I guess that's a bit of an edge case. Thank you for considering! 😊

zachleat commented 1 year ago

webc.filterPublicAttributes(webc.attributes) will ship with WebC 0.10.1!

solution-loisir commented 1 year ago

Thank you!

zachleat commented 1 year ago

Docs building to https://www.11ty.dev/docs/languages/webc/#extra-data-for-javascript-render-functions