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.
<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.
<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>.
<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.
<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
| Prop | Descripció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 false | Muestra 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 true | Si 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"esrole="status"y conlive="assertive"esrole="alert". Usaassertivesolo 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>conaria-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 enonDismissa un lugar que siga existiendo, como la acción siguiente o el título de la sección (contabindex="-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
secondaryoghostde tallasm.