import { cn } from "@/presentation/utils"; import type { FC, HTMLAttributes } from "react"; type Size = "xs" | "sm" | "md" | "lg" | "xl"; const sizes: Record = { xs: { radius: 15, strokeWidth: 3 }, sm: { radius: 19, strokeWidth: 4 }, md: { radius: 32, strokeWidth: 6 }, lg: { radius: 52, strokeWidth: 8 }, xl: { radius: 80, strokeWidth: 10 }, }; interface ProgressCircleProps extends HTMLAttributes { value?: number; size?: Size; radius?: number; strokeWidth?: number; showAnimation?: boolean; } const ProgressCircle: FC = ({ className, children, value = 0, size = "md", radius, strokeWidth, showAnimation = true, ...props }) => { const currentValue = getLimitedValue(value); const currentRadius = radius ?? sizes[size].radius; const currentStrokeWidth = strokeWidth ?? sizes[size].strokeWidth; const normalizedRadius = currentRadius - currentStrokeWidth / 2; const circumference = normalizedRadius * 2 * Math.PI; const strokeDashoffset = (currentValue / 100) * circumference; const offset = circumference - strokeDashoffset; return (
{currentValue >= 0 && ( )}
{children}
); }; function getLimitedValue(input: number | undefined): number { if (input === undefined) { return 0; } if (input > 100) { return 100; } return input; } export { ProgressCircle };