refactor: UniversalListPage externalIsLoading 지원 및 스켈레톤 개선
- UniversalListPage에 externalIsLoading prop 추가 - CardTransactionDetailClient DevFill 자동입력 기능 추가 - 여러 컴포넌트 로딩 상태 처리 개선 - skeleton 컴포넌트 확장 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -451,7 +451,95 @@ function ListPageSkeleton({
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 12. 페이지 헤더 스켈레톤
|
||||
// 12. 콘텐츠 스켈레톤 (범용 - ContentLoadingSpinner 대체용)
|
||||
// ============================================
|
||||
interface ContentSkeletonProps {
|
||||
/** 스켈레톤 유형 */
|
||||
type?: 'list' | 'detail' | 'form' | 'table' | 'cards';
|
||||
/** 행/카드 개수 (default: 5) */
|
||||
rows?: number;
|
||||
/** 메시지 표시 (deprecated - 스켈레톤은 메시지 없음) */
|
||||
text?: string;
|
||||
}
|
||||
|
||||
function ContentSkeleton({
|
||||
type = 'list',
|
||||
rows = 5,
|
||||
}: ContentSkeletonProps) {
|
||||
switch (type) {
|
||||
case 'detail':
|
||||
return (
|
||||
<div className="p-6 space-y-4 animate-pulse">
|
||||
{/* 상세 정보 그리드 */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<div key={i} className="space-y-2">
|
||||
<Skeleton className="h-4 w-20" />
|
||||
<Skeleton className="h-10 w-full rounded-md" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
case 'form':
|
||||
return (
|
||||
<div className="p-6 space-y-4 animate-pulse">
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<div key={i} className="space-y-2">
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-10 w-full rounded-md" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
case 'table':
|
||||
return (
|
||||
<div className="p-4 animate-pulse">
|
||||
<div className="space-y-3">
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<div key={i} className="flex items-center gap-4">
|
||||
<Skeleton className="h-4 w-4 rounded" />
|
||||
<Skeleton className="h-4 flex-1" />
|
||||
<Skeleton className="h-4 w-20" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
case 'cards':
|
||||
return (
|
||||
<div className="p-4 space-y-3 animate-pulse">
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<div key={i} className="p-4 border rounded-lg space-y-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<Skeleton className="h-5 w-32" />
|
||||
<Skeleton className="h-5 w-16 rounded-full" />
|
||||
</div>
|
||||
<Skeleton className="h-4 w-24" />
|
||||
<Skeleton className="h-4 w-full" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
case 'list':
|
||||
default:
|
||||
return (
|
||||
<div className="p-4 space-y-3 animate-pulse">
|
||||
{Array.from({ length: rows }).map((_, i) => (
|
||||
<div key={i} className="flex items-center gap-3 py-2">
|
||||
<Skeleton className="h-5 w-5 rounded" />
|
||||
<Skeleton className="h-4 w-8" />
|
||||
<Skeleton className="h-4 flex-1" />
|
||||
<Skeleton className="h-8 w-8 rounded" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 13. 페이지 헤더 스켈레톤
|
||||
// ============================================
|
||||
interface PageHeaderSkeletonProps {
|
||||
showActions?: boolean;
|
||||
@@ -498,4 +586,5 @@ export {
|
||||
StatCardGridSkeleton,
|
||||
ListPageSkeleton,
|
||||
PageHeaderSkeleton,
|
||||
ContentSkeleton,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user