@coin-voyage/paykit
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
41 lines (40 loc) • 2.35 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useState } from "react";
const CircleTimer = ({ total, size = 24, stroke = 3, currentTime, onTimeChange, children }) => {
const initial = currentTime ?? total;
// ⭐ Keyed reset: React remounts state when initial changes
const [left, setLeft] = useState(initial);
// External system → interval (allowed)
useEffect(() => {
if (left === 0)
return;
const id = setInterval(() => {
setLeft((prev) => {
const next = Math.max(0, prev - 1);
onTimeChange?.(next);
if (next === 0)
clearInterval(id);
return next;
});
}, 1000);
return () => clearInterval(id);
}, [left, onTimeChange]);
const ratio = total > 0 ? Math.round((left * 100) / total) : 0;
const radius = Math.floor((size - stroke) / 2);
const circumference = Math.round((2 * 314 * radius) / 100);
const dashoffset = Math.round((circumference * (100 - ratio)) / 100);
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 }) }))] }, initial));
};
export default CircleTimer;