npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vikeriait/vue-viewport

v1.2.0

Published

Vue directive & composable: viewport detection + Tailwind scroll animations

Readme

@vikeriait/vue-viewport

Documentation npm version

A lightweight, high-performance Vue 3 directive and composable to detect when elements enter the viewport, featuring "Smart Presets", automatic margin compensation for smooth reveals, and seamless Tailwind CSS integration.

📚 Full Documentation: https://vue-viewport.vikeria.it

Features

  • 👁 Viewport Detection: Track when elements enter or leave with precision.
  • 🎨 Tailwind Presets: Ready-to-use animations like fade-up, scale-up, slide-left.
  • 🧠 Smart Presets: fade-y and slide-y automatically adapt direction based on scroll.
  • 📐 Auto RootMargin: Intelligently calculates the optimal rootMargin based on your applied styles (e.g., translate-y-20 or --viewport-distance) to ensure animations start exactly when the element enters, preventing "late" triggers or blank spaces.
  • 🧩 Modular: Use presets via the directive and control timing (delay, duration) via standard Tailwind classes.
  • 🔀 Conditional Logic: Apply animations only when scrolling down or up.
  • 🛠 Customizable: Works with custom CSS, inline styles (style="transform:..."), and Tailwind classes.
  • 📦 Composable: useInViewport for programmatic control.
  • Accessibility: Respects prefers-reduced-motion out of the box.
  • 🦾 TypeScript: Fully typed.

Installation

pnpm add @vikeriait/vue-viewport
# or
npm install @vikeriait/vue-viewport

Setup

1. Global Plugin Registration

import { createApp } from 'vue'
import ViewportPlugin from '@vikeriait/vue-viewport'

const app = createApp(App)

app.use(ViewportPlugin)
app.mount('#app')

2. Import Styles

For Tailwind CSS (v4) users: Import the library's Tailwind configuration to enable the presets and custom variants (like inviewport:).

@import "tailwindcss";

@import "@vikeriait/vue-viewport"; 
/* or explicitly: @import "@vikeriait/vue-viewport/tailwind"; */

For Standard CSS users: If you don't use Tailwind, import the CSS bundle to enable the built-in presets.

import '@vikeriait/vue-viewport/css'

Usage

Directive v-viewport

1. Basic Presets

Simply pass the preset name string.

<div v-viewport="'fade-up'">
  I will fade up when scrolled into view!
</div>

2. Utility Classes

If you want to add Tailwind (or custom) utility classes like delays or durations, apply them directly to the class attribute. The directive handles the preset logic separately.

<!-- ✅ CORRECT: Separate preset and utility classes -->
<div v-viewport="'fade-up'" class="delay-200 duration-1000">
  I appear slowly with a delay.
</div>

3. Smart Presets (-y)

These presets automatically detect the scroll direction and animate accordingly (e.g., slide up when scrolling down, slide down when scrolling up).

<div v-viewport="'fade-y'">
  I enter naturally from whichever side you scroll from.
</div>

4. Directional Modifiers

Restrict animations to a specific scroll direction by appending -down (scrolling down / enter from bottom) or -up (scrolling up / enter from top).

<!-- Animates only when you scroll DOWN to it -->
<div v-viewport="'fade-up-down'">
  I appear only on normal scroll.
</div>

5. Staggering

Delay animations for elements entering at the same time. The library guarantees DOM order execution.

You can pass:

  • number: Delay in milliseconds (e.g. 100).
  • string: CSS time value (e.g. '200ms', '0.1s').
  • true: Uses the global default --viewport-stagger (default: 100ms).

Note: The stagger delay is additive to any existing CSS delay.

<!-- Explicit value -->
<div v-for="i in 6" v-viewport="{ animation: 'fade-up', stagger: 100 }"></div>

<!-- Use default from CSS variable -->
<div v-for="i in 6" v-viewport="{ animation: 'fade-up', stagger: true }"></div>

6. Inline Timing Control

You can override the global defaults or utility classes directly via options. This is useful for dynamic values.

<div v-viewport="{ animation: 'fade-up', duration: 1000, delay: 500, easing: 'ease-in-out' }">
  I have custom timing!
</div>

Component <VViewport />

Prefer components over directives? We got you.

Global Usage: The plugin registers the component globally as <VViewport />.

<VViewport preset="fade-up">
  <h1>Hello World</h1>
</VViewport>

Local Import: You can also import it directly (exported as Viewport).

<script setup>
import { Viewport } from '@vikeriait/vue-viewport'
</script>

<template>
  <Viewport as="section" preset="fade-up" :stagger="100">
    ...
  </Viewport>
</template>

Props:

  • as: (string) HTML tag (default: 'div').
  • preset: (string) Animation name.
  • stagger: (number/string/boolean) Delay logic.
  • duration: (number/string) Custom duration.
  • delay: (number/string) Custom delay.
  • easing: (string) Custom easing.
  • once: (boolean) Disconnect after first entry.
  • threshold: (number) Intersection threshold.
  • rootMargin: (string) Custom margin.

Advanced: Tailwind & Custom Styles

The library is smart. If you use custom transforms (via Tailwind classes or inline styles), it detects them and automatically adjusts the IntersectionObserver's rootMargin to ensure the animation triggers precisely when the visual element enters the screen.

Example with Tailwind: The library sees translate-y-20 (80px), calculates the offset, and triggers the animation 80px earlier to prevent any "blank space" or jump.

<div 
  v-viewport 
  class="opacity-0 translate-y-20 transition-all duration-700 
         inviewport:opacity-100 inviewport:translate-y-0"
>
  I am a fully custom Tailwind animation handled perfectly.
</div>

Example with Inline Style:

<div 
  v-viewport
  style="opacity: 0; transform: translateY(100px); transition: 1s"
  class="inviewport:opacity-100 inviewport:translate-y-0"
>
  I work too!
</div>

Composable useInViewport

<script setup lang="ts">
import { ref } from 'vue'
import { useInViewport } from '@vikeriait/vue-viewport'

const target = ref(null)
const { isInView, entry } = useInViewport(target)
</script>

<template>
  <div ref="target">
    {{ isInView ? 'Visible' : 'Hidden' }}
  </div>
</template>

Built-in Presets

| Preset | Description | |:-------------------|:----------------| | fade | Simple fade | | fade-up/down | Fade + Slide Y | | fade-left/right | Fade + Slide X | | slide-up/down | Slide Y | | slide-left/right | Slide X | | scale-up/down | Scale Transform | | blur-in | Blur Reveal |

Note: All presets support -down (on scroll down) and -up (on scroll up) suffixes.

CSS Variables

You can customize the global defaults in your CSS:

:root {
    --viewport-duration: 0.6s;
    --viewport-ease: ease-out;
    --viewport-delay: 0s; /* Global default delay */
    --viewport-distance: 2rem;
    --viewport-stagger: 100ms;
    --viewport-scale-in: 0.95;
    --viewport-scale-out: 1.05;
    --viewport-blur: 12px;
}

Accessibility & Print

The library is designed to be inclusive and reliable:

  • Reduced Motion: If a user has enabled "Reduce Motion" in their system settings, the library automatically detects the @media (prefers-reduced-motion: reduce) preference. In this case, all animations are disabled, and elements appear instantly in their final state (opacity: 1, transform: none).
  • Print Friendly: When printing a page, all animations and initial "hidden" states are stripped away via @media print. This ensures that all content is fully visible and correctly positioned on the physical or PDF page.

API Reference

Plugin Options

Options passed to app.use(ViewportPlugin, options).

| Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | presets | Record<string, string> | DEFAULT_PRESETS | Custom presets map. |

Directive Options

Options object passed as v-viewport="{ ... }".

| Option | Type | Default | Description | | :--- | :--- | :--- | :--- | | animation | string | undefined | The animation class or preset name(s). | | stagger | number \| string \| boolean | undefined | Delay (ms/string) or true for global default. | | duration | number \| string | undefined | Custom duration. | | delay | number \| string | undefined | Custom delay. | | easing | string | undefined | Custom easing function. | | once | boolean | false | Disconnect after first entry. | | threshold | number \| number[] | 0.1 | IntersectionObserver threshold. | | rootMargin | string | auto | Manually override the calculated margin. | | onEnter | function | - | Callback when entering viewport. | | onLeave | function | - | Callback when leaving viewport. |

Directive Modifiers

| Modifier | Description | | :--- | :--- | | .once | Disconnect after first entry. |

Directive Events

| Event | Type | Description | | :--- | :--- | :--- | | @view-enter | ViewportEvent | Dispatched when entering viewport. | | @view-leave | ViewportEvent | Dispatched when leaving viewport. |

License

MIT