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

vertex-gallery

v1.2.3

Published

A production-ready, feature-rich image gallery component with modal, masonry layout, filters, and extensive customization options

Readme

Vertex Gallery

A feature-rich image gallery component with modal, masonry layout, filters, and extensive customization options.

Masonry Layout Example

Live Demo & Resources

Features

  • 🖼️ Multiple Layouts: Grid and masonry layouts
  • 🎨 Highly Customizable: Extensive configuration options and CSS variables
  • 📱 Responsive: Works on all devices with touch support
  • 🎭 Modal Gallery: Full-screen modal with zoom, rotate, flip, and reset transform controls
  • 🔍 Image Filters: Built-in filters (grayscale, sepia, blur, etc.)
  • 🎯 Category Filtering: Filter images by category
  • Performance: Lazy loading and optimized rendering
  • 🎪 Animations: Smooth transitions and animations
  • 🌓 Theme Support: Dark and light themes
  • Accessible: Keyboard navigation, ARIA labels, focus trapping, and screen reader support
  • 🌍 RTL Support: Automatic right-to-left language detection and layout
  • 👆 Touch Gestures: Pinch-to-zoom, pan, and swipe support for mobile devices
  • 🎛️ Reduced Motion: Respects prefers-reduced-motion for accessibility

Installation

npm install vertex-gallery

CDN

You can also use Vertex Gallery directly from a CDN without installing it. Both regular and minified versions are available.

jsDelivr

Regular (Development):

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vertex-gallery@latest/dist/vertex-gallery.css">
</head>
<body>
  <div id="gallery"></div>
  
  <script src="https://cdn.jsdelivr.net/npm/vertex-gallery@latest/dist/vertex-gallery.js"></script>
  <script>
    const gallery = new VertexGallery(document.getElementById('gallery'), {
      data: [
        {
          thumb: 'thumb1.jpg',
          large: 'large1.jpg',
          title: 'Image 1',
          desc: 'Description',
          category: 'nature'
        }
      ]
    });
  </script>
</body>
</html>

Minified (Production - Recommended):

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vertex-gallery@latest/dist/vertex-gallery.min.css">
</head>
<body>
  <div id="gallery"></div>
  
  <script src="https://cdn.jsdelivr.net/npm/vertex-gallery@latest/dist/vertex-gallery.min.js"></script>
  <script>
    const gallery = new VertexGallery(document.getElementById('gallery'), {
      data: [
        {
          thumb: 'thumb1.jpg',
          large: 'large1.jpg',
          title: 'Image 1',
          desc: 'Description',
          category: 'nature'
        }
      ]
    });
  </script>
</body>
</html>

unpkg

Regular (Development):

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://unpkg.com/vertex-gallery@latest/dist/vertex-gallery.css">
</head>
<body>
  <div id="gallery"></div>
  
  <script src="https://unpkg.com/vertex-gallery@latest/dist/vertex-gallery.js"></script>
  <script>
    const gallery = new VertexGallery(document.getElementById('gallery'), {
      data: [
        {
          thumb: 'thumb1.jpg',
          large: 'large1.jpg',
          title: 'Image 1',
          desc: 'Description',
          category: 'nature'
        }
      ]
    });
  </script>
</body>
</html>

Minified (Production - Recommended):

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://unpkg.com/vertex-gallery@latest/dist/vertex-gallery.min.css">
</head>
<body>
  <div id="gallery"></div>
  
  <script src="https://unpkg.com/vertex-gallery@latest/dist/vertex-gallery.min.js"></script>
  <script>
    const gallery = new VertexGallery(document.getElementById('gallery'), {
      data: [
        {
          thumb: 'thumb1.jpg',
          large: 'large1.jpg',
          title: 'Image 1',
          desc: 'Description',
          category: 'nature'
        }
      ]
    });
  </script>
</body>
</html>

Note:

  • Use minified versions (.min.js and .min.css) for production to reduce file size by ~48% for JS and ~27% for CSS
  • Replace @latest with a specific version (e.g., @1.2.2) for production use to ensure stability
  • Both regular and minified versions provide identical functionality

Quick Start

HTML

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="node_modules/vertex-gallery/dist/vertex-gallery.css">
</head>
<body>
  <div id="gallery"></div>
  
  <script src="node_modules/vertex-gallery/dist/vertex-gallery.js"></script>
  <script>
    const gallery = new VertexGallery(document.getElementById('gallery'), {
      data: [
        {
          thumb: 'thumb1.jpg',
          large: 'large1.jpg',
          title: 'Image 1',
          desc: 'Description',
          category: 'nature'
        },
        {
          thumb: 'thumb2.jpg',
          large: 'large2.jpg',
          title: 'Image 2',
          desc: 'Description',
          category: 'urban'
        }
      ]
    });
  </script>
</body>
</html>

ES Modules

import VertexGallery from 'vertex-gallery';
import 'vertex-gallery/dist/vertex-gallery.css';

const gallery = new VertexGallery(document.getElementById('gallery'), {
  data: [
    {
      thumb: 'thumb1.jpg',
      large: 'large1.jpg',
      title: 'Image 1',
      desc: 'Description',
      category: 'nature'
    }
  ]
});

CommonJS

const VertexGallery = require('vertex-gallery');
require('vertex-gallery/dist/vertex-gallery.css');

const gallery = new VertexGallery(document.getElementById('gallery'), {
  data: [
    {
      thumb: 'thumb1.jpg',
      large: 'large1.jpg',
      title: 'Image 1',
      desc: 'Description',
      category: 'nature'
    }
  ]
});

React

import { useEffect, useRef } from 'react';
import VertexGallery from 'vertex-gallery';
import 'vertex-gallery/dist/vertex-gallery.css';

function GalleryComponent() {
  const galleryRef = useRef(null);
  const galleryInstanceRef = useRef(null);

  useEffect(() => {
    if (galleryRef.current) {
      // Clean up previous instance if exists
      if (galleryInstanceRef.current) {
        galleryInstanceRef.current.destroy();
      }

      // Initialize gallery
      galleryInstanceRef.current = new VertexGallery(galleryRef.current, {
        data: [
          {
            thumb: 'thumb1.jpg',
            large: 'large1.jpg',
            title: 'Image 1',
            desc: 'Description',
            category: 'nature'
          }
        ]
      });
    }

    // Cleanup on unmount
    return () => {
      if (galleryInstanceRef.current) {
        galleryInstanceRef.current.destroy();
      }
    };
  }, []);

  return <div ref={galleryRef} />;
}

export default GalleryComponent;

Configuration Options

Visual Theme

  • cornerStyle: 'rounded' | 'flat' - Corner style for cards (default: 'rounded')
  • showCardShadow: boolean - Show shadow on cards (default: true)
  • galleryMaxWidth: string | number | null - Maximum width of gallery (default: null)

Grid Layout

  • layout: 'grid' | 'masonry' - Layout type (default: 'grid')
  • columns: 'auto' | number | { mobile?: number; tablet?: number; desktop?: number } - Number of columns (default: 'auto')
  • gap: number - Gap between items in pixels (default: 16)
  • itemAspectRatio: string | null - Aspect ratio for items, e.g., '16/9' (default: null, ignored in masonry)

UI Toggles (Gallery)

  • showGalleryFilter: boolean - Show filter buttons (default: true)
  • showGalleryCaption: 'always' | 'hover' | 'hide' - Caption visibility (default: 'hover')

Image Filters

  • imageFilter: 'none' | 'grayscale' | 'sepia' | 'blur' | 'brightness' | 'contrast' | 'saturate' - Filter type (default: 'none')
  • imageFilterAmount: number - Filter intensity 0-100 for grayscale/sepia, 0-200 for others (default: 100)
  • imageFilterOnHover: 'color' | 'filter' | 'none' - Hover effect (default: 'color')

UI Toggles (Modal)

  • enableModal: boolean - Enable full-screen modal (default: true)
  • modalTheme: 'dark' | 'light' - Modal theme (default: 'dark')
  • modalBackdropOpacity: number - Backdrop opacity 0.0-1.0 (default: 0.8)
  • showModalPlayPause: boolean - Show autoplay button (default: true)
  • showModalSpeed: boolean - Show speed slider (default: true)
  • showModalCount: boolean - Show image count (default: true)
  • showModalThumbnails: boolean - Show thumbnail strip (default: true)
  • showModalThumbnailsToggle: boolean - Show thumbnail toggle button (default: true)
  • showModalFullscreen: boolean - Show fullscreen button (default: true)
  • showModalTransformControls: boolean | null - Master toggle for all transform controls (rotate, flip, zoom). When null, individual settings are used (default: null)
  • showModalRotateControls: boolean - Show rotate left/right controls (default: true)
  • showModalFlipControls: boolean - Show flip horizontal/vertical controls (default: true)
  • showModalZoomControls: boolean - Show zoom in/out controls (default: true)
  • showModalThemeToggle: boolean - Show theme toggle button (default: false)
  • showModalAutoplayProgress: boolean - Show autoplay progress bar (default: false)
  • showModalDownload: boolean - Show download button (default: false)
  • showModalShare: boolean - Show share button (default: false)
  • disableModalRightClick: boolean - Disable right-click in modal (default: true)

Modal Config

  • enableCaptions: boolean - Show captions in modal (default: true)
  • modalThumbnailHeight: number - Thumbnail height in pixels (default: 60)
  • modalTransition: 'fade' | 'crossfade' | 'slide' - Transition type (default: 'fade')
  • modalThumbnailStyle: 'crop' | 'natural' - Thumbnail style (default: 'crop')

Branding

  • accentColor: string | null - Accent color, e.g., '#10b981' (default: null)

Interaction Settings

  • modalAutoplayInterval: number - Autoplay interval in milliseconds (default: 3000, minimum: 100, maximum: 60000)
  • modalSwipeThreshold: number - Swipe threshold in pixels (default: 50)

Content

  • data: VertexGalleryItem[] - Array of gallery items

Gallery Behavior

  • randomize: boolean - Randomize gallery order (default: false)
  • showSingleImage: boolean - Show one image initially, expand on click (default: false)

Data Structure

Each item in the data array should have the following structure:

interface VertexGalleryItem {
  thumb: string;      // Thumbnail image URL
  large: string;      // Large/full-size image URL
  title?: string;     // Optional title
  desc?: string;      // Optional description
  category?: string;  // Optional category for filtering
  default?: boolean;  // Optional: When `showSingleImage` is true, marks this as the preview image
}

Note: When using showSingleImage: true, you can set default: true on one item to specify which image should be shown initially. If no item has default: true, the first item will be used.

API Methods

setFilter(category: string)

Set the active filter category.

gallery.setFilter('nature');

updateGrid()

Update the gallery grid layout.

gallery.updateGrid();

openModal(card: HTMLElement)

Open the modal with a specific card.

const card = document.querySelector('.vg-card');
gallery.openModal(card);

closeModal()

Close the modal.

gallery.closeModal();

nextModalImage()

Navigate to the next image in the modal.

gallery.nextModalImage();

prevModalImage()

Navigate to the previous image in the modal.

gallery.prevModalImage();

toggleModalAutoplay()

Toggle autoplay in the modal.

gallery.toggleModalAutoplay();

updateModalAutoplaySpeed(newInterval: number)

Update the autoplay speed.

gallery.updateModalAutoplaySpeed(5000); // 5 seconds

toggleModalTheme()

Toggle between dark and light theme.

gallery.toggleModalTheme();

toggleThumbnailsVisibility()

Toggle thumbnail strip visibility.

gallery.toggleThumbnailsVisibility();

toggleFullscreen()

Toggle fullscreen mode.

gallery.toggleFullscreen();

downloadCurrentImage()

Download the current image in the modal.

gallery.downloadCurrentImage();

shareCurrentImage()

Share the current image.

gallery.shareCurrentImage();

handleRotate(direction: 'left' | 'right')

Rotate the current image.

gallery.handleRotate('left');
gallery.handleRotate('right');

handleFlip(axis: 'horizontal' | 'vertical')

Flip the current image.

gallery.handleFlip('horizontal');
gallery.handleFlip('vertical');

handleZoomIn()

Zoom in on the current image.

gallery.handleZoomIn();

handleZoomOut()

Zoom out on the current image.

gallery.handleZoomOut();

resetPanZoom()

Reset pan, zoom, rotation, and flip transforms to default. Also available via the reset transform button in the modal toolbar.

gallery.resetPanZoom();

destroy()

Destroy the gallery instance and clean up resources.

gallery.destroy();

Keyboard Shortcuts

Vertex Gallery supports comprehensive keyboard navigation:

Gallery View

  • Enter or Space: Open modal for focused card
  • Arrow Left/Right: Navigate between thumbnail items (when focused)

Modal View

  • Escape: Close modal
  • Arrow Left: Previous image
  • Arrow Right: Next image
  • Home: Jump to first image
  • End: Jump to last image
  • Tab: Navigate between controls (focus trapping enabled)

Autoplay Speed Slider (when focused)

  • Arrow Left/Down: Decrease speed
  • Arrow Right/Up: Increase speed
  • Home: Set to minimum speed
  • End: Set to maximum speed

Touch Gestures

On touch devices, Vertex Gallery supports:

  • Swipe Left/Right: Navigate between images in modal
  • Pinch-to-Zoom: Zoom in/out on images in modal
  • Pan/Drag: Move zoomed images around
  • Tap: Open modal from gallery cards
  • Long Press: Context menu (if right-click is enabled)

RTL (Right-to-Left) Support

Vertex Gallery automatically detects RTL languages by checking:

  • The dir attribute on the root element or document
  • CSS direction property

When RTL is detected, all UI elements (navigation arrows, thumbnails, controls) automatically flip to the correct orientation.

CSS Customization

Vertex Gallery uses CSS variables for easy theming. Override these variables in your CSS:

:root {
  /* Base Colors */
  --vg-bg-color: #0f172a;
  --vg-card-bg: #1e293b;
  --vg-accent: #0005f0;
  --vg-text-main: #f8fafc;
  --vg-text-muted: #94a3b8;
  
  /* Filter Button Colors */
  --vg-filter-btn-bg: #000000;
  --vg-filter-btn-color: #ffffff;
  --vg-filter-btn-hover-bg: #3333ff;
  
  /* Modal Colors */
  --vg-modal-text-color: #ffffff;
  --vg-modal-backdrop-opacity: 0.8;
  
  /* Light Theme Colors */
  --vg-light-text: #1a1a1a;
  --vg-light-bg-overlay: rgba(0, 0, 0, 0.1);
  
  /* Layout & Spacing */
  --vg-gap: 16px;
  --vg-thumb-height: 60px;
  
  /* And many more... */
}

Complete list: See dist/vertex-gallery.css for all available CSS variables. Variables are organized into sections:

  • Base Colors
  • Glass/Overlay Effects
  • Filter Button Colors
  • Modal Text Colors
  • Light Theme Colors
  • Card Colors
  • Modal Elements
  • Layout & Spacing

Configuration Validation

Vertex Gallery automatically validates configuration values:

  • gap: Must be >= 0 (defaults to 16 if invalid)
  • modalAutoplayInterval: Must be >= 100ms and <= 60000ms (defaults to 3000ms if invalid)
  • modalBackdropOpacity: Must be between 0.0 and 1.0 (defaults to 0.8 if invalid)
  • modalSwipeThreshold: Must be >= 0 (defaults to 50 if invalid)
  • imageFilterAmount: Must be >= 0 (defaults to 100 if invalid)
  • cornerStyle: Must be 'rounded' or 'flat' (defaults to 'rounded' if invalid)
  • layout: Must be 'grid' or 'masonry' (defaults to 'grid' if invalid)
  • imageFilterOnHover: Must be 'color', 'filter', or 'none' (defaults to 'color' if invalid)

Invalid values will log warnings to the console and use safe defaults.

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Note: Masonry layout uses CSS Grid's grid-template-rows: masonry, which requires Firefox or a fallback positioning system for other browsers.

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.