Skip to main content

InView

InView is a component for declaratively using the IntersectionObserver.

Calls a specific action function when the observed target enters the viewport (onIntersectStart) or leaves it (onIntersectEnd).


Polymorphism

The InView component supports the as prop for polymorphism.

  • By default, wraps children in a div, and the as prop allows changing the wrapper element tag (e.g., div → article).
  • The wrapper element becomes the observed target of the IntersectionObserver.

Composition & Rendering Delegation

The InView component supports Composition and Rendering Delegation patterns via the asChild prop.

  • When asChild is true, it renders the child element as-is via Slot without a wrapper element.
  • The child element becomes the observed target of the IntersectionObserver.
    • Slot only accepts a single child element.
    • If a component is passed as a child to Slot, it must support forwardRef and spread props. Otherwise it will not work correctly.
    • When using the asChild prop, please refer to the Slot documentation.

Code

🔗 View source code


Interface

typescript
interface InViewProps extends UseIntersectionObserverProps {
children: React.ReactNode;
asChild?: boolean;
}
typescript
const InView: PolyForwardComponent<"div", InViewProps, React.ElementType>

Usage

Basic Usage

  • By default, wrapped in a div, which becomes the observed target of the IntersectionObserver.
  • Calls the onIntersectStart/onIntersectEnd callback when the element enters or leaves the viewport.
typescript
import { InView } from '@modern-kit/react';

const Example = () => {
const handleIntersectStart = () => {/* action */}
const handleIntersectEnd = () => {/* action */}

return (
<InView onIntersectStart={handleIntersectStart} onIntersectEnd={handleIntersectEnd}>
<div>Box1</div>
</InView>
);
};

as Prop Usage

  • The as prop allows rendering with a specific element, which becomes the observed target.
  • Calls the onIntersectStart/onIntersectEnd callback when the element enters or leaves the viewport.
typescript
import { InView } from '@modern-kit/react';

const Example = () => {
const handleIntersectStart = () => {/* action */}
const handleIntersectEnd = () => {/* action */}

return (
<InView
as='ul' // wraps children in a `ul` element instead of `div`
onIntersectStart={handleIntersectStart}
onIntersectEnd={handleIntersectEnd}
>
<li>List Item1</li>
<li>List Item2</li>
</InView>
);
};

asChild Prop Usage

  • When asChild is true, renders the child element as-is via Slot without a wrapper, and that element becomes the observed target.
  • Calls the onIntersectStart/onIntersectEnd callback when the child enters or leaves the viewport.
typescript
import { InView } from '@modern-kit/react';

const Example = () => {
const handleIntersectStart = () => {/* action */}
const handleIntersectEnd = () => {/* action */}

return (
<InView asChild onIntersectStart={handleIntersectStart} onIntersectEnd={handleIntersectEnd}>
<div>Box1</div>
</InView>
);
};

Example

Scroll down.

Check the browser developer console.

Box1

calledOnce: true

as: div

  • Box2
  • calledOnce: false
  • as: ul
  • Box3

    calledOnce: false

    asChild: true

    Note