Automatically load more content during scrolling.
Shipped the new checkout flow today.
Design review moved to Thursday.
Scroll for more posts.
Loading more posts…
You're all caught up — 24 posts loaded.
<section class="is" aria-label="Team feed" style="--accent:#F5C2E0;" data-state="loading">
<h3 class="is__heading">Team feed</h3>
<ul class="is__feed">
<li class="is__post"><span class="is__avatar" aria-hidden="true">NO</span><div><p class="is__author">Nina Osei</p><p class="is__text">Shipped the new checkout flow today.</p></div></li>
<li class="is__post"><span class="is__avatar" aria-hidden="true">TN</span><div><p class="is__author">Tomas Novak</p><p class="is__text">Design review moved to Thursday.</p></div></li>
</ul>
<p class="is__sentinel is__sentinel--idle" role="status">Scroll for more posts.</p>
<p class="is__sentinel is__sentinel--loading" role="status">Loading more posts…</p>
<p class="is__sentinel is__sentinel--end" role="status">You're all caught up — 24 posts loaded.</p>
</section>
<style>
.is { font: 13.5px/1.4 system-ui, sans-serif; color: #241430; background: #FAF7F2; max-width: 320px; width: 320px; padding: 16px; border-radius: 12px; box-sizing: border-box; }
.is__heading { margin: 0 0 10px; font-size: 15px; font-weight: 700; }
.is__feed { list-style: none; margin: 0; padding: 0; }
.is__post { display: flex; gap: 8px; padding: 10px; background: #fff; border-radius: 8px; margin-bottom: 8px; }
.is__avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--accent); flex-shrink: 0; display: grid; place-items: center; font-size: 10px; font-weight: 700; }
.is__author { margin: 0; font-weight: 700; font-size: 12.5px; }
.is__text { margin: 2px 0 0; color: #241430b3; }
.is__sentinel { display: none; margin: 10px 0 0; font-size: 12px; color: #241430a0; text-align: center; }
.is[data-state="idle"] .is__sentinel--idle,
.is[data-state="loading"] .is__sentinel--loading,
.is[data-state="end"] .is__sentinel--end { display: block; }
</style><section class="is-tw font-sans text-[13.5px] text-[#241430] bg-[#FAF7F2] max-w-[320px] w-[320px] p-4 rounded-xl box-border" aria-label="Team feed" style="--accent:#F5C2E0" data-state="loading">
<h3 class="m-0 mb-2.5 text-[15px] font-bold">Team feed</h3>
<ul class="list-none m-0 p-0">
<li class="flex gap-2 p-2.5 bg-white rounded-lg mb-2"><span aria-hidden="true" class="w-[26px] h-[26px] rounded-full flex-shrink-0 grid place-items-center text-[10px] font-bold" style="background:#F5C2E0">NO</span><div><p class="m-0 font-bold text-[12.5px]">Nina Osei</p><p class="mt-0.5 mb-0 text-[#241430b3]">Shipped the new checkout flow today.</p></div></li>
<li class="flex gap-2 p-2.5 bg-white rounded-lg"><span aria-hidden="true" class="w-[26px] h-[26px] rounded-full flex-shrink-0 grid place-items-center text-[10px] font-bold" style="background:#F5C2E0">TN</span><div><p class="m-0 font-bold text-[12.5px]">Tomas Novak</p><p class="mt-0.5 mb-0 text-[#241430b3]">Design review moved to Thursday.</p></div></li>
</ul>
<p role="status" class="is-tw__sentinel is-tw__sentinel--idle mt-2.5 mb-0 text-xs text-[#241430a0] text-center">Scroll for more posts.</p>
<p role="status" class="is-tw__sentinel is-tw__sentinel--loading mt-2.5 mb-0 text-xs text-[#241430a0] text-center">Loading more posts…</p>
<p role="status" class="is-tw__sentinel is-tw__sentinel--end mt-2.5 mb-0 text-xs text-[#241430a0] text-center">You're all caught up — 24 posts loaded.</p>
</section>
<style>
.is-tw__sentinel { display: none; }
.is-tw[data-state="idle"] .is-tw__sentinel--idle,
.is-tw[data-state="loading"] .is-tw__sentinel--loading,
.is-tw[data-state="end"] .is-tw__sentinel--end { display: block; }
</style>export function InfiniteScroll({
heading = "Team feed",
accent = "#F5C2E0",
state = "loading",
postCount = 24,
showAvatar = true,
}) {
const sentinelText = { idle: "Scroll for more posts.", loading: "Loading more posts…", end: `You're all caught up — ${postCount} posts loaded.` }[state];
const posts = [["NO", "Nina Osei", "Shipped the new checkout flow today."], ["TN", "Tomas Novak", "Design review moved to Thursday."]];
return (
<section aria-label={heading} style={{ fontFamily: "system-ui, sans-serif", fontSize: 13.5, color: "#241430", background: "#FAF7F2", maxWidth: 320, width: 320, padding: 16, borderRadius: 12, boxSizing: "border-box" }}>
<h3 style={{ margin: "0 0 10px", fontSize: 15, fontWeight: 700 }}>{heading}</h3>
<ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
{posts.map(([initials, author, text], i) => (
<li key={author} style={{ display: "flex", gap: 8, padding: 10, background: "#fff", borderRadius: 8, marginBottom: i === posts.length - 1 ? 0 : 8 }}>
{showAvatar && <span aria-hidden="true" style={{ width: 26, height: 26, borderRadius: "50%", background: accent, flexShrink: 0, display: "grid", placeItems: "center", fontSize: 10, fontWeight: 700 }}>{initials}</span>}
<div><p style={{ margin: 0, fontWeight: 700, fontSize: 12.5 }}>{author}</p><p style={{ margin: "2px 0 0", color: "#241430b3" }}>{text}</p></div>
</li>
))}
</ul>
<p role="status" style={{ margin: "10px 0 0", fontSize: 12, color: "#241430a0", textAlign: "center" }}>{sentinelText}</p>
</section>
);
}