Files
buzz/components/customized/progress/circular-progress.tsx
T
dmgnr f7bd43087d
Build and Push Image / build-backend (push) Successful in 1m4s
Build and Push Image / build-frontend (push) Successful in 2m52s
Build and Push Image / push (push) Successful in 1m16s
feat: add mobile upload
2026-08-29 15:32:47 +07:00

89 lines
2.1 KiB
TypeScript

"use client";
import { cn } from "@/lib/utils";
interface CircularProgressProps {
value: number;
renderLabel?: (progress: number) => number | string;
size?: number;
strokeWidth?: number;
circleStrokeWidth?: number;
progressStrokeWidth?: number;
shape?: "square" | "round";
className?: string;
progressClassName?: string;
labelClassName?: string;
showLabel?: boolean;
}
export const CircularProgress = ({
value,
renderLabel,
className,
progressClassName,
labelClassName,
showLabel,
shape = "round",
size = 100,
strokeWidth,
circleStrokeWidth = 10,
progressStrokeWidth = 10,
}: CircularProgressProps) => {
const radius = size / 2 - 10;
const circumference = Math.ceil(3.14 * radius * 2);
const percentage = Math.ceil(circumference * ((100 - value) / 100));
const viewBox = `-${size * 0.125} -${size * 0.125} ${size * 1.25} ${
size * 1.25
}`;
return (
<div className="relative">
<svg
className="relative"
height={size}
style={{ transform: "rotate(-90deg)" }}
version="1.1"
viewBox={viewBox}
width={size}
xmlns="http://www.w3.org/2000/svg"
>
{/* Base Circle */}
<circle
className={cn("stroke-primary/25", className)}
cx={size / 2}
cy={size / 2}
fill="transparent"
r={radius}
strokeDasharray={circumference}
strokeDashoffset="0"
strokeWidth={strokeWidth ?? circleStrokeWidth}
/>
{/* Progress */}
<circle
className={cn("stroke-primary", progressClassName)}
cx={size / 2}
cy={size / 2}
fill="transparent"
r={radius}
strokeDasharray={circumference}
strokeDashoffset={percentage}
strokeLinecap={shape}
strokeWidth={strokeWidth ?? progressStrokeWidth}
/>
</svg>
{showLabel && (
<div
className={cn(
"absolute inset-0 flex items-center justify-center text-lg",
labelClassName,
)}
>
{renderLabel ? renderLabel(value) : value}
</div>
)}
</div>
);
};