KDS
Feedback

Progress

Indicador determinado de progresso (0–100) — uploads, multi-step, batch jobs.

Overview

Progress é uma barra determinada — você sabe a percentagem. Use em uploads, multi-step forms, jobs que reportam progresso real. Quando a duração é desconhecida, use Skeleton ou spinner em vez disso.

A regra firme: nunca renderize a barra silenciosa. Sempre pareie com um valor numérico ou label de contexto — barras sem número confundem sobre o estado real ("É 60%? 70%?").

Preview
Progress 72% com label.
Importando ativos72%

Anatomy

<Progress value={0..100}>
  ├─ [data-slot="progress"]            ← track (h-2, bg-primary/20)
  └─ <Indicator />                      ← preenchimento (transform translateX)
</Progress>

Usage

import { Progress } from "@kalvner/kds/feedback/progress";

export function Upload({ pct }: { pct: number }) {
  return <Progress value={pct} aria-label={`${pct} por cento`} />;
}

Props

PropTipoDefaultDescrição
valuenumber | null00..100. null reservado para indeterminado.
maxnumber100Valor máximo.
aria-labelstringObrigatório se não houver label visível associado.
classNamestringOverride no track (h, w, bg).

Subcomponents

Progress é monolítico — exporta apenas o root. O indicator é interno (data-slot="progress-indicator") e estilizado via descendentes do track.

Variants

Não há variantes embutidas. Para tamanhos custom, ajuste className:

<Progress value={50} className="h-1" />     // mais fino
<Progress value={50} className="h-3" />     // mais grosso

Para cor de status (sucesso/aviso/erro), aplique no descendente:

<Progress
  value={100}
  className="bg-green-500/20 [&>[data-slot=progress-indicator]]:bg-green-500"
/>

States

Empty
value=0
Half
value=50
Full
value=100

Composition

Padrão clássico de upload — label + porcentagem + barra:

<div className="space-y-2">
  <div className="flex items-baseline justify-between">
    <Label>Enviando arquivo</Label>
    <span className="tabular-nums text-muted-foreground">{pct}%</span>
  </div>
  <Progress value={pct} aria-label={`${pct} por cento`} />
</div>

Em multi-step forms, mostre current/total em vez de porcentagem:

<div className="space-y-2">
  <span className="text-sm">Passo 2 de 4</span>
  <Progress value={(2 / 4) * 100} aria-label="Passo 2 de 4" />
</div>

When to use

  • Uploads / downloads em andamento.
  • Multi-step forms (passo N de M).
  • Batch jobs com porcentagem real.
  • Onboarding com checklist progressivo.

When not to use

  • Operações de duração desconhecida — use Skeleton ou spinner.
  • "Loading..." curto (menos de 1s) — não vale a pena mostrar.
  • Dados em tempo real que sobem e descem (CPU, memória) — use um gráfico Sequential da Chart layer.

Best practices

  • Sempre pareie com número visível ou label dinâmico.
  • Use tabular-nums no número para evitar saltos de largura.
  • Em uploads que podem cancelar, ofereça botão Cancel ao lado da barra.
  • Para 100%, troque a label para uma confirmação ("Concluído") e mantenha a barra cheia 800ms antes de remover — evita flash.

Accessibility

ConcernComportamento
RolesRadix expõe role="progressbar" com aria-valuenow, aria-valuemin=0, aria-valuemax=100.
Labelaria-label ou aria-labelledby é obrigatório.
Live regionPara feedback de operação, embrulhe num aria-live="polite" no container.
Reduced motionA transition-all no indicator respeita prefers-reduced-motion.
  • Skeleton — quando a duração é desconhecida.
  • Alert — para reportar resultado final (sucesso/erro).
  • Sonner — toast de upload concluído.

On this page