salesforce / lwc

⚡️ LWC - A Blazing Fast, Enterprise-Grade Web Components Foundation
https://lwc.dev
Other
1.63k stars 393 forks source link

`lwc:spread` applies props rather than attributes #4425

Open nolanlawson opened 3 months ago

nolanlawson commented 3 months ago

Description

lwc:spread applies property names to an element (similar to Object.assign()), but not attributes, which may be unexpected.

For example, a developer might assume that this will render as class="red":

<h1 lwc:spread={props}>Hello world!</h1>
export default class extends LightningElement {
  props = {
    'class': 'red',
  }
}

However, it does not. Instead, you must use className:

export default class extends LightningElement {
  props = {
    'className': 'red',
  }
}

Similarly, you cannot apply attributes that do not have a property equivalent:

  props = {
    'data-foo': 'foo', // will not render the `data-foo` attribute
  }

Steps to Reproduce

See repro

Potential workaround

Use the property format (e.g. className instead of class), or use renderedCallback to manually call setAttribute() on the element.

Potential solution

This would be an overhaul of how lwc:spread currently works and would have the potential for backwards-incompatible breakages. For the time being, though, this issue can at least serve as documentation about the current behavior.

ekashida commented 1 month ago

For context, this behavior is by design. I recall having a dev sync discussion where the outcome was to keep it as simple as possible and to avoid any special handling.

ekashida commented 1 month ago

The documentation could be better--it feels like we could add more detail around event handlers and IDL attributes that reflect as content attributes.