Visualizations
Progress Circle
Visual element to indicate progress, performance, or status represented in a circular shape.
import { ProgressCircle } from '@/components/ProgressCircle'
export const ProgressCircleHero = () => ( <ProgressCircle value={62} className="mx-auto" />)
Installation
npm i tailwind-variants
- Copy and paste the code into your project’s component directory. Do not forget to update the import paths.
// Tremor ProgressCircle [v0.0.3] import React from "react"import { tv, VariantProps } from "tailwind-variants" import { cx } from "@/lib/utils" const progressCircleVariants = tv({ slots: { background: "", circle: "", }, variants: { variant: { default: { background: "stroke-blue-200 dark:stroke-blue-500/30", circle: "stroke-blue-500 dark:stroke-blue-500", }, neutral: { background: "stroke-gray-200 dark:stroke-gray-500/40", circle: "stroke-gray-500 dark:stroke-gray-500", }, warning: { background: "stroke-yellow-200 dark:stroke-yellow-500/30", circle: "stroke-yellow-500 dark:stroke-yellow-500", }, error: { background: "stroke-red-200 dark:stroke-red-500/30", circle: "stroke-red-500 dark:stroke-red-500", }, success: { background: "stroke-emerald-200 dark:stroke-emerald-500/30", circle: "stroke-emerald-500 dark:stroke-emerald-500", }, }, }, defaultVariants: { variant: "default", },}) interface ProgressCircleProps extends Omit<React.SVGProps<SVGSVGElement>, "value">, VariantProps<typeof progressCircleVariants> { value?: number max?: number showAnimation?: boolean radius?: number strokeWidth?: number children?: React.ReactNode} const ProgressCircle = React.forwardRef<SVGSVGElement, ProgressCircleProps>( ( { value = 0, max = 100, radius = 32, strokeWidth = 6, showAnimation = true, variant, className, children, ...props }: ProgressCircleProps, forwardedRef, ) => { const safeValue = Math.min(max, Math.max(value, 0)) const normalizedRadius = radius - strokeWidth / 2 const circumference = normalizedRadius * 2 * Math.PI const offset = circumference - (safeValue / max) * circumference const { background, circle } = progressCircleVariants({ variant }) return ( <div className={cx("relative")} role="progressbar" aria-label="Progress circle" aria-valuenow={value} aria-valuemin={0} aria-valuemax={max} data-max={max} data-value={safeValue ?? null} tremor-id="tremor-raw" > <svg ref={forwardedRef} width={radius * 2} height={radius * 2} viewBox={`0 0 ${radius * 2} ${radius * 2}`} className={cx("-rotate-90 transform", className)} {...props} > <circle r={normalizedRadius} cx={radius} cy={radius} strokeWidth={strokeWidth} fill="transparent" stroke="" strokeLinecap="round" className={cx("transition-colors ease-linear", background())} /> {safeValue >= 0 ? ( <circle r={normalizedRadius} cx={radius} cy={radius} strokeWidth={strokeWidth} strokeDasharray={`${circumference} ${circumference}`} strokeDashoffset={offset} fill="transparent" stroke="" strokeLinecap="round" className={cx( "transition-colors ease-linear", circle(), showAnimation && "transform-gpu transition-all duration-300 ease-in-out", )} /> ) : null} </svg> <div className={cx("absolute inset-0 flex items-center justify-center")} > {children} </div> </div> ) },) ProgressCircle.displayName = "ProgressCircle" export { ProgressCircle, type ProgressCircleProps }
Example
The ProgressCircle accepts input values ranging from 0 to 100, where 100 represents 100 percent. If no data is available or if value is equal to zero, the progress indicator is not displayed, leaving only the background.
import { ProgressCircle } from "@/components/ProgressCircle"
export const ProgressCircleExample = () => ( <div className="flex flex-wrap justify-center gap-12"> <ProgressCircle /> <ProgressCircle value={62} /> </div>)
Example with variants
There are five variants.
Default
Neutral
Warning
Success
Error
import { ProgressCircle } from '@/components/ProgressCircle'
export const ProgressCircleVariantExample = () => ( <div className="flex flex-wrap justify-center gap-8"> <ProgressCircle variant="default" value={62} radius={50}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50">Default</span> </ProgressCircle> <ProgressCircle variant="neutral" value={62} radius={50}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50">Neutral</span> </ProgressCircle> <ProgressCircle variant="warning" value={62} radius={50}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50">Warning</span> </ProgressCircle> <ProgressCircle variant="success" value={62} radius={50}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50">Success</span> </ProgressCircle> <ProgressCircle variant="error" value={62} radius={50}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50">Error</span> </ProgressCircle> </div>)
Example with Children
The component allows the addition of children.
75%
$340/$450
Spend management control
import { ProgressCircle } from '@/components/ProgressCircle';
export const ProgressCircleChildrenExample = () => ( <div className="flex items-center justify-center gap-x-5"> <ProgressCircle value={75}> <span className="text-sm font-medium text-gray-900 dark:text-gray-50"> 75% </span> </ProgressCircle> <div> <p className="text-sm font-medium text-gray-900 dark:text-gray-50"> $340/$450 </p> <p className="text-sm text-gray-500 dark:text-gray-500"> Spend management control </p> </div> </div>)
Example with custom strokeWidth and radius
import { ProgressCircle } from '@/components/ProgressCircle';
export function ProgressCircleSizeExample() { return ( <div className="flex flex-wrap items-center justify-center gap-6"> <ProgressCircle value={72} radius={16} strokeWidth={4} /> <ProgressCircle value={72} radius={25} strokeWidth={6} /> <ProgressCircle value={72} radius={40} strokeWidth={10} /> <ProgressCircle value={72} radius={45} strokeWidth={5} /> <ProgressCircle value={72} radius={50} strokeWidth={8} /> </div> )}
API Reference: ProgressCircle
- value
- Sets the value of the progress indicator.
number
Default: 0
- variant
- Set a predefined look.
"default" | "neutral" | "warning" | "error" | "success"
Default: "default"
- radius
- Set radius of the progress circle.
number
Default: 32
- strokeWidth
- Set stroke width of the progress circle.
number
Default: 6
- showAnimation
- Sets an animation to the chart when value changes.
boolean
Default: true
- max
- Sets the upper boundary vale of the Progess Circle.
number
Default: 100
- children
- Accept and render child components.
React.ReactNode;