139 lines
4.8 KiB
TypeScript
139 lines
4.8 KiB
TypeScript
import React from 'react';
|
|
|
|
interface DynamicListSkeletonProps {
|
|
count?: number;
|
|
showHeader?: boolean;
|
|
}
|
|
|
|
/**
|
|
* 动态列表骨架屏组件
|
|
* 遵循前端开发规范的加载状态设计
|
|
*/
|
|
export const DynamicListSkeleton: React.FC<DynamicListSkeletonProps> = ({
|
|
count = 3,
|
|
showHeader = true,
|
|
}) => {
|
|
return (
|
|
<div className="space-y-6 animate-pulse">
|
|
{/* 头部骨架 */}
|
|
{showHeader && (
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<div className="w-5 h-5 bg-gray-200 rounded"></div>
|
|
<div className="w-24 h-5 bg-gray-200 rounded"></div>
|
|
<div className="w-8 h-4 bg-gray-200 rounded"></div>
|
|
</div>
|
|
<div className="w-16 h-8 bg-gray-200 rounded-lg"></div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 动态卡片骨架 */}
|
|
<div className="grid gap-4">
|
|
{[...Array(count)].map((_, index) => (
|
|
<div
|
|
key={index}
|
|
className="bg-white rounded-xl border border-gray-200 p-5"
|
|
style={{ animationDelay: `${index * 0.1}s` }}
|
|
>
|
|
{/* 头部信息骨架 */}
|
|
<div className="flex justify-between items-start mb-4">
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex items-center gap-2 mb-2">
|
|
<div className="w-2 h-2 bg-gray-200 rounded-full"></div>
|
|
<div className="w-32 h-4 bg-gray-200 rounded"></div>
|
|
</div>
|
|
<div className="space-y-2">
|
|
<div className="w-full h-3 bg-gray-200 rounded"></div>
|
|
<div className="w-3/4 h-3 bg-gray-200 rounded"></div>
|
|
</div>
|
|
</div>
|
|
<div className="flex flex-col items-end gap-1 ml-4 flex-shrink-0">
|
|
<div className="w-16 h-3 bg-gray-200 rounded"></div>
|
|
<div className="w-12 h-3 bg-gray-200 rounded"></div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 提示词骨架 */}
|
|
<div className="bg-gray-50 rounded-lg p-3 mb-4 border border-gray-200">
|
|
<div className="w-16 h-3 bg-gray-200 rounded mb-2"></div>
|
|
<div className="space-y-1">
|
|
<div className="w-full h-3 bg-gray-200 rounded"></div>
|
|
<div className="w-2/3 h-3 bg-gray-200 rounded"></div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* 源图片骨架 */}
|
|
<div className="mb-4">
|
|
<div className="w-16 h-3 bg-gray-200 rounded mb-2"></div>
|
|
<div className="aspect-video bg-gray-200 rounded-lg"></div>
|
|
</div>
|
|
|
|
{/* 视频网格骨架 */}
|
|
<div>
|
|
<div className="w-24 h-3 bg-gray-200 rounded mb-3"></div>
|
|
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
|
|
{[...Array(3)].map((_, videoIndex) => (
|
|
<div
|
|
key={videoIndex}
|
|
className="aspect-video bg-gray-200 rounded-lg"
|
|
></div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 紧凑版动态列表骨架屏
|
|
*/
|
|
export const CompactDynamicListSkeleton: React.FC<DynamicListSkeletonProps> = ({
|
|
count = 5,
|
|
showHeader = true,
|
|
}) => {
|
|
return (
|
|
<div className="space-y-4 animate-pulse">
|
|
{/* 头部骨架 */}
|
|
{showHeader && (
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-2">
|
|
<div className="w-4 h-4 bg-gray-200 rounded"></div>
|
|
<div className="w-20 h-4 bg-gray-200 rounded"></div>
|
|
</div>
|
|
<div className="w-12 h-6 bg-gray-200 rounded"></div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 紧凑卡片骨架 */}
|
|
<div className="space-y-3">
|
|
{[...Array(count)].map((_, index) => (
|
|
<div
|
|
key={index}
|
|
className="bg-white rounded-lg border border-gray-200 p-4"
|
|
style={{ animationDelay: `${index * 0.05}s` }}
|
|
>
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-3 flex-1 min-w-0">
|
|
<div className="w-12 h-12 bg-gray-200 rounded-lg flex-shrink-0"></div>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="w-24 h-4 bg-gray-200 rounded mb-1"></div>
|
|
<div className="w-32 h-3 bg-gray-200 rounded"></div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
<div className="w-16 h-3 bg-gray-200 rounded"></div>
|
|
<div className="w-6 h-6 bg-gray-200 rounded"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default DynamicListSkeleton;
|