UNPKG

@daimo/pay

Version:

Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.

49 lines (46 loc) 2.66 kB
import { jsxs, jsx } from 'react/jsx-runtime'; import { useState, useEffect } from 'react'; const CircleTimer = ({ total, size = 24, stroke = 3, currentTime, onTimeChange, children, }) => { // timestamp (ms) when timer ends const [target, setTarget] = useState(Date.now() + (currentTime ?? total) * 1000); const [left, setLeft] = useState(currentTime ?? total); // react to external currentTime updates useEffect(() => { if (currentTime !== undefined) { setTarget(Date.now() + currentTime * 1000); setLeft(currentTime); } }, [currentTime]); // interval tick useEffect(() => { const id = setInterval(() => { const secs = Math.max(0, Math.ceil((target - Date.now()) / 1000)); setLeft(secs); onTimeChange?.(secs); if (secs === 0) clearInterval(id); }, 1000); return () => clearInterval(id); }, [target, onTimeChange]); const ratio = Math.round((left * 100) / total); // 0-100 // Ensure stroke stays within viewBox: use floor to be conservative const radius = Math.floor((size - stroke) / 2); const circumference = Math.round((2 * 314 * radius) / 100); // 2πr, π≈3.14 const dashoffset = Math.round((circumference * (100 - ratio)) / 100); // colour transition: green → orange → red const color = ratio <= 10 ? "var(--timer-red, #D92D20)" : ratio <= 40 ? "var(--timer-orange, #F79009)" : "var(--timer-green, #12D18E)"; const center = Math.round(size / 2); return (jsxs("svg", { viewBox: `0 0 ${size} ${size}`, width: size, height: size, role: "img", "aria-label": `Timer: ${left}s left of ${total}s`, children: [jsx("circle", { cx: center, cy: center, r: radius, fill: "transparent", stroke: "var(--ck-body-background-secondary, #EEE)", strokeWidth: stroke }), jsx("circle", { cx: center, cy: center, r: radius, fill: "transparent", stroke: color, strokeWidth: stroke, strokeDasharray: circumference, strokeDashoffset: dashoffset, strokeLinecap: "round", style: { transition: "stroke-dashoffset 1s linear" }, transform: `rotate(-90 ${center} ${center})` }), children && (jsx("foreignObject", { x: "0", y: "0", width: size, height: size, children: jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "100%", height: "100%", }, children: children }) }))] })); }; export { CircleTimer as default }; //# sourceMappingURL=CircleTimer.js.map