1.0.0 • Published 3 months ago

react-load-on-view v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
3 months ago

React Load on View

React Higher-Order Component (HOC) that tracks UI elements to dynamically fetch data, load images, or trigger animations based on visibility.

GitHub Demo

Features

  • 🔍 Intersection Observer integration
  • 🎨 Animation triggers on visibility
  • 📦 Lazy loading of data
  • 🌳 Tree-shakeable exports
  • ⚡ Optimized bundle size

Installation

npm install react-load-on-view
# or
yarn add react-load-on-view

Usage

Basic Animation Example

import { withViewObserver } from "react-load-on-view";

function MyComponent() {
  return <div>This will animate when scrolled into view</div>;
}

const AnimatedComponent = withViewObserver(MyComponent, {
  animate: true,
  threshold: 0.3,
  afterWrapperIsVisibleClass: "visible_wrapper",
  initialWrapperClass: "invisible_wrapper",
});

Lazy Loading Example

import { withViewObserver } from "react-load-on-view";

function DataComponent({ data, loading, error }) {
  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      {/* Access images */}
      {data.images && data.images.map((img) => <img src={img.src} />)}
      {/* Access other data */}
      {data.someContent && <p>{data.someContent}</p>}
    </div>
  );
}

const LazyLoadedComponent = withViewObserver(DataComponent, {
  lazyLoad: true,
  paths: ["/path/to/image.webp", "/path/to/data.js"],
  animate: true,
});

Using Individual Hooks

import { useElementObserver, useLazyLoadAssets } from "react-load-on-view";

function CustomComponent() {
  const { ref, inView } = useElementObserver({
    rootMargin: "50px",
    threshold: 0.5,
  });

  const { data, loading, error } = useLazyLoadAssets(
    ["/path/to/image.webp", "/path/to/data.js"],
    inView
  );

  return (
    <div ref={ref}>
      {loading && <div>Loading...</div>}
      {error && <div>{error}</div>}
      {data.images && <img src={data.images[0].src} alt="" />}
    </div>
  );
}

API

withViewObserver

withViewObserver(WrappedComponent, options);

Options

OptionTypeDefaultDescription
animatebooleanfalseWhether to apply animation classes
afterWrapperIsVisibleClassstring"visible_wrapper"Class to apply when visible
initialWrapperClassstring"invisible_wrapper"Initial class when not visible
rootMarginstring"0px"Margin around the root element
thresholdnumber0Visibility threshold (0-1)
rootElementnullRoot element for intersection observer
triggerOncebooleantrueWhether to trigger only once
lazyLoadbooleanfalseWhether to enable lazy loading
pathsstring[][]Paths to assets to lazy load

useElementObserver

const { ref, inView } = useElementObserver(options);

Options

OptionTypeDefaultDescription
rootMarginstring"0px"Margin around the root element
thresholdnumber0Visibility threshold (0-1)
triggerOncebooleantrueWhether to trigger only once
rootElementnullRoot element for intersection observer

useLazyLoadAssets

const { data, error, loading } = useLazyLoadAssets(paths, inView);

Parameters

ParameterTypeDescription
filesstring[]Array of file paths to load
inViewbooleanWhether the element is in view

Previous sections remain the same...

Animation Control

Default vs Special Animations

The package provides two ways to apply animations:

  1. Default Animation Classes:
const AnimatedComponent = withViewObserver(MyComponent, {
  animate: true,
  afterWrapperIsVisibleClass: "general-animation",
  initialWrapperClass: "invisible-wrapper",
});
  1. Special Animation Override:
// The special_animation prop takes precedence over afterWrapperIsVisibleClass
<AnimatedComponent special_animation="stagger-1" />

This is particularly useful for creating staggered animations:

function StaggeredList({ items }) {
  return items.map((item, i) => (
    <AnimatedComponent key={i} special_animation={`stagger-${i}`} />
  ));
}

CSS Example

.invisible_wrapper {
  opacity: 0;
}

.visible_wrapper {
  animation: fade_in 2s ease-in-out;
}

/* Scale and opacity transition */
.unclear {
  opacity: 0.1;
  transform: scale(0.9);
  transition: 0.5s;
}

.clear {
  transform: scale(1);
  animation: clear 0.5s ease-in-out;
}

/* Staggered animation */
.stagger-0,
.stagger-1 {
  opacity: 0;
  animation: stagger 1s ease-out forwards;
}

.stagger-1 {
  animation-delay: 0.4s;
}

Browser Support

This package uses the Intersection Observer API. For browsers that don't support it, you'll need to include a polyfill:

import "intersection-observer";

Changelog

1.0.0 - 2024-03-04

  • Initial release
  • Added withViewObserver HOC
  • Added useElementObserver hook
  • Added useLazyLoadAssets hook
  • Added tree-shaking support
  • Added minification support

License

MIT

Author

Nad1m-A-A