For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. An agent skill is available at /.well-known/agent-skills/site-skill.md.
Home

Progress

A horizontal bar that visualises completion of a task or process.

Uploading…0%
import { useEffect, useState } from "react";
import { Progress } from "@/components/ui/progress";

export const ProgressDemo = () => {
  const [value, setValue] = useState(0);

  useEffect(() => {
    const timer = setTimeout(() => setValue(68), 300);
    return () => clearTimeout(timer);
  }, []);

  return (
    <div className="flex w-full max-w-sm flex-col gap-6">
      {/* Animated on mount */}
      <div className="flex flex-col gap-1.5">
        <div className="flex justify-between text-sm">
          <span className="text-muted-foreground">Uploading…</span>
          <span className="font-medium">{value}%</span>
        </div>
        <Progress value={value} />
      </div>
      {/* Fixed values */}
      <div className="flex flex-col gap-3">
        <Progress value={0} />
        <Progress value={25} />
        <Progress value={50} />
        <Progress value={75} />
        <Progress value={100} />
      </div>
      {/* Thick */}
      <Progress value={42} className="h-3" />
    </div>
  );
};

With label

Pair with a label row above for a named progress indicator.

<div className="flex flex-col gap-1.5">
  <div className="flex justify-between text-sm">
    <span className="text-muted-foreground">Uploading…</span>
    <span className="font-medium">68%</span>
  </div>
  <Progress value={68} />
</div>

Animated value

Drive the value prop from state. The indicator transitions smoothly via transition-all.

"use client";
 
const [progress, setProgress] = useState(0);
 
useEffect(() => {
  const timer = setTimeout(() => setProgress(68), 300);
  return () => clearTimeout(timer);
}, []);
 
<Progress value={progress} />

Indeterminate

Omit value (or pass null) to show an indeterminate state — Radix sets aria-valuenow to null and data-state="indeterminate".

<Progress />

Custom height

Override h-2 (default) on the root.

<Progress value={60} className="h-1" />   {/* slim */}
<Progress value={60} className="h-3" />   {/* thick */}

Custom colors

Target the root and indicator separately. The indicator inherits bg-primary — override on the root's [&>[data-slot=progress-indicator]] selector or apply inline style.

{/* Muted track, green fill */}
<Progress
  value={80}
  className="bg-green-100 dark:bg-green-950 [&>[data-slot=progress-indicator]]:bg-green-500"
/>

Props

Progress

Extends all Radix Progress.Root props.
PropTypeDefaultDescription
valuenumber | nullnullCurrent value (0–100). null = indeterminate
maxnumber100Maximum value
classNamestring—Applied to the track. Default height h-2

Usage

import { Progress } from "@/components/ui/progress";
 
<Progress value={60} />

Specs

# Mint — Progress Specs
 
## Component
- name: progress
- file: registry/mint/progress.tsx
- installs to: components/ui/progress.tsx
- dependencies: radix-ui
- registryDependencies: none
 
## What is it
A horizontal bar that visualises the completion of a task or process. Use it
for file uploads, multi-step flows, or any operation with a measurable
percentage. Prefer Progress over a spinner when a numeric value is available;
omit `value` for indeterminate states where progress cannot be measured.
 
## Visual identity
Full-width, pill-shaped track (rounded-full) with a thin 8 px default height.
The track uses a 20 % opacity tint of --primary, giving a soft mint-green
contrast against the solid --primary indicator — fresh and vivid in Mint.
 
## Design tokens
--primary: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)   — indicator fill and track tint base
 
## Sub-components
- Progress    → root track element (h-2, rounded-full, bg-primary/20, overflow-hidden)
- Indicator   → inner fill bar (h-full, bg-primary, transition-all, translateX transform)
 
## States
- determinate:    value 0–100 drives translateX(-${100 - value}%) on the indicator
- indeterminate:  value=null → Radix sets data-state="indeterminate" and omits aria-valuenow; indicator rests at translateX(-100%) (hidden); no built-in animation — add a custom keyframe if a looping animation is needed
 
## Conventions
- Default height is h-2 (8 px); override on the root with h-1 (slim) or h-3 (thick) via className
- Override the indicator colour with [&>[data-slot=progress-indicator]]:bg-{color} on the root
- Always pair with a visible label or aria-label when used in isolation (Radix does not add one automatically)
- Sub-components expose data-slot="progress" and data-slot="progress-indicator" for CSS targeting
- value accepts 0–100; values outside that range are not clamped by the component — clamp in consuming code

Installation

GIN Design Plugin
$ npx shadcn add https://gin-design.vercel.app/progress