# 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 (
); } ``` ## Options | Prop | Type | Description | Default | | ---------- | ----------------------------- | -------------------------------------------------------------------------------------------------------- | ------- | | `shape` | `"box" \| "pill" \| "circle"` | The shape of the skeleton placeholder. | `"box"` | | `size` | `number \| string` | Sets both width and height simultaneously. Overrides individual `width` and `height` props. | — | | `width` | `number \| string` | The width of the skeleton. | — | | `height` | `number \| string` | The height of the skeleton. | — | | `show` | `boolean` | When `true`, renders the skeleton overlay. When `false`, renders only the children without the skeleton. | `true` | | `children` | `ReactNode` | Optional content rendered behind the skeleton overlay. | — | Any additional props are forwarded to the wrapping `
` 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 ( }> ); } ```