Feedback
Progress.
A thin orange bar on a dark 2px to 6px track, modeled on the turtle fuel gauge.
"use client";
import * as React from "react";
import { Progress } from "@/components/ui/progress";
export default function ProgressDemo() {
const [value, setValue] = React.useState(18);
React.useEffect(() => {
const timer = setTimeout(() => setValue(66), 500);
return () => clearTimeout(timer);
}, []);
return (
<div className="flex w-full max-w-sm flex-col gap-5">
<Progress value={value} size="sm" aria-label="Sync progress" />
<Progress value={value} aria-label="Upload progress" />
<Progress value={value} size="lg" aria-label="Fuel level" />
</div>
);
}Installation#
With the CLI
$npx lanterncn add progressThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/progress. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install radix-uiCopy the source into your project
components/ui/progress.tsx"use client"; import * as React from "react"; import { Progress as ProgressPrimitive } from "radix-ui"; import { cn } from "@/lib/utils"; const trackSizes = { sm: "h-0.5", default: "h-1", lg: "h-1.5", } as const; /** A thin orange bar on a dark track, like a turtle's fuel gauge. */ function Progress({ className, value, size = "default", indicatorClassName, ...props }: React.ComponentProps<typeof ProgressPrimitive.Root> & { size?: keyof typeof trackSizes; indicatorClassName?: string; }) { return ( <ProgressPrimitive.Root data-slot="progress" value={value} className={cn("relative w-full overflow-hidden rounded-[1px] bg-[#2b352f]", trackSizes[size], className)} {...props} > <ProgressPrimitive.Indicator data-slot="progress-indicator" className={cn("h-full w-full flex-1 bg-primary transition-transform duration-300", indicatorClassName)} style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }} /> </ProgressPrimitive.Root> ); } export { Progress };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import { Progress } from "@/components/ui/progress";<Progress value={66} aria-label="Fuel level" />Use size="sm", "default" or "lg" for a 2px, 4px or 6px track. Pass indicatorClassName to recolor the bar, for example bg-destructive when a value is low.
Examples#
Labeled with a percentage
T-01 minerFuel 82%
T-02 lumberFuel 24%
T-03 farmerFuel 7%
import { Progress } from "@/components/ui/progress";
const turtles = [
{ name: "T-01 miner", fuel: 82 },
{ name: "T-02 lumber", fuel: 24 },
{ name: "T-03 farmer", fuel: 7 },
];
export default function ProgressLabeled() {
return (
<div className="flex w-full max-w-sm flex-col gap-5">
{turtles.map((t) => {
const id = `fuel-${t.name.split(" ")[0]}`;
return (
<div key={t.name} className="space-y-2">
<div className="flex items-baseline justify-between gap-3">
<span id={id} className="text-sm">
{t.name}
</span>
<span className="font-mono text-[11px] tracking-[0.12em] text-muted-foreground tabular-nums uppercase">
Fuel {t.fuel}%
</span>
</div>
<Progress
value={t.fuel}
size="lg"
aria-labelledby={id}
indicatorClassName={t.fuel < 10 ? "bg-destructive" : undefined}
/>
</div>
);
})}
</div>
);
}