ui
ui copied to clipboard
Circular Progress Indicator
why we don't have any circular progress indicator in library?
This can be easily done with tailwind animate-spin
;
// Icon.tsx
import {Loader2} from 'lucide-react';
export const Icons = {
spinner: Loader2,
};
// Usage
<Icons.spinner className="h-4 w-4 animate-spin" />
I think they meant something like this, where you can have a specific progress % rather than a general spinner:
@sonigeez , @AnandChowdhary provided more context. I think everyone meant the above.
@sonigeez @AnandChowdhary any chance this will get picked up again?
+1
+1 was also looking for this
+1
+1
+1
+1
+1
This would be a great addition
+1
+1
+1
+1
+1
+1
+1
+1
+1 for Radial progress
+1
+1
+1
+1
+1
+1
Paste this code into progress.tsx and utilize CircleProgress.
export const CircleProgress = React.forwardRef<
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>
>(({ className, value, ...props }, ref) => (
<ProgressPrimitive.Root
ref={ref}
className={cn(
`relative h-20 w-20 overflow-hidden rounded-full bg-primary/20 flex justify-center items-center`,
className
)}
{...props}
style={{ background: `radial-gradient(closest-side, white 79%, transparent 80% 100%), conic-gradient(green ${(value || 0)}%, pink 0)` }}
>
<div className="">{`${(value || 0)}%`}</div>
</ProgressPrimitive.Root>
))
this is my solution
import { motion } from 'framer-motion';
type Props = {
value: number;
};
export default function CircleProgress({ value }: Props) {
const percentage = Math.min(Math.max(value, 0), 100);
const width = 216;
const radius = 98;
const circumference = 2 * Math.PI * radius;
const offset = circumference - (percentage / 100) * circumference;
return (
<svg width={width} height={width} xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient
id="circle-progress"
cx="0"
cy="0"
r="1"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(53.1659 -18.1884) rotate(51.1683) scale(267.012 282.957)"
>
<stop stopColor="#F05F84" />
<stop offset="1" stopColor="#FD312E" />
</radialGradient>
</defs>
<circle
cx={width / 2}
cy={width / 2}
r={radius}
strokeLinecap="round"
className="fill-none stroke-neutral-300 stroke-[20px]"
style={{
strokeDasharray: circumference,
strokeDashoffset: circumference,
}}
/>
<motion.circle
cx={'108'}
cy={'108'}
r="98"
strokeLinecap="round"
className="fill-none stroke-[url('#circle-progress')] stroke-[20px]"
initial={{
strokeDashoffset: circumference,
strokeDasharray: circumference,
}}
animate={{ strokeDashoffset: offset }}
transition={{
stiffness: 260,
damping: 20,
delay: 0.5,
duration: 1,
ease: 'easeOut',
}}
/>
</svg>
);
}