Open justinfagnani opened 2 years ago
Great suggestion, some questions:
classList
which would reflect upon mutation?class
, part
) but other forms exist that we might want to support like exportparts
("innerA: outerA, innerB: outerB").input.type
seems similar to the enum case and perhaps we should model after it? In that case setting the attribute sets the property to one of the enum values or text
as default and setting the property actually does the same (e.g. input.type = 'foo' => type attr == 'foo', type prop == 'text')I think they should support reflection, so should implement toAttribute
and serializing to a string should be straight forward.
I don't think it's really necessary to implement a DOMTokenList-like thing. That would be a lot more infrastructure than just a converter and I don't think it's a great API, since the more natural thing is to mutate the array. Not that the DOM has an observable array, we might also consider offering an observable array that's also a reactive controller, like:
class MyElement extends LitElement {
@property({converter: new ListConverter()})
items = new ObservableArray(this, []);
}
Good point. input/type has the behavior where if you set it to an invalid value and then read it, the value is "text"
. I actually don't like this behavior much, since it violates the standard behavior of properties. I expect that when I set a property and read it right back, it'll have the value I set.
I weakly feel like if an author wants to go that far, maybe they should implement their own setter. I think not changing a property from the value that's set is coherent with the attribute behavior too: a converter will not change the value of an invalid attribute, it'll just reflect the default value to the property.
I mention that we could support custom separators. I think it's ok, but likely a bad pattern to use too much. A microsyntax like for exportparts
will require a custom converter anyway.
See above. I think <input>
in general is a little problematic to use a prototype case to follow - it's far too overridden IMO. I'd look to see how other enum values behave in the platform, and even then I'm not personally sold on properties spontaneously changing without any other code apparently running, if that's done elsewhere.
Motivation
It's relatively common to have attributes that take a list of tokens (ie,
class
,part
) or a token from a specific enum (input/type
,rel
, etc.). Lit doesn't provide converters for these common cases, but probably should.Example
Enums
An attribute may have a set of valid values, say
"happy"
and"sad"
in this example.When the attribute value is valid, the property will have the same value as the attribute. When the attribute value is invalid, we can choose the fallback value.
The default fallback would be undefined.
Option possible features
Case-insensitivity / Normalization
We can match attributes case insensitively and normalize property values to upper or lower case.
Non-string Enums
For non-string properties we could offer a mapping (bi-directional for reflection). That could be a function or an object provided to the converter.
Lists
Authors may want to support a different list separator, but we should encourage space as a separator to be compatible with the attribute selector operator
|=
.How
Current Behavior
Authors have to write their own converters.
Desired Behavior
Authors can use one of our well-written ones.
References