Skip to main content

Common Examples

Basic Usage

Scrollable content with infinite loading:
import { InfiniteContent } from "@servicetitan/ext-atlas";

function InfiniteList() {
  const [items, setItems] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const [loading, setLoading] = useState(false);

  const loadMore = async () => {
    setLoading(true);
    const newItems = await fetchMoreItems();
    setItems((prev) => [...prev, ...newItems]);
    setHasMore(newItems.length > 0);
    setLoading(false);
  };

  return (
    <InfiniteContent
      hasMore={hasMore}
      loadingMore={loading}
      onLoadMore={loadMore}
      renderEndMessage={() => <div>No more items</div>}
    >
      {items.map((item) => (
        <Item key={item.id} {...item} />
      ))}
    </InfiniteContent>
  );
}

With Scroll Callbacks

Track scroll position:
import { InfiniteContent } from "@servicetitan/ext-atlas";

function ScrollTrackingList() {
  const [atTop, setAtTop] = useState(true);

  return (
    <InfiniteContent
      hasMore={hasMore}
      onLoadMore={loadMore}
      onScrollDown={() => setAtTop(false)}
      onScrollTop={() => setAtTop(true)}
    >
      {children}
    </InfiniteContent>
  );
}

Custom Loading Indicators

Customize loading and end messages:
import { InfiniteContent, Loader } from "@servicetitan/ext-atlas";

function CustomLoadingList() {
  return (
    <InfiniteContent
      hasMore={hasMore}
      loadingMore={isLoading}
      onLoadMore={loadMore}
      renderLoadingMore={() => <Loader />}
      renderEndMessage={() => (
        <div className="end-message">You've reached the end!</div>
      )}
    >
      {children}
    </InfiniteContent>
  );
}
Last modified on February 12, 2026