75 lines
1.7 KiB
Plaintext
75 lines
1.7 KiB
Plaintext
---
|
|||
|
|
export interface Props {
|
||
|
|
variant?: "text" | "card" | "circle" | "rect";
|
||
|
|
width?: string;
|
||
|
|
height?: string;
|
||
|
|
class?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
const {
|
||
|
|
variant = "text",
|
||
|
|
width,
|
||
|
|
height,
|
||
|
|
class: className = "",
|
||
|
|
} = Astro.props;
|
||
|
|
|
||
|
|
const style: Record<string, string> = {};
|
||
|
|
if (width) style.width = width;
|
||
|
|
if (height) style.height = height;
|
||
|
|
---
|
||
|
|
|
||
|
|
<div
|
||
|
|
aria-hidden="true"
|
||
|
|
role="presentation"
|
||
|
|
class:list={[`skeleton skeleton--${variant}`, className]}
|
||
|
|
style={Object.keys(style).length > 0 ? style : undefined}
|
||
|
|
>
|
||
|
|
<slot />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<style is:global>
|
||
|
|
.skeleton {
|
||
|
|
background: linear-gradient(
|
||
|
|
90deg,
|
||
|
|
oklch(var(--muted)) 25%,
|
||
|
|
oklch(var(--muted-foreground) / 0.15) 50%,
|
||
|
|
oklch(var(--muted)) 75%
|
||
|
|
);
|
||
|
|
background-size: 200% 100%;
|
||
|
|
animation: shimmer 1.5s ease-in-out infinite;
|
||
|
|
border-radius: 0.5rem;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Variant: text (default) ───────────────────── */
|
||
|
|
|
||
|
|
.skeleton--text {
|
||
|
|
width: 100%;
|
||
|
|
height: 1rem;
|
||
|
|
border-radius: calc(var(--radius, 1rem) - 4px);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Variant: card ─────────────────────────────── */
|
||
|
|
|
||
|
|
.skeleton--card {
|
||
|
|
width: 100%;
|
||
|
|
height: 8rem;
|
||
|
|
border-radius: var(--radius, 1rem);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Variant: circle ───────────────────────────── */
|
||
|
|
|
||
|
|
.skeleton--circle {
|
||
|
|
width: 2.5rem;
|
||
|
|
height: 2.5rem;
|
||
|
|
border-radius: 50%;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ── Variant: rect ─────────────────────────────── */
|
||
|
|
|
||
|
|
.skeleton--rect {
|
||
|
|
width: 100%;
|
||
|
|
height: 3rem;
|
||
|
|
border-radius: calc(var(--radius, 1rem) - 2px);
|
||
|
|
}
|
||
|
|
</style>
|