Files
mixvideo-v2/apps/desktop/src/components/DynamicListSkeleton.tsx
2025-07-18 18:45:13 +08:00

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;