Skeleton
Marcadores de carga con contorno, compuestos en una tarjeta de perfil completa; pulso opcional y respeto al movimiento reducido.
Instalación
Agrega el componente y sus dependencias desde el registro que está ejecutándose en tu computadora.
npx shadcn@latest add https://brutallab.facilito.dev/r/skeleton.jsonUso
Importa el componente en tu proyecto y conserva el código bajo tu control.
'use client';
import { useState } from 'react';
import { Skeleton } from '@/components/ui/skeleton';
import { Button } from '@/components/ui/button';
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
import { Card } from '@/components/ui/card';
export default function Demo() {
const [loading, setLoading] = useState(true);
const [following, setFollowing] = useState(false);
return (
<div className="grid w-full min-w-0 max-w-lg gap-6">
<Card aria-busy={loading} className="min-h-72 gap-5 p-5">
{loading ? <>
<div className="flex items-center gap-4"><Skeleton className="size-10 shrink-0 rounded-full" /><div className="grid flex-1 gap-2"><Skeleton className="h-4 w-3/4" /><Skeleton className="h-3 w-1/2" /></div></div>
<div className="grid gap-2"><Skeleton className="h-3 w-full" /><Skeleton className="h-3 w-5/6" /><Skeleton className="h-3 w-2/3" /></div>
<Skeleton className="mt-auto h-11 w-32" />
</> : <>
<div className="flex items-center gap-4"><Avatar tone="purple"><AvatarFallback>AN</AvatarFallback></Avatar><div><strong className="font-medium">Ana Rivera</strong><p className="bl-type-small text-muted-foreground">Product designer · Study Club</p></div></div>
<p className="bl-type-small">Interfaces con carácter, pequeñas ideas y espacio para aprender. Construyendo una pieza a la vez.</p>
<Button variant="accent" className="mt-auto w-fit" aria-pressed={following} onClick={() => setFollowing(!following)}>{following ? 'Siguiendo / Following' : 'Seguir / Follow'}</Button>
</>}
</Card>
<output className="bl-type-small" aria-live="polite">{loading ? 'Loading profile / Cargando perfil' : 'Profile ready / Perfil listo'}</output>
<Button variant="outline" className="h-auto min-h-11 w-fit max-w-full whitespace-normal py-2 text-center" onClick={() => setLoading(!loading)}>{loading ? 'Show content / Mostrar contenido' : 'Show loading / Mostrar carga'}</Button>
<div className="grid gap-3"><p className="bl-type-label">Static / Sin animación</p><Skeleton animated={false} className="h-4 w-full" /><Skeleton animated={false} className="h-4 w-2/3" /></div>
</div>
);
}
Estados e interacción
Aspecto, comportamiento y comprobación con teclado.
- Carga animada o estática con animated={false}. Respeta prefers-reduced-motion.
- No recibe foco ni hover. Las formas se ocultan a lectores de pantalla; el contenedor anuncia la carga una vez y conserva el espacio del contenido final.
Referencia API
Propiedades propias de BrutalLab. También acepta los atributos nativos correspondientes.
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| animated | boolean | true | Pulse while loading. false gives a static placeholder. Reduced motion always disables animation. |
| className | string | — | Set the width, height and shape to reserve the space of the final content. |
Accesibilidad
Reglas que deben conservarse cuando el componente se adapte a un producto.
Conserva las etiquetas visibles y el HTML semántico del ejemplo.
Mantén el foco visible y comprueba la composición mediante el teclado.
Personaliza el aspecto con className sin reemplazar los atributos ARIA de la primitiva.