@sankaran-8600/component-viewer
v1.0.7
Published
jQuery plugin for attachment and media preview in an overlay
Maintainers
Readme
ComponentViewer
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
- Installation
- Quick start
- Options reference
- Item data
- Content types
- Toolbar
- Keyboard shortcuts
- Poll options
- Callbacks
- Public API
- Accessibility (WCAG)
- Browser support
- Examples
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
- Mark up your items with a common selector (default:
.cv-item) and usedata-*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>- Initialize the viewer on the container:
$('#my-gallery').componentViewer({
toolbar: { download: true, zoom: true },
pdf: { workerSrc: 'path/to/pdf.worker.min.js' }
});- 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. |
| 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
- onRender(item, $stage, viewer) — If it appends to
$stage, the built-in renderer is skipped. Can return{ toolbar: [...], destroy: function() }. - Built-in by type: image, video, audio, pdf, inline, markdown, error, html.
- 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 whentoolbar.zoomis true. - onToolbar can modify or replace the toolbar array before it is rendered.
- onRender can return a
toolbararray 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;
selectedis 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-labelwhere 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 itemFile 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 whenpdf.twoPageView: true. The button shows the “other” mode as tooltip (e.g. “Single-page view” when in two-page mode). It gets thecv-activeclass 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-spreadlays out the two pages side by side.I18N and icon
New default strings:twoPageView,singlePageView. New iconIcons.twoPageView(two side-by-side rectangles) used for the toggle button.Example
Case 8a inexample.htmldemonstrates 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 inexample.htmlupdated to describe the option, default (single-page), and toggle behavior.
License
MIT. See the plugin header in component-viewer.js for details.
