FeedbackDisponible

Skeleton

Marcadores de carga con contorno, compuestos en una tarjeta de perfil completa; pulso opcional y respeto al movimiento reducido.

Loading example…

Instalación

Agrega el componente y sus dependencias desde el registro que está ejecutándose en tu computadora.

terminal
npx shadcn@latest add https://brutallab.facilito.dev/r/skeleton.json

Uso

Importa el componente en tu proyecto y conserva el código bajo tu control.

tsx
'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.

PropTipoDefaultDescripción
booleantruePulse while loading. false gives a static placeholder. Reduced motion always disables animation.
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.