JSFiddle - React, Tailwind, and code Playground

by graphettion

HTML

<audio-player
  src="https://cdn.pixabay.com/download/audio/2023/02/02/audio_1380f61ac0.mp3?filename=crowd-source-137642.mp3"
  title="Crowd Source"
  artist="daub_audio">
</audio-player>

JavaScript

class AudioPlayer extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
  }

  static get observedAttributes() {
    return ['src'];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'src' && this.shadowRoot) {
      const audio = this.shadowRoot.querySelector('audio');
      if (audio) {
        audio.src = newValue;
      }
    }
  }

  connectedCallback() {
    this.render();
    this.setupEventListeners();
  }

  render() {
    this.shadowRoot.innerHTML = `
      <style>
        :host {
          display: block;
          width: 100%;
          max-width: 600px;
          margin: 0 auto;
        }

        .container {
          position: relative;
          border-radius: 8px;
          overflow: hidden;
          background: #1a1a1a;
          padding: 20px;
        }

        audio {
          display: none;
        }

        .controls {
          display: flex;
          flex-direction: column;
          gap: 16px;
        }

        .progress-bar {
          width: 100%;
          height: 4px;
          background: rgba(255, 255, 255, 0.3);
          cursor: pointer;
          position: relative;
          border-radius: 2px;
        }

        .progress-fill {
          height: 100%;
          background: #ffffff;
          width: 0%;
          position: absolute;
          border-radius: 2px;
          transition: width 0.1s;
        }

        .buttons-container {
          display: flex;
          justify-content: space-between;
          align-items: center;
          color: #ffffff;
        }

        .left-controls, .right-controls {
          display: flex;
          gap: 16px;
          align-items: center;
        }

        button {
          background: none;
          border: none;
          color: #ffffff;
          cursor: pointer;
          padding: 5px;
          display: flex;
          align-items: center;
          justify-content: center;
          transition:...