Moving highlight across loading placeholders.
Loading content…
<div class="mot-shm-stage" data-shape="text-lines" aria-hidden="true">
<div class="mot-shm-avatar"></div>
<div class="mot-shm-lines">
<span class="mot-shm-bar mot-shm-bar--w"></span>
<span class="mot-shm-bar mot-shm-bar--m"></span>
<span class="mot-shm-bar mot-shm-bar--s"></span>
</div>
</div>
<p role="status" aria-live="polite" class="mot-shm-status">Loading content…</p>
<style>
.mot-shm-stage { width: 100%; max-width: 320px; padding: 16px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; display: flex; gap: 12px; align-items: center; }
.mot-shm-avatar { display: none; width: 40px; height: 40px; border-radius: 999px; background: #24143014; flex: none; }
[data-shape="avatar-row"] .mot-shm-avatar { display: block; }
.mot-shm-lines { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.mot-shm-bar { display: block; height: 12px; border-radius: 6px; background: #24143014; background-image: linear-gradient(90deg, #24143014 0%, #FAF7F2 50%, #24143014 100%); background-size: 200% 100%; }
.mot-shm-bar--w { width: 100%; } .mot-shm-bar--m { width: 80%; } .mot-shm-bar--s { width: 55%; }
.mot-shm-status { margin: 10px 0 0; font: 13px system-ui, sans-serif; color: #241430aa; }
@media (prefers-reduced-motion: no-preference) {
.mot-shm-bar { animation: mot-shm-sweep 1400ms linear infinite; }
@keyframes mot-shm-sweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
}
</style><div class="w-full max-w-[320px] p-4 bg-[#FAF7F2] border border-[#24143022] rounded-xl flex gap-3 items-center" data-shape="text-lines" aria-hidden="true">
<div class="tw-shm-avatar hidden w-10 h-10 rounded-full bg-[#24143014] flex-none"></div>
<div class="flex-1 flex flex-col gap-2">
<span class="tw-shm-bar block h-3 rounded-md w-full" style="background-image:linear-gradient(90deg,#24143014 0%,#FAF7F2 50%,#24143014 100%); background-size:200% 100%;"></span>
<span class="tw-shm-bar block h-3 rounded-md w-4/5" style="background-image:linear-gradient(90deg,#24143014 0%,#FAF7F2 50%,#24143014 100%); background-size:200% 100%;"></span>
<span class="tw-shm-bar block h-3 rounded-md w-3/5" style="background-image:linear-gradient(90deg,#24143014 0%,#FAF7F2 50%,#24143014 100%); background-size:200% 100%;"></span>
</div>
</div>
<p role="status" aria-live="polite" class="mt-2.5 text-sm text-[#241430]/70">Loading content…</p>
<style>
[data-shape="avatar-row"] .tw-shm-avatar { display: block; }
@media (prefers-reduced-motion: no-preference) {
.tw-shm-bar { animation: mot-shm-tw-sweep 1400ms linear infinite; }
@keyframes mot-shm-tw-sweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
}
</style>export function SkeletonShimmer({
shimmer = true,
duration = 1400,
shape = "text-lines",
accent = "#FAF7F2",
}) {
const barStyle = { display: "block", height: 12, borderRadius: 6, backgroundImage: `linear-gradient(90deg, #24143014 0%, ${accent} 50%, #24143014 100%)`, backgroundSize: "200% 100%" };
return (
<div>
<div aria-hidden="true" style={{ width: "100%", maxWidth: 320, padding: 16, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, display: "flex", gap: 12, alignItems: "center" }}>
{shape === "avatar-row" && <div style={{ width: 40, height: 40, borderRadius: 999, background: "#24143014", flex: "none" }} />}
<div style={{ flex: 1, display: "flex", flexDirection: "column", gap: 8 }}>
<span className="bar" style={{ ...barStyle, width: "100%" }} />
<span className="bar" style={{ ...barStyle, width: "80%" }} />
<span className="bar" style={{ ...barStyle, width: "55%" }} />
</div>
</div>
<p role="status" aria-live="polite" style={{ margin: "10px 0 0", fontSize: 13, color: "#241430aa" }}>Loading content…</p>
<style>{`
@media (prefers-reduced-motion: no-preference) {
${shimmer ? `.bar { animation: mot-shm-sweep ${duration}ms linear infinite; }` : ""}
@keyframes mot-shm-sweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
}
`}</style>
</div>
);
}