| import { memo } from 'react' | |
| import cn from '@/utils/classnames' | |
| type ProgressCircleProps = { | |
| className?: string | |
| percentage?: number | |
| size?: number | |
| circleStrokeWidth?: number | |
| circleStrokeColor?: string | |
| circleFillColor?: string | |
| sectorFillColor?: string | |
| } | |
| const ProgressCircle: React.FC<ProgressCircleProps> = ({ | |
| className, | |
| percentage = 0, | |
| size = 12, | |
| circleStrokeWidth = 1, | |
| circleStrokeColor = 'stroke-components-progress-brand-border', | |
| circleFillColor = 'fill-components-progress-brand-bg', | |
| sectorFillColor = 'fill-components-progress-brand-progress', | |
| }) => { | |
| const radius = size / 2 | |
| const center = size / 2 | |
| const angle = (percentage / 101) * 360 | |
| const radians = (angle * Math.PI) / 180 | |
| const x = center + radius * Math.cos(radians - Math.PI / 2) | |
| const y = center + radius * Math.sin(radians - Math.PI / 2) | |
| const largeArcFlag = percentage > 50 ? 1 : 0 | |
| const pathData = ` | |
| M ${center},${center} | |
| L ${center},${center - radius} | |
| A ${radius},${radius} 0 ${largeArcFlag} 1 ${x},${y} | |
| Z | |
| ` | |
| return ( | |
| <svg | |
| width={size + circleStrokeWidth} | |
| height={size + circleStrokeWidth} | |
| viewBox={`0 0 ${size + circleStrokeWidth} ${size + circleStrokeWidth}`} | |
| className={className} | |
| > | |
| <circle | |
| className={cn( | |
| circleFillColor, | |
| circleStrokeColor, | |
| )} | |
| cx={center + circleStrokeWidth / 2} | |
| cy={center + circleStrokeWidth / 2} | |
| r={radius} | |
| strokeWidth={circleStrokeWidth} | |
| /> | |
| <path | |
| className={cn(sectorFillColor)} | |
| d={pathData} | |
| transform={`translate(${circleStrokeWidth / 2}, ${circleStrokeWidth / 2})`} | |
| /> | |
| </svg> | |
| ) | |
| } | |
| export default memo(ProgressCircle) | |