forked from sagnik/Velocity-OS
63 lines
1.5 KiB
TypeScript
63 lines
1.5 KiB
TypeScript
import { motion } from 'framer-motion';
|
|
|
|
/**
|
|
* PillarSkeleton
|
|
* Loading state shown by React Suspense while lazy pillar components load.
|
|
* Matches the approximate layout of each pillar to avoid layout shift.
|
|
*/
|
|
export function PillarSkeleton() {
|
|
return (
|
|
<motion.div
|
|
style={{
|
|
padding: 'var(--space-8)',
|
|
display: 'flex',
|
|
flexDirection: 'column',
|
|
gap: 'var(--space-5)',
|
|
}}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
transition={{ duration: 0.2 }}
|
|
>
|
|
{/* Page title skeleton */}
|
|
<div
|
|
className="shimmer"
|
|
style={{
|
|
height: 36,
|
|
width: 200,
|
|
borderRadius: 'var(--radius-md)',
|
|
background: 'var(--glass-bg)',
|
|
}}
|
|
/>
|
|
|
|
{/* Card row skeleton */}
|
|
<div style={{ display: 'flex', gap: 'var(--space-4)' }}>
|
|
{[0, 1, 2].map(i => (
|
|
<div
|
|
key={i}
|
|
className="shimmer"
|
|
style={{
|
|
flex: 1,
|
|
height: 96,
|
|
borderRadius: 'var(--radius-xl)',
|
|
background: 'var(--glass-bg)',
|
|
}}
|
|
/>
|
|
))}
|
|
</div>
|
|
|
|
{/* Content area skeleton */}
|
|
{[0, 1, 2].map(i => (
|
|
<div
|
|
key={i}
|
|
className="shimmer"
|
|
style={{
|
|
height: 80,
|
|
borderRadius: 'var(--radius-lg)',
|
|
background: 'var(--glass-bg)',
|
|
}}
|
|
/>
|
|
))}
|
|
</motion.div>
|
|
);
|
|
}
|