Statuses

Progress Circle

A modern circular progress indicator designed for visually representing task completion, downloads, or loading animations.

Basic

Progress bars show how much an operation is done, either exactly or roughly, over time.

Installation

If you hit any issues, make sure you check out the installation guide here for more information.

npx @intentui/cli@latest add progress-circle

Manual installation

Make sure you also install the composed components and the required packages for the component to function properly.

npm i react-aria-components

You can copy the code below and paste it into your component folder.

progress-circle.tsx
"use client"

import { ProgressBar, type ProgressBarProps } from "react-aria-components"
import { twMerge } from "tailwind-merge"

interface ProgressCircleProps extends Omit<ProgressBarProps, "className"> {
  className?: string
  ref?: React.RefObject<HTMLDivElement>
}

const ProgressCircle = ({ className, ref, ...props }: ProgressCircleProps) => {
  const c = "50%"
  const r = "calc(50% - 2px)"
  return (
    <ProgressBar {...props} ref={ref}>
      {({ percentage, isIndeterminate }) => (
        <svg
          className={twMerge("size-4 shrink-0", className)}
          viewBox="0 0 24 24"
          fill="none"
          data-slot="icon"
        >
          <circle cx={c} cy={c} r={r} strokeWidth={3} stroke="currentColor" strokeOpacity={0.25} />
          {!isIndeterminate ? (
            <circle
              cx={c}
              cy={c}
              r={r}
              strokeWidth={3}
              stroke="currentColor"
              pathLength={100}
              strokeDasharray="100 200"
              strokeDashoffset={100 - (percentage ?? 0)}
              strokeLinecap="round"
              transform="rotate(-90)"
              className="origin-center"
            />
          ) : (
            <circle
              cx={c}
              cy={c}
              r={r}
              strokeWidth={3}
              stroke="currentColor"
              pathLength={100}
              strokeDasharray="100 200"
              strokeDashoffset={100 - 30}
              strokeLinecap="round"
              className="origin-center animate-[spin_1s_cubic-bezier(0.4,_0,_0.2,_1)_infinite]"
            />
          )}
        </svg>
      )}
    </ProgressBar>
  )
}

export type { ProgressCircleProps }
export { ProgressCircle }

Anatomy

Import the components and use them as shown below, adapting the structure to fit each component.

import { ProgressCircle } from "@/components/ui/progress-circle"
<ProgressCircle aria-label="Loading…" value={25

Indeterminate

You can also make the progress circle indeterminate by setting the isIndeterminate prop.

Custom Size

You can customize the size of the progress circle by using className with tailwind classes or style props.

Controlled

You can control the progress circle by using the value prop.

10

Combine with button

The button includes an isPending prop to indicate a pending state, allowing for seamless integration with the progress circle.

Custom color

The progress circle can be customized with the color prop.

Flexible blocks and templates
Use ready-made blocks to craft unique pages without starting from scratch.
blocks.intentui.com