New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

viewport-scroll

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

viewport-scroll

A simple React component to track the window's viewport-scroll position.

latest
Source
npmnpm
Version
1.0.2
Version published
Maintainers
1
Created
Source

Viewport Scroll

A simple and lightweight React component to effortlessly track the window's viewport-scroll position and trigger actions like infinite scrolling.

Viewport Scroll Demo

✨ Features

  • Easy to use: Simply wrap your content with the ViewportScroll component.
  • Performant: Uses a single scroll listener to track the viewport position.
  • Customizable: Control the scroll threshold and loading state.
  • Asynchronous actions: Easily trigger async functions when the scroll threshold is reached.
  • TypeScript support: Fully typed for a better development experience.

📦 Installation

npm install viewport-scroll

or

yarn add viewport-scroll

🚀 Usage

Here's a simple example of how to use ViewportScroll to implement infinite scrolling:

import ViewportScroll, { type ScrollHandlerType } from "viewport-scroll";
import { useState } from "react";

type State = {
   isLoading: boolean;
   data: {
      id: number;
      name: string;
   }[];
};

export default function App() {
   const [user, setUser] = useState<State>({ isLoading: false, data: [] });

   const getCharacter: ScrollHandlerType = async ({ page, setHasMore }) => {
      try {
         setUser((prev) => ({ ...prev, isLoading: true }));
         await new Promise((resolve) => setTimeout(resolve, 1000));
         const data = await (await fetch(`https://rickandmortyapi.com/api/character?page=${page}`)).json();
         const results = data?.results ?? [];
         if (results.length === 0 || !data.info?.next) {
            setHasMore(false);
         }
         setUser((prev) => ({ isLoading: false, data: [...prev.data, ...results] }));
      } catch (error) {
         setUser((prev) => ({ ...prev, isLoading: false }));
         setHasMore(false);
      }
   };

   return (
      <div className="App">
         <h1>Infinite Scroll with ViewportScroll</h1>
         <ViewportScroll
            threshold={200}
            isLoading={user.isLoading}
            asyncHandler={getCharacter}
            style={{ height: "400px", width: "80%", overflowY: "auto", margin: "auto", border: "1px solid #ccc", padding: "1rem" }}
         >
            {user.data.map((char) => (
               <div key={char.id} style={{ padding: "1rem", borderBottom: "1px solid #eee" }}>
                  <h3>{char.name}</h3>
               </div>
            ))}
            {user.isLoading && <div style={{ textAlign: "center", padding: "1rem" }}>Loading more characters...</div>}
         </ViewportScroll>
      </div>
   );
}

⚙️ Props

PropTypeDefaultDescription
thresholdnumber200The distance in pixels from the bottom of the scrollable element at which the asyncHandler is triggered.
isLoadingbooleanfalseA boolean to indicate if the asyncHandler is currently running. This prevents multiple calls.
asyncHandler({ page, setHasMore }) => Promise<void>-The asynchronous function to call when the scroll threshold is reached.
styleReact.CSSProperties-Custom styles to apply to the scrollable container.
childrenReact.ReactNode-The content to be rendered inside the scrollable container.

🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.

📝 License

This project is ISC licensed.

FAQs

Package last updated on 10 Aug 2025

Related posts