Spaces:
Running
Running
| class CustomTicker extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| const items = JSON.parse(this.getAttribute('items') || '[]'); | |
| const speed = this.getAttribute('speed') || '30'; | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| :host { | |
| display: block; | |
| overflow: hidden; | |
| background: #000; | |
| border-bottom: 1px solid #222; | |
| } | |
| .ticker-container { | |
| display: flex; | |
| overflow: hidden; | |
| white-space: nowrap; | |
| } | |
| .ticker-track { | |
| display: flex; | |
| animation: scroll ${speed}s linear infinite; | |
| } | |
| .ticker-item { | |
| display: inline-flex; | |
| align-items: center; | |
| padding: 0.75rem 2rem; | |
| color: #888; | |
| font-family: monospace; | |
| font-size: 0.875rem; | |
| } | |
| .ticker-item .value { | |
| color: #fff; | |
| font-weight: 600; | |
| } | |
| .ticker-item .value.up { | |
| color: #00ff9d; | |
| } | |
| .ticker-item .value.down { | |
| color: #ff003c; | |
| } | |
| .ticker-item .divider { | |
| color: #333; | |
| margin: 0 1rem; | |
| } | |
| @keyframes scroll { | |
| 0% { transform: translateX(0); } | |
| 100% { transform: translateX(-50%); } | |
| } | |
| </style> | |
| <div class="ticker-container"> | |
| <div class="ticker-track" id="ticker-track"> | |
| ${this.generateTickerItems(items)} | |
| ${this.generateTickerItems(items)} <!-- Duplicate for seamless loop --> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| generateTickerItems(items) { | |
| return items.map(item => ` | |
| <div class="ticker-item"> | |
| <span class="label">${item.label}</span> | |
| <span class="divider">•</span> | |
| <span class="value ${item.change >= 0 ? 'up' : 'down'}">${item.value}</span> | |
| ${item.change ? `<span class="divider">•</span><span class="${item.change >= 0 ? 'up' : 'down'}">${item.change >= 0 ? '▲' : '▼'} ${Math.abs(item.change)}%</span>` : ''} | |
| </div> | |
| `).join(''); | |
| } | |
| updateItems(items) { | |
| const track = this.shadowRoot.getElementById('ticker-track'); | |
| track.innerHTML = this.generateTickerItems(items) + this.generateTickerItems(items); | |
| } | |
| } | |
| customElements.define('custom-ticker', CustomTicker); |