Trying to extend an custom element :
class ABC extends HTMLDivElement {
connectedCallback() { console.log('ABC here') }
}
customElements.define("x-abc", ABC, {
extends: 'div'
})
class XYZ extends ABC {
connectedCallback() { console.log('XYZ here') }
}
customElements.define("x-xyz", XYZ, {
extends: 'x-abc'
})
<div is="x-abc"></div>
<div is="x-xyz"></div>
but getting this error :
Uncaught DOMException: Failed to execute 'define' on 'CustomElementRegistry': "x-abc" is a valid custom element name
The err is confusing because it say 'is valid', not 'is not valid' !!
On the other hand FF says :
Uncaught DOMException: CustomElementRegistry.define: 'x-xyz' cannot extend a custom element
I want to build hierarchy of custom elements.
The error may sound confusing at first, but actually it is very clear. The spec clearly defines that you can only extend built-ins using the is
syntax. As it is currently designed, using ABC
as a base class is definitely not the brightest idea (until you drop extending HTMLDivElement
in favour of HTMLElement
).
You have not explained why you need to extend div
elements, which is definitely not what you typically build a component hierarchy on. It is not even (and probably never will be) supported in Safari.
Instead, extend HTMLElement
, and omit the is
-syntax.
class ABC extends HTMLElement {
connectedCallback() {
console.log('ABC here')
}
}
customElements.define('x-abc', ABC)
class XYZ extends ABC {
connectedCallback() {
super.connectedCallback();
console.log('XYZ here')
}
}
customElements.define('x-xyz', XYZ)
<x-abc></x-abc>
<x-xyz></x-xyz>
If for whatever strange reason you need to keep extending HTMLDivElement
(instead of HTMLElement
which would be the proper way), here you go:
Just replace the {extends: 'x-abc'}
part with {extends: 'div'}
.
Both your components extend div
(their defining tag name).
class ABC extends HTMLDivElement {
connectedCallback() {
console.log('ABC here')
}
}
customElements.define('x-abc', ABC, {
extends: 'div'
})
class XYZ extends ABC {
connectedCallback() {
super.connectedCallback();
console.log('XYZ here')
}
}
customElements.define('x-xyz', XYZ, {
extends: 'div'
})
<div is="x-abc"></div>
<div is="x-xyz"></div>