Loading skeleton components that mirror the exact layout of `DeviceCard` to prevent layout shifts during data fetching. ## Key Components ### `DeviceCardSkeleton` A single animated placeholder card replicating the three-row structure of `DeviceCard`: - **Row 1:** Device icon + device name + more button - **Row 2:** OS badge + organization icon + organization name - **Row 3:** Status badge + last seen timestamp Uses `animate-pulse` on placeholder elements and matches exact dimensions to eliminate layout jumps. | Prop | Type | Description | |------|------|-------------| | `className` | `string` | Optional additional CSS classes | ### `DeviceCardSkeletonGrid` A responsive grid wrapper that renders `count` skeleton cards, matching the `DevicesGrid` column layout. | Prop | Type | Default | Description | |------|------|---------|-------------| | `count` | `number` | `12` | Number of skeleton cards to render | | `className` | `string` | — | Optional additional CSS classes | **Responsive breakpoints:** | Breakpoint | Columns | |-----------|---------| | Mobile | 1 | | `md` (tablet) | 2 | | `lg` (desktop) | 4 | ## Usage Example ```typescript // Single skeleton card import { DeviceCardSkeleton } from "./device-card-skeleton" function DevicePanel({ isLoading }: { isLoading: boolean }) { if (isLoading) return return } // Skeleton grid during list fetch import { DeviceCardSkeletonGrid } from "./device-card-skeleton" function DevicesPage({ isLoading, devices }) { if (isLoading) return return } ``` **Source:** [`device-card-skeleton.tsx`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/device-card-skeleton.tsx)