Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot pass data into web component properties that use camel casing #9325

Closed
OvidijusParsiunas opened this issue Oct 17, 2023 · 8 comments · Fixed by #9328
Closed

Cannot pass data into web component properties that use camel casing #9325

OvidijusParsiunas opened this issue Oct 17, 2023 · 8 comments · Fixed by #9328

Comments

@OvidijusParsiunas
Copy link

Describe the bug

Scope:
Web Components

Description:
Cannot pass data into web components' properties that use camel casing for their names e.g. camelCaseProperty.
It appears that Svelte searches for the lower cased property name versions instead e.g. camelcaseproperty.

This is also reflected in the unit tests of the custom elements everywhere website.

Reproduction

Live CodeSandbox

Logs

No response

System Info

System:
    OS: macOS 13.5.2
    CPU: (8) arm64 Apple M1 Pro
    Memory: 760.98 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 16.14.0 - /usr/local/bin/node
    npm: 8.3.1 - /usr/local/bin/npm
  Browsers:
    Chrome: 118.0.5993.70
    Edge: 117.0.2045.47
    Safari: 16.6
  npmPackages:
    svelte: ^4.2.1 => 4.2.1

Severity

annoyance

@dummdidumm
Copy link
Member

The Dom spec specifies that attributes are case insensitive / cannot have uppercase characters, therefore Svelte works that way to be in line with the spec - so this works as intended.
You may adjust the attribute name to have dashes if you prefer that instead using the custom element options: https://stackoverflow.com/questions/44347580/can-custom-elements-attributes-be-camelcased

@dummdidumm dummdidumm closed this as not planned Won't fix, can't repro, duplicate, stale Oct 17, 2023
@dummdidumm
Copy link
Member

Maybe I closed too soon - properties are case sensitive, so in that case it doesn't make sense to lowercase it.

@brunnerh
Copy link
Member

Another recent issue related to casing of attributes and properties:

@dummdidumm
Copy link
Member

dummdidumm commented Oct 18, 2023

I looked into how Lit handles this:

  • if both the passing and receiving component is compiled with Lit, it "just works"
  • if the receiving component is not from Lit, you need to prepend a . to signal to Lit that this should be set as a property, not as an attribute, otherwise it doesn't work

So we either also introduce some kind of "I want this set as a property"-option, or enhance our logic for custom elements so that their attributes are not lowercased. For backwards compatibility the algorithm would be

  • check if camelCase exists as a prop, if yes set (this wasn't done before)
  • if not, check if camelcase exists as a prop, if yet set
  • else set as attribute

dummdidumm added a commit that referenced this issue Oct 18, 2023
while attributes are case insensitive, properties are not. to not introduce a breaking change, the lowercased variant is checked first.
fixes #9325
dummdidumm added a commit that referenced this issue Oct 18, 2023
while attributes are case insensitive, properties are not. to not introduce a breaking change, the lowercased variant is checked first.
fixes #9325
@justinfagnani
Copy link

justinfagnani commented Oct 18, 2023

Just to add some info here:

if both the passing and receiving component is compiled with Lit, it "just works"

Lit doesn't know or care that the child component is built with Lit (and there's no compiler). It just sets attributes or properties based on the syntax used at the binding site. If you have a . prefix, it sets a property, no matter what.

I wouldn't look at what Lit does though if you don't want to have a syntax. Lit is explicit about this. Preact has an implicit heuristic that seems to work well, which is simply to do an in check.

check if camelCase exists as a prop, if yes set (this wasn't done before)

This should be sufficient

if not, check if camelcase exists as a prop, if yet set

I would not do this. I can't think of a reason you'd want to set a property of a different name like this. If the property doesn't exist on the element, just set the attribute.

@dummdidumm
Copy link
Member

I would not do this. I can't think of a reason you'd want to set a property of a different name like this. If the property doesn't exist on the element, just set the attribute.

We'll likely remove that in Svelte 5, but we can't now, it's a breaking change strictly speaking.

kelvinsjk pushed a commit to kelvinsjk/svelte that referenced this issue Oct 19, 2023
while attributes are case insensitive, properties are not. to not introduce a breaking change, the lowercased variant is checked first.
fixes sveltejs#9325
@OvidijusParsiunas
Copy link
Author

OvidijusParsiunas commented Oct 20, 2023

Thankyou very much for your efforts @dummdidumm! I have tested it on my projects and everything runs as expected.

Working sandbox for reference.

@fnimick
Copy link

fnimick commented Nov 1, 2023

This fix did not fix the underlying issue for #9305 - for built-in components, the type definitions and properties that work at runtime do not align.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants