= {
text: { width: "100%", height: "1em" },
heading: { width: "60%", height: "1.5em" },
paragraph: { width: "100%", height: "1em" },
card: { width: "100%", height: "120px" },
button: { width: "120px", height: "40px" },
avatar: { width: "40px", height: "40px" },
image: { width: "100%", height: "200px" },
list: { width: "100%", height: "40px" },
circular: { width: "40px", height: "40px" },
};
const d = defaults[variant];
const w = width || d.width;
const h = height || d.height;
// Build style object
const style: React.CSSProperties = {
width: typeof w === "number" ? `${w}px` : w,
height: typeof h === "number" ? `${h}px` : h,
};
// Animation classes
const animationClasses = animated ? "animate-skeleton-pulse" : "";
// Variant-specific classes (reserved)
const _variantClasses = clsx({
circular: "rounded-full",
card: "rounded-lg",
button: "rounded-lg",
avatar: "rounded-full",
image: "rounded-lg",
// Default to rounded for text/paragraph/heading/list
});
if (variant === "paragraph" && lines > 1) {
return (
{Array.from({ length: lines }).map((_, i) => (
))}
);
}
if (variant === "list" && lines > 1) {
return (
{Array.from({ length: lines }).map((_, i) => (
))}
);
}
return (
);
}
// =============================================================================
// Skeleton Containers
// =============================================================================
// Card skeleton (matching SharedCard)
export function SkeletonCard({
lines = 3,
className,
...props
}: { lines?: number } & Omit) {
return (
{Array.from({ length: lines }).map((_, i) => (
))}
);
}
// Button skeleton
export function SkeletonButton({ className, ...props }: Omit) {
return (
);
}
// Input skeleton
export function SkeletonInput({ className, ...props }: Omit) {
return (
);
}
// Avatar skeleton
export function SkeletonAvatar({
size = 40,
className,
...props
}: { size?: number } & Omit) {
return (
);
}