覆蓋層與回饋

Circular Progress

動畫百分比環形進度/量表,支援漸層、gauge 弧度與計數揭示。

以 SVG 環形呈現進度,弧線與中央數字由單一動畫節奏同步推進,支援完整環或量表 gauge。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add circular-progress

還沒有專案,或安裝遇到問題?看快速開始 →

Circular Progress 是用 React、SVG 與 Motion 做的圓形進度條(環形進度、圓環百分比)元件:進度弧與中央數字由同一個動畫值驅動,支援漸層色、端點圓頭與柔光,把 arc 調小於 360 就能當成半圓或 270 度的量表。

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

72
160
12
360
編輯中的呼叫預設屬性
<CircularProgress/>

完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。

適用情境

  • 上傳、匯出、批次處理這類有明確百分比的任務進度
  • 帳號設定或新手引導的「完成度」指標
  • 方案用量、儲存空間、配額使用率的摘要卡片
  • 儀表板上的 KPI 達成率
  • 不適合:需要刻度、指針與色段分區的儀表,改用 Gauge Meter

安裝

npx webberui@latest add https://webberui.com/r/circular-progress.json

或在 components.json 設定 registries 後,改用 @webberui/circular-progress 安裝。

使用

import { CircularProgress } from "@/components/ui/circular-progress";

<CircularProgress value={72} />;

做成量表 gauge:把 arc 設成小於 360,再用 startAngle 對齊開口方向。

<CircularProgress value={86} arc={270} startAngle={135} />;

範例

隨上傳進度更新

value 改變時,弧線與數字會從目前的值補間到新的值,不會從 0 重來,可以直接接進度事件。

"use client";

import * as React from "react";
import { CircularProgress } from "@/components/ui/circular-progress";

export function UploadProgress({ file }: { file: File }) {
  const [percent, setPercent] = React.useState(0);

  React.useEffect(() => {
    const xhr = new XMLHttpRequest();
    xhr.upload.onprogress = (e) => {
      if (e.lengthComputable) setPercent((e.loaded / e.total) * 100);
    };
    xhr.open("POST", "/api/upload");
    xhr.send(file);
    return () => xhr.abort();
  }, [file]);

  return <CircularProgress value={percent} size={120} duration={0.4} decimals={0} />;
}

中央改放自訂內容

傳入 children 會取代預設的百分比數字,適合顯示「3 / 5 步」這類非百分比資訊;value 仍需換算成 0 到 100。

<CircularProgress value={(3 / 5) * 100} size={140} strokeWidth={10}>
  <span className="text-2xl font-semibold">3 / 5</span>
  <span className="text-xs text-neutral-500">設定步驟</span>
</CircularProgress>

單色加柔光的儲存空間用量

color 傳字串就是單色,glow 會用同一個顏色加上 drop-shadow 柔光;trackColor 自訂底軌。

<CircularProgress
  value={82.4}
  decimals={1}
  color="#f97316"
  trackColor="#fed7aa"
  glow
  rounded={false}
/>

Props

Prop型別預設值說明
valuenumber—進度百分比(0 ~ 100)
sizenumber160元件邊長(px)
strokeWidthnumber12環的線寬(px)
colorstring | string[]青靛洋紅漸層單色字串或沿弧線的漸層陣列
trackColorstringcurrentColor 低透明底軌顏色
arcnumber360弧線總跨度(度),小於 360 即為量表
startAnglenumber-90起始角度(度),-90 為正上方
durationnumber1.2進場動畫時長(秒)
delaynumber0進場前延遲(秒)
roundedbooleantrue端點是否為圓頭
showValuebooleantrue是否顯示中央百分比數字
decimalsnumber0數字小數位數
suffixstring"%"數字後綴
glowbooleanfalse為進度弧加上同色柔光
childrenReactNode—中央自訂內容,覆蓋預設數字

可及性

  • 使用者系統開啟「減少動態效果」時,直接以最終值渲染,不播放計數與掃描動畫
  • svg 帶 role="img" 與 aria-label,朗讀時報出目前百分比

常見問題

可以在 Next.js App Router 使用嗎?

可以。原始碼已經有 "use client",在 Server Component 頁面直接 import 即可。伺服器端與首次渲染會先輸出 0,掛載後才播放到目標值。

超過 100 或小於 0 的值會怎樣?

value 會被夾在 0 到 100 之間,NaN 視為 0,所以弧線與數字不會溢出。

漸層的方向可以調整嗎?

陣列形式的 color 會建立一條從左上到右下的 linearGradient,顏色依陣列順序平均分佈,方向本身沒有開放成 prop。需要不同方向時,可以直接修改原始碼裡的 x1、y1、x2、y2。

螢幕閱讀器會怎麼讀?

svg 帶有 role="img" 與 aria-label,內容是目標值加上 suffix,例如「72%」。系統開啟「減少動態效果」時,直接顯示最終值,不播放動畫。

需要哪些依賴?

motion、clsx、tailwind-merge,以及 @/lib/utils 的 cn。不使用 CLI 時,切到「手動」分頁複製原始碼即可。