11ty / webc

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

Props with dashes in their names are handled as public attributes #202

Open jsahlen opened 4 months ago

jsahlen commented 4 months ago

I'm working on a project where I utilize the ability to pass on a lot of attributes to my WebC components, but at the same time using props to control rendering and behavior of those components.

I ran into an issue when trying to use @attributes to automatically render passed attributes, where supposedly private props would be included in the final HTML output. I think that props that have dashes in them (and camelCased when using in the component) aren't marked as private correctly by WebC.

Here's a small test case:

page.webc:

<test-component
  mylowercaseattr="foo"
  my-public-attr="bar"
  @mylowercaseprop="baz"
  @my-dashed-prop="qux"
></test-component>

test-component.webc:

<script webc:type="js">
  console.log(webc.attributes);
  console.log(webc.filterPublicAttributes(webc.attributes));
  ('');
</script>
<div @attributes></div>

Result:

// console.log(webc.attributes)
{
  "myDashedProp": "qux",
  "mylowercaseattr": "foo",
  "mylowercaseprop": "baz",
  "myPublicAttr": "bar",
  "uid": "webc-Ht-95",
  "my-dashed-prop___webc_privacy": "private",
  "my-public-attr___webc_privacy": "public",
  "mylowercaseattr___webc_privacy": "public",
  "mylowercaseprop___webc_privacy": "private",
  "uid___webc_privacy": "private",
}

// console.log(webc.filterPublicAttributes(webc.attributes));
{
  "myDashedProp": "qux",
  "mylowercaseattr": "foo",
  "myPublicAttr": "bar",
}
<div mylowercaseattr="foo" myPublicAttr="bar" myDashedProp="qux"></div>

As you can see, myDashedProp is included in the output, because the property marking it as private within the attributes object is named my-dashed-prop___webc_privacy instead of myDashedProp___webc_privacy.

I'm guessing that these lines in attributeSerializer.js is where it goes wrong, but I don't feel I understand the internals of WebC enough to make a PR at this time.

https://github.com/11ty/webc/blob/a2f548c23490929aa8c9cd25159549eba3e869c7/src/attributeSerializer.js#L121-L140