Skip to content

Instantly share code, notes, and snippets.

@JLarky
Last active August 14, 2020 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JLarky/f324fdc0ec1813a9d5a928420241685a to your computer and use it in GitHub Desktop.
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
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