
Security News
npm Tooling Bug Incorrectly Marks One-Character Packages as Security Holders
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.
@page-speed/lightbox
Advanced tools

High‑performance, media‑rich lightbox for React, professionally designed by the UI/UX team at OpenSite for their Semantic UI engine.
Below you can see the wide range of layouts that are available automatically, enabling a modern UI experience for users. And since the component was specifically engineered for our Semantic UI engine, in addition to the default layout and style variants, the Lightbox components are also completely customizable.
@page-speed/lightbox renders images, videos, PDFs, and custom React components inside a responsive, keyboard‑friendly lightbox. It is built to be:
You can use it both inside the DashTrack platform and in standalone React apps.
image, video, pdf, and component (custom React content).fullscreen, vertical-split, or horizontal layout based on viewport (overridable via props).core, hooks, components, and renderers.@page-speed/pdf-viewer, lazily loaded only when needed.The library has React 18+ as a peer dependency and ships TypeScript typings out of the box.
pnpm add @page-speed/lightbox
npm install @page-speed/lightbox
yarn add @page-speed/lightbox
The Lightbox component is intentionally controlled by mount/unmount. You decide when it is shown by conditionally rendering it in your component.
import { useState } from "react";
import { Lightbox, type LightboxItem } from "@page-speed/lightbox";
const items: LightboxItem[] = [
{ id: "1", type: "image", src: "/images/hero.jpg", alt: "Hero" },
{ id: "2", type: "video", src: "/videos/demo.mp4", title: "Demo" },
];
export function Gallery() {
const [isOpen, setIsOpen] = useState(false);
const [initialIndex, setInitialIndex] = useState(0);
return (
<>
<button
onClick={() => {
setInitialIndex(0);
setIsOpen(true);
}}
>
Open gallery
</button>
{isOpen && (
<Lightbox
items={items}
initialIndex={initialIndex}
onClose={() => setIsOpen(false)}
/>
)}
</>
);
}
How it works:
isOpen to true, which mounts the <Lightbox />.onOpen (if provided).onClose, and the parent should unmount it by toggling isOpen.Items are strongly typed via LightboxItem and support different media strategies:
import type { LightboxItem } from "@page-speed/lightbox";
const items: LightboxItem[] = [
{ id: "img-1", type: "image", src: "/images/hero.jpg", alt: "Hero" },
{ id: "pdf-1", type: "pdf", src: "/docs/brochure.pdf", title: "Brochure" },
{
id: "component-1",
type: "component",
component: MyCustomSlide,
data: { heading: "Custom slide" },
},
];
Key fields:
id: string – unique per item.type: "image" | "video" | "pdf" | "component" – controls which renderer is used.src?: string – URL for image/video/PDF.alt?: string – alt text for images.title? / caption? – shown in the chrome/caption area when enabled.component?: React.ComponentType<any> – for type: "component", your own React slide.download? / share? – optional download/share configuration.The full LightboxProps type lives in src/types.ts and is exported from the package. The most commonly used props are:
items: LightboxItem[] – required list of slides.initialIndex?: number – index of the item to show first.layout?: "horizontal" | "vertical-split" | "custom-slide" | "fullscreen" | "inline" – override automatic layout.controls?: Partial<LightboxControls> – enable/disable UI features.height?: string | number – e.g. "80vh".maxWidth?: string | number – e.g. "1200px".className?, style? – for wrapping container.onOpen?, onClose? – lifecycle callbacks.onSelect?(index: number) – called when the current index changes.onNext?, onPrev? – called on navigation.enableKeyboardShortcuts?: boolean – default true.disableScroll?: boolean – default true (locks body scroll while open).closeOnBackdropClick?: boolean – default true.Example configuring layout and controls:
<Lightbox
items={items}
layout="horizontal"
controls={{ navigation: true, keyboard: true, captions: true }}
onSelect={(index) => console.log("Selected index", index)}
/>
For more advanced usage (especially inside the Semantic Site Builder), you can work directly with the hooks and core exports.
useLightbox (core)useLightbox composes gallery navigation and open/close state into a single hook. It is exported from both @page-speed/lightbox and @page-speed/lightbox/core.
import { useLightbox } from "@page-speed/lightbox/core";
const lb = useLightbox({ items, onSelect: (i) => console.log(i) });
// lb: { isOpen, open, close, currentIndex, currentItem, next, prev, canNext, canPrev, goTo, items }
You can build your own UI around this hook if you need something different from the default <Lightbox /> shell.
The hooks subpath provides granular imports for tree‑shaking:
import { useGalleryState, useResponsiveness } from "@page-speed/lightbox/hooks";
Available hooks:
useGalleryState – navigation state for a list of LightboxItems.useLightboxState – open/close + scroll locking.useLightbox – composed lightbox controller.useKeyboardShortcuts – attach keyboard handlers.useResponsiveness – responsive breakpoint info.You can import the building blocks individually when constructing custom UIs or integrating into block registries.
import {
Lightbox,
LightboxOverlay,
LightboxContent,
LightboxChrome,
HorizontalLayout,
} from "@page-speed/lightbox/components";
import {
ImageRenderer,
VideoRenderer,
PDFRenderer,
ComponentRenderer,
} from "@page-speed/lightbox/renderers";
These renderers are what LightboxContent uses under the hood for each LightboxItem.type.
items: LightboxItem[] as the projection of your Chai/semantic payload for a gallery block.<Lightbox /> with the appropriate items and initialIndex.useLightbox from @page-speed/lightbox/core and wire it into your block registry.See dev-docs/lightbox-implementation-guide.md and dev-docs/SEMANTIC_SITE_BUILDER.md in this repo for deeper, platform‑specific details.
/core, /hooks, /components, /renderers).For broader ecosystem performance guidelines, see dev-docs/ECOSYSTEM_GUIDELINES.md.
Contributions are welcome. Please open issues or pull requests on the GitHub repo:
Follow the existing code style, add tests for new behavior, and ensure pnpm test, pnpm run type-check, and pnpm run build all pass before submitting.
This project is licensed under the MIT License. See the LICENSE file for details.
FAQs
High-performance, feature-rich lightbox for OpenSite platform
The npm package @page-speed/lightbox receives a total of 83 weekly downloads. As such, @page-speed/lightbox popularity was classified as not popular.
We found that @page-speed/lightbox demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
npm confirmed a tooling bug incorrectly marked several one-character packages as security holders and said it was working on a rollback.

Research
/Security News
Newer packages in this compromise use native extensions and .pth loaders to execute JavaScript stealers in developer environments.

Research
Socket found 37 malicious PyPI wheels that abuse Python startup hooks to launch a Bun-powered credential stealer tied to Mini Shai-Hulud/Miasma.