const template = document.createElement('template'); template.innerHTML = ` <style> audio { height: 2rem; margin: .5rem; } #audioPlayerContainer { background: var(--background); display: flex; flex-flow: column nowrap; height: 13.5rem; } #audioDetailsContainer { display: flex; flex-flow: row nowrap; } #audioTextContainer { padding: 0 1rem 0 1rem; height: 10rem; overflow-y: scroll; } img { height: 10rem; margin: .5rem 0rem 0rem .5rem; object-fit: cover; width: 10rem; } /* Utilities */ .round-corners { border-radius: 10px; } .small-shadow { box-shadow: 0 4px 8px 0 rgba(0,0,0,.2); } </style> <div id="audioPlayerContainer" class="small-shadow round-corners"> <div id="audioDetailsContainer"> <img src="" alt="" class="small-shadow round-corners"> <div id="audioTextContainer"> <slot name="title"><h3>TITLE</h3></slot> <slot name="description"><p>DESCRIPTION</p></slot> </div> </div> <audio class="small-shadow round-corners" controls> <source src=""> Your browser does not support the audio element. </audio> </div> ` class AudioPlayer extends HTMLElement { constructor() { super(); this._shadowRoot = this.attachShadow({ 'mode': 'open' }); this._shadowRoot.appendChild(template.content.cloneNode(true)); this.$audioPlayer = this._shadowRoot.querySelector('#audioPlayerContainer'); } static get observedAttributes() { return ['audio', 'cover', 'cover_alt']; } attributeChangedCallback(name, oldVal, newVal) { if (oldVal != newVal) { this[name] = newVal; this.render(); } } render() { this.cover ? this.$audioPlayer.querySelector('img').src = this.cover : null; this.cover_alt ? this.$audioPlayer.querySelector('img').alt = this.cover_alt : null; this.audio ? this.$audioPlayer.querySelector('audio source').src = this.audio : null; } } window.customElements.define('audio-player', AudioPlayer);