Netflix / x-element

A dead simple starting point for custom elements.
Apache License 2.0
28 stars 12 forks source link

Deserialize `""` to `NaN` for `Number` type. #148

Closed theengineear closed 1 year ago

theengineear commented 1 year ago

It would always be counter-intuitive to declare <my-element number> in HTML markup and introspect the element to find element.number === 0.

In other words, while it’s true that in JS Number('') === 0, this is not sensible behavior when deserializing values in markup into typed objects in JS.

This is mostly due to the concept of so-called “boolean attributes”. As a custom element author, you don’t want to coerce a boolean attribute to a Number. In otherwords, when dealing with numbers, the markup <my-element number> should not equal <my-element number="0">.

While this change makes a strong opinion, part of the goal of x-element is to reduce obvious boiler plate. Since it seems incredibly unlikely that any author would actually desire the Number('') >> 0 behavior, taking a stance here seems more helpful than hurtful.

Additionally, we will always, conceptually, have a default deserializer. In the future, if needed, we could allow authors to declare their own deserializers / serializers within property declarations.

Closes #147.

theengineear commented 1 year ago

@klebba — I really wrestled with myself over whether this opinion makes sense or not in x-element. Ultimately, I think because we have to opine on some default, we may as well choose the one we think is best. We can always introduce serialize and deserialize functions as declarations in property blocks:

number: {
  type: Number,
  reflect: true,
  serialize: value => /* custom serialization routine to run on reflection */,
  deserialize: string => /* custom deserialization routine to run on sync */,
}
klebba commented 1 year ago

Thanks @theengineear — it's worth noting that the impetus for this change was a UI bug in which a null value was unexpectedly represented as "0" in a property pipeline and subsequently depicted as a Unix Epoch 1970-01-01 timestamp by a date formatter (or some such thing, I can't recall the details) — in other words, not a default behavior anyone actually wants.