# Skeleton
A placeholder loading component that mimics the shape of content while it loads. Supports box, pill, and circle shapes with configurable dimensions.
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function SkeletonDemo() {
return (
` element.
## Examples
### Basic usage
Render a `Skeleton` by giving it a `width` and `height`:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function BasicSkeleton() {
return
;
}
```
If the `width` and `height` of the `Skeleton` are the same, you can also use the `size` prop to set both the `width` and `height` at the same time:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function SizedSkeleton() {
return
;
}
```
### Skeleton shapes
A `Skeleton` can be rendered in one of three shapes: `"box"`, `"pill"`, or `"circle"`. The default shape is `"box"`, which is a rectangle with slightly rounded corners:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function BoxSkeleton() {
return
;
}
```
Pass `shape="circle"` to render an ellipse:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function CircleSkeleton() {
return
;
}
```
Pass `shape="pill"` to render a rectangle with corners that round to a semicircle:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function PillSkeleton() {
return
;
}
```
### Rendering children
`Skeleton` can be rendered with content, in which case the `Skeleton` takes the dimensions of the bounding box of its children, so you don't need to pass a `width` and `height`:
```tsx demo
import { Skeleton } from "@tenstorrent/vesper/skeleton";
export default function SkeletonWithChildren() {
return (
);
}
```
### Conditional rendering
You will typically be using `Skeleton` to conditionally render loading states for your components. The easiest way to do this is to simply render the `Skeleton` in place of other elements while they are loading:
```tsx
import { Skeleton } from "@tenstorrent/vesper/skeleton";
import { Typography } from "@tenstorrent/vesper/typography";
export default function LoadingContent({ loading }: { loading: boolean }) {
if (loading) {
return
;
}
return
Content loaded!;
}
```
You can also use the `show` prop to hide/show `Skeleton` children conditionally. When `show` is set to `true`, the `Skeleton` will mask its children. When `show` is set to `false`, the children are rendered in place with no masking instead.
In the example below, we fetch data asynchronously in a `useEffect` callback, masking the `Skeleton`'s children while the request is being made:
```tsx
import { useEffect, useState } from "react";
import { Skeleton } from "@tenstorrent/vesper/skeleton";
import { Typography } from "@tenstorrent/vesper/typography";
export default function MaskedChildrenExample() {
const [data, setData] = useState
(null);
useEffect(() => {
const controller = new AbortController();
const signal = controller.signal;
fetch("https://example.com/api/v1/data", { signal })
.then((res) => res.json())
.then((data) => setData(data))
.catch(() => {
if (!signal.aborted) setData("Failed to fetch data");
});
return () => controller.abort();
}, []);
return (
{data ?? "Fallback text while data is loading"}
);
}
```
### Usage with Suspense
`Skeleton` can also be used as a [Suspense](https://react.dev/reference/react/Suspense) fallback. This is useful for when you are reading data from a promise client-side using `use`, streaming data from [Server Components](https://react.dev/reference/rsc/server-components), or lazy-loading component code with [lazy](https://react.dev/reference/react/lazy):
```tsx
import { Suspense, use } from "react";
import { Avatar } from "@tenstorrent/vesper/avatar";
import { Skeleton } from "@tenstorrent/vesper/skeleton";
function UserAvatar({ userId }: { userId: string }) {
const avatar = use(fetchAvatar(userId));
return ;
}
export default function UserProfile() {
return (
}>
);
}
```