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

@get-set/gs-zoom

v0.0.13

Published

Get-Set Zoom

Readme

GSZoom

A dependency-free image lightbox & magnifier with drag, pinch-zoom, wheel-zoom, autoplay, fullscreen, a thumbnail filmstrip and keyboard navigation — available in two flavours from one codebase:

  • Native / vanilla JS — a window.GSZoom(images, params) factory (also exposed as a jQuery plugin and an HTMLElement.prototype method).
  • React — a <GSZoom /> component.

Both share the exact same engine (actions/, constants/, helpers/, types/), so behaviour is identical across the two.

Features

  • Two modes: lightbox (full-screen viewer over a collection of images) and magnifier (in-place zoom lens that follows the cursor).
  • Backdrop / overlay catalog: dim, blur, glass, gradient, vignette, tint, none — tunable colour, opacity and blur radius.
  • Open / close animation catalog: flip (flies from the clicked thumbnail via the FLIP technique), fade, zoom, slide, flipIn, none — tunable duration and easing.
  • Themeable chrome (dark / light) plus a custom accent colour for active states, progress, spinner and the active thumbnail.
  • Opt-in frosted glassControls for the prev / next / close / zoom buttons.
  • Drag to pan, pinch-to-zoom (touch), mouse-wheel zoom, and double-tap zoom, with a tunable maxZoom ceiling.
  • Prev / next arrows and ← → keyboard navigation, with wrap-around.
  • Thumbnail filmstrip (showAdditionals) that can be kept open by default (showThumbnails).
  • Autoplay with a loading-progress ring and a tunable interval.
  • Fullscreen on open (can be disabled), with the lightbox restored on exit.
  • Per-image data-gs* attributes for title / subtitle / description and an alternate high-res magnifier source.
  • Query-string injection for main and thumbnail image URLs (CDN sizing, cache-busting, etc.).
  • Responsive breakpoints overriding any param (and the magnifier config) per viewport width.
  • Lifecycle hooks: beforeInit, afterInit, beforeLightBoxOpen, afterLightBoxOpen, beforeLightBoxClose, afterLightBoxClose, afterChange.

Compatibility

| Target | Requirement | |---|---| | React (the <GSZoom> component) | React 16.8+ (Hooks are required), and 17 / 18 / 19. React is an optional peer dependency — you only need it for the component. | | Native / vanilla (window.GSZoom) | No framework. Any modern evergreen browser. Optional jQuery ($(...).GSZoom(...)) and HTMLElement.prototype.GSZoom(...) adapters are registered automatically if present. | | TypeScript | First-class — type declarations (.d.ts) ship in the package. | | SSR / Next.js | Safe to import server-side (no DOM access at module load). The viewer itself is browser-only, so render it inside a Client Component ('use client'). |

The peer range is ^16.8.0 || ^17.0 || ^18.0 || ^19.0, with react/react-dom marked optional so the native build has zero framework dependencies.

Installation

npm i @get-set/gs-zoom

Project layout

GSZoom.ts                 # native entry  (webpack -> dist-js/bundle.js, window global)
components/GSZoom.tsx      # React component (tsc -> dist/, npm entry)
actions/                  # shared engine (open/close/change/draw/magnifier/autoplay/drag…)
constants/                # shared constants (defaults, type/backdrop/animation/theme catalogs, icons)
helpers/uihelpers.ts      # shared helpers
types/                    # Params / Ref / Window augmentation
components/styles/         # SCSS + compiled CSS + CSS-as-TS (runtime injection for React)
styles/                   # SCSS + compiled CSS (for <link> use by the native build)

Build

npm install
npm run build          # builds both targets
npm run build:js       # native bundle -> dist-js/bundle.js
npm run build:react    # React + types  -> dist/components/GSZoom.js

Tests

Unit tests use Vitest + jsdom:

npm test         # run once
npm run test:watch

Usage — Native JS

The factory takes a single image, a NodeList, or an array of <img> elements, plus the params object. Include the stylesheet and the bundle, then call new GSZoom(...):

<link rel="stylesheet" href="styles/GSZoom.css" />

<!-- Lightbox on a collection -->
<div class="gallery">
  <img src="photo1.jpg" data-gstitle="Photo 1" data-gssubtitle="Subtitle" />
  <img src="photo2.jpg" data-gsdescription="A longer caption." />
  <img src="photo3.jpg" data-gszoomsrc="photo3-hi-res.jpg" />
</div>

<script src="dist-js/bundle.js"></script>
<script>
  new GSZoom(document.querySelectorAll('.gallery img'), {
    type: 'lightbox',
    arrows: true,
    navigateWithKeys: true,
    maxZoom: 5,
    backdrop: 'glass',
    animation: 'flip',
    theme: 'dark',
    accent: '#34d1ff',
    autoplaySpeed: 4000,
    responsive: [
      { windowSize: 768, params: { arrows: false } },
    ],
    afterLightBoxOpen: () => console.log('opened'),
  });
</script>

Equivalent jQuery / element forms (registered by the bundle):

// jQuery
$('.gallery img').GSZoom({ type: 'lightbox' });

// HTMLElement.prototype
document.querySelector('img').GSZoom({ type: 'magnifier' });

Note: the jQuery $(sel).GSZoom(...) and el.GSZoom(...) forms initialise each matched element as its own viewer (jQuery's per-element convention) — ideal for standalone images or magnifiers. For a single navigable gallery (prev/next across the whole set), pass the images to the window.GSZoom(images, params) factory, or render the React <GSZoom> with the images as children.

Instance registry & methods

Every instance is stored in a global registry keyed by its reference. Look one up with window.GSZoomConfigue.instance(key) to get its raw Ref (state object). The registry also exposes references (the list of { key, ref }) and openedZoom (the reference of the currently open lightbox, or undefined).

new GSZoom(document.querySelectorAll('.gallery img'), { reference: 'main' });

const ref = window.GSZoomConfigue.instance('main'); // the Ref for this instance
window.GSZoomConfigue.openedZoom;                   // which lightbox is open (if any)

The imperative actions are importable functions in the native build that operate on a Ref: initOpen(ref, index), initClose() and initChange(ref, index) (advance/rewind is initChange with the next/previous index). The React component ref wraps these as open / close / next / prev (below) — see Methods.

Usage — React

import GSZoom from '@get-set/gs-zoom';

// Lightbox — collection mode (wrap multiple images)
<GSZoom type="lightbox" arrows navigateWithKeys maxZoom={5} backdrop="glass" animation="flip">
  <img src="photo1.jpg" data-gstitle="Photo one" data-gssubtitle="Subtitle" />
  <img src="photo2.jpg" />
</GSZoom>

// Lightbox — single image mode (use the `src` prop, no children)
<GSZoom type="lightbox" src="photo1.jpg" data-gstitle="Photo one" />

// Magnifier
<GSZoom
  type="magnifier"
  src="product.jpg"
  data-gszoomsrc="product-hi-res.jpg"
  magnifier={{ zoom: 4, form: 'circle', size: 180 }}
/>

In collection mode each <img> you pass as a child is registered automatically (the wrapper gets a .gs-zoom-collection class). In single-image mode pass the image via the src prop instead of children. The CSS is injected at runtime — no stylesheet import required. The React-only prop gsx lets you scope inline styles to a single instance.

Next.js (App Router)

The viewer is browser-only, so use it from a Client Component:

'use client';
import GSZoom from '@get-set/gs-zoom';

export default function Gallery() {
  return (
    <GSZoom type="lightbox" arrows backdrop="vignette">
      <img src="/1.jpg" />
      <img src="/2.jpg" />
    </GSZoom>
  );
}

Options

Every option is optional; the table lists the default applied when omitted.

| Option | Type | Default | Description | |---|---|---|---| | reference | string | random GUID | Unique key (used by the registry / instance() lookup). | | type | 'lightbox' \| 'magnifier' | 'lightbox' | Plugin mode — full-screen viewer or in-place zoom lens. | | arrows | boolean | true | Show prev / next arrow buttons in the lightbox. | | navigateWithKeys | boolean | true | Enable ← → keyboard navigation. | | showAdditionals | boolean | true | Build the bottom thumbnail strip in the lightbox. | | showThumbnails | boolean | false | Keep the thumbnail filmstrip open by default (instead of toggled). | | zoomOnWheel | boolean | true | Zoom the image with the mouse wheel. | | maxZoom | number | 5 | Maximum zoom multiplier. | | disableFullScreen | boolean | false | Don't request the Fullscreen API when the lightbox opens. | | imgLoading | string | '' | HTML string shown in place of the image while it loads. | | autoplaySpeed | number | 5000 | Autoplay interval (ms) between images. | | mainImageQueryParameters | string | '' | Query string appended to the main (full-size) image src. | | additionalImageQueryParameters | string | '' | Query string appended to each thumbnail src. | | backdrop | 'dim' \| 'blur' \| 'glass' \| 'gradient' \| 'vignette' \| 'tint' \| 'none' | 'dim' | Overlay layer rendered behind the lightbox. See Backdrops. | | backdropColor | string | '' | Base colour (any CSS colour) for dim / glass / gradient / vignette / tint. | | backdropOpacity | number | 0.92 | Backdrop opacity, 01. | | backdropBlur | number | 50 | Blur radius (px) for the blur / glass backdrops. | | animation | 'flip' \| 'fade' \| 'zoom' \| 'slide' \| 'flipIn' \| 'none' | 'flip' | Open / close transition. See Animations. | | animationDuration | number | 420 | Open / close transition duration (ms). | | animationEasing | string | 'cubic-bezier(0.22, 1, 0.36, 1)' | Any CSS easing for the open / close transition. | | theme | 'dark' \| 'light' | 'dark' | Lightbox chrome theme. See Themes. | | accent | string | '' | Accent colour (any CSS colour) for the counter, autoplay progress, spinner and active thumbnail. | | glassControls | boolean | true | Render the prev / next / close / zoom controls as frosted-glass buttons. | | showCounter | boolean | true | Show the n / total counter in the header. | | magnifier | Partial<MagnifierParams> | see MagnifierParams | Magnifier-mode settings. | | responsive | ResponsiveOption[] | [] | Per-breakpoint overrides (sorted automatically). See ResponsiveOption. | | gsx | NestedCSS | – | React only — scoped inline styles for this instance (see gsx). |

React component props

In addition to every option above, the React <GSZoom> component accepts:

| Prop | Type | Description | |---|---|---| | src | string | Single-image mode — renders one <img> from this URL instead of reading children. | | children | React.ReactNode | Collection mode — every <img> inside is registered as a gallery item. |

Any other DOM attributes you pass (e.g. className, data-gstitle) are forwarded to the rendered <img> (single mode) — plugin-only props are stripped so they never leak onto the DOM node.

MagnifierParams

Passed via the magnifier option.

| Prop | Type | Default | Description | |---|---|---|---| | zoom | number | 3 | Zoom multiplier inside the lens. | | form | 'circle' \| 'square' | 'circle' | Shape of the magnifier lens. | | size | number | 150 | Lens diameter / side length (px). |

ResponsiveOption

Each entry in the responsive array overrides params (and optionally the magnifier config) at or below windowSize.

| Prop | Type | Description | |---|---|---| | windowSize | number | Breakpoint width (px). | | params | Partial<Params> | Params to apply at this breakpoint. | | magnifier | Partial<MagnifierParams> | Magnifier overrides at this breakpoint (optional). |

Per-image data attributes

Set these on the <img> elements (works in both vanilla and React).

| Attribute | Used by | Description | |---|---|---| | data-gstitle | lightbox | Title text shown below the image. | | data-gssubtitle | lightbox | Subtitle text. | | data-gsdescription | lightbox | Description / caption text. | | data-gszoomsrc | magnifier | Alternate high-res source used inside the lens (falls back to src). |

Callbacks

All are optional () => void hooks.

| Callback | Fires | |---|---| | beforeInit | before the plugin initialises | | afterInit | after the plugin initialises | | beforeLightBoxOpen | before the lightbox opens | | afterLightBoxOpen | after the lightbox opens | | beforeLightBoxClose | before the lightbox closes | | afterLightBoxClose | after the lightbox closes | | afterChange | after the active image changes |

Backdrop catalog

The backdrop option selects the overlay layer rendered behind the lightbox (each maps to a gs-zoom-backdrop-<name> class on the container).

| Value | Description | |---|---| | dim | Solid dark dim layer (classic, default). | | blur | Frosted blur of the page behind the lightbox (uses backdropBlur). | | glass | Blur + translucent tint + a hairline border (glassmorphism). | | gradient | Radial / linear gradient wash. | | vignette | Darkened edges fading to a clearer centre. | | tint | Flat solid colour fill (uses backdropColor). | | none | No backdrop at all (transparent). |

Tune any of them with backdropColor, backdropOpacity and backdropBlur.

Animation catalog

The animation option selects the open / close transition. Tune it with animationDuration and animationEasing.

| Value | Description | |---|---| | flip | FLIP zoom-from-thumbnail — the image flies from the clicked thumbnail's rect to full screen (default). | | fade | Simple cross-fade. | | zoom | Scale up from the centre. | | slide | Slide up from the bottom. | | flipIn | 3D flip-in. | | none | No animation. |

Theme catalog

The theme option sets the chrome palette.

| Value | Description | |---|---| | dark | Dark chrome (default). | | light | Light chrome. |

Layer a custom accent colour on top of either theme.

The gsx prop (React only)

gsx accepts a nested CSS map that is compiled and injected scoped to this instance only (matched on the instance's data-key), so you can theme one viewer without a global stylesheet:

<GSZoom
  type="lightbox"
  gsx={{ '.gs-zoom-counter': { fontWeight: 700, letterSpacing: '0.04em' } }}
>
  <img src="photo1.jpg" />
  <img src="photo2.jpg" />
</GSZoom>

Methods (imperative API)

| Method | Description | |---|---| | open(index?) | Open the lightbox at a 0-based index (defaults to the current index). | | close() | Close the currently open lightbox. | | next() / prev() | Advance / rewind by one image (wraps around). | | getInstance() | React only — returns the raw plugin instance (registry Ref) for this component. |

Access — Native — the registry stores each instance's Ref (state object) under its reference:

new GSZoom(document.querySelectorAll('.gallery img'), { reference: 'main' });
const z = window.GSZoomConfigue.instance('main'); // raw Ref { list, currentParams, currentIndex, … }

Access — React (via a ref to the component):

import GSZoom, { GSZoomHandle } from '@get-set/gs-zoom';
import { useRef } from 'react';

function Gallery() {
  const ref = useRef<GSZoomHandle>(null);
  return (
    <>
      <button onClick={() => ref.current?.open(0)}>Open first</button>
      <GSZoom ref={ref} type="lightbox">
        <img src="photo1.jpg" />
        <img src="photo2.jpg" />
      </GSZoom>
    </>
  );
}

next() / prev() only act while this instance's lightbox is the one currently open (window.GSZoomConfigue.openedZoom); they are no-ops otherwise.

License

ISC.