UNPKG

phx-react

Version:

PHX REACT

64 lines 3.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PHXMiniProgressBar = void 0; const tslib_1 = require("tslib"); const react_1 = tslib_1.__importStar(require("react")); const easeOutExpo = (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)); const PHXMiniProgressBar = ({ percent, isCompleted, className }) => { const barRef = (0, react_1.useRef)(null); const rafRef = (0, react_1.useRef)(null); const startTimeRef = (0, react_1.useRef)(null); const startValueRef = (0, react_1.useRef)(0); (0, react_1.useEffect)(() => { if (percent == null) { if (barRef.current) { barRef.current.style.transform = 'translateX(-100%)'; } startValueRef.current = 0; return; } const target = Math.max(0, Math.min(100, Number(percent))); const duration = 1200; startValueRef.current = startValueRef.current || 0; const animate = (now) => { if (!startTimeRef.current) startTimeRef.current = now; const elapsed = now - startTimeRef.current; const progress = Math.min(elapsed / duration, 1); const eased = easeOutExpo(progress); const current = startValueRef.current + (target - startValueRef.current) * eased; if (barRef.current) { barRef.current.style.transform = `translateX(${current - 100}%)`; } if (progress < 1) { rafRef.current = requestAnimationFrame(animate); } else { if (barRef.current) { barRef.current.style.transform = `translateX(${target - 100}%)`; } startValueRef.current = target; startTimeRef.current = null; } }; rafRef.current = requestAnimationFrame(animate); return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current); rafRef.current = null; }; }, [percent]); const displayPercent = percent == null ? '--' : `${Math.round(Number(percent))}%`; return (react_1.default.createElement("div", { className: 'flex justify-start items-center pr-4' }, react_1.default.createElement("div", { className: 'flex items-center gap-3' }, react_1.default.createElement("div", { className: `flex-1 w-[91px] ${className}` }, react_1.default.createElement("div", { className: 'h-2 bg-gray-200 rounded-full overflow-hidden relative' }, react_1.default.createElement("div", { ref: barRef, className: `absolute inset-y-0 left-0 ${isCompleted ? 'bg-green-600' : 'bg-gray-900'} transition-colors duration-300`, style: { transform: 'translateX(-100%)', width: '100%', } }))), react_1.default.createElement("span", { className: 'text-sm font-medium text-left text-gray-500 w-[32px] tabular-nums' }, displayPercent)))); }; exports.PHXMiniProgressBar = PHXMiniProgressBar; exports.default = exports.PHXMiniProgressBar; //# sourceMappingURL=MiniProgressBar.js.map