Components / Feedback
Progress
Determinate progress bars showing completion.
Default
Progress60%
Sizes
sm
md
lg
Animated
Progress0%
Source ProgressDemo.tsx
The exact code behind the live demo above. Fetch it raw at /components/source/progress.txt.
import React, { useState } from "react";
function Section({ title, children }: { title: string; children: React.ReactNode }) {
return (
<div className="mb-8">
<h3 className="text-sm font-bold text-[var(--flux-heading)] mb-3">{title}</h3>
<div className="p-6 rounded border border-[var(--flux-grey-100)] bg-[var(--flux-surface)]">
{children}
</div>
</div>
);
}
function ProgressBar({
value,
height = "h-2",
showLabel = false,
}: {
value: number;
height?: string;
showLabel?: boolean;
}) {
return (
<div className="w-full">
{showLabel && (
<div className="flex justify-between mb-1.5">
<span className="text-xs font-bold text-[var(--flux-black)]">Progress</span>
<span className="text-xs font-bold text-[var(--flux-black)]">{value}%</span>
</div>
)}
<div className={`w-full ${height} rounded-full bg-[var(--flux-grey-100)]`}>
<div
className={`${height} rounded-full bg-[var(--flux-primary-400)] transition-all duration-500`}
style={{ width: `${value}%` }}
/>
</div>
</div>
);
}
export default function ProgressDemo() {
const steps = [0, 25, 50, 75, 100];
const [stepIndex, setStepIndex] = useState(0);
const cycle = () => {
setStepIndex((prev) => (prev + 1) % steps.length);
};
return (
<div>
<Section title="Default">
<ProgressBar value={60} showLabel />
</Section>
<Section title="Sizes">
<div className="space-y-4">
<div>
<span className="text-xs text-[var(--flux-grey-300)] mb-1 block">sm</span>
<ProgressBar value={45} height="h-1" />
</div>
<div>
<span className="text-xs text-[var(--flux-grey-300)] mb-1 block">md</span>
<ProgressBar value={45} height="h-2" />
</div>
<div>
<span className="text-xs text-[var(--flux-grey-300)] mb-1 block">lg</span>
<ProgressBar value={45} height="h-3" />
</div>
</div>
</Section>
<Section title="Animated">
<div className="space-y-4">
<ProgressBar value={steps[stepIndex]} showLabel />
<button
onClick={cycle}
className="px-4 py-2 text-sm font-bold rounded bg-[var(--flux-primary-400)] text-white hover:opacity-90 transition-opacity"
>
Advance to {steps[(stepIndex + 1) % steps.length]}%
</button>
</div>
</Section>
</div>
);
}