Gesture to refresh content.
<div class="rsp-pr-stage">
<div class="rsp-pr-pull" style="height:40px;">
<span class="rsp-pr-arrow">↓ pull 40px</span>
</div>
<div class="rsp-pr-list"><div>Item one</div><div>Item two</div></div>
</div>
<style>
.rsp-pr-stage { width: 100%; max-width: 320px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 12px; overflow: hidden; font: 12px system-ui, sans-serif; color: #241430aa; }
.rsp-pr-pull { display: flex; align-items: center; justify-content: center; background: #24143008; }
.rsp-pr-spin { width: 22px; height: 22px; border: 3px solid #24143022; border-radius: 999px; }
.rsp-pr-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; }
.rsp-pr-list div { padding: 12px; border-top: 1px solid #24143014; color: #241430; }
@media (prefers-reduced-motion: no-preference) {
.rsp-pr-spin { animation: rsp-pr-spin 800ms linear infinite; }
@keyframes rsp-pr-spin { to { transform: rotate(360deg); } }
}
</style><div class="w-full max-w-[320px] bg-[#FAF7F2] border border-[#24143022] rounded-xl overflow-hidden font-sans text-xs text-[#241430]/70">
<div class="flex items-center justify-center bg-[#24143008]" style="height:40px;">
<span>↓ pull 40px</span>
</div>
<div><div class="p-3 border-t border-[#24143014] text-[#241430]">Item one</div><div class="p-3 border-t border-[#24143014] text-[#241430]">Item two</div></div>
</div>
<style>
@media (prefers-reduced-motion: no-preference) {
.tw-pr-spin { animation: rsp-pr-tw-spin 800ms linear infinite; }
@keyframes rsp-pr-tw-spin { to { transform: rotate(360deg); } }
}
</style>export function PullToRefresh({
released = false,
pullDistance = 40,
duration = 800,
accent = "#A8E6C1",
}) {
return (
<div style={{ width: "100%", maxWidth: 320, background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 12, overflow: "hidden", fontFamily: "system-ui, sans-serif", fontSize: 12, color: "#241430aa" }}>
<div style={{ display: "flex", alignItems: "center", justifyContent: "center", background: "#24143008", height: released ? 50 : pullDistance }}>
{released ? (
<span role="status" aria-live="polite" className="spin" style={{ width: 22, height: 22, border: "3px solid #24143022", borderTopColor: accent, borderRadius: 999 }}>
<span style={{ position: "absolute", width: 1, height: 1, overflow: "hidden" }}>Refreshing…</span>
</span>
) : (
<span>↓ pull {pullDistance}px</span>
)}
</div>
<div>
<div style={{ padding: 12, borderTop: "1px solid #24143014", color: "#241430" }}>Item one</div>
<div style={{ padding: 12, borderTop: "1px solid #24143014", color: "#241430" }}>Item two</div>
</div>
<style>{`
@media (prefers-reduced-motion: no-preference) {
.spin { animation: rsp-pr-spin ${duration}ms linear infinite; }
@keyframes rsp-pr-spin { to { transform: rotate(360deg); } }
}
`}</style>
</div>
);
}