I have the following Node class which I am using to create a custom element node-element
.
class Node extends SVGCircleElement{
static get observedAttributes() {
return ["coordinates"];
}
constructor()
{
super();
this.attributeMap = {coordinates:(coordinates)=>this.updateCoordinates(coordinates)}
}
connectedCallback(){
this.initNode();
}
updateCoordinates(coordinates)
{
this.setAttribute("cx",`${coordinates.x}`);
this.setAttribute("cy",`${coordinates.y}`);
this.setAttribute("r",50);
}
initNode()
{
this.className="node";
}
attributeChangedCallback(name,oldValue,newValue)
{
if(oldValue!==newValue)
{
this.attributeMap[name](JSON.parse(newValue))
}
}
}
I register this element using:-
customElements.define('node-element',Node);
I am creating this element as follows:-
let newNode = document.createElement("node-element");
This is where I get the following error:-
Uncaught TypeError: Illegal constructor
at new Node (index.js:9)
at SVGSVGElement.drawNode (index.js:43)
Line 43 corresponds to the createElement code.
Would love to be proven wrong, just spent 2 months on an SVG project
AFAIK, you can NOT extend SVG elements
You can only create Custom Elements in the HTML Namespace http://www.w3.org/1999/xhtml
SVG Elements are in the SVG Namespace http://www.w3.org/2000/svg
From the docs: https://html.spec.whatwg.org/multipage/custom-elements.html#element-definition
If the element interface for extends and the HTML namespace is HTMLUnknownElement,
then throw a "NotSupportedError" DOMException.
and
if namespace is not the HTML namespace, return null
The ongoing W3C discussion on allowing other namespaces is here: https://github.com/w3c/webcomponents/issues/634
The HTML Namespace has restrictions too
Apple/Safari implemented the Autonomous Custom Elements (extend from HTMLElement)
but will not implement Customized Built-In Elements (extend any Built-In element from the HTML Namespace)
If you want to generate SVG, you have to extend HTMLElement
and generate the whole SVG tag:
customElements.define("svg-circle", class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'>
<circle cx='50%' cy='50%' r='48%'/>
</svg>`;
}
});