A client-side React component and companion hook for managing content loading states with skeleton overlays, smooth transitions, and stable layout dimensions.
## Key Components
### `ContentLoadingContainer`
A wrapper component that overlays a skeleton placeholder during loading, then fades in the actual content once data is ready. Prevents layout jumps by preserving container dimensions throughout the loading lifecycle.
**Props:**
| Prop | Type | Default | Description |
|---|---|---|---|
| `isLoading` | `boolean` | — | Controls skeleton/content visibility |
| `children` | `ReactNode` | — | Content rendered when not loading |
| `skeletonComponent` | `ReactNode` | — | Skeleton UI shown during loading |
| `className` | `string?` | — | Additional Tailwind classes |
| `minHeight` | `string?` | `"min-h-[300px] md:min-h-[800px]"` | Prevents layout jumps |
| `loadingOpacity` | `number?` | `1` | Skeleton overlay opacity (0–1) |
| `transitionDuration` | `number?` | `300` | Fade transition in milliseconds |
### `useContentLoading`
A utility hook that returns accessibility attributes and layout helpers scoped to content type.
**Returns:**
| Key | Description |
|---|---|
| `containerProps` | `aria-busy` and `data-loading` attributes |
| `getSkeletonCount(type)` | Returns skeleton card count (12 for `vendor`, 6 for `blog`) |
| `getMinHeight(type)` | Returns appropriate min-height class per content type |
## Usage Example
```typescript
import {
ContentLoadingContainer,
useContentLoading
} from "./content-loading-container"
import { CardSkeletonGrid } from "./card-skeleton-grid"
function VendorSection({ vendors, isLoading }) {
const { getMinHeight, getSkeletonCount } = useContentLoading(isLoading)
return (
}
minHeight={getMinHeight("vendor")}
transitionDuration={400}
>
)
}
```
## Accessibility
The component includes built-in ARIA support: `role="region"` with `aria-live="polite"` on the wrapper, `role="status"` on the skeleton overlay, and `aria-hidden` on content while loading — ensuring screen readers announce state transitions correctly.
## Source
[`content-loading-container.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/content-loading-container.tsx)