Files
ponytail/examples/infinite-scroll.md
DietrichGebertandClaude Opus 4.8 ff5d0936be docs: sweep em dashes out of the active published surface (#180)
Em dashes crept back into examples, docs/platform-native.md, several READMEs,
the ponytail-debt skill, and a command file since 88431de. Replaced with plain
punctuation (commas, matching the house convention), .openclaw mirror
regenerated. Follows 88431de's scope: leaves untouched the vendored caveman
SKILL.md and the dated benchmarks/results/ writeups (historical records).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 02:37:02 +02:00

1.5 KiB

Infinite Scroll

Task: "Load more items when the user scrolls to the bottom."

Without Ponytail

npm install react-infinite-scroll-component
import InfiniteScroll from "react-infinite-scroll-component";

export function Feed({ items, fetchMore, hasMore }) {
  return (
    <InfiniteScroll
      dataLength={items.length}
      next={fetchMore}
      hasMore={hasMore}
      loader={<Spinner />}
      endMessage={<p>No more items</p>}
      scrollThreshold={0.9}
    >
      {items.map(item => <Card key={item.id} item={item} />)}
    </InfiniteScroll>
  );
}

A dependency to watch scroll position and fire a callback.

With Ponytail

// ponytail: IntersectionObserver does this, no scroll listener needed
import { useEffect, useRef } from "react";

export function Feed({ items, fetchMore, hasMore }) {
  const sentinel = useRef(null);

  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting && hasMore) fetchMore();
    });
    if (sentinel.current) observer.observe(sentinel.current);
    return () => observer.disconnect();
  }, [hasMore, fetchMore]);

  return (
    <>
      {items.map(item => <Card key={item.id} item={item} />)}
      <div ref={sentinel} />
    </>
  );
}

1 dependency → 0 dependencies. IntersectionObserver fires only when the sentinel enters the viewport, no scroll event, no throttling, no jank. Ships in every browser. The library wraps exactly this API.