CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-waypoint

A React component to execute functions when scrolling to specific elements in any scrollable container

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

index.mddocs/

React Waypoint

React Waypoint is a React component that executes callback functions whenever you scroll to an element. It works in all containers that can scroll, including the browser window, and provides callbacks for enter/leave events when elements cross viewport boundaries.

Package Information

  • Package Name: react-waypoint
  • Package Type: npm
  • Language: JavaScript (with TypeScript definitions included)
  • Installation: npm install react-waypoint

Core Imports

import { Waypoint } from 'react-waypoint';

For CommonJS:

const { Waypoint } = require('react-waypoint');

Basic Usage

import React from 'react';
import { Waypoint } from 'react-waypoint';

function App() {
  const handleWaypointEnter = (args) => {
    console.log('Waypoint entered!', args.currentPosition);
  };

  const handleWaypointLeave = (args) => {
    console.log('Waypoint left!', args.currentPosition);
  };

  return (
    <div>
      <div style={{ height: '1000px' }}>Scroll down...</div>
      
      {/* Basic waypoint */}
      <Waypoint
        onEnter={handleWaypointEnter}
        onLeave={handleWaypointLeave}
      />
      
      {/* Waypoint with child element */}
      <Waypoint onEnter={handleWaypointEnter}>
        <div style={{ padding: '20px', background: '#f0f0f0' }}>
          This content triggers waypoint events
        </div>
      </Waypoint>
    </div>
  );
}

Architecture

React Waypoint operates through several key mechanisms:

  • Event-Driven Architecture: Uses scroll and resize event listeners to detect position changes
  • Position Calculation: Calculates element position relative to viewport using getBoundingClientRect()
  • Offset Support: Supports both pixel and percentage-based offsets for flexible triggering
  • Scrollable Ancestor Detection: Automatically finds the closest scrollable container or allows custom specification
  • Lazy Evaluation: Uses onNextTick scheduling to optimize performance and avoid layout thrashing

Capabilities

Waypoint Component

The main React component that provides scroll-based element visibility detection.

class Waypoint extends React.Component<WaypointProps, {}> {
  static above: string;
  static below: string;
  static inside: string;
  static invisible: string;
}

interface WaypointProps {
  /** Function called when waypoint enters viewport */
  onEnter?: (args: CallbackArgs) => void;
  /** Function called when waypoint leaves viewport */
  onLeave?: (args: CallbackArgs) => void;
  /** Function called when waypoint position changes */
  onPositionChange?: (args: CallbackArgs) => void;
  /** Whether to activate on horizontal scrolling instead of vertical */
  horizontal?: boolean;
  /** Distance from top of container in pixels or percentage (e.g., "20px", "20%") */
  topOffset?: string | number;
  /** Distance from bottom of container in pixels or percentage (e.g., "20px", "20%") */
  bottomOffset?: string | number;
  /** Custom ancestor to determine if the target is visible in it */
  scrollableAncestor?: any;
  /** If the onEnter/onLeave events are to be fired on rapid scrolling */
  fireOnRapidScroll?: boolean;
  /** Use this prop to get debug information in the console log */
  debug?: boolean;
  /** Child elements to wrap with waypoint functionality */
  children?: React.ReactNode;
}

interface CallbackArgs {
  /** The position that the waypoint has at the moment */
  currentPosition: string;
  /** The position that the waypoint had before */
  previousPosition: string;
  /** The native scroll event that triggered the callback (may be missing) */
  event?: Event;
  /** The waypoint's distance to the top of the viewport */
  waypointTop: number;
  /** The waypoint's distance to the bottom of the viewport */
  waypointBottom: number;
  /** The distance from the scrollable ancestor to the viewport top */
  viewportTop: number;
  /** The distance from the bottom of the scrollable ancestor to the viewport top */
  viewportBottom: number;
}

Position Constants

Static constants representing different waypoint positions relative to the viewport.

/** Waypoint is above the viewport */
Waypoint.above: string; // "above"
/** Waypoint is below the viewport */
Waypoint.below: string; // "below"
/** Waypoint is inside (visible in) the viewport */
Waypoint.inside: string; // "inside"
/** Waypoint is invisible (e.g., display: none) */
Waypoint.invisible: string; // "invisible"

Callback Events

React Waypoint provides three main callback events for different use cases:

onEnter: Triggered when the waypoint becomes visible in the viewport

<Waypoint
  onEnter={({ currentPosition, previousPosition, event, waypointTop, waypointBottom, viewportTop, viewportBottom }) => {
    console.log('Element entered viewport');
    // Useful for: lazy loading content, analytics tracking, animations
  }}
/>

onLeave: Triggered when the waypoint leaves the viewport

<Waypoint
  onLeave={({ currentPosition, previousPosition, event, waypointTop, waypointBottom, viewportTop, viewportBottom }) => {
    console.log('Element left viewport'); 
    // Useful for: cleanup, pausing videos, stopping animations
  }}
/>

onPositionChange: Triggered whenever the waypoint's position changes

<Waypoint
  onPositionChange={({ currentPosition, previousPosition, event, waypointTop, waypointBottom, viewportTop, viewportBottom }) => {
    console.log(\`Position changed from \${previousPosition} to \${currentPosition}\`);
    // Useful for: scroll spies, position-based UI updates
  }}
/>

Offset Configuration

Control when waypoint events trigger using flexible offset options:

Percentage-based offsets (relative to container height):

<Waypoint
  topOffset="20%"     // Trigger 20% from top of viewport
  bottomOffset="10%"  // Trigger 10% from bottom of viewport
/>

Pixel-based offsets:

<Waypoint
  topOffset={100}        // Trigger 100px from top
  bottomOffset="50px"    // Trigger 50px from bottom
/>

Negative offsets (trigger before entering viewport):

<Waypoint
  topOffset="-100px"     // Trigger 100px before entering viewport
  bottomOffset="-20%"    // Trigger when 20% outside bottom
/>

Horizontal Scrolling

Enable horizontal scroll detection for side-scrolling interfaces:

<Waypoint
  horizontal={true}
  onEnter={() => console.log('Entered horizontal viewport')}
/>

Custom Scrollable Containers

Specify a custom scrollable ancestor instead of auto-detection:

function ScrollableContainer() {
  const containerRef = useRef(null);
  
  return (
    <div ref={containerRef} style={{ height: '300px', overflow: 'auto' }}>
      <div style={{ height: '1000px' }}>
        <Waypoint
          scrollableAncestor={containerRef.current}
          onEnter={() => console.log('Entered custom container viewport')}
        />
      </div>
    </div>
  );
}

Rapid Scroll Handling

Control behavior during rapid scrolling where waypoint might be skipped:

<Waypoint
  fireOnRapidScroll={true}  // Default: fires both onEnter and onLeave during rapid scroll
  fireOnRapidScroll={false} // Skip events during rapid scroll
/>

Debug Mode

Enable detailed console logging for development:

<Waypoint
  debug={true}
  onEnter={() => console.log('Debug information will show in console')}
/>

Child Element Wrapping

Wrap existing elements to track their visibility:

{/* Without children - creates invisible span element */}
<Waypoint onEnter={handleEnter} />

{/* With children - tracks the child element */}
<Waypoint onEnter={handleEnter}>
  <img src="image.jpg" alt="Lazy loaded image" />
</Waypoint>

{/* Multiple children */}
<Waypoint onEnter={handleEnter}>
  <div className="content-section">
    <h2>Section Title</h2>
    <p>Section content...</p>
  </div>
</Waypoint>

Common Use Cases

Lazy Loading Images:

<Waypoint
  onEnter={() => setImageSrc(actualImageUrl)}
  topOffset="-100px" // Start loading before entering viewport
>
  <img src={imageSrc || placeholderSrc} alt="Lazy loaded" />
</Waypoint>

Infinite Scroll:

<Waypoint
  key={currentPage} // Important: use key to recreate waypoint
  onEnter={loadMoreContent}
  bottomOffset="100px" // Trigger before reaching bottom
/>

Scroll Spy Navigation:

<Waypoint
  onPositionChange={({ currentPosition }) => {
    if (currentPosition === 'inside') {
      setActiveSection('section1');
    }
  }}
>
  <section id="section1">Content...</section>
</Waypoint>

Analytics Tracking:

<Waypoint
  onEnter={() => analytics.track('Section Viewed')}
  topOffset="50%" // Trigger when 50% visible
/>

docs

index.md

tile.json