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

bos-lightbox

v1.0.0

Published

React-based lightbox component for previewing images, PDFs, and other documents with keyboard navigation, zoom, and touch support.

Readme

bos-lightbox

A React lightbox component for previewing images, PDFs, videos, and other documents with keyboard navigation, zoom, touch support, and an imperative ref API.

Features

  • 🖼️ Image Preview — Zoom, pan (drag when zoomed), and download images
  • 🖼️ Thumbnail Strip — Bottom thumbnail row for visual navigation between items
  • 📄 PDF Preview — Native PDF viewer integration via iframe
  • 🎬 Video Support — Native <video> playback with controls and autoplay
  • 📱 Touch Gestures — Swipe navigation on mobile devices
  • ⌨️ Keyboard Navigation — Arrow keys, Escape to close (modal and inline)
  • Accessibility — ARIA attributes, focus trapping via native <dialog>, screen reader support
  • 🔗 Circular Navigation — Optional loop through items
  • 🎨 CustomizableclassName, style, and renderItem props for full control
  • 🎯 TypeScript — Full type definitions included
  • 🎞️ Animations — Smooth fade-in on open and fade transitions between items
  • 🔁 Slideshow — Auto-play with configurable interval and play/pause control
  • 📦 Lightweight — No external dependencies beyond React. Tree-shakeable ESM and UMD builds
  • 🖥️ SSR Compatible — Safe for server-side rendering environments

Installation

npm install bos-lightbox

Quick Start

import { useState } from "react";
import { BosLightbox } from "bos-lightbox";
import type { PreviewItem } from "bos-lightbox";

function Gallery() {
  const [open, setOpen] = useState(false);

  const items: PreviewItem[] = [
    { url: "image1.jpg", type: "image", name: "Photo" },
    { url: "doc.pdf",    type: "pdf",   name: "Document" },
    { url: "video.mp4",  type: "video", name: "Clip" },
    { url: "file.zip",   type: "other", name: "Archive" },
  ];

  return (
    <>
      <button onClick={() => setOpen(true)}>Open Gallery</button>
      <BosLightbox
        items={items}
        open={open}
        onClose={() => setOpen(false)}
      />
    </>
  );
}

Imperative Ref API

For more control, use the ref prop:

import { useRef, useState } from "react";
import { BosLightbox } from "bos-lightbox";
import type { BosLightboxRef, PreviewItem } from "bos-lightbox";

function Gallery() {
  const ref = useRef<BosLightboxRef>(null);
  const [open, setOpen] = useState(false);

  const items: PreviewItem[] = [
    { url: "image1.jpg", type: "image", name: "Landscape" },
    { url: "doc.pdf",    type: "pdf",   name: "Report" },
    { url: "arch.zip",   type: "other", name: "Archive" },
  ];

  return (
    <>
      <BosLightbox ref={ref} items={items} open={open} onClose={() => setOpen(false)} />
      <button onClick={() => ref.current?.openAt(0)}>Open Landscape</button>
      <button onClick={() => ref.current?.next()}>Next</button>
      <button onClick={() => ref.current?.prev()}>Previous</button>
    </>
  );
}

Display Modes

Modal (default)

Uses the native <dialog> element with a focus trap, backdrop blur, and Escape-to-close behavior.

<BosLightbox items={items} open={open} displayMode="modal" onClose={() => setOpen(false)} />

Inline (full-page overlay)

Renders as a fixed-position overlay without the <dialog> element — useful when you need full control over the overlay behavior. Inline mode supports Escape-to-close and overlay click-to-close just like modal mode.

<BosLightbox items={items} open={open} displayMode="inline" onClose={() => setOpen(false)} />

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | items | PreviewItem[] | — (required) | Array of items to preview | | open | boolean | — (required) | Whether the lightbox is open | | initialIndex | number | 0 | Index of the item to show when opened | | loop | boolean | false | Enable circular navigation (last ↔ first) | | closeOnOverlay | boolean | true | Close when clicking the overlay background | | closeOnEscape | boolean | true | Close when pressing Escape | | downloadable | boolean | true | Show the download button in the header | | displayMode | "modal" \| "inline" | "modal" | Display mode | | renderItem | (item) => ReactNode | — | Custom render function for item content | | slideshow | boolean | false | Enable auto-playing slideshow mode | | slideshowInterval | number | 3000 | Interval in ms between slideshow advances | | thumbnails | boolean | false | Show a bottom thumbnail strip for visual navigation | | className | string | — | CSS class for the root element | | style | React.CSSProperties | — | Inline styles for the root element | | onOpen | () => void | — | Callback when the lightbox opens | | onClose | () => void | — | Callback when the lightbox closes | | onItemChange | (detail) => void | — | Callback with { previousIndex, currentIndex, item } | | onDownload | (detail) => void | — | Callback with { item } when download is triggered | | onError | (detail) => void | — | Callback with { item, error } on load errors |

PreviewItem

interface PreviewItem {
  type: "image" | "pdf" | "video" | "other";
  url: string;
  name: string;
}

renderItem

For complete control over content rendering, pass a custom function:

<BosLightbox
  items={items}
  open={open}
  onClose={() => setOpen(false)}
  renderItem={(item) => {
    if (item.type === "image") {
      return <CustomImageViewer url={item.url} />;
    }
    // Fall back to default rendering for other types
    return null; // or <DefaultViewer />
  }}
/>

When renderItem is provided, it takes precedence over the built-in type-based rendering. Return null to render nothing for a particular item.

Ref Methods (BosLightboxRef)

| Method | Description | |--------|-------------| | openAt(index: number) | Open the lightbox at a specific item index | | goTo(index: number) | Navigate to a specific item by index | | next() | Navigate to the next item | | prev() | Navigate to the previous item | | close() | Close the lightbox programmatically | | getCurrentIndex() | Return the current item index | | getCurrentItem() | Return the current item object | | toggleSlideshow() | Toggle slideshow play/pause | | isSlideshowActive() | Return whether slideshow is currently active |

Keyboard Shortcuts

| Key | Action | |-----|--------| | Arrow Left | Previous item | | Arrow Right | Next item | | Esc | Close lightbox (modal and inline) |

Touch Gestures

  • Swipe left/right — Navigate between items
  • Tap on overlay — Close lightbox (if closeOnOverlay is true)

Browser Support

  • Chrome 54+
  • Firefox 63+
  • Safari 10.1+
  • Edge 79+

License

MIT