Skip to main content

Progress

Show task completion. Manage user expectations. Reduce abandonment.

Storage

6.4 GB of 10 GB

Backups and build artifacts count toward this limit.

1import { Progress } from '@/components/ui/progress';
2
3export function Default() {
4 return (
5 <div className="border-border bg-card w-full max-w-sm rounded-xl border p-5">
6 <div className="flex items-baseline justify-between">
7 <p className="text-sm font-medium">Storage</p>
8 <p className="text-muted-foreground text-xs">6.4 GB of 10 GB</p>
9 </div>
10 <Progress value={64} className="mt-3" />
11 <p className="text-muted-foreground mt-3 text-xs">
12 Backups and build artifacts count toward this limit.
13 </p>
14 </div>
15 );
16}

Installation

pnpm dlx nachui add progress

Anatomy

1import { Progress } from '@/components/ui/progress';
1<Progress value={33} />

Variants

Default

Storage

6.4 GB of 10 GB

Backups and build artifacts count toward this limit.

1import { Progress } from '@/components/ui/progress';
2
3export function Default() {
4 return (
5 <div className="border-border bg-card w-full max-w-sm rounded-xl border p-5">
6 <div className="flex items-baseline justify-between">
7 <p className="text-sm font-medium">Storage</p>
8 <p className="text-muted-foreground text-xs">6.4 GB of 10 GB</p>
9 </div>
10 <Progress value={64} className="mt-3" />
11 <p className="text-muted-foreground mt-3 text-xs">
12 Backups and build artifacts count toward this limit.
13 </p>
14 </div>
15 );
16}

Indeterminate

When the progress value is missing or undefined, the bar animates infinitely to show an unknown duration process.

Importing contacts from HubSpot

We do not know the total yet, so this bar keeps moving until the import finishes.

You can close this page, we will email you when it is done.

1import { Progress } from '@/components/ui/progress';
2
3export function Indeterminate() {
4 return (
5 <div className="border-border bg-card w-full max-w-sm rounded-xl border p-5">
6 <p className="text-sm font-medium">Importing contacts from HubSpot</p>
7 <p className="text-muted-foreground mt-1 text-xs">
8 We do not know the total yet, so this bar keeps moving until the import finishes.
9 </p>
10 <Progress className="mt-4" />
11 <p className="text-muted-foreground mt-3 text-xs">
12 You can close this page, we will email you when it is done.
13 </p>
14 </div>
15 );
16}

With Value Display

Combine the component with custom value labels.

q3-report.pdf

12%

3.0 MB of 24.6 MB uploaded

1'use client';
2
3import * as React from 'react';
4
5import { cn } from '@/lib/cn';
6import { Progress } from '@/components/ui/progress';
7
8const TOTAL_MB = 24.6;
9
10export function WithValue() {
11 const [percent, setPercent] = React.useState(12);
12
13 React.useEffect(() => {
14 if (percent >= 100) return;
15 const timer = setTimeout(() => setPercent((current) => Math.min(current + 11, 100)), 700);
16 return () => clearTimeout(timer);
17 }, [percent]);
18
19 const done = percent >= 100;
20 const uploaded = ((TOTAL_MB * percent) / 100).toFixed(1);
21
22 return (
23 <div className="border-border bg-card w-full max-w-sm rounded-xl border p-5">
24 <div className="flex items-baseline justify-between gap-3">
25 <p className="truncate text-sm font-medium">q3-report.pdf</p>
26 <p className="text-muted-foreground shrink-0 text-xs">{percent}%</p>
27 </div>
28 <Progress value={percent} max={100} className="mt-3" />
29 <p className={cn('mt-3 text-xs', done ? 'text-success-text' : 'text-muted-foreground')}>
30 {done ? 'Upload complete, ready to share' : `${uploaded} MB of ${TOTAL_MB} MB uploaded`}
31 </p>
32 </div>
33 );
34}

API Reference

Progress

PropTypeDefaultDescription
valuenumber | null-The progress value (shows indeterminate if null/missing)
maxnumber100The maximum value of the progress bar
classNamestring-Additional CSS classes
Found something to improve?

Notice a bug, typo, or missing detail on this page? Help us make the documentation better by opening a GitHub issue.

Create an Issue
Ctrl+I