Progress
Communicates determinate completion or an indeterminate operation in progress.
Playground
valueSets completed work before clamping to the valid range.
maxSets the positive total used to calculate completion.
indeterminateMakes this example pass a null value when completion is unknown.
schemeSets the indicator color.
Usage
import { Progress } from "earthling-ui/progress";
export function Example() {
return (
<>
<Progress aria-label="Uploading assets" max={100} value={64} />
</>
);
}
- Provide an accessible label that names the operation rather than repeating a percentage.
- Set value to null for indeterminate work; finite values are clamped between zero and max.
- Pair long-running progress with nearby text so completion remains understandable without color.
Installation
Start with the project setup for React and Tailwind CSS 4. Both paths use the same component and theme.
npm install earthling-uiUse the component import shown above. Package updates keep the implementation current.
API reference
Declarations from the current library build, including inherited primitive props. Playground controls above show selected options; they are not the complete API.
// Generated by dts-bundle-generator v9.5.1
import * as ProgressPrimitive from '@radix-ui/react-progress';
import { VariantProps } from 'class-variance-authority';
import { ComponentPropsWithoutRef } from 'react';
export declare const progressVariants: (props?: ({
scheme?: "default" | "primary" | "secondary" | "tertiary" | "neutral" | "muted" | "good" | "caution" | "bad" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
export interface ProgressProps extends ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>, VariantProps<typeof progressVariants> {
}
export declare const Progress: import("react").ForwardRefExoticComponent<ProgressProps & import("react").RefAttributes<HTMLDivElement>>;
export {};Runtime dependencies: @radix-ui/react-progress, class-variance-authority, cnfast.
Source
Use the eject command to copy this implementation with its required helpers and project-specific imports.
View Progress implementation
"use client";
import {
type ComponentPropsWithoutRef,
type ComponentRef,
forwardRef,
} from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "@/utils/cn";
import { schemes } from "@/utils/variants";
import { cva, type VariantProps } from "class-variance-authority";
const progressVariants = cva(
"relative h-2 w-full overflow-hidden rounded-full bg-muted",
{
variants: {
scheme: schemes,
},
defaultVariants: { scheme: "default" },
},
);
export interface ProgressProps
extends
ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>,
VariantProps<typeof progressVariants> {}
const Progress = forwardRef<
ComponentRef<typeof ProgressPrimitive.Root>,
ProgressProps
>(({ className, value, max = 100, scheme, ...props }, ref) => {
const normalizedMax = Number.isFinite(max) && max > 0 ? max : 100;
const normalizedValue =
value == null || !Number.isFinite(value)
? null
: Math.min(Math.max(value, 0), normalizedMax);
const percentage =
normalizedValue === null ? null : (normalizedValue / normalizedMax) * 100;
return (
<ProgressPrimitive.Root
ref={ref}
value={normalizedValue}
max={normalizedMax}
className={cn(progressVariants({ scheme }), className)}
{...props}
>
<ProgressPrimitive.Indicator
className="h-full w-full bg-(--scheme-tint) transition-transform duration-300 ease-out data-[state=indeterminate]:w-1/2 data-[state=indeterminate]:translate-x-1/2 data-[state=indeterminate]:animate-pulse motion-reduce:animate-none motion-reduce:transition-none"
style={
percentage === null
? undefined
: { transform: `translateX(-${100 - percentage}%)` }
}
/>
</ProgressPrimitive.Root>
);
});
Progress.displayName = ProgressPrimitive.Root.displayName;
export { Progress, progressVariants };