Last active
August 14, 2020 14:07
-
-
Save JLarky/f324fdc0ec1813a9d5a928420241685a to your computer and use it in GitHub Desktop.
React component to show progress ring based on @twitter/CountdownCircle @twitter/ProgressCircle https://css-tricks.com/building-progress-ring-quickly/; see also https://github.com/kevinsqi/react-circular-progressbar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const CharCount: React.FC<{ | |
count: number; | |
warningLength: number; | |
maxLength: number; | |
}> = React.memo(({ count, warningLength, maxLength }) => { | |
const progress = Math.min(100, (count * 100) / maxLength); | |
return count > warningLength ? ( | |
<ProgressRing | |
progress={progress} | |
inactiveColor="#4a5568" // gray-700 | |
size={26} | |
> | |
{maxLength - count} | |
</ProgressRing> | |
) : ( | |
<ProgressRing | |
progress={progress} | |
inactiveColor="#4a5568" // gray-700 | |
size={20} | |
/> | |
); | |
}); | |
const ProgressRing: React.FC<{ | |
progress: number; | |
inactiveColor?: string; | |
size: number; | |
}> = React.memo(({ progress, inactiveColor, size, children }) => { | |
const stroke = 2; | |
const radius = (size - stroke) / 2; | |
const circumference = radius * 2 * Math.PI; | |
const offset = circumference * (1 - progress / 100); | |
return ( | |
<div | |
className="transition-all duration-75 relative" | |
style={{ height: size, width: size }} | |
> | |
<div | |
aria-valuemax={100} | |
aria-valuemin={0} | |
aria-valuenow={progress} | |
role="progressbar" | |
className="" | |
> | |
<div className="transform -rotate-90"> | |
<svg | |
height="100%" | |
viewBox={`0 0 ${size} ${size}`} | |
width="100%" | |
style={{ overflow: 'visible' }} | |
> | |
<circle | |
cx="50%" | |
cy="50%" | |
fill="none" | |
strokeWidth={stroke} | |
r={radius} | |
stroke={inactiveColor} | |
/> | |
<circle | |
cx="50%" | |
cy="50%" | |
fill="none" | |
strokeWidth={stroke} | |
r={radius} | |
stroke="currentColor" | |
strokeLinecap="round" | |
style={{ | |
strokeDashoffset: offset, | |
strokeDasharray: circumference, | |
}} | |
/> | |
</svg> | |
</div> | |
</div> | |
{children !== undefined && ( | |
<div className="absolute top-0 bottom-0 right-0 left-0 flex justify-center items-center"> | |
{children} | |
</div> | |
)} | |
</div> | |
); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment