preact-custom-element
preact-custom-element copied to clipboard
Hyphenated attributes and camelCased properties
When a component is connected, preact-custom-element will loop through all attributes and set them as props on the component - both with the original casing and with a camelCased name. Automatic camelCasing is also done for observed attributes.
On the other hand, when determining which attributes to observe, the wrapper does not perform any corresponding transformation - it simply uses the given propNames
directly (passed in explicitly, or extracted from the component definition). This is a problem because component props are usually in camelCase, while HTML attributes must be in lowercase (usually hyphenated).
If propNames
are extracted from the component's propTypes
, there is virtually no chance that they will be hyphenated, and the wrapper will only listen for (and try to reflect) changes to a camelCased attribute, not a hyphenated one. However, the spec requires attributes to be in lowercase, and attempting to set a camelCase attribute in a framework like Vue, manually through browser dev tools, or in the HTML source, will lead to a lowercase attribute being set instead. This effectively means that any prop name with a capital letter cannot be observed (as an attribute) by preact-custom-element. Initial values will still be set, since preact-custom-element loops through all attributes and converts them to camelCase props, but that only happens once. The DOM property will also work, but supporting the attribute - for simple data - would be nice.
propNames
could be hyphenated if they are explicitly passed, or defined as observedAttributes
on the component. But in this case the wrapper will set up a hyphenated DOM property instead of a camelCased one.
Should preact-custom-element camelCase all propNames
before defining properties, and hyphenate them before setting observedAttributes
?
- This is the option I would prefer as a consumer, but I would like some feedback on the idea before putting together a PR
Should consumers pass in camelCased names for complex types (which will use properties) and hyphenated names for simple types (which will use attributes)? Maybe both forms for simple types?
- This would avoid registering complex types as
observedAttributes
, which won't work anyways - This could probably be extracted automatically from propTypes, but would require some additional logic compared to just getting the names.
Should properties and attributes be separated in the preact-custom-element API?
- Removes unnecessary
observedAttributes
(for properties) ordefineProperty
calls (for attributes) - Attributes and properties have some important differences. Maybe trying to abstract them into one thing isn't a good idea anyways?
- Would probably be a breaking change, although perhaps compatibility could be maintained by using
propNames
in both places if the consumer does not specify