# Skeleton

A pulse-animated loading placeholder. Compose a named region with decorative bones sized by CSS lengths.

## Installation

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";
```
## Usage

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function BasicDemo() {
  return (
    <div className="w-80">
      <Skeleton aria-label="Loading">
        <SkeletonItem blockSize="40px" />
        <SkeletonItem blockSize="40px" inlineSize="60%" />
      </Skeleton>
    </div>
  );
}
```
## Examples

### Stretch

`stretch="full"` (the default) takes the parent's inline size; `stretch="auto"` fits the region to its widest sized bone. A bone is full width unless you pass `inlineSize` for a percentage or fixed length.

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function StretchDemo() {
  return (
    <div className="flex w-80 flex-col gap-6">
      <Skeleton aria-label="Full width bars">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
      <Skeleton aria-label="Fixed width bars" stretch="auto">
        <SkeletonItem blockSize="32px" inlineSize="8rem" />
        <SkeletonItem blockSize="32px" inlineSize="5rem" />
      </Skeleton>
    </div>
  );
}
```

### Layout

`layout="stack"` (the default) is a column; `layout="row"` places bones on one line.

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function LayoutDemo() {
  return (
    <div className="flex w-80 flex-col gap-6">
      <Skeleton aria-label="Stacked bones" layout="stack">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
      <Skeleton aria-label="Row of bones" layout="row">
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
        <SkeletonItem blockSize="32px" />
      </Skeleton>
    </div>
  );
}
```

### Circle

`variant="circle"` is a disc. A lone `blockSize` is the diameter.

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function CircleDemo() {
  return (
    <Skeleton aria-label="Loading avatar" stretch="auto" layout="row">
      <SkeletonItem variant="circle" blockSize="40px" />
      <SkeletonItem variant="circle" blockSize="2.5rem" />
    </Skeleton>
  );
}
```

### Fill slot

Size the region with `blockSize` and omit size on the item so the bone fills the slot. In a region without a `blockSize`, an unsized bone is one text line tall rather than invisible.

```tsx
import { Skeleton, SkeletonItem } from "@makeplane/propel/components/skeleton";

export default function FillSlotDemo() {
  return (
    <div className="w-80">
      <Skeleton aria-label="Loading chart" blockSize="10rem">
        <SkeletonItem />
      </Skeleton>
    </div>
  );
}
```
## API Reference

### Skeleton

A pulse-animated loading region that groups placeholder bones. Grafts `role="status"` onto the
styled `elements` `Skeleton` and requires an `aria-label` so the region is never unnamed. Compose
`SkeletonItem` children for the bones.

`layout` and `stretch` own the region's flex axis and inline size. Exact geometry uses
`blockSize` / `inlineSize` (not `height` / `width`).

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `aria-label` (required) | `string` | — | Accessible name for the loading region. |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, {}>` | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `layout` | `"stack" \| "row"` | `"stack"` | Arrangement of bones: `stack` is a column, `row` is a row. |
| `stretch` | `"auto" \| "full"` | `"full"` | `full` takes the parent's inline size; `auto` is fit-content — the region shrinks to the widest bone that carries an `inlineSize`. A passed `inlineSize` overrides both. |
| `blockSize` | `string` | — | CSS block-size (height) of the loading region, e.g. `"10rem"` or `"160px"`. Omit to size to the bones inside. |
| `inlineSize` | `string` | — | CSS inline-size (width) of the loading region, e.g. `"8rem"`. Omit to follow `stretch`. Passing a length overrides `stretch`. |

### SkeletonItem

One decorative placeholder bone. `variant="bar"` (default) is a rounded-md block;
`variant="circle"` is a disc. Full width unless `inlineSize` narrows it. Bakes `aria-hidden` —
the enclosing `Skeleton` names the loading region.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, {}>` | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `variant` | `"circle" \| "bar"` | `"bar"` | Look of the bone: `bar` is a rounded-md block; `circle` is a disc. |
| `blockSize` | `string` | — | CSS block-size (height) of the bone, e.g. `"50px"`, `"100%"`, or `"1rem"`. Omit to fill a region that has a `blockSize`; in a region without one the bone is one text line tall (16px). On `variant="circle"`, a lone `blockSize` is also the inline size (square). |
| `inlineSize` | `string` | — | CSS inline-size (width) of the bone, e.g. `"70px"` or `"60%"`. Omit for the parent's full inline size. |
