Custom Element with Shadow and Template
by stevenkaspar
HTML
<xy-graph x='10' y='20'></xy-graph>
<graph-axis-button axis='x' value='1'>x +1</graph-axis-button>
<graph-axis-button axis='x' value='-1'>x -1</graph-axis-button>
<graph-axis-button axis='y' value='1'>y +1</graph-axis-button>
<graph-axis-button axis='y' value='-1'>y -1</graph-axis-button>
<template data-xy-graph-styling>
<style>
x-axis {
width: 1px;
height: 100%;
background: #444;
}
y-axis {
width: 100%;
height: 1px;
background: #444;
}
</style>
</template>
CSS
body {
min-height: 300px;
}
xy-graph {
width: 100%;
background: white;
}
JavaScript
class XAxis extends HTMLElement {
constructor(){
super();
}
connectedCallback(){
this.style.position = 'absolute';
this.style.display = 'block';
}
static get observedAttributes() {
return ['index'];
}
attributeChangedCallback(attr, oldValue, newValue) {
if (attr === 'index') {
this.style.left = (newValue * 10) + 'px';
}
}
}
class YAxis extends HTMLElement {
constructor(){
super();
}
connectedCallback(){
this.style.position = 'absolute';
this.style.display = 'block';
}
static get observedAttributes() {
return ['index'];
}
attributeChangedCallback(attr, oldValue, newValue) {
if (attr === 'index') {
this.style.top = (newValue * 10) + 'px';
}
}
}
class XyGraph extends HTMLElement {
constructor(){
super();
this.shadow = this.attachShadow({mode: 'open'});
this.shadow.appendChild(document.querySelector('[data-xy-graph-styling]').content.querySelector('style'));
}
connectedCallback(){
this.style.position = 'relative';
this.style.display = 'block';
}
static get observedAttributes() {
return ['x', 'y'];
}
attributeChangedCallback(attr, oldValue, newValue) {
if (attr === 'x' && oldValue !== newValue) {
var diff = newValue - oldValue;
if(diff > 0){
while(diff > 0){
let x = document.createElement('x-axis');
x.setAttribute('index', this.shadow.querySelectorAll('x-axis').length);
this.shadow.appendChild(x);
diff += -1;
}
}
else if(diff < 0){
while(diff < 0){
let x_axes = this.shadow.querySelectorAll('x-axis');
x_axes[x_axes.length - 1].parentNode.removeChild(x_axes[x_axes.length - 1]);
diff += 1;
}
}
}
else if (attr === 'y' && oldValue !== newValue) {
this.style.height = (((newValue-1) * 10) + 1) + 'px';
var diff = newValue - oldValue;
if(diff > 0){
while(diff > 0){
let y...