class MyThing extends LitElement {
draggable:string = "true";
results in
TS2416: Property 'draggable' in type 'MyThing' is not assignable to the same property in base type 'LitElement'. Type 'string' is not assignable to type 'boolean'.
Which is bad, because https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable says
This attribute is an enumerated one and not a Boolean one. This means that the explicit usage of one of the values true or false is mandatory and that a shorthand like <label draggable>Example Label</label> is not allowed. The correct usage is <label draggable="true">Example Label</label>.
https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable
That site is talking about the global html attribute draggable:
<div draggable="true"></div>
You are setting the javascript property draggable which is specified to be boolean:
https://html.spec.whatwg.org/multipage/dom.html#htmlelement
myDivElement.draggable = true;
This is by the way an error related to TypeScript not LitElement.
Huh! So... er.... can I fix it? If I need to spit out <my-thing draggable="true"></my-thing> what would I do?
doing this.setAttribute('draggable', true) in the connectedCallback should work
@salamanders tracking native attributes/properties in LitElement can sometimes be tricky, and works a little differently between browsers. Without a little more information about what you're doing I'd lean towards thinking this isn't really what you're trying to do. In which case, some of the notes above might prove useful to you. If it is, and you really want this tracked by your element, there are a couple of ways forward for you:
The _easiest_ (least dangerous) way to manage this would be to create an element specific attribute/property pair that used a different name (i.e. myDraggable but better...) , but you responded to changed by using this.setAttribute('draggable', this.myDraggable ? 'true' : 'false') in response to each change.
A fancier way that I haven't fully tested x-browser, but takes advantage of the all the LitElement bells and whistles would be to try something like the following in your property definition:
draggable: {
type: Boolean,
reflect: true,
converter: {
fromAttribute: (value, type) => {
return value === 'true' ? true : false
},
toAttribute: (value, type) => {
return value ? 'true' : 'false'
}
}
}
}
Here you're adding listening for the attribute draggable and binding it to the property this.draggable with reflect = true so that changes go both ways. When the attribute changes, it expects it to be a string and when that string it "true" it sets this.draggable to true. When the property is set, it expects a Boolean and applies that as a string of its value back to the attribute.
Closing as not a LitElement specific issue. I'm not sure how many other odd boolean-like enum attributes there are, but I'm not sure it would warrant us adding a built-in converter for it.
Most helpful comment
@salamanders tracking native attributes/properties in LitElement can sometimes be tricky, and works a little differently between browsers. Without a little more information about what you're doing I'd lean towards thinking this isn't really what you're trying to do. In which case, some of the notes above might prove useful to you. If it is, and you really want this tracked by your element, there are a couple of ways forward for you:
The _easiest_ (least dangerous) way to manage this would be to create an element specific attribute/property pair that used a different name (i.e.
myDraggablebut better...) , but you responded to changed by usingthis.setAttribute('draggable', this.myDraggable ? 'true' : 'false')in response to each change.A fancier way that I haven't fully tested x-browser, but takes advantage of the all the LitElement bells and whistles would be to try something like the following in your property definition:
Here you're adding listening for the attribute
draggableand binding it to the propertythis.draggablewithreflect = trueso that changes go both ways. When the attribute changes, it expects it to be a string and when that string it"true"it setsthis.draggabletotrue. When the property is set, it expects a Boolean and applies that as a string of its value back to the attribute.