Ir al contenido

Componentes · Ola 1 · Estados

Alert

Aviso dentro de la página, con el ícono y el color de su estado. Tiene un título, una descripción y acciones opcionales, y se puede cerrar. Por defecto es una nota que se lee al recorrer la página; con live se anuncia al aparecer.

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

Ejemplos

Variantes

info, success, warning, danger y neutral (por defecto), cada una con su ícono.

Mantenimiento programado

El domingo de 02:00 a 04:00 (UTC−5) la consola funcionará en modo lectura.

Dominio verificado

portal.arche.dev ya apunta a tu proyecto.

Te queda el 12 % de la cuota

Al ritmo actual, se agota en 3 días.

El pago fue rechazado

Actualiza tu tarjeta antes del 5 de octubre para no perder el acceso.

Sin cambios desde el último despliegue

La versión publicada es la misma que la del repositorio.
Svelte
<script lang="ts">
	import { Alert } from '@archeblack/ui';
</script>

<div style="display: grid; gap: var(--arche-spacing-3); width: 100%">
	<Alert variant="info" title="Mantenimiento programado">
		El domingo de 02:00 a 04:00 (UTC−5) la consola funcionará en modo lectura.
	</Alert>
	<Alert variant="success" title="Dominio verificado">
		portal.arche.dev ya apunta a tu proyecto.
	</Alert>
	<Alert variant="warning" title="Te queda el 12 % de la cuota">
		Al ritmo actual, se agota en 3 días.
	</Alert>
	<Alert variant="danger" title="El pago fue rechazado">
		Actualiza tu tarjeta antes del 5 de octubre para no perder el acceso.
	</Alert>
	<Alert title="Sin cambios desde el último despliegue">
		La versión publicada es la misma que la del repositorio.
	</Alert>
</div>

Con acciones

El snippet actions va debajo de la descripción: una o dos acciones de talla sm.

Te queda el 12 % de la cuota

Al ritmo actual, se agota en 3 días. Después, las solicitudes nuevas se rechazan.
Svelte
<script lang="ts">
	import { Alert, Button } from '@archeblack/ui';
</script>

<div style="width: 100%">
	<Alert variant="warning" title="Te queda el 12 % de la cuota">
		Al ritmo actual, se agota en 3 días. Después, las solicitudes nuevas se rechazan.
		{#snippet actions()}
			<Button variant="secondary" size="sm">Ampliar plan</Button>
			<Button variant="ghost" size="sm">Ver el uso</Button>
		{/snippet}
	</Alert>
</div>

Se puede cerrar

dismissible suma el botón de cerrar; bind:open y onDismiss avisan al producto. Al cerrar, onDismiss lleva el foco al botón siguiente; sin eso caería en el <body>.

Dominio verificado

portal.arche.dev ya apunta a tu proyecto.
Svelte
<script lang="ts">
	import { Alert, Button } from '@archeblack/ui';

	let open = $state(true);
	let actions = $state<HTMLElement>();

	// El botón de cerrar desaparece con el aviso y el foco caería en el <body>. Lo llevamos a la
	// acción siguiente, que sigue en la página.
	function moveFocus() {
		actions?.querySelector('button')?.focus();
	}
</script>

<div style="display: grid; justify-items: start; gap: var(--arche-spacing-4); width: 100%">
	<Alert
		variant="success"
		title="Dominio verificado"
		dismissible
		bind:open
		onDismiss={moveFocus}
		style="justify-self: stretch"
	>
		portal.arche.dev ya apunta a tu proyecto.
	</Alert>
	<div bind:this={actions}>
		<Button variant="secondary" onclick={() => (open = true)}>Mostrar el aviso</Button>
	</div>
</div>

Anunciado

Con live en polite el aviso es un status: se monta vacío, el texto llega dos cuadros después y el lector de pantalla lo lee sin interrumpir.

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

	let saved = $state(false);
</script>

<div style="display: grid; justify-items: start; gap: var(--arche-spacing-4); width: 100%">
	<Button variant="secondary" onclick={() => (saved = true)}>Guardar cambios</Button>
	<!--
		role="status": el lector de pantalla lo lee al aparecer, sin interrumpir. Aunque se monte con
		{#if}, el aviso pinta primero la región vacía y el texto llega dos cuadros después.
	-->
	{#if saved}
		<Alert variant="success" live="polite" title="Cambios guardados">
			La configuración nueva se aplica en el próximo despliegue.
		</Alert>
	{/if}
</div>

Props

Props de Alert
PropDescripción
variant? 'info' | 'success' | 'warning' | 'danger' | 'neutral' Por defecto 'neutral'Estado del aviso. Cada uno trae su ícono (info-circle, circle-check, alert-triangle, circle-x; neutral usa info-circle), su fondo suave y su borde.
title? string Título en una línea, en texto fuerte. Es el visible; no es el tooltip nativo.
children? Snippet La descripción, debajo del título.
actions? Snippet Acciones debajo de la descripción: uno o dos Button de talla sm, o un link.
icon? IconGlyph Otro ícono en lugar del de la variante. No se puede quitar: el estado nunca depende solo del color.
live? 'polite' | 'assertive' Anuncio al aparecer: polite pone role="status" (espera a que el lector termine) y assertive pone role="alert" (interrumpe). La región se monta vacía y el contenido, con el botón de cerrar, llega dos cuadros después. Sin live el aviso es una nota (role="note").
dismissible? boolean Por defecto falseMuestra el botón de cerrar (un ícono x).
dismissLabel? string Por defecto 'Cerrar'Nombre accesible del botón de cerrar, para productos en otro idioma.
bind:open? boolean Por defecto trueSi el aviso se muestra. Pasa a false al cerrarlo con el botón.
onOpenChange? (open: boolean) => void Se llama cuando el aviso cambia open por sí mismo (al cerrarse con el botón), con el estado nuevo. Llega después de actualizar open y solo si el cambio se aceptó: si un bind:open de función lo rechaza, no se llama.
onDismiss? () => void Se llama al cerrar el aviso con el botón, después de que open pasa a false y de onOpenChange. Aquí el producto mueve el foco, que si no cae en el <body>. Si un bind:open de función rechaza el cierre, no se llama.
class? ClassValue Clases del producto; se suman a arche-alert.
...rest HTMLAttributes<HTMLDivElement> Cualquier otro atributo va al <div> raíz. El rol lo decide live y title es el título visible.

Accesibilidad

  • Por defecto es una nota (role="note"): no se anuncia al aparecer y se lee al recorrer la página. Sirve para avisos que ya están al cargar.
  • Con live="polite" es role="status" y con live="assertive" es role="alert". Usa assertive solo para lo que no puede esperar, como un error que bloquea.
  • NVDA y JAWS solo anuncian los cambios de una región viva que ya estaba en la página. Por eso, con live, el aviso monta primero la región vacía (con su rol; el ícono decorativo queda fuera) y pinta el título y la descripción dos cuadros después. Así se anuncia aunque el producto lo monte entero con {#if}. La región es solo el mensaje: las acciones y el botón de cerrar quedan fuera y no se leen con el anuncio.
  • Si el aviso aparece al responder a una acción, muéstralo cerca de donde la persona está mirando.
  • El ícono es decorativo: el estado lo nombran el título y la descripción. Escríbelos para que se entiendan sin el color.
  • El botón de cerrar es un <button> con aria-label («Cerrar» por defecto) y mide 28 px.
  • Al cerrar, el aviso sale de la página con su botón y el foco cae en el <body>: quien usa el teclado vuelve al principio de la página y el lector de pantalla no dice nada. El componente no sabe adónde llevarlo; el producto lo mueve en onDismiss a un lugar que siga existiendo, como la acción siguiente o el título de la sección (con tabindex="-1").
  • El título y la descripción pasan AA contra el fondo suave de cada estado; el ícono, 3:1.

Qué evitar

  • Un aviso para confirmar una acción pasajera («Guardado»), que queda en la página para siempre. Un aviso que se puede cerrar, o un Toast para confirmaciones breves.
  • live="assertive" en avisos informativos o de éxito. polite, o ninguno si el aviso ya está al cargar la página.
  • Varios avisos apilados con el mismo peso. Uno por tema, del más urgente al menos urgente, o un resumen con un link al detalle.
  • Solo el color para diferenciar un error de una advertencia. Un título que diga qué pasó («El pago fue rechazado») y qué hacer después.
  • Más de dos acciones, o una acción primaria dentro del aviso. Una o dos acciones secondary o ghost de talla sm.