- Button: suppress react-refresh/only-export-components for buttonVariants re-export - Skeleton: replace empty interface with type alias, replace Math.random() with static widths array Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
61 lines
1.7 KiB
TypeScript
61 lines
1.7 KiB
TypeScript
import { cn } from '@/lib/utils'
|
|
|
|
type SkeletonProps = React.HTMLAttributes<HTMLDivElement>
|
|
|
|
export function Skeleton({ className, ...props }: SkeletonProps) {
|
|
return (
|
|
<div
|
|
className={cn(
|
|
'animate-pulse rounded-lg bg-brand-border',
|
|
className
|
|
)}
|
|
{...props}
|
|
/>
|
|
)
|
|
}
|
|
|
|
export function CardSkeleton({ className }: { className?: string }) {
|
|
return (
|
|
<div className={cn('glass-card-static p-5 space-y-3', className)}>
|
|
<Skeleton className="h-5 w-3/4" />
|
|
<Skeleton className="h-4 w-1/2" />
|
|
<div className="flex gap-2 mt-4">
|
|
<Skeleton className="h-6 w-16 rounded-full" />
|
|
<Skeleton className="h-6 w-20 rounded-full" />
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
const COL_WIDTHS = ['35%', '45%', '25%', '40%', '30%', '50%']
|
|
|
|
export function TableRowSkeleton({ cols = 4 }: { cols?: number }) {
|
|
return (
|
|
<div className="flex items-center gap-4 px-4 py-3">
|
|
{Array.from({ length: cols }).map((_, i) => (
|
|
<Skeleton
|
|
key={i}
|
|
className="h-4"
|
|
style={{ width: COL_WIDTHS[i % COL_WIDTHS.length] }}
|
|
/>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export function ListSkeleton({ count = 5, className }: { count?: number; className?: string }) {
|
|
return (
|
|
<div className={cn('space-y-3', className)}>
|
|
{Array.from({ length: count }).map((_, i) => (
|
|
<div key={i} className="flex items-center gap-3 px-4 py-3 rounded-lg bg-white/[0.02]">
|
|
<Skeleton className="size-8 rounded-full shrink-0" />
|
|
<div className="flex-1 space-y-2">
|
|
<Skeleton className="h-4 w-2/3" />
|
|
<Skeleton className="h-3 w-1/3" />
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)
|
|
}
|