Skeleton
A pulsing placeholder block for cards, avatars, and tables while data loads — with the neobrutalist thick-border treatment.
import { Skeleton } from "@/components/ui/skeleton"
export function SkeletonDemo() {The skeleton is a pulsing placeholder that holds a piece of UI's shape while its data loads. It's a single div — no primitive underneath — with animate-pulse, a muted background, and the neobrutalist recipe's thick border.
Reach for it when:
- Cards and lists — mirror the final layout so content pops in without a shift.
- Avatars and media — reserve the circle or thumbnail box before the image arrives.
- Tables and forms — keep rows and fields in place during a slow fetch.
Installation#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/skeleton.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/skeleton.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/skeleton.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/skeleton.json
Copy and paste the following code into your project.
import { cn } from "@/lib/utils"
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="skeleton"
className={cn("animate-pulse rounded border-2 bg-muted", className)}
{...props}
/>
)
}
export { Skeleton }
Update the import paths to match your project setup.
Usage#
import { Skeleton } from "@/components/ui/skeleton"<Skeleton className="h-[20px] w-[100px] rounded-full" />Examples#
Avatar#
import { Skeleton } from "@/components/ui/skeleton"
export function SkeletonAvatar() {Card#
import { Card, CardContent, CardHeader } from "@/components/ui/card"
import { Skeleton } from "@/components/ui/skeleton"
Text#
import { Skeleton } from "@/components/ui/skeleton"
export function SkeletonText() {Form#
import { Skeleton } from "@/components/ui/skeleton"
export function SkeletonForm() {Table#
import { Skeleton } from "@/components/ui/skeleton"
export function SkeletonTable() {RTL#
To enable RTL support in Neobrutalism.com, see the RTL configuration guide.
"use client"
import * as React from "react"Accessibility#
Skeletons are decorative — hide them from assistive tech with aria-hidden="true" so screen readers don't announce empty pulsing boxes. Convey the loading state itself separately: set aria-busy="true" on the region being loaded, or update a visually hidden live region ("Loading results…") that clears when content lands. Once the real content renders, remove the skeletons from the DOM entirely.