# Skeleton

> Loading placeholder matching content layout. Shimmer animation with reduced-motion support.

- Available in: `@sisyphos-ui/react`, `@sisyphos-ui/vue`, `@sisyphos-ui/angular`
- Docs: https://www.sisyphosui.com/docs/components/skeleton

## Installation

Pick the framework binding that matches your stack:

```bash
pnpm add @sisyphos-ui/react   # React 18+
pnpm add @sisyphos-ui/vue     # Vue 3+
pnpm add @sisyphos-ui/angular # Angular 17+
```

## Import

```tsx
import "@sisyphos-ui/react/styles.css";
import { Skeleton } from "@sisyphos-ui/react";
```

## Framework usage

### React 18+

```tsx
import { Skeleton } from "@sisyphos-ui/react";

export const Loading = () => <Skeleton width="60%" height={16} />;
```

### Vue 3+

```vue
<script setup lang="ts">
import { Skeleton } from "@sisyphos-ui/vue";
</script>

<template>
  <Skeleton width="60%" :height="16" />
</template>
```

### Angular 17+

```ts
import { Component } from "@angular/core";
import { Skeleton } from "@sisyphos-ui/angular";

@Component({
  selector: "app-loading",
  standalone: true,
  imports: [Skeleton],
  template: `<sui-skeleton width="60%" [height]="16" />`,
})
export class LoadingComponent {}
```

## Examples

### Default

Mix `Skeleton` shapes with `SkeletonText` for realistic loading placeholders.

```tsx
import { Skeleton, SkeletonText } from "@sisyphos-ui/react";

export function Example() {
  return (
    <div className="w-full max-w-sm space-y-3">
      <div className="flex items-center gap-3">
        <Skeleton shape="circular" width={40} height={40} />
        <div className="flex-1">
          <Skeleton height={12} width="60%" />
          <div className="mt-2">
            <Skeleton height={10} width="40%" />
          </div>
        </div>
      </div>
      <SkeletonText lines={3} />
    </div>
  );
}
```

### Animation modes

`animation` supports `shimmer` (default), `pulse`, and `none` for reduced motion.

```tsx
import { Skeleton } from "@sisyphos-ui/react";

export function Example() {
  return (
    <>
      <Skeleton animation="shimmer" height={10} width="70%" />
      <Skeleton animation="pulse"   height={10} width="70%" />
      <Skeleton animation="none"    height={10} width="70%" />
    </>
  );
}
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| shape | `"rectangular" \| "circular" \| "text"` | `"rectangular"` | Placeholder shape; `text` defaults to a `1em`-tall line. |
| animation | `"shimmer" \| "pulse" \| "none"` | `"shimmer"` | Loading animation style. |
| width | `number \| string` | — | CSS width (numbers are treated as px). |
| height | `number \| string` | — | CSS height (numbers are treated as px). |
| radius | `number \| string` | — | Corner radius; ignored when `shape` is `circular`. |
| children | `ReactNode` | — | When provided, the skeleton wraps the children and derives its dimensions from them if `width`/`height` are omitted. |

## Accessibility notes

- The root is `aria-hidden="true"` — the placeholder is completely invisible to assistive technology.
- Wrapped children render inside the hidden ghost span only to size the skeleton; they are never announced while loading.
- No role or live region is added — announce the loading state elsewhere (e.g. a `Spinner` or `aria-busy` on the containing region).

<!-- exports: { "Skeleton": "@sisyphos-ui/react" } -->