Progress
A slim bar that fills as a task completes — uploads, installs, multi-step onboarding — with the neobrutalist borders-and-shadows treatment.
"use client"
import * as React from "react"The progress bar reports how much of a task is done — a track that fills from 0 to 100. Built on the Base UI Progress component and styled to the neobrutalist recipe: thick border, hard shadow, solid fill.
Reach for it when:
- File uploads and downloads — determinate, byte-driven progress with a visible percentage.
- Multi-step flows — onboarding, checkout, and wizards; the bar shows how far along the user is.
- Long-running jobs — imports, exports, and installs that report completion from the server.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/progress.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/progress.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/progress.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/progress.json
Install the following dependencies:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
Copy and paste the following code into your project.
"use client"
import * as React from "react"
import { Progress as ProgressPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
function Progress({
className,
value,
...props
}: React.ComponentProps<typeof ProgressPrimitive.Root>) {
return (
<ProgressPrimitive.Root
data-slot="progress"
className={cn(
"relative flex h-4 w-full items-center overflow-hidden rounded border-2 bg-background",
className
)}
{...props}
>
<ProgressPrimitive.Indicator
data-slot="progress-indicator"
className="size-full flex-1 bg-primary transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>
)
}
export { Progress }
Update the import paths to match your project setup.
Usage#
import { Progress } from "@/components/ui/progress"<Progress value={33} />Composition#
With label and value#
Use ProgressLabel and ProgressValue to add a label and value display.
import {
Progress,
ProgressLabel,
ProgressValue,
} from "@/components/ui/progress"
;<Progress value={56} className="w-full max-w-sm">
<ProgressLabel>Upload progress</ProgressLabel>
<ProgressValue />
</Progress>Progress
├── ProgressLabel
├── ProgressValue
└── ProgressTrack
└── ProgressIndicatorExamples#
Label#
Use ProgressLabel and ProgressValue to add a label and value display.
import {
Progress,
ProgressLabel,Controlled#
A progress bar that can be controlled by a slider.
"use client"
import * as React from "react"RTL#
To enable RTL support in Neobrutalism.com, see the RTL configuration guide.
"use client"
import * as React from "react"Accessibility#
Progress is a status indicator, not a control — it never takes focus and has no keyboard interactions. Base UI renders role="progressbar" with aria-valuemin, aria-valuemax, and aria-valuenow, and ProgressLabel is associated automatically via aria-labelledby — prefer it (or an aria-label) over an unlabeled bar so screen readers can say what is loading, not just the percentage. Pass value={null} when completion is unknown; the bar switches to an indeterminate state.
API Reference#
See the Base UI Progress documentation.