Progress
A visual indicator showing the completion status of a task or operation.
Overview
The Progress component shows completion for a task or operation. Use the linear progress component for standard flows, ProgressCircle for compact circular status, and ProgressRadial for gauge-style displays.
Progress tracks are surface-aware. The track lands four levels above its parent surface and the indicator uses the default brand fill.
Usage
import {
Progress,
ProgressCircle,
ProgressRadial,
ProgressValue,
} from "@tilt-legal/cubitt-components/progress";<Progress value={45}>
<ProgressValue />
</Progress>
<ProgressCircle value={75} showValue />
<ProgressRadial value={60} startAngle={180} endAngle={360} showValue />Examples
With Value
Show the formatted value under the linear progress track.
"use client";
import { useEffect, useState } from "react";
import {
Progress,
ProgressValue,
} from "@tilt-legal/cubitt-components/progress";
export default function Example() {
const [progress, setProgress] = useState(13);
useEffect(() => {
const timer = setTimeout(() => {
setProgress(66);
}, 500);
return () => {
clearTimeout(timer);
};
}, []);
return (
<div className="w-80 space-y-2">
<Progress value={progress}>
<ProgressValue />
</Progress>
</div>
);
}Sizes
Adjust the track height with className.
"use client";
import { useEffect, useState } from "react";
import { Progress } from "@tilt-legal/cubitt-components/progress";
export default function Example() {
const [progress, setProgress] = useState(13);
useEffect(() => {
const timer = setTimeout(() => {
setProgress(66);
}, 500);
return () => {
clearTimeout(timer);
};
}, []);
return (
<div className="w-80 space-y-6">
<div className="space-y-2">
<p className="text-fg-2 text-sm">Small</p>
<Progress className="h-1" value={progress} />
</div>
<div className="space-y-2">
<p className="text-fg-2 text-sm">Default</p>
<Progress value={progress} />
</div>
<div className="space-y-2">
<p className="text-fg-2 text-sm">Large</p>
<Progress className="h-2.5" value={progress} />
</div>
</div>
);
}Animated
Animate progress value changes over time.
"use client";
import { useEffect, useState } from "react";
import {
Progress,
ProgressValue,
} from "@tilt-legal/cubitt-components/progress";
export default function Example() {
const [progress, setProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setProgress((current) => (current >= 100 ? 0 : current + 10));
}, 500);
return () => {
clearInterval(timer);
};
}, []);
return (
<div className="w-80 space-y-2">
<Progress value={progress}>
<ProgressValue />
</Progress>
</div>
);
}With Status
Show contextual status text alongside progress changes.
"use client";
import { useEffect, useState } from "react";
import { Progress } from "@tilt-legal/cubitt-components/progress";
function getStatusMessage(progress: number): string {
if (progress < 5) return "Initializing download...";
if (progress < 15) return "Setting up environment...";
if (progress < 25) return "Connecting to server...";
if (progress < 35) return "Verifying permissions...";
if (progress < 50) return "Downloading core files...";
if (progress < 65) return "Downloading assets...";
if (progress < 80) return "Downloading dependencies...";
if (progress < 90) return "Extracting files...";
if (progress < 95) return "Validating integrity...";
if (progress < 100) return "Finalizing installation...";
return "Download complete!";
}
export default function Example() {
const [downloadProgress, setDownloadProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setDownloadProgress((current) => {
if (current >= 100) {
return 0;
}
return current + Math.random() * 3 + 1;
});
}, 150);
return () => {
clearInterval(timer);
};
}, []);
return (
<div className="w-80 space-y-2">
<div className="flex justify-between text-sm">
<span>Workspace Setup</span>
<span className="text-fg-2">{Math.round(downloadProgress)}%</span>
</div>
<Progress value={downloadProgress} />
<div className="text-fg-2 text-xs">
{getStatusMessage(downloadProgress)}
</div>
</div>
);
}Circular Progress
Show progress as a full circle with custom center content.
"use client";
import { useEffect, useState } from "react";
import { ProgressCircle } from "@tilt-legal/cubitt-components/progress";
export default function Example() {
const [cpuUsage, setCpuUsage] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCpuUsage((current) => {
const target =
30 +
Math.sin(Date.now() / 3000) * 20 +
Math.random() * 15;
return current + (target - current) * 0.1;
});
}, 100);
return () => {
clearInterval(timer);
};
}, []);
return (
<div className="flex flex-col items-center gap-3">
<ProgressCircle size={80} strokeWidth={6} value={cpuUsage}>
<div className="text-center">
<div className="font-bold text-base">{Math.round(cpuUsage)}%</div>
<div className="text-fg-2 text-xs">CPU</div>
</div>
</ProgressCircle>
<span className="text-fg-2 text-xs">Processor Usage</span>
</div>
);
}Radial Progress
Show progress as a partial arc with custom angles.
"use client";
import { useEffect, useState } from "react";
import { ProgressRadial } from "@tilt-legal/cubitt-components/progress";
export default function Example() {
const [taskProgress, setTaskProgress] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setTaskProgress((current) => {
if (current >= 100) {
return 0;
}
return current + Math.random() * 2 + 0.5;
});
}, 200);
return () => {
clearInterval(timer);
};
}, []);
return (
<div className="flex flex-col items-center gap-3">
<ProgressRadial
endAngle={360}
size={80}
startAngle={180}
strokeWidth={5}
value={taskProgress}
>
<div className="text-center">
<div className="font-bold text-base">
{Math.round(taskProgress)}%
</div>
<div className="text-fg-2 text-xs">Upload</div>
</div>
</ProgressRadial>
<span className="text-fg-2 text-xs">Upload Status</span>
</div>
);
}API Reference
Progress
The accessible linear progress root.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | — | Current progress value. Use null for indeterminate progress. |
min | number | 0 | The minimum value. |
max | number | 100 | The maximum value. |
getAriaValueText | (formatted, value) => string | — | Function returning human-readable text for the current value. |
aria-valuetext | string | — | String value that provides a user-friendly name for the current value. |
locale | Intl.LocalesArgument | — | Locale used by Intl.NumberFormat when formatting the value. |
format | Intl.NumberFormatOptions | — | Number formatting options for the value. |
className | string | (state) => string | — | Classes applied to the progress track, commonly used for height. |
render | ReactElement | (props) => ReactElement | — | Allows composing the root with another element. Receives props to spread. |
children | ReactNode | — | Child elements, typically ProgressValue. |
ProgressValue
Displays the formatted progress value for linear progress.
| Prop | Type | Description |
|---|---|---|
className | string | (state) => string | CSS classes or function that returns classes based on component state. |
render | ReactElement | (props) => ReactElement | Allows composing the component with another element. Receives props to spread. |
ProgressCircle
Circular progress indicator built with SVG.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | 0 | Progress value from 0 to 100. null and 0 are indeterminate. |
size | number | 48 | Size of the circle in pixels. |
strokeWidth | number | 4 | Width of the progress stroke. |
showValue | boolean | false | Whether to show the percentage value in the center. |
indicatorClassName | string | — | Additional className for the progress indicator stroke. |
trackClassName | string | — | Additional className for the progress track. |
className | string | — | Additional CSS classes for the container. |
children | ReactNode | — | Custom content to display in the center. Overrides showValue. |
ProgressRadial
Radial progress indicator built with SVG.
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | null | 0 | Progress value from 0 to 100. null and 0 are indeterminate. |
size | number | 120 | Size of the radial in pixels. |
strokeWidth | number | 8 | Width of the progress stroke. |
startAngle | number | -90 | Start angle in degrees. |
endAngle | number | 90 | End angle in degrees. |
showValue | boolean | false | Whether to show the percentage value in the center. |
indicatorClassName | string | — | Additional className for the progress indicator stroke. |
trackClassName | string | — | Additional className for the progress track. |
className | string | — | Additional CSS classes for the container. |
children | ReactNode | — | Custom content to display in the center. Overrides showValue. |