| 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) |
|
|