Import
import { Skeleton } from '@raystack/apsara';
Usage
Multiple lines
Custom dimensions
<Skeleton width={200} height={20} />
<Skeleton width="100%" height="200px" />
Inline skeleton
<div>
<Skeleton inline width={100} /> is loading...
</div>
Custom border radius
<Skeleton borderRadius={"var(--rs-radius-4)"} width={200} height={200} />
<Skeleton borderRadius="50%" width={48} height={48} />
Without animation
<Skeleton enableAnimation={false} />
Custom duration
<Skeleton duration={2.5} />
Custom colors
<Skeleton
baseColor="#e0e0e0"
highlightColor="#f5f5f5"
/>
Loading patterns
Card skeleton
import { Card, Flex } from '@raystack/apsara';
function CardSkeleton() {
return (
<Card>
<Flex direction="column" gap="3">
<Skeleton width={48} height={48} borderRadius="50%" />
<Skeleton width="60%" height={24} />
<Skeleton count={3} />
</Flex>
</Card>
);
}
List skeleton
function ListSkeleton() {
return (
<div>
{[...Array(5)].map((_, i) => (
<Flex key={i} gap="3" align="center" style={{ marginBottom: '1rem' }}>
<Skeleton width={40} height={40} borderRadius="50%" />
<div style={{ flex: 1 }}>
<Skeleton width="80%" />
<Skeleton width="60%" />
</div>
</Flex>
))}
</div>
);
}
Table skeleton
function TableSkeleton() {
return (
<table style={{ width: '100%' }}>
<thead>
<tr>
<th><Skeleton width="100%" /></th>
<th><Skeleton width="100%" /></th>
<th><Skeleton width="100%" /></th>
</tr>
</thead>
<tbody>
{[...Array(5)].map((_, i) => (
<tr key={i}>
<td><Skeleton /></td>
<td><Skeleton /></td>
<td><Skeleton /></td>
</tr>
))}
</tbody>
</table>
);
}
Profile skeleton
function ProfileSkeleton() {
return (
<Flex direction="column" align="center" gap="4">
<Skeleton width={120} height={120} borderRadius="50%" />
<Skeleton width={200} height={28} />
<Skeleton width={300} height={20} />
<Skeleton width="100%" height={100} />
</Flex>
);
}
Using Skeleton.Provider
<Skeleton.Provider
baseColor="#e0e0e0"
highlightColor="#f5f5f5"
duration={2}
>
<Skeleton width={200} />
<Skeleton width={300} />
<Skeleton width={150} />
</Skeleton.Provider>
Conditional rendering
function UserProfile() {
const { user, isLoading } = useUser();
if (isLoading) {
return (
<div>
<Skeleton width={48} height={48} borderRadius="50%" />
<Skeleton width={200} height={24} />
<Skeleton count={2} />
</div>
);
}
return (
<div>
<img src={user.avatar} alt={user.name} />
<h2>{user.name}</h2>
<p>{user.bio}</p>
</div>
);
}
API reference
Skeleton
Width of the skeleton. Can be a number (px) or string (e.g., “100%”, “200px”). Defaults to “100%” for block elements or “50px” for inline elements.
height
string | number
default:"var(--rs-space-4)"
Height of the skeleton. Can be a number (px) or string (e.g., “100px”, “2rem”).
borderRadius
string | number
default:"var(--rs-radius-2)"
Border radius of the skeleton. Can be a number (px) or string.
When true, renders the skeleton as an inline element.
Number of skeleton lines to render.
Controls whether the skeleton displays the shimmer animation.
Duration of the animation in seconds.
Base color of the skeleton. Overrides the default theme color.
Highlight color used in the shimmer animation. Overrides the default theme color.
Additional CSS class names to apply to the skeleton.
Inline styles to apply to the skeleton.
CSS class names to apply to the container element.
Inline styles to apply to the container element.
Skeleton.Provider
Provides shared configuration for multiple skeleton components.
Base color applied to all child skeletons.
Highlight color applied to all child skeletons.
Animation duration applied to all child skeletons.
Controls animation for all child skeletons.
The skeleton components to be wrapped by the provider.