first commit
Some checks failed
Build / run (push) Has been cancelled

This commit is contained in:
maher
2025-10-29 11:42:25 +01:00
commit 703f50a09d
4595 changed files with 385164 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
.skeleton:before {
content: "\00a0";
}
.skeleton-wave {
animation: skeleton-wave 2s ease-in-out infinite;
background-size: 200px 100%;
background-image: linear-gradient(
90deg,
rgba(255, 255, 255, 0),
rgba(255, 255, 255, 0.6),
rgba(255, 255, 255, 0)
);
}
.dark .skeleton-wave {
background-image: linear-gradient(
90deg,
rgba(255, 255, 255, 0),
rgba(255, 255, 255, 0.15),
rgba(255, 255, 255, 0)
);
}
.skeleton-pulsate {
animation: skeleton-pulsate 1.5s ease-in-out infinite;
animation-delay: 0.5s;
}
@keyframes skeleton-wave {
0% {
background-position: -200px 0;
}
100% {
background-position: calc(200px + 100%) 0;
}
}
@keyframes skeleton-pulsate {
0% {
opacity: 1;
}
50% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}

View File

@@ -0,0 +1,61 @@
import clsx from 'clsx';
interface SkeletonProps {
variant?: 'avatar' | 'text' | 'rect' | 'icon';
animation?: 'pulsate' | 'wave' | null; // disable animation completely with null
className?: string;
size?: string;
display?: string;
radius?: string;
style?: React.CSSProperties;
}
export function Skeleton({
variant = 'text',
animation = 'wave',
size,
className,
display = 'block',
radius = 'rounded',
style,
}: SkeletonProps) {
return (
<span
style={style}
className={clsx(
'skeleton relative overflow-hidden bg-fg-base/4 bg-no-repeat will-change-transform',
radius,
skeletonSize({variant, size}),
display,
variant === 'text' && 'origin-[0_55%] scale-y-[0.6]',
variant === 'avatar' && 'flex-shrink-0',
variant === 'icon' && 'mx-8 flex-shrink-0',
animation === 'wave' && 'skeleton-wave',
animation === 'pulsate' && 'skeleton-pulsate',
className,
)}
aria-busy
aria-live="polite"
/>
);
}
interface SkeletonSizeProps {
variant: SkeletonProps['variant'];
size: SkeletonProps['size'];
}
function skeletonSize({variant, size}: SkeletonSizeProps): string | undefined {
if (size) {
return size;
}
switch (variant) {
case 'avatar':
return 'h-40 w-40';
case 'icon':
return 'h-24 h-24';
case 'rect':
return 'h-full w-full';
default:
return 'w-full';
}
}