shadcn.io is not affiliated with official shadcn/ui
Shadcn Progress for React and Tailwind
Displays task progress with a linear indicator.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/progress.jsonpnpm dlx shadcn@latest add https://kit.dev/r/progress.jsonnpx shadcn@latest add https://kit.dev/r/progress.jsonyarn shadcn@latest add https://kit.dev/r/progress.json<Step>This component depends on Field. Install it first if you haven't already.</Step>
Install the following dependencies:
bun add @ark-ui/reactpnpm add @ark-ui/reactnpm install @ark-ui/reactyarn add @ark-ui/reactAdd the following animations to your globals.css.
@theme inline {
--animate-indeterminate: indeterminate 1.5s ease-in-out infinite;
@keyframes indeterminate {
0% { transform: translateX(-100%); }
100% { transform: translateX(400%); }
}
}Copy and paste the following code into your project.
"use client";
import {
Progress as ArkProgress,
useProgressContext,
} from "@ark-ui/react/progress";
import type React from "react";
import { cn } from "@/lib/utils";
import { FieldLabel } from "@/components/ui/field";
export const useProgress = useProgressContext;
interface ProgressProps
extends Omit<React.ComponentProps<typeof ArkProgress.Root>, "value"> {
/**
* Shows indeterminate progress
*
* @default false
*/
indeterminate?: boolean;
/**
* The value of the progress bar
*
* @default 0
*/
value?: number;
}
export const Progress = (props: ProgressProps) => {
const {
value,
orientation = "horizontal",
indeterminate = false,
className,
children,
...rest
} = props;
return (
<ArkProgress.Root
className={cn(
"flex flex-wrap gap-3",
"data-[orientation=horizontal]:w-full",
"data-[orientation=vertical]:-scale-y-100",
className
)}
data-slot="progress"
orientation={orientation}
value={indeterminate ? null : value}
{...rest}
>
{children}
<ProgressTrack>
<ProgressRange />
</ProgressTrack>
</ArkProgress.Root>
);
};
export const ProgressTrack = (
props: React.ComponentProps<typeof ArkProgress.Track>
) => (
<ArkProgress.Track
className={cn(
"bg-input",
"rounded-full",
"overflow-x-hidden",
"data-[orientation=horizontal]:h-2 data-[orientation=horizontal]:w-full",
"data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2"
)}
data-slot="progress-track"
{...props}
/>
);
export const ProgressRange = (
props: React.ComponentProps<typeof ArkProgress.Range>
) => (
<ArkProgress.Range
className={cn(
"bg-primary",
"transition-all duration-300 ease-out",
"data-[orientation=horizontal]:h-full",
"data-[orientation=vertical]:h-full",
"motion-reduce:animate-none! motion-reduce:transition-none!",
"data-[state=indeterminate]:w-1/3 data-[state=indeterminate]:animate-indeterminate! data-[state=indeterminate]:duration-100"
)}
data-slot="progress-range"
{...props}
/>
);
export const ProgressValue = (
props: React.ComponentProps<typeof ArkProgress.ValueText>
) => {
const { className, ...rest } = props;
return (
<FieldLabel asChild>
<ArkProgress.ValueText
className={cn("ms-auto tabular-nums", className)}
data-slot="progress-value"
{...rest}
/>
</FieldLabel>
);
};Update the import paths to match your project setup.
Usage
import { Progress } from "@/components/ui/progress";<Progress value={50} />Controlled
Use value and to control the progress bar.
Orientation
Use the orientation prop to orient the progress bar horizontally or vertically.
Horizontal
Vertical
Examples
With label
Use ProgressValue and FieldLabel to add a label to the progress bar.
Indeterminate
Use the indeterminate prop when the completion percentage is unknown.
API Reference
Progress
Root element of the progress bar.
| Prop | Type | Default |
|---|---|---|
value | number | null | - |
defaultValue | number | - |
onValueChange | (details: ValueChangeDetails) => void | - |
indeterminate | boolean | false |
min | number | 0 |
max | number | 100 |
orientation | "horizontal" | "vertical" | "horizontal" |
className | string | - |
For a complete list of props, see the Ark UI documentation.