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

@sankaran-8600/component-viewer

v1.0.7

Published

jQuery plugin for attachment and media preview in an overlay

Readme

ComponentViewer

npm version

A jQuery plugin that opens attachments (images, video, audio, PDF, inline content, and more) in a shared overlay with a consistent toolbar, themes, and optional accessibility (WCAG) support. Built for feed- or post-style UIs where each container has its own set of items.

Install from npm: npm i @sankaran-8600/component-viewer · License: MIT


Table of contents


Demo

Try the plugin in your browser with the full example page, which includes all content types, toolbar customisation, themes, poll options, loop/counter options, and image failure handling.

Open example.html — open this file in a browser to see multiple demo cases and use the programmatic API buttons to open specific items.

The example page uses jQuery 3.7, jPlayer, and PDF.js (loaded from CDN). Without jPlayer or PDF.js, the plugin uses native HTML5 media and an iframe for PDF — use a minimal page that loads only jQuery + the plugin to try that.


Installation

Dependencies

  • jQuery (1.7+ or 2.x/3.x)
  • Optional: jPlayer for video/audio playback
  • Optional: PDF.js for PDF rendering
  • Optional: marked for full Markdown (CommonMark) preview; otherwise a minimal built-in parser is used

Include the plugin and stylesheet after jQuery:

<link rel="stylesheet" href="component-viewer.css" />
<script src="jquery.min.js"></script>
<script src="component-viewer.js"></script>

When embedding in another project: Load component-viewer.css after your app’s base/reset styles so the viewer’s look isn’t overridden. The stylesheet is plain CSS; if you bundle with Less, do not process this file as Less (Less interprets min()/max() and can change output). Either link to it as a separate stylesheet or import it unchanged: @import (inline) "component-viewer.css";

For video/audio with jPlayer, include jPlayer before the plugin. For PDF with pdf.js, include the library and set pdf.workerSrc. For full Markdown support, include marked (e.g. from a CDN) before the plugin.

Minified build: From this folder run npm install then npm run build to generate component-viewer.min.js and component-viewer-japanese.min.js (Terser). Use the .min.js files in production for smaller downloads.

To run the project’s code check (ESLint, aligned with CodeCheck): npm run lint or npm run codecheck. To lint the CodeCheck + I18N variant: npm run lint:codecheck.

CodeCheck + I18N variant: component-viewer.codecheck.js is a copy of the plugin maintained for full CodeCheck and I18N compliance. It uses the same ESLint config; all user-facing strings go through str(inst, key) and DEFAULT_STRINGS; non-translatable blocks (e.g. SVG in Icons) are wrapped with /* ignorei18n_start */ and /* ignorei18n_end */ per I18N code check. Use this file when you need a build that satisfies strict CodeCheck and I18N rules.


Quick start

  1. Mark up your items with a common selector (default: .cv-item) and use data-* attributes for type, source, and title:
<div id="my-gallery">
  <a class="att cv-item" data-type="image" data-title="Photo.jpg" href="https://example.com/photo.jpg">
    <img src="https://example.com/photo-thumb.jpg" alt="" />
  </a>
  <div class="att cv-item" data-type="pdf" data-title="Doc.pdf" data-src="https://example.com/doc.pdf" data-ext="PDF">
    PDF
  </div>
</div>
  1. Initialize the viewer on the container:
$('#my-gallery').componentViewer({
  toolbar: { download: true, zoom: true },
  pdf: { workerSrc: 'path/to/pdf.worker.min.js' }
});
  1. Click any item to open it in the overlay. Use prev/next to move between items.

Options reference

All options are optional. Defaults are in $.fn.componentViewer.defaults.

General

| Option | Type | Default | Description | |--------|------|---------|-------------| | selector | string | '.cv-item' | CSS selector for items inside the container. | | loop | boolean | true | If true, prev from first goes to last and next from last goes to first. If false, prev/next are hidden at first/last. | | overlayClose | boolean | true | Close overlay when clicking the backdrop. | | keyboardNav | boolean | true | Escape closes; Left/Right move prev/next; Space/M/D and custom shortcuts when applicable. | | shortcutsPopup | boolean | true | If true, pressing ? opens a popup listing keyboard shortcuts for the current view. Set to false to disable. | | showCounter | boolean | true | Show the "1 / 6" counter in the header. Set to false to hide it. | | preloadAdjacentImages | boolean | true | When true, the next and previous items are preloaded if they are images, so navigating to them is instant (Colorbox-style). Set to false to disable. | | carousel | object | { enabled: false, navThreshold: 4 } | Carousel options. Set carousel.enabled: true to show a header button that toggles a strip of thumbnails below the stage. carousel.navThreshold (default 4): when item count exceeds this, prev/next buttons appear on the strip. | | slideshow | object | null | null | When set to an object with enabled: true, the viewer auto-advances to the next item. Options: interval (seconds, default 4), autoStart (default true), advanceMedia: 'interval' or 'onEnd'. A "Play slideshow" / "Pause slideshow" toolbar button is shown; when autoStart: true, the button shows "Pause slideshow" initially. | | theme | string | 'dark' | Initial theme: 'dark' or 'light'. | | themeToggle | boolean | true | Show the theme (dark/light) toggle in the header. | | fullscreen | boolean | true | Show a header button to toggle overlay fullscreen (native Fullscreen API). Set to false to hide. Does not affect video/audio fullscreen. | | onThemeChange | function | null | function(theme, viewer) called when theme changes. |

PDF

| Option | Type | Default | Description | |--------|------|---------|-------------| | pdf.workerSrc | string | null | URL to pdf.js worker (required for PDF.js). | | pdf.cMapUrl | string | null | Optional CMap URL for fonts. | | pdf.cMapPacked | boolean | true | Use packed CMaps. | | pdf.annotations | boolean | true | Render PDF annotations. | | pdf.autoFit | boolean | true | Scale page to fit stage (width and height), within min/max scale for readability. | | pdf.autoFitMinScale | number | 0.75 | When autoFit is true, scale never goes below this (75%) so the PDF stays readable. | | pdf.autoFitMaxScale | number | 2.5 | Max scale when autoFit is true. | | pdf.twoPageView | boolean | false | When true, a toolbar button is shown to toggle single/two-page view. PDF opens in single-page; user can switch to side-by-side (spread) view. Auto-fit fits both pages in width when in two-page mode. |

Media (jPlayer)

| Option | Type | Default | Description | |--------|------|---------|-------------| | supportedVideoFormats | string | null | Comma-separated jPlayer formats for video (e.g. 'm4v, webmv'). | | supportedAudioFormats | string | null | Comma-separated jPlayer formats for audio (e.g. 'mp3, oga'). |

Inline (Highlight.js)

For inline (source/code) items you can enable syntax highlighting with Highlight.js. The plugin does not bundle it; the host page must include the script and a theme CSS.

| Option | Type | Default | Description | |--------|------|---------|-------------| | inline.syntaxHighlight | boolean | false | When true, use window.hljs to highlight code (if present). | | inline.getLanguage | function | null | function(item) returning a language string (e.g. 'javascript', 'java'). If null, language is inferred from item.fileExt / item.title. | | onInlineHtml | function | null | function(content, item, viewer) returning HTML for the inline body. When set, overrides built-in rendering (e.g. custom highlighter). |

Loading Highlight.js for the highlight case: Include the library and a theme in your page (before or with the viewer). The plugin only calls window.hljs.highlight(); all colors and styles come from the theme CSS you load. Example:

<script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/github.min.css">

Then enable highlighting: inline: { syntaxHighlight: true }. The viewer’s CSS only keeps Highlight.js token spans aligned (e.g. .cv-inline-body .cv-inline-code [class*="hljs-"]); it does not provide a theme.

Data and callbacks

| Option | Type | Default | Description | |--------|------|---------|-------------| | itemData | function | null | function($el, defaultItem) — returns the item object for each element. Second argument is the item the plugin would build from data-* and DOM; you can add properties to defaultItem and return it, or return a new object. If null, item is built from data-* and DOM. | | onDownload | function | null | function(item, viewer). If provided, called when Download is clicked; otherwise default link download. | | onRender | function | null | function(item, $stage, viewer). If it appends to $stage, built-in renderer is skipped. May return { toolbar, destroy }. | | onToolbar | function | null | function(item, defaultToolbar, viewer). Modify or replace the toolbar array. | | onLoading | function | null | function(item, viewer) before an item is loaded. | | onOpen | function | null | function(item, $stage, viewer) after the item is shown and toolbar is built. | | onComplete | function | null | function(item, viewer) right after content is displayed (after transition if any). Like Colorbox onComplete. | | onCleanup | function | null | function(item, viewer) at the start of the close process, before teardown. Like Colorbox onCleanup. | | onClose | function | null | function(item, viewer) when the overlay has closed (item was the visible one). Like Colorbox onClosed. |

Accessibility

| Option | Type | Default | Description | |--------|------|---------|-------------| | wcag | boolean | false | If true, enables focus trap, focus save/restore, dialog ARIA, and button labels. |

Poll option

| Option | Type | Default | Description | |--------|------|---------|-------------| | pollOption | object | null | When set (e.g. { enabled: true, mode: 'radio', onSelect }), items with pollOptionLabel show a row above the toolbar. | | pollOption.enabled | boolean | — | Must be true to show poll UI. | | pollOption.mode | string | 'radio' | 'radio' or 'checkbox'. | | pollOption.onSelect | function | — | function(item, selected, viewer). selected is the new checked state. | | showAttachmentComment | boolean | false | When true, items with a non-empty item.comments array show a compact dark overlay and a header button to toggle it (LC-Lightbox style). Only item.comments is supported: array of { title?, author?, text }. For one comment use [{ title?, author?, text }]. Multiple comments show in-panel prev/next arrows and a counter. Use itemData or data-comments (JSON). |


Item data

When itemData is not used, each item is built from the matched element:

| Field | Source | |-------|--------| | type | data-type, or 'markdown' when file extension is .md, or 'image' | | src | data-src or href or first img[src] | | title | data-title or title or '' | | downloadUrl | data-download | | fileExt | data-ext | | fileSize | data-size | | thumbnailUrl | data-thumbnail or data-poster | | message | data-message | | html | data-html (for type html) | | content | data-content (for type markdown or inline) | | pollOptionLabel | data-poll-option-label | | pollOptionId | data-poll-option-id | | supplied | data-supplied (jPlayer format override) |

Use itemData to return a custom object per element. The callback receives ($el, defaultItem); you can add or override properties on defaultItem and return it, or return a new object (e.g. from your API).


Content types

The plugin chooses a renderer by item.type (default 'image').

Renderer order

  1. onRender(item, $stage, viewer) — If it appends to $stage, the built-in renderer is skipped. Can return { toolbar: [...], destroy: function() }.
  2. Built-in by type: image, video, audio, pdf, inline, markdown, error, html.
  3. Unsupported — If the stage is still empty, a "no preview" card is shown.

Built-in types

| Type | Description | |------|-------------| | image | Image with zoom slider, wheel/pinch zoom, and drag pan. Invalid or failed load shows an error card without download; toolbar and footer are hidden. | | video | jPlayer (or native <video> if jPlayer not loaded). | | audio | jPlayer (or native <audio>). | | pdf | PDF.js with page nav, thumbnails, zoom, rotate, print. Falls back to iframe if PDF.js not loaded. | | inline | Source/code view with line numbers. Content from item.content or fetched from item.src. | | markdown | Markdown rendered as HTML. Content from item.content or fetched from item.src. Include marked (e.g. from CDN) for full CommonMark support; otherwise a minimal built-in parser is used. Files with .md extension default to this type. | | error | "Cannot preview" card with optional message and Download. | | html | User-provided HTML in the stage. No toolbar, no download. | | Other | Unsupported card with file icon, name, and optional Download. |


Toolbar

| Option | Type | Default | Description | |--------|------|---------|-------------| | toolbar.download | boolean | true | Show the built-in Download button (when applicable). | | toolbar.zoom | boolean | true | Show zoom widget for image items. | | toolbarItems | array | [] | Custom toolbar items (objects, 'separator', or DOM nodes). | | zoom.min | number | 1 | Minimum image zoom. | | zoom.max | number | 5 | Maximum image zoom. | | zoom.step | number | 0.01 | Slider step. | | zoom.wheelStep | number | 0.15 | Zoom change per mouse wheel step. | | zoom.showPercentage | boolean | false | Show zoom percentage (e.g. "150%") in the zoom widget. | | zoom.onZoom | function | null | function(zoomLevel, item, viewer) when zoom changes. |

  • Resolution: For built-in renderers, toolbar = renderer toolbar + toolbarItems + Download (when enabled). Zoom widget is shown for image items when toolbar.zoom is true.
  • onToolbar can modify or replace the toolbar array before it is rendered.
  • onRender can return a toolbar array for full control (no auto download/zoom).

Ways to build the toolbar

| Source | Description | |--------|-------------| | Renderer | Built-in renderers (e.g. PDF) can return a toolbar array (buttons, separators, or DOM nodes). | | toolbarItems | Option array merged after the renderer toolbar (with an optional separator before it). | | onToolbar | Callback receives the merged array and can modify or replace it before rendering. | | onRender | If you return { toolbar: [...] }, that array is used as the full toolbar (no auto download/zoom). | | Download | When toolbar.download is true, a Download button is appended after all items. | | Zoom widget | Shown for image items when toolbar.zoom is true (separate from the toolbar array). |

Toolbar entry types

Each element in a toolbar array can be one of:

| Type | Syntax | Description | |------|--------|-------------| | Object | { id, icon, label, ... } | Rendered as a button. See object properties below. | | Separator | 'separator' or '-' | Rendered as a visual separator between buttons. | | DOM | HTMLElement or jQuery object | Appended as-is (e.g. a span for "Page 1 / 10"). |

Toolbar item object properties

When an entry is an object, the following properties are supported:

| Property | Type | Default | Description | |----------|------|---------|-------------| | id | string | — | Optional. Adds CSS class cv-tb-id to the button. | | icon | string | — | Icon: HTML string (e.g. <svg>...</svg>) or CSS class (e.g. fa fa-share). HTML is sanitized. | | label | string | — | Text label; used as tooltip if tooltip is not set. | | tooltip | string | — | Button title and, when wcag is true, aria-label. Falls back to label or id. | | showLabel | boolean | false | If true, the label is shown as text beside the icon. | | className | string | — | Extra CSS class(es) on the button. | | shortcutKey | string | — | Optional. Single-character keyboard shortcut (e.g. 'e') to trigger this button. Shown in the shortcuts popup (?) when the item is visible. Reserved keys: Escape, Arrow keys, Space, M, R, Q, D, P, ?, +, -, =. | | visible | boolean or function | true | If false or a function that returns false, the button is not rendered. Function: visible(item, viewer). | | onClick | function | — | function(item, viewer) — called when the button is clicked. |

Example:

toolbarItems: [
  { id: 'share', icon: 'fa fa-share', label: 'Share', onClick: function(item) { /* ... */ } },
  'separator',
  { id: 'delete', label: 'Delete', visible: function(item) { return item.canDelete; }, onClick: fn }
]

Keyboard shortcuts

When keyboardNav is true, the following shortcuts are available. Press ? (Shift+/) to open a popup that lists only the shortcuts enabled for the current item (by type and toolbar options).

| Key | Action | |-----|--------| | Escape | Close overlay (or close shortcuts popup if open). | | / | Previous / next item. | | + / - | Zoom in / out (image only, when zoom is enabled). | | Space | Play / Pause (video or audio only when rendered by the plugin; not for custom-rendered or slideshow). | | M | Mute / Unmute (video or audio only when plugin-rendered). | | R | Cycle playback speed (video or audio only when plugin-rendered; cycles 0.5x → 0.75x → 1x → 1.25x → 1.5x → 2x). | | Q | Toggle HD quality (video only when HD source is available). | | D | Download (when the download button is visible). | | P | Print (PDF view only; when the PDF print button is visible). | | F | Toggle fullscreen (when the fullscreen button is visible). | | T | Toggle theme dark/light (when the theme toggle is visible). | | C | Toggle carousel / attachments strip (when carousel is enabled). | | S | Play / Pause slideshow (when slideshow is enabled and the slideshow button is visible). | | ? | Show or hide the keyboard shortcuts popup. |

Custom toolbar shortcuts: Add shortcutKey: 'e' (or any single character) to a toolbar item to give it a keyboard shortcut. That shortcut appears in the popup only when the button is visible. Reserved keys (Escape, arrows, Space, M, R, Q, D, P, F, T, C, S, ?, +, -, =) are not available for custom items.

Set shortcutsPopup: false to disable the ? popup.


Poll options

When pollOption.enabled is true and an item has pollOptionLabel, a row appears above the toolbar with the label and a radio or checkbox.

  • mode: 'radio' (single choice) or 'checkbox' (multiple).
  • onSelect(item, selected, viewer) is called when the user toggles; selected is the new checked state.

Useful for polls where each option is an image or attachment.


Callbacks

| Callback | When | |----------|------| | onLoading(item, viewer) | Before the item is loaded. | | onOpen(item, $stage, viewer) | After the item is shown and toolbar is built. | | onComplete(item, viewer) | Right after content is displayed (after transition if any). | | onCleanup(item, viewer) | At the start of the close process, before teardown. | | onClose(item, viewer) | When the overlay has closed (item was the visible one). | | onThemeChange(theme, viewer) | When the user toggles theme. | | onDownload(item, viewer) | When the Download button is clicked (if provided). | | onRender(item, $stage, viewer) | First chance to render; if you append to $stage, built-in is skipped. | | onToolbar(item, defaultToolbar, viewer) | To modify the toolbar before it is rendered. |


Public API

Call methods via the jQuery plugin or on the stored instance.

Initialization

$(container).componentViewer(options);

Methods

$(container).componentViewer('open', index);   // Open at index (default 0)
$(container).componentViewer('close');
$(container).componentViewer('next');
$(container).componentViewer('prev');
$(container).componentViewer('goTo', index);
$(container).componentViewer('currentItem');   // Returns current item object
$(container).componentViewer('setTheme', 'light' | 'dark');
$(container).componentViewer('refresh');      // Re-collect items, re-bind clicks
$(container).componentViewer('destroy');

Globals

  • Defaults: $.fn.componentViewer.defaults
  • Icons: $.fn.componentViewer.Icons (SVG strings for close, prev, next, zoom, download, etc.)

Accessibility (WCAG)

Set wcag: true to enable:

  • Focus trap — Tab and Shift+Tab cycle only inside the overlay.
  • Focus save/restore — Focus is saved on open and restored on close.
  • Initial focus — Focus moves to the close button when the overlay opens.
  • ARIA — Overlay and shell get appropriate roles and attributes; buttons get aria-label where needed.

When wcag is false, these behaviors are disabled and no dialog ARIA is applied.


Browser support

| Browser | Minimum version | |---------|------------------| | Chrome (desktop) | 87 | | Firefox (desktop) | 85 | | Safari (desktop) | 14.1 | | Edge (Chromium) | 87 | | Safari (iOS) | 14.5 | | Chrome (Android) | 87 | | Internet Explorer | 11 (partial; not recommended) |

Requires jQuery 1.7+. Optional: jPlayer and PDF.js have their own browser requirements.


Examples

Basic gallery

$('#gallery').componentViewer({
  toolbar: { download: true, zoom: true },
  pdf: { workerSrc: 'pdf.worker.min.js' }
});

Loop disabled, no counter

$('#gallery').componentViewer({
  loop: false,
  showCounter: false,
  toolbar: { download: true, zoom: true }
});

Custom item data

$('#gallery').componentViewer({
  itemData: function($el, defaultItem) {
    defaultItem.canDelete = $el.data('can-delete');
    defaultItem.attachmentId = $el.data('id');
    return defaultItem;
  },
  toolbar: { download: true }
});

With WCAG and custom download

$('#gallery').componentViewer({
  wcag: true,
  onDownload: function(item, viewer) {
    // Custom download logic
    window.location = item.downloadUrl || item.src;
  }
});

Programmatic open

var $gallery = $('#gallery').componentViewer({ toolbar: { download: true } });
$gallery.componentViewer('open', 2);  // Open third item

File structure

component-viewer-v2/
├── component-viewer.js    # Plugin script
├── component-viewer.css   # Styles
├── README.md              # This documentation
├── documentation.html     # Full API docs (HTML, JavaDoc-style)
└── example.html           # Full examples (multiple cases)

HTML documentation: Open documentation.html in a browser for a detailed, navigable API reference (options, item data, content types, toolbar, callbacks, public API, browser support, and examples).


  • Toolbar toggle
    The two-page toggle appears in the PDF toolbar only when pdf.twoPageView: true. The button shows the “other” mode as tooltip (e.g. “Single-page view” when in two-page mode). It gets the cv-active class when two-page view is on. Toggling re-applies auto-fit and re-renders all pages.

  • Two-page rendering
    In two-page mode, pages are rendered in pairs (1–2, 3–4, …); the last page appears alone if the total is odd. A fixed gap between the two pages is used; auto-fit scale is computed so both pages fit in the stage width. New CSS class .cv-pdf-spread lays out the two pages side by side.

  • I18N and icon
    New default strings: twoPageView, singlePageView. New icon Icons.twoPageView (two side-by-side rectangles) used for the toggle button.

  • Example
    Case 8a in example.html demonstrates the two-page view: pdf: { twoPageView: true } with one PDF attachment. Open the PDF to see the toggle and switch between single- and two-page view.

  • Documentation
    README, documentation.html, and the Case 8a description in example.html updated to describe the option, default (single-page), and toggle behavior.


License

MIT. See the plugin header in component-viewer.js for details.