Components
Skeleton
Layout-matching shimmer placeholder for loading states where the final structure is known.
Overview
Skeleton is the preferred loading primitive when the final layout is already known.
It renders a gray shimmer placeholder and is commonly used for:
- page headers and body regions
- table rows and cells
- cards and grid items
- avatars and other fixed-shape content
Basic Usage
<div className="space-y-3">
<Skeleton className="h-6 w-48" />
<Skeleton className="h-32 w-full" />
</div>Layout-Matching Example
<div className="h-full flex flex-col">
<div className="px-6 py-4 border-b border-default">
<Skeleton className="h-8 w-48" />
</div>
<div className="flex-1 p-6">
<Skeleton className="h-64 w-full" />
</div>
</div>This mirrors the pattern used in ProjectDetail.tsx.
Props
Skeleton supports standard HTMLAttributes<HTMLSpanElement>, including:
classNamestylearia-*- data attributes
Sizing and shape are controlled entirely through classes such as h-*, w-*, and rounded-*.
Important Behavior
- renders as a block-level
span - includes shimmer animation by default
- sets
aria-live="polite"andaria-busy="true"
Brand Dashboard And Shared Usage
| Pattern | Path | Notes |
|---|---|---|
| Full page-region placeholder | fsai/apps/brand-dashboard/src/pages/Projects/ProjectDetail/ProjectDetail.tsx | Good example of matching the eventual page structure. |
| In-table progressive loading | fsai/apps/brand-dashboard/src/pages/Marketing/Finder/FinderResultsTable.tsx | Skeleton cells mixed into a real table flow. |
| Card loading state | fsai/apps/brand-dashboard/src/pages/Helpdesk/components/FeaturedCarousel.tsx | Card-shaped skeletons preserve layout and rhythm. |
| Inline control placeholder | fsai/apps/brand-dashboard/src/pages/Home/CalendarSidebar/CalendarSidebar.components.tsx | Small text-line skeletons inside a loaded surface. |
| Primitive-level loading | fsai/packages/shared-ui/src/primitives/Avatar/Avatar.tsx | Avatar switches to a size-matched skeleton during loading. |
Guidelines
- Do prefer
Skeletonwhen the final layout is known - Do match the approximate shape of the real content
- Do use
Spinnerinstead when the layout is unknown or the load is purely transactional - Don't replace a well-understood page structure with a centered spinner if a skeleton would preserve context better