I realise this is not a support forum; I am trying to sneak this in as a documentation request.
Short question: what's the recommended way of creating elements that behave exactly the same as native ones, in all respects? (offering extras, yes, but being 100% compatible drop-in replacement of native ones)
Long version:
I need to extend the native
In Polymer, it's always been clear that you cannot inherit from a native element. I assume this is still the case?
Following this way, I have a <button> in the shadow dom, and reflect _all_ attributes and properties (meaning that any change to my-button will be reflected to the button element in the shadow DOM). [EDITED: the element won't need to reflect all events, thanks to shadow dom's retargeting of events]
For "Way 2", it would mean a lot of attribute replication, etc. This can be done fairly easily with lit-element (the behaviour for all attributes would be identical, and it would apply for a rather long list of them). But... before I get to it, am I entering a rabbit hole?
I can think of so many things that can go wrong... for example, should I even bother reflecting tabindex? Will the form attribute even works, since the button will be in a shadow root? And so on and so forth.
So... Is there an easy way to replicate 100% of the functionality of a specific HTML element without having to reflect each single attribute? And would it work?
this article outlines how to extend standard elements -- we have to provide an awkward option "extends" to the "customElements.define" call:
class ConfirmLink extends HTMLAnchorElement {
...
}
customElements.define("confirm-link", ConfirmLink, {
extends: "a"
});
i think this is what you are looking to do
in the above example, i don't know if you need to extends HTMLAnchorElement given the awkward "extends" option
if so, this might be a problem with lit-element, in which case we'd need a lit-element mixin or decorator we can use to class extends lit(HTMLAnchorElement) {}
Do note that this is not, and will not be supported by Safari
I would vote for option 2. First and foremost, because as @thepassle pointed out, option 1 is not supported by Safari. Also I think this gives you a bit more finegrained control over what you want the user of your component actually be able to customize. Most of the time, I just need/want a small subset of what builtin controls can do.
Also, delegatesFocus helps a lot with gluing your control and the builtin control together as a button inside the shadowRoot will still be focused: https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus
In terms of best practices I also like to look at what the material web components team does: https://github.com/material-components/material-components-web-components/blob/master/packages/button/src/mwc-button.ts
Hello, I'll have to bring this problem up in our next meeting on this, but a way that we made "lighter" elements in polymer 2+ after the removal of is=..., because of Safari support, was to project your light Dom.
e.g.
<my-input-lite>
<input slot="maybeYouWontUseASlotHere">
</my-input-lite>
Downside is listening to slotchange event and initializing after the fact.
I just opened a comment thread on this topic at https://dev.to/lkraav/comment/ad06
AFAICS https://github.com/ungap/custom-elements-builtin should be safe to use to get Safari compatibility, and you're on your way.
I was thinking of the same and google sent me here. In react, inheritance is possible to extend non-native components, but composition is always preferred (docs), even with composition, spread operator can handle this perfectly, and we can extend functionalities by composition or adjusting individual props:
render() {
const { props } = this;
return (
<button prop1={val1} {...props}></button>
);
}
Really hope lit-element docs shed some light on this topic 馃槂
Hi ,
I'm fan a of Polymer since Polymer 2 , and trying to change my mind from P2 to P3 , lit-element & lit-html, and I was facing same sort of problem.
I needed a lit-element to extend HTMLSelectElement
It seems that i found a solution with the "named slot" functionnality.
in the parent, I got that
<solid-folders
url="${constraint.reference}"
@change=${this.selectorChange}
@select-event="${(e) => { this.changeValue(e) }}" >
<select slot="mySelect"
@change=${this.selectorChange}>
</select>
</solid-folders>
and in the child element, i got this
<select class="teal lighten-4"
title="${this.url}"
@change=${this.selectorChange}>
<slot name="mySelect">
<option value="" disabled selected>${this.url}</option>
<option value="" ></option>
${this.folder.files.map(i => html`
<option value="${i.url}" >${i.label || i.name}</option>
`)}
</slot>
</select>
Ok, there is lot of @change=${this.selectorChange} but I can catch the event & fire a custom event

It's just a try but hope it can help.
can be tested here : https://scenaristeur.github.io/spoggy-simple/shexy/shexy-lit/index.html
full code : https://github.com/scenaristeur/spoggy-simple/commit/95823cd93f864e95c9d42db348564f31df312c87
Maybe worth looking at:
https://github.com/ungap/custom-elements-builtin
Safari isn't going to implement customized built-ins. I suggest using an alternate approach like @e111077 pointed out rather than forcing all Safari users to use a polyfill indefinitely.
We would need to make LitElement a mixin to support this. That's not in the plans at the moment. If that changes we'll take a look at this again.