Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 1x 8x 24x | import React from 'react';
/**
* Props for LoadingSkeleton component
*/
export interface LoadingSkeletonProps {
/**
* Number of skeleton lines to display
* @default 3
*/
lines?: number;
/**
* Optional test ID for automated testing
*/
testId?: string;
/**
* Optional CSS class name
*/
className?: string;
}
/**
* Loading skeleton component for better perceived performance
*
* ## Business Perspective
*
* Improves perceived performance by showing content placeholders while
* data loads, making the application feel more responsive and reducing
* user anxiety during loading operations. 📊
*
* ## Technical Perspective
*
* Provides animated placeholder content that mimics the structure of
* the actual content being loaded. Uses CSS animations for smooth
* skeleton shimmer effect.
*
* @example
* ```tsx
* // Default 3-line skeleton
* <LoadingSkeleton />
*
* // Custom number of lines
* <LoadingSkeleton lines={5} />
*
* // With custom test ID
* <LoadingSkeleton lines={4} testId="metrics-skeleton" />
* ```
*/
export const LoadingSkeleton: React.FC<LoadingSkeletonProps> = ({
lines = 3,
testId = 'loading-skeleton',
className = ''
}) => {
return (
<div
className={`animate-pulse space-y-4 ${className}`}
data-testid={testId}
role="status"
aria-label="Loading content"
>
{Array.from({ length: lines }).map((_, i) => (
<div
key={`skeleton-line-${i}`}
className="h-4 bg-gray-200 dark:bg-gray-700 rounded"
data-testid={`${testId}-line-${i}`}
aria-hidden="true"
/>
))}
<span className="sr-only">Loading...</span>
</div>
);
};
export default LoadingSkeleton;
|