ഉള്ളടക്കത്തിലേക്ക് പോകുക
ബീറ്റ · പരീക്ഷണാത്മകംReact 19പിയർ ഡിപൻഡൻസികളില്ല

Progress

A bar or a ring for work with a known end, where an unknown length is a different thing from zero.

ബീറ്റ കമ്പോണന്റുകൾ മാറാൻ സാധ്യതയുണ്ട്; അവ നിങ്ങളുടെ കോഡ് തകരാറിലാക്കിയേക്കാം. സ്വന്തം ഉത്തരവാദിത്തത്തിൽ ഉപയോഗിക്കുക, ബഗ് ട്രാക്കർ വഴി അഭിപ്രായം അറിയിക്കുക.

ഈ പേജ് ഇതുവരെ വിവർത്തനം ചെയ്തിട്ടില്ല, അതിനാൽ ഇംഗ്ലീഷ് പതിപ്പാണ് താഴെ കാണിക്കുന്നത്.
ഈ പേജിൽ

Installation

npx gbs-add-block@latest -a Progress -beta

The block copies the progress folder into your project, along with the small shared folder that every component imports. You own the code and can change it freely. There are no peer dependencies other than React.

Requirements

  • React 19 and @types/react 19
  • TypeScript target ES2022 or newer, with "jsx": "react-jsx"
  • Browsers from 2024 or newer (the styles use light-dark() and color-mix())

Import the stylesheet once, for example in your global CSS:

css
@import "../components/progress/styles.css";

or in your root layout / entry file:

ts
import "@/components/progress/styles.css";

Progress is a bar for something with a known end: an upload, an import, a quota, a wizard. CircularProgress is the same thing as a ring, for a tile or a table cell where a bar would be too wide.

Set the --gbs-* variables on :root to theme every component at once, the grid included. Each component's own variables fall back to them, and then to the built-in palette, so components look identical out of the box.

Default

Live preview

Quick Start

tsx
import { CircularProgress, Progress } from "@/components/progress";
 
<Progress label="Uploading report.pdf" value={62} showValue />
<CircularProgress value={62} size={56} showValue />

Unknown is not zero

tsx
<Progress value={null} label="Preparing export" />

value={null} says the length is not known yet. The bar sweeps instead of filling, and — the part that matters — aria-valuenow is left off the element entirely. That absence is what makes a screen reader say "busy" rather than announcing a task that is 0% done and apparently stuck.

Use a Spinner when there is nothing to measure at all and never will be. A progress bar that spends its whole life indeterminate is a spinner drawn as a promise it cannot keep.

Props Table

Progress

Accepts every <div> attribute, plus:

PropTypeDefaultDescription
valuenumber | nullnullHow far along. null means the length is unknown.
maxnumber100What value is measured against.
labelReactNodeShown above the bar, and used as its accessible name.
showValuebooleanfalseShow the percentage beside the label.
valueTextReactNodeReplace what is shown and read: "3.2 MB of 8 MB".
variant"accent" | "success" | "warning" | "danger""accent"
size"sm" | "md" | "lg""md"Track 4 / 8 / 12 px.
classNamesPartial<Record<ProgressSlot, string>>root header label value track bar
localeTextPartial<ProgressLocaleText>label, valueText(percent), working

CircularProgress

The same value props, plus size in pixels (default 44), thickness (default 4), label, and showValue or children for the middle.

Accessibility

The visible label names the bar through aria-labelledby, so the name and what is on screen can never drift apart. Without one, the bar falls back to aria-label or the locale's word for "Progress".

aria-valuetext carries the formatted string — "9.2 GB of 10 GB" rather than "92" — whenever valueText or showValue gives one.

A bar that updates several times a second will flood a screen reader, because every change to aria-valuenow is announced. For a fast upload, update the value on a timer a few times a second rather than on every progress event.

Styling and Theming

All rules are in the CSS components layer, so utility classes passed through className override them.

The bar is drawn with scale: var(--pr-fraction) 1 rather than a width in percent, so it animates on the compositor: a bar ticking up every few milliseconds costs nothing in layout. The fraction is unrounded, so a 99.6% bar does not snap to full while the last bytes are still moving, even though the label says 100%.

VariableUsed for
--pr-barThe filled part. Set by variant.
--pr-trackThe groove.
--pr-heightBar thickness (set by size).
--pr-durationHow long a change takes to animate (240ms).

Under prefers-reduced-motion the transitions go and the indeterminate sweep slows rather than stopping — a frozen indeterminate bar looks broken.

Data attributes

ElementAttributes
Root (.pr-root)data-variant, data-size, data-indeterminate
Ring (.pr-circle)data-variant, data-indeterminate

Headless Use

ExportDescription
describeProgress(value, max?){ indeterminate, value, fraction, percent }, clamped and safe.
stepFraction(step, total)A wizard's fraction: step 2 of 5 is 0.4.

describeProgress is where a max of zero stops being a division by zero shown as NaN%, and where a value outside the range is clamped rather than drawn past the end.

Next.js

Neither component has state, and both render on the server — so a quota bar on a server-rendered dashboard paints filled, with no hydration flash.

Notes

  • The ring is one circle with a dashed stroke, not an arc path, so it scales with size without any trigonometry.
  • CircularProgress centres whatever children it is given, which is a handy place for an icon once the task is finished.