@samline/is-visible
v0.5.1
Published
Lightweight IntersectionObserver utility for visibility enter/leave callbacks.
Downloads
565
Maintainers
Readme
Element Visibility Observer
A lightweight TypeScript utility built on top of the Intersection Observer API that lets you execute callbacks when a DOM element enters or leaves the viewport.
It provides a small abstraction for common tasks like:
- Scroll-triggered animations
- Lazy loading content
- Auto-playing or pausing media
- Infinite scroll triggers
- Analytics visibility tracking
The package ships a shared vanilla API plus framework-specific entrypoints for React, Vue and Svelte. It also includes a browser bundle for projects that load JavaScript directly in the page without a build step.
Table of Contents
- Installation
- Entry Points
- Quick Start
- Documentation Guides
- Shared API Summary
- Shared Options
- Notes
- License
Installation
Choose the installation method that matches your environment.
npm
npm install @samline/is-visiblepnpm
pnpm add @samline/is-visibleyarn
yarn add @samline/is-visiblebun
bun add @samline/is-visibleCDN / Browser
Use the browser bundle when your project loads scripts directly in the page and cannot compile npm modules.
This is useful in environments such as Shopify themes, WordPress templates, or plain HTML pages with no build step.
<script src="https://cdn.jsdelivr.net/npm/@samline/[email protected]/dist/browser/is-visible.global.js"></script>Then use it from a normal script:
<script>
document.addEventListener('DOMContentLoaded', () => {
const element = document.querySelector('[data-track-visibility]')
if (!element) return
window.IsVisible.observe(element, {
inOut: true,
visible: () => {
console.log('Element entered the viewport')
element.classList.add('is-visible')
},
notVisible: () => {
console.log('Element left the viewport')
}
})
})
</script>After the CDN script loads, the browser build exposes window.isVisible(...) and window.IsVisible.observe(...).
Use one of the package manager commands above when your project has a build step. If you are working in Shopify, WordPress or any browser-only template without compilation, use the browser bundle described in docs/browser.md.
Entry Points
Choose the entrypoint that matches your stack so you only import the implementation you need.
| Use case | Import | Guide |
| --------------------------- | ----------------------------------------------------------------------------------- | ---------------------------------- |
| Vanilla JS | import isVisible from '@samline/is-visible' | docs/vanilla.md |
| Vanilla JS explicit subpath | import isVisible from '@samline/is-visible/vanilla' | docs/vanilla.md |
| Browser / CDN | <script src=".../dist/browser/is-visible.global.js"></script> | docs/browser.md |
| React | import { VisibilityObserver, useIsVisible } from '@samline/is-visible/react' | docs/react.md |
| Vue | import { VisibilityObserver, useIsVisible } from '@samline/is-visible/vue' | docs/vue.md |
| Svelte | import { createVisibilityAction, useIsVisible } from '@samline/is-visible/svelte' | docs/svelte.md |
No external runtime dependencies are required for the shared vanilla or browser bundle APIs. The package uses the native IntersectionObserver API.
Quick Start
import isVisible from '@samline/is-visible'
const disconnect = isVisible(targetElement, {
visible: () => console.log('Element is visible'),
notVisible: () => console.log('Element left the viewport'),
inOut: true
})
disconnect()For detailed setup and additional examples:
- Vanilla DOM usage: docs/vanilla.md
- Browser/CDN usage: docs/browser.md
- React usage: docs/react.md
- Vue usage: docs/vue.md
- Svelte usage: docs/svelte.md
Documentation Guides
Vanilla
Use the shared DOM-oriented API with direct element references and callbacks.
Guide: docs/vanilla.md
Browser and CDN
Use the browser bundle when your project loads scripts directly in the page and cannot compile npm modules.
Guide: docs/browser.md
React
Use the React-native hook and component entrypoint instead of wiring the vanilla API manually inside effects.
Guide: docs/react.md
Vue
Use the Vue-native composable and component entrypoint instead of wiring the vanilla API manually in lifecycle hooks.
Guide: docs/vue.md
Svelte
Use the Svelte-native helper and action entrypoint instead of wiring the vanilla API manually in onMount blocks.
Guide: docs/svelte.md
Shared API Summary
The shared vanilla API has the following shape:
isVisible(element, options?)Parameters
| Parameter | Type | Description | | --------- | ---------------- | ------------------------------- | | element | Element | DOM element to observe | | options | IsVisibleOptions | Optional observer configuration |
Returns
() => voidThe returned cleanup function disconnects the observer.
Shared Options
| Property | Type | Default | Description |
| ---------- | ------------------------ | -------- | ----------------------------------------------------------------- |
| inOut | boolean | false | Enables detection when the element leaves the viewport |
| visible | () => void | () => {} | Runs when the element enters the viewport |
| notVisible | () => void | () => {} | Runs when the element leaves the viewport when inOut is enabled |
| once | boolean | false | Stops observing after the first visible trigger |
| options | IntersectionObserverInit | {} | Native IntersectionObserver configuration |
All framework-specific implementations map to these same visibility semantics, even if their return values differ by framework.
Notes
- Requires IntersectionObserver support in the runtime environment
- Supported by modern browsers
- A polyfill may be required for older browsers
License
MIT
