Ir al contenido

Componentes · Ola 3 · Estados

Progress

Muestra cuánto va de una tarea, o que hay una en curso sin saber cuánto falta. El riel es el del Slider, oscuro y con un borde visible en cualquier capa, y el relleno se ilumina con el color de selección. El valor, si se muestra, va en mono.

import { Progress } from '@archeblack/ui';

Ejemplos

Con texto y valor

label nombra la barra y showValue muestra el porcentaje.

Subiendo archivos
Svelte
<script lang="ts">
	import { Progress } from '@archeblack/ui';
</script>

<div style:width="min(100%, 20rem)">
	<Progress label="Subiendo archivos" value={62} showValue />
</div>

Indeterminada

Sin value: un tramo cruza el riel mientras no se sepa cuánto falta.

Preparando el despliegue
Svelte
<script lang="ts">
	import { Progress } from '@archeblack/ui';
</script>

<!-- Sin value: se sabe que hay trabajo en curso, no cuánto falta. -->
<div style:width="min(100%, 20rem)">
	<Progress label="Preparando el despliegue" />
</div>

Tallas

sm (4 px) para filas y tarjetas densas; md (6 px) por defecto.

Talla sm
Talla md
Svelte
<script lang="ts">
	import { Progress } from '@archeblack/ui';
</script>

<div style="display: grid; gap: var(--arche-spacing-6); width: min(100%, 20rem)">
	<Progress label="Talla sm" value={40} size="sm" showValue />
	<Progress label="Talla md" value={40} showValue />
</div>

Con formato

format escribe el valor en pantalla y en aria-valuetext; max no tiene que ser 100.

Importando
Svelte
<script lang="ts">
	import { Button, Progress } from '@archeblack/ui';

	const total = 8;
	let done = $state(3);
</script>

<!-- En pantalla y en el lector: «3 de 8 archivos». -->
<div
	style="display: grid; justify-items: start; gap: var(--arche-spacing-4); width: min(100%, 20rem)"
>
	<Progress
		label="Importando"
		value={done}
		max={total}
		showValue
		format={(value, max) => `${value} de ${max} archivos`}
		style="justify-self: stretch"
	/>
	<Button variant="secondary" size="sm" onclick={() => (done = done >= total ? 0 : done + 1)}>
		{done >= total ? 'Empezar de nuevo' : 'Importar otro'}
	</Button>
</div>

Nombrada por otro texto

Si un título ya dice qué mide, aria-labelledby apunta a él y la barra va sin texto propio.

Uso del mes

184.302 de 250.000 solicitudes.

Se reinicia el 1 de octubre.

Svelte
<script lang="ts">
	import { Card, Progress } from '@archeblack/ui';
</script>

<!-- El título de la tarjeta ya nombra la barra: aria-labelledby, sin texto repetido. -->
<Card style="width: 100%; max-width: 24rem">
	{#snippet header()}
		<h4 id="usage-title">Uso del mes</h4>
	{/snippet}
	<div style="display: grid; gap: var(--arche-spacing-3)">
		<p>184.302 de 250.000 solicitudes.</p>
		<Progress aria-labelledby="usage-title" value={184302} max={250000} />
		<p style="color: var(--arche-color-text-muted)">Se reinicia el 1 de octubre.</p>
	</div>
</Card>

Props

Props de Progress
PropDescripción
value? number | null Lo que va hecho, de 0 a max. Sin valor (o con null) la barra es indeterminada. Un valor fuera de rango se recorta.
max? number Por defecto 100El valor que completa la barra. Si no es positivo, se usa 100.
label? string Texto visible encima de la barra, con el aspecto de la etiqueta de Field. La nombra con aria-labelledby.
aria-label? string Nombre de la barra cuando no hay texto visible; si otro texto de la página ya la nombra, aria-labelledby con su id. Hace falta uno de label, aria-label o aria-labelledby: TypeScript rechaza una barra sin nombre.
showValue? boolean Por defecto falseMuestra el valor en mono, con cifras tabulares, a la derecha del texto. Solo en una barra determinada.
format? (value: number, max: number) => string Cómo se escribe el valor, en pantalla y en aria-valuetext («3 de 8 archivos»). Sin format, el porcentaje redondeado («62 %»).
size? 'sm' | 'md' Por defecto 'md'Alto del interior del riel: 4 px o 6 px, más el borde de 1 px.
class? ClassValue Clases del producto; se suman a arche-progress, el contenedor.
...rest HTMLAttributes<HTMLDivElement> id, style y data-* van al contenedor; aria-describedby va a la barra (role="progressbar").

Accesibilidad

  • La barra es un role="progressbar" con aria-valuemin, aria-valuemax, aria-valuenow y aria-valuetext (el mismo texto que format escribe en pantalla). Indeterminada, no lleva valor: así lo pide ARIA para un progreso desconocido.
  • El nombre es obligatorio: label visible, aria-label o aria-labelledby. Sin nombre, el lector dice solo «barra de progreso, 62 %».
  • El valor visible (showValue) está oculto para el lector: la barra ya lo expone y se oiría dos veces.
  • Una barra de progreso no se anuncia sola cuando cambia. Si el final importa («Carga completa»), anúncialo con un Toast o un Alert con live.
  • Con movimiento reducido, la barra indeterminada deja de desplazarse: el riel entero late despacio, solo con la opacidad, y sigue diciendo que hay trabajo en curso. El avance de la determinada salta sin transición.
  • El riel es el mismo del Slider: interior bg con un borde de 1 px en border-control. El borde llega a 3:1 contra todas las capas (3,08:1 o más), así se ve el largo total aunque el relleno vaya por la mitad. El relleno es el color de selección y llega a 3:1 contra el interior oscuro en todos los productos (20:1 en Arche, 7,77:1 en el producto de ejemplo). En colores forzados, el riel es Canvas con borde CanvasText y el relleno Highlight.

Qué evitar

  • Una barra determinada con un valor inventado, que avanza sola aunque no se sepa cuánto falta. Una barra indeterminada, sin value, hasta tener un avance real.
  • Una barra de progreso para una espera de menos de un segundo. Nada, o el loading de Button si la espera sale de un botón.
  • Una barra para mostrar una cantidad que no avanza hacia un final (una puntuación, un nivel). El número en mono, o un medidor propio con role="meter".
  • Varias barras indeterminadas a la vez en la misma vista. Una sola para el conjunto, o un Spinner por fila.