Feedback
Progress
Determinate bar with label and value, in four tones.
Tracing this week’s conversations
Channels connected
Evaluation coverage
pnpm dlx shadcn@latest add @paragon/progressBrings in@base-ui/reactclass-variance-authoritycn
registry/paragon/ui/progress.tsx
"use client"
import { Progress as ProgressPrimitive } from "@base-ui/react/progress"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "cn"
const indicatorVariants = cva(
"h-full rounded-full transition-[width] duration-(--duration-slower) ease-paragon motion-reduce:transition-none",
{
variants: {
tone: {
default: "bg-primary",
brand: "bg-brand",
fjord: "bg-fjord dark:bg-[#9db7dc]",
oasis: "bg-oasis dark:bg-[#a8cf9f]",
},
},
defaultVariants: {
tone: "default",
},
}
)
/**
* A determinate bar. Put a ProgressLabel and ProgressValue inside for the
* caption row; the track wraps onto its own line beneath them.
*/
function Progress({
className,
children,
value,
tone,
...props
}: ProgressPrimitive.Root.Props & VariantProps<typeof indicatorVariants>) {
return (
<ProgressPrimitive.Root
value={value}
data-slot="progress"
className={cn("flex w-full flex-wrap items-baseline gap-x-3 gap-y-2", className)}
{...props}
>
{children}
<ProgressTrack>
<ProgressIndicator className={indicatorVariants({ tone })} />
</ProgressTrack>
</ProgressPrimitive.Root>
)
}
function ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {
return (
<ProgressPrimitive.Track
data-slot="progress-track"
className={cn("relative flex h-1.5 w-full items-center overflow-hidden rounded-full bg-foreground/8", className)}
{...props}
/>
)
}
function ProgressIndicator({ className, ...props }: ProgressPrimitive.Indicator.Props) {
return <ProgressPrimitive.Indicator data-slot="progress-indicator" className={cn(className)} {...props} />
}
function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
return <ProgressPrimitive.Label data-slot="progress-label" className={cn("text-sm font-medium", className)} {...props} />
}
function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
return (
<ProgressPrimitive.Value
data-slot="progress-value"
className={cn("ms-auto text-sm text-muted-foreground tabular-nums", className)}
{...props}
/>
)
}
export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValue }