65 lines
1.7 KiB
JavaScript
65 lines
1.7 KiB
JavaScript
const getSpinnerCss = ({background, foreground, size}) => {
|
|
return `
|
|
@keyframes __spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
.loader {
|
|
display: inline-block;
|
|
vertical-align: top;
|
|
margin: 0 0.25em;
|
|
border: ${size * 0.2}px solid ${background};
|
|
border-top: ${size * 0.2}px solid ${foreground};
|
|
border-radius: 50%;
|
|
width: ${size}px;
|
|
height: ${size}px;
|
|
animation: __spin 2s linear infinite;
|
|
}`
|
|
}
|
|
|
|
/**
|
|
* Loading spinner
|
|
* @attribute background - background color of the spinner
|
|
* @attribute foreground - foreground color of the spinner
|
|
* @attribute size - size of the spinner in pixels
|
|
*/
|
|
// TODO: Accept other size formats (ie. %, vh)
|
|
// TODO: Use style attribute instead...?
|
|
class DjlSpinner extends HTMLElement {
|
|
shadow // ShadowRoot
|
|
spinner // HTMLDivElement
|
|
style // HTMLStyleElement
|
|
|
|
static get observedAttributes() {
|
|
return ['background', 'foreground', 'size']
|
|
}
|
|
|
|
constructor() {
|
|
super()
|
|
|
|
this.shadow = this.attachShadow({ mode: 'open' })
|
|
|
|
this.spinner = document.createElement('div')
|
|
this.spinner.classList.add('loader')
|
|
this.style = document.createElement('style')
|
|
this.style.innerHTML = getSpinnerCss(this.props())
|
|
|
|
this.shadow.appendChild(this.style)
|
|
this.shadow.appendChild(this.spinner)
|
|
}
|
|
|
|
props = () => ({
|
|
background: this.getAttribute('background') || '#eee',
|
|
foreground: this.getAttribute('foreground') || '#333',
|
|
size: parseInt(this.getAttribute('size')) || 20,
|
|
})
|
|
|
|
attributeChangedCallback() {
|
|
this.style.innerHTML = getSpinnerCss(this.props())
|
|
}
|
|
|
|
}
|
|
|
|
customElements.define('djl-spinner', DjlSpinner)
|
|
|