Misc
Skeleton
A grey pulsing placeholder that holds the shape of content that is still loading.
Import
import { Skeleton } from "@booleanpress/ui/skeleton"Usage
A skeleton is an empty div with a pulse. You size and shape it with classes, so it matches the content that will replace it.
import { Skeleton } from "@booleanpress/ui/skeleton"
export function LogLoading() {
return (
<div aria-busy="true" className="flex flex-col gap-2">
<p role="status" className="sr-only">Loading the email log</p>
<Skeleton className="h-4 w-full" />
<Skeleton className="h-4 w-2/3" />
</div>
)
}Use it for the first load only. When a table already has rows and refreshes, keep the rows and dim them, so they do not jump. Match the placeholder's size to the real content so the page does not shift when it arrives.
Examples
Lines
Three text lines of different widths.
Loading the message
Profile
A round placeholder for an avatar beside two lines.
Loading the person
Table rows
Rows of two cells, with a button that swaps to the loaded content.
Accessibility
- Semantics
- A
divwith no role. It is invisible to assistive technology. - Labels
- Say that something is loading yourself: a visually hidden
role="status"message, andaria-busy="true"on the region being filled, as the examples do. - Focus
- A skeleton takes no focus and has no keyboard behaviour of its own, so it has no keyboard rows.
- Known limits
- The pulse is
animate-pulse.theme.cssstops it underprefers-reduced-motion, and the grey block stays. - A skeleton alone tells a screen-reader user nothing. Never ship it without the status text.
- The pulse is
Keyboard
| Key | Behaviour |
|---|
API
Skeleton
Renders a div and passes it every other prop.
Every part takes className, merged with its defaults by cn(), and ref, which reaches the element it renders.
Data attributes: data-slot="skeleton" (Skeleton).
Theming
The fill is --accent.
The tokens its classes read. Change their values in your theme, and it follows.
| Token | Used for |
|---|---|
--accent | background |