Progress
Determinate linear and circular progress indicators with tokenized variants and sizing.
pnpm dlx @glinui/cli@latest add progressUploading 3 files
About 40 seconds left
Installation
pnpm dlx @glinui/cli@latest add progressPrefer the package?
Usage
Onboarding steps
A circular summary, a bar and a checklist share one value.
Get started
2 of 4 steps complete
- Create workspace
- Invite your team
- Connect a repository
- Ship your first deploy
import { CheckCircle } from "@phosphor-icons/react"import { Card, CardContent, CardDescription, CardHeader, CardTitle, Progress, ProgressCircle} from "@glinui/ui"
export function Demo() { const steps = [ { label: "Create workspace", done: true }, { label: "Invite your team", done: true }, { label: "Connect a repository", done: false }, { label: "Ship your first deploy", done: false } ] const done = steps.filter((step) => step.done).length return ( <Card className="w-full max-w-sm"> <CardHeader> <div className="flex items-center justify-between gap-4"> <div> <CardTitle>Get started</CardTitle> <CardDescription>{done} of {steps.length} steps complete</CardDescription> </div> <ProgressCircle value={(done / steps.length) * 100} size="lg" showValue aria-label="Onboarding progress" /> </div> </CardHeader> <CardContent className="flex flex-col gap-3"> <Progress aria-label="Onboarding progress" value={(done / steps.length) * 100} /> <ul className="flex flex-col gap-2 text-sm"> {steps.map((step) => ( <li key={step.label} className="flex items-center gap-2"> <CheckCircle aria-hidden weight={step.done ? "fill" : "regular"} className={step.done ? "size-4 text-[var(--tone-success)]" : "size-4 text-[var(--color-muted)]"} /> <span className={step.done ? "text-[var(--color-muted)] line-through" : "font-medium"}>{step.label}</span> </li> ))} </ul> </CardContent> </Card> )}Variants
import { Progress } from "@glinui/ui"
export function Demo() { return ( <div className="space-y-3"> <Progress variant="glinr" value={30} aria-label="glinr" /> <Progress variant="solid" value={38} aria-label="solid" /> <Progress variant="plain" value={46} aria-label="plain" /> <Progress variant="soft" value={54} aria-label="soft" /> <Progress variant="outline" value={62} aria-label="outline" /> <Progress variant="ghost" value={70} aria-label="ghost" /> <Progress variant="gradient" value={78} aria-label="gradient" /> </div> )}Sizes and indeterminate
Three sizes animate in sync. Use indeterminate when the duration is unknown.
import { useEffect, useState } from "react"import { Progress } from "@glinui/ui"
export function Demo() { const [value, setValue] = useState(35) useEffect(() => { const id = window.setInterval(() => setValue((current) => (current >= 100 ? 8 : current + 9)), 900) return () => window.clearInterval(id) }, []) return ( <div className="flex w-full max-w-md flex-col gap-5"> {(["sm", "md", "lg"] as const).map((size) => ( <div key={size} className="flex flex-col gap-1.5"> <span className="font-mono text-xs text-[var(--color-muted)]">size {size}</span> <Progress aria-label={`Progress ${size}`} size={size} value={value} /> </div> ))} <div className="flex flex-col gap-1.5"> <span className="font-mono text-xs text-[var(--color-muted)]">indeterminate</span> <Progress aria-label="Waiting for server" indeterminate /> </div> </div> )}Variants
import { Progress } from "@glinui/ui"
export function ProgressVariantDemo() {
return (
<div className="space-y-3">
<Progress value={52} />
<Progress variant="glass" value={68} />
<Progress variant="liquid" value={82} />
<Progress variant="matte" value={38} />
</div>
)
}Sizes
import { Progress } from "@glinui/ui"
export function ProgressSizeDemo() {
return (
<div className="space-y-3">
<Progress size="sm" value={30} />
<Progress size="md" value={50} />
<Progress size="lg" value={80} />
</div>
)
}Circular Progress
import { ProgressCircle } from "@glinui/ui"
export function ProgressCircleDemo() {
return (
<div className="flex flex-wrap items-center gap-5">
<ProgressCircle size="sm" value={28} aria-label="Small progress" />
<ProgressCircle size="md" variant="glass" value={64} aria-label="Glass progress" />
<ProgressCircle size="lg" variant="liquid" value={86} aria-label="Liquid progress" />
</div>
)
}Accessibility
- Built on Radix Progress with `role="progressbar"`.
- Provide `aria-label` for screen readers.
- Root uses Radix Progress semantics with `role="progressbar"`.
- Circular variant also exposes `role="progressbar"` with proper value attrs.
- Provide `aria-label` or external label for non-visual users.
- Values are clamped between `0` and `100`.
ARIA Attributes
- `role="progressbar"`
- `aria-valuenow`
- `aria-valuemin`
- `aria-valuemax`
Reduced Motion
Width transition respects `prefers-reduced-motion` via `motion-reduce:transition-none`.
Width transitions are disabled when `prefers-reduced-motion` is enabled.
Affected properties
widthAPI Reference
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
variant | ControlVariantProp | No | ambient (glinr) | Look. Omit to follow the ambient design style: glinr is an inset track with an accent fill. Glass is opt-in. |
size | "sm" | "md" | "lg" | No | md | Track height (h-2/h-3/h-4). |
value | number | No | 0 | Progress value (0-100, clamped). |
indeterminate | boolean | No | false | Loading state without a specific value. |
Source
Import directly from the package or browse the source on GitHub. Click any file to view it.
Import
import { Progress } from "@glinui/ui"Source Files
Dependencies
@glinui/uiGenerated API Snapshot
Beta
Generated API Snapshot
BetaAuto-extracted from TypeScript source in packages/ui/src/components/progress.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.
Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata
Primary Props Type
ProgressProps
ProgressCircleProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
cap | "round" | "square" | "butt" | No | "round" | - |
formatValue | (value: number) => React.ReactNode | No | - | - |
indeterminate | boolean | No | false | - |
showValue | boolean | No | true | - |
size | "sm" | "md" | "lg" | No | "md" | Variant option from progressCircleVariants. |
strokeWidth | number | No | 4 | - |
value | number | No | - | - |
variant | ControlVariantProp | No | - | - |
ProgressProps
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
indeterminate | boolean | No | false | Render loading state without aria-valuenow and fixed width indicator. |
size | "sm" | "md" | "lg" | No | "md" | Variant option from progressVariants. |
value | number | No | - | Current progress value from 0 to 100. |
variant | ControlVariantProp | No | - | Look. Omit to follow the ambient design style (glinr = inset track, accent fill). Also: solid, plain, soft, outline, ghost, gradient, glass (opt-in), liquid, matte. |