Bloom Logo

Progress

Linear progress bar indicating completion status of a process or task.

progress.tsx

Progress bar built with Radix Primitive supporting colors, sizes, indeterminate state, and labels.

ReactRadix UITailwindUI ComponentProgress
"use client";

import * as React from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "@/lib/utils";
import { designColors } from "@/lib/design-system";

export interface ProgressProps
  extends React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> {
  value?: number;
  size?: "sm" | "md" | "lg";
  color?: keyof typeof designColors;
  isIndeterminate?: boolean;
  label?: string;
  showValueLabel?: boolean;
}

const progressSizes = {
  sm: "h-1.5",
  md: "h-2.5",
  lg: "h-4",
};

const progressColors = {
  default: "bg-foreground",
  primary: "bg-primary",
  secondary: "bg-secondary",
  accent: "bg-accent",
  success: "bg-emerald-500",
  warning: "bg-amber-500",
  danger: "bg-rose-500",
};

const Progress = React.forwardRef<
  React.ElementRef<typeof ProgressPrimitive.Root>,
  ProgressProps
>(
  (
    {
      className,
      value = 0,
      size = "md",
      color = "primary",
      isIndeterminate = false,
      label,
      showValueLabel = false,
      ...props
    },
    ref
  ) => {
    const clampedValue = Math.min(100, Math.max(0, value));

    return (
      <div className="w-full space-y-1.5">
        {(label || showValueLabel) && (
          <div className="flex items-center justify-between text-sm font-medium text-foreground">
            {label ? <span>{label}</span> : <span />}
            {showValueLabel && !isIndeterminate && (
              <span className="text-xs text-muted-foreground">{Math.round(clampedValue)}%</span>
            )}
          </div>
        )}

        <ProgressPrimitive.Root
          ref={ref}
          aria-label={label || "Progress bar"}
          value={isIndeterminate ? undefined : clampedValue}
          className={cn(
            "relative w-full overflow-hidden rounded-full bg-muted/60 shrink-0",
            progressSizes[size],
            className
          )}
          {...props}
        >
          <ProgressPrimitive.Indicator
            className={cn(
              "h-full w-full flex-1 transition-all duration-300 ease-in-out rounded-full",
              progressColors[color],
              isIndeterminate && "animate-progress-indeterminate origin-left"
            )}
            style={
              isIndeterminate
                ? undefined
                : { transform: `translateX(-${100 - clampedValue}%)` }
            }
          />
        </ProgressPrimitive.Root>
      </div>
    );
  }
);

Progress.displayName = "Progress";

export { Progress };

Basic Usage

Displays a progress bar with a numeric percentage value from 0 to 100.

value: number

Colors

Apply custom color themes using the color prop.

color: default | primary | secondary | accent | success | warning | danger

Sizes

Adjust the height scale using sm, md, or lg.

size: sm | md | lg

Labels & Value Display

Combine text description and numeric percentage with label and showValueLabel.

label: stringshowValueLabel: boolean
Uploading file...75%
Storage used100%

Animated Progress (0% to 100%)

Demonstrates a real-time animated progress simulation from 0% to 100% with restart capability.

Simulating download...0%

Indeterminate State

Set isIndeterminate for ongoing processes without a fixed completion percentage.

isIndeterminate: boolean
Fetching server status...
API Reference

Props — Progress

Properties for configuring the Progress component.

PropTypeDefaultDescription
valuenumber0Completion percentage value from 0 to 100.
size'sm' | 'md' | 'lg''md'Height dimension of the progress track.
color'default' | 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'danger''primary'Color theme fill of the indicator bar.
isIndeterminatebooleanfalseEnables animated continuous loading mode without fixed value.
labelstringOptional text label displayed above the progress bar.
showValueLabelbooleanfalseDisplays formatted percentage text on the top right.