Spaces:
Sleeping
Sleeping
| import './Loader.css'; | |
| /** | |
| * Loader component — Spinner + Skeleton variants | |
| * @param {Object} props | |
| * @param {boolean} [props.fullScreen] - Show centered full-screen loader | |
| * @param {string} [props.size] - 'sm' | 'md' | 'lg' | |
| * @param {string} [props.text] - Loading text | |
| */ | |
| export default function Loader({ fullScreen = false, size = 'md', text = '' }) { | |
| const spinner = ( | |
| <div className={`loader loader--${size}`}> | |
| <div className="loader__spinner"> | |
| <div className="loader__ring"></div> | |
| <div className="loader__ring"></div> | |
| <div className="loader__ring"></div> | |
| <img src="/logo.png" alt="" className="loader__logo" /> | |
| </div> | |
| {text && <p className="loader__text">{text}</p>} | |
| </div> | |
| ); | |
| if (fullScreen) { | |
| return <div className="loader__fullscreen">{spinner}</div>; | |
| } | |
| return spinner; | |
| } | |
| /** | |
| * Skeleton — Placeholder loading state | |
| */ | |
| export function Skeleton({ width = '100%', height = '20px', radius = '8px', className = '' }) { | |
| return ( | |
| <div | |
| className={`skeleton ${className}`} | |
| style={{ width, height, borderRadius: radius }} | |
| /> | |
| ); | |
| } | |
| /** | |
| * Card Skeleton | |
| */ | |
| export function CardSkeleton({ count = 1 }) { | |
| return ( | |
| <> | |
| {Array.from({ length: count }).map((_, i) => ( | |
| <div key={i} className="card" style={{ padding: '1rem' }}> | |
| <Skeleton height="200px" radius="12px" /> | |
| <div style={{ padding: '1rem 0' }}> | |
| <Skeleton width="40%" height="14px" /> | |
| <div style={{ height: '8px' }} /> | |
| <Skeleton width="80%" height="20px" /> | |
| <div style={{ height: '8px' }} /> | |
| <Skeleton width="100%" height="14px" /> | |
| <div style={{ height: '4px' }} /> | |
| <Skeleton width="60%" height="14px" /> | |
| </div> | |
| </div> | |
| ))} | |
| </> | |
| ); | |
| } | |