# ASCII Skeleton

> Loading placeholders that shimmer through shade blocks.

Category: Interface. Docs: https://asciicn.sumak.dev/docs/ascii-skeleton

## Installation

```bash
npx shadcn@latest add @asciicn/ascii-skeleton
```

Needs the `@asciicn` registry in components.json: `"registries": { "@asciicn": "https://asciicn.sumak.dev/r/{name}.json" }`.

## Usage

```tsx
import { AsciiSkeleton } from "@/components/ascii/ascii-skeleton"

<div aria-busy="true">
  <AsciiSkeleton lines={3} />
</div>
```

## Examples

### Loading feed

Compose the variants into the shape of the content on its way. Every skeleton on the page shares one clock, so the wave runs across them in step.

```tsx
<div aria-busy="true" className="flex gap-3 text-muted-foreground/60">
  <AsciiSkeleton variant="avatar" />
  <div className="flex flex-1 flex-col gap-2">
    <AsciiSkeleton lines={1} width={14} />
    <AsciiSkeleton lines={2} />
  </div>
</div>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `"text" | "block" | "avatar"` | `"text"` | Text rows are spaced and taper on the last line; block and avatar are solid. |
| `lines` | `number` | `3 (2 for block, avatar)` | Rows of glyphs. |
| `width` | `number | string` | `"100%" (4 for avatar)` | A number is characters, a string any CSS width. |

## Notes

- **Accessibility.** The skeleton is `aria-hidden`, since shade glyphs mean nothing to a screen reader. Put `aria-busy="true"` on the region that is loading and remove it when content arrives.
- **Motion.** A ░▒▓ crest travels diagonally across the rows. Under `prefers-reduced-motion` it is plain ░.
- **Theming.** Glyphs take the CSS `color`. `text-muted-foreground/60` reads as a placeholder without competing with real content.
- **Performance.** One 60 ms timer drives every skeleton on the page and stops when the last one unmounts. Server rendering outputs the static ░ frame, so hydration matches.
