# Skeleton

Skeleton is a neobrutalist React component from Cruise UI. Pulsing placeholder blocks while content loads, with text, avatar, card and table-row presets.

Install (with the @cruiseui registry in components.json, see Installation):

```bash
npx shadcn@latest add @cruiseui/skeleton
```

Import: `import { CruiseSkeleton, CruiseSkeletonRegion, CruiseSkeletonText, CruiseSkeletonAvatar, CruiseSkeletonCard, CruiseSkeletonTableRow } from "@/components/cruise/skeleton";`

## When to use

Content that takes a moment to load and has a known shape.

## When not to

Unknown waits or actions (use a Progress spinner). Waits under ~300ms (show nothing).

## Example (React)

```tsx
import {
  CruiseSkeletonAvatar,
  CruiseSkeletonCard,
  CruiseSkeletonRegion,
  CruiseSkeletonTableRow,
  CruiseSkeletonText,
} from "@/components/cruise/skeleton";

export default function SkeletonExample() {
  return (
    <CruiseSkeletonRegion label="Loading orders…" className="grid gap-6 md:grid-cols-2">
      <div className="flex flex-col gap-4">
        <div className="flex items-center gap-3">
          <CruiseSkeletonAvatar />
          <div className="flex-1">
            <CruiseSkeletonText lines={2} />
          </div>
        </div>
        <CruiseSkeletonTableRow />
        <CruiseSkeletonTableRow />
      </div>
      <CruiseSkeletonCard />
    </CruiseSkeletonRegion>
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<div aria-busy="true">
  <span class="visually-hidden">Loading orders…</span>
  <div class="skeleton-stack" aria-hidden="true">
    <span class="skeleton skeleton-circle" style="width: 40px; height: 40px"></span>
    <span class="skeleton skeleton-line"></span>
    <span class="skeleton skeleton-line"></span>
    <span class="skeleton skeleton-line" style="width: 60%"></span>
  </div>
</div>
```

## Props: CruiseSkeleton

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `width?` | `Width<string \| number>` | — | — |
| `height?` | `Height<string \| number>` | — | — |
| `circle?` | `boolean` | `false` | — |
| `className?` | `string` | — | — |

## Props: CruiseSkeletonRegion

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `loading?` | `boolean` | `true` | — |
| `label?` | `string` | `"Loading…"` | — |
| `children` | `ReactNode` | — | — |
| `className?` | `string` | — | — |

## Props: CruiseSkeletonText

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `lines?` | `number` | `3` | — |

## Props: CruiseSkeletonAvatar

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `size?` | `32 \| 40 \| 56` | `40` | — |

## Props: CruiseSkeletonTableRow

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `cells?` | `number` | `3` | — |

## Accessibility

- Skeleton blocks are hidden from screen readers.
- The loading area has aria-busy and a hidden "Loading…".
- Static (no pulse) under reduced motion.
