thirukalyanamweb/src/components/common/Skeleton.jsx

73 lines
1.6 KiB
JavaScript

import React, { useEffect } from "react";
const STYLE_ID = "skeleton-shimmer-styles";
const injectSkeletonStyles = () => {
if (typeof document === "undefined") return;
if (document.getElementById(STYLE_ID)) return;
const style = document.createElement("style");
style.id = STYLE_ID;
style.textContent = `
.skeleton-shimmer {
position: relative;
overflow: hidden;
background: #e5e7eb;
}
.skeleton-shimmer::after {
content: "";
position: absolute;
inset: 0;
transform: translateX(-100%);
background: linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.7) 50%, rgba(255,255,255,0) 100%);
animation: skeleton-shimmer 1.6s infinite;
}
@keyframes skeleton-shimmer {
100% { transform: translateX(100%); }
}
`;
document.head.appendChild(style);
};
export const Skeleton = ({
width = "100%",
height = 12,
rounded = 6,
className = "",
}) => {
useEffect(() => {
injectSkeletonStyles();
}, []);
return (
<div
className={`skeleton-shimmer ${className}`}
style={{ width, height, borderRadius: rounded }}
/>
);
};
export const SkeletonText = ({
lines = 3,
gap = 10,
height = 12,
className = "",
}) => {
useEffect(() => {
injectSkeletonStyles();
}, []);
return (
<div className={className} style={{ display: "grid", gap }}>
{Array.from({ length: lines }).map((_, idx) => (
<Skeleton
key={idx}
height={height}
width={idx === lines - 1 ? "70%" : "100%"}
/>
))}
</div>
);
};
export default Skeleton;