CryptoTicker
cryptoticker-1779379195773.tsx
'use client'
import { useState, useEffect } from 'react'
const BASE_PRICES: Record<string, { price: number; change: number; cap: string; icon: string; color: string }> = {
BTC: { price: 67420, change: 2.4, cap: '1.32T', icon: '₿', color: '#f59e0b' },
ETH: { price: 3180, change: -1.2, cap: '382B', icon: 'Ξ', color: '#6366f1' },
SOL: { price: 142, change: 5.8, cap: '63B', icon: '◎', color: '#22c55e' },
USDC: { price: 1.00, change: 0.01, cap: '32B', icon: '$', color: '#2775ca' },
}
function randomize(v: number, pct = 0.002): number {
return v * (1 + (Math.random() - 0.5) * pct)
}
export default function CryptoTicker() {
const [prices, setPrices] = useState(BASE_PRICES)
const [alerts, setAlerts] = useState<Record<string, boolean>>({})
useEffect(() => {
const t = setInterval(() => {
setPrices(p => Object.fromEntries(
Object.entries(p).map(([k, v]) => [k, { ...v, price: randomize(v.price), change: v.change + (Math.random() - 0.5) * 0.05 }])
))
}, 2000)
return () => clearInterval(t)
}, [])
return (
<div style={{ background: '#0D0D0D', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, overflow: 'hidden' }}>
<div style={{ padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', justifyContent: 'space-between' }}>
<div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 600 }}>Crypto Markets</div>
<div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
<span style={{ width: 6, height: 6, borderRadius: '50%', background: '#22c55e', display: 'inline-block', animation: 'pulse 2s infinite' }} />
<span style={{ color: 'rgba(255,255,255,0.35)', fontSize: 12 }}>Live</span>
</div>
</div>
{Object.entries(prices).map(([symbol, data]) => (
<div key={symbol} style={{ display: 'flex', alignItems: 'center', padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,0.04)' }}>
<div style={{ width: 36, height: 36, borderRadius: '50%', background: data.color + '18', border: `1px solid ${data.color}30`, display: 'flex', alignItems: 'center', justifyContent: 'center', color: data.color, fontWeight: 800, fontSize: 15, marginRight: 12, flexShrink: 0 }}>
{data.icon}
</div>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ color: '#F5F5F0', fontSize: 14, fontWeight: 600 }}>{symbol}</div>
<div style={{ color: 'rgba(255,255,255,0.35)', fontSize: 11 }}>Market cap: ${data.cap}</div>
</div>
<div style={{ textAlign: 'right', marginRight: 14 }}>
<div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>
${symbol === 'USDC' ? data.price.toFixed(2) : data.price >= 1000 ? data.price.toLocaleString('en', { maximumFractionDigits: 0 }) : data.price.toFixed(2)}
</div>
<div style={{ color: data.change >= 0 ? '#22c55e' : '#ef4444', fontSize: 12, fontWeight: 600 }}>
{data.change >= 0 ? '+' : ''}{data.change.toFixed(2)}%
</div>
</div>
<button onClick={() => setAlerts(a => ({ ...a, [symbol]: !a[symbol] }))}
style={{ background: alerts[symbol] ? 'rgba(201,168,76,0.12)' : 'rgba(255,255,255,0.04)', border: '1px solid', borderColor: alerts[symbol] ? 'rgba(201,168,76,0.25)' : 'rgba(255,255,255,0.08)', borderRadius: 6, padding: '4px 8px', cursor: 'pointer', fontSize: 14 }}>
{alerts[symbol] ? '🔔' : '🔕'}
</button>
</div>
))}
<style>{`@keyframes pulse { 0%,100% { opacity:1 } 50% { opacity:0.3 } }`}</style>
</div>
)
}Component info
CategoryFinance
Frameworkreact
TierFREE
Views0
Copies0
About
Live crypto price ticker with sparklines, price alerts, percentage changes, and market cap