OptionalselectorOptionalitemsDynamic-mode item list; mutate live via gallery.updateSlides().
OptionalindexIndex to open on — used both as open()'s default argument and, with openOnInit, as the index opened automatically at construction.
OptionalopenOpens the lightbox immediately at construction (to index, default 0),
instead of the normal default of staying closed until the host calls
open() or a scanned/layout-rendered thumbnail is clicked. Default
false. Useful for hash/deep-link-style integrations that should land
straight in the lightbox; everyone else should leave this off — a
gallery that pops open on page load without a click is rarely what's
wanted.
OptionallocaleFlat locale key map — see CLAUDE.md: no hardcoded English in UI.
OptionalpluginsRegistered plugins; each plugin's own options nest under options[plugin.name].
OptionalautoDESIGN.md §2.8 — ms of inactivity before all buttons/overlays (toolbar,
prev/next, counter, caption) auto-hide; default 5000. 0 does not turn
auto-hide off — it does the opposite: controls are hidden immediately
on open and stay hidden permanently, regardless of activity. false is
the actual "always visible" value: the idle timer never arms at all, so
controls just stay shown, same as if activity kept resetting it forever
(other explicit hides — hideControls(), drag-to-close's own live cue —
are unrelated to this option and still work regardless).
OptionalmaxDESIGN.md §3.1a — the most ctx.ui.toolbar('right', ...)-registered
plugin buttons (in registration order) that stay pinned directly on
the toolbar row once it overflows; default 2. A ceiling, not a
guarantee — if pinning even this many would still wrap the row (e.g.
a wide counter or other left-slot content leaves less room than
usual), more collapse into the popover until it fits, down to zero if
it must; the counter and closeButton are never allowed to wrap.
The rest collapse into the overflow popover, latest-registered first.
closeButton and the overflow caret itself are never counted against
this — they're always on the row regardless.
OptionalpreloadDESIGN.md §2.3 — how many slides on each side of the active one are
kept mounted and proactively decoded ahead of time; default 1.
Navigating to any index within that window shows instantly, no loading
spinner — its content was already decoded and cached (by item index,
surviving the pool's internal slot reshuffling) before you got there.
Navigating further than preload away (a fast flick through several
slides, or a direct goTo()/deep link) still shows the spinner while
that one decodes, same as ever — this only changes what counts as
"already ready."
OptionalcounterShows the "N / M" counter badge; default true. Purely visual — the live-region announcement (§2.6) always includes position regardless.
OptionalshowDESIGN.md §2.3a — starts a video slide's caption shown instead of hidden; default false. No effect on a photo's caption.
OptionalloopDESIGN.md §2.2 — next()/prev() (and the arrow-key/toolbar-button paths
that call them) wrap past the last/first item instead of stopping; default
true. Does not affect goTo(index) with an explicit out-of-range index
(still clamps — a directed jump, not a step) or Home/End (still an
absolute jump to the first/last item).
OptionalclosableDefault true. false disables every viewer-facing way to close the
lightbox: the close button (hidden entirely, not just inert), clicking
the backdrop, Escape, and vertical swipe-to-close (no live drag
feedback either, not just a release that fails to close). For
non-closable embeds — a gallery meant to stay open permanently once
shown. gallery.close() itself is unaffected — this only gates the
four built-in viewer-triggered paths, host code can still close it
programmatically at any time.
OptionalbackdropThe backdrop's real, honest opacity — 0 fully transparent, 1 fully
opaque (solid --shoji-color-backdrop, shoji.css, itself a fully
opaque hue by default), without needing to know or override the full
color value. Clamped to [0, 1]. Unset (the default) leaves the CSS
custom property --shoji-backdrop-opacity (default 0.92 dark /
0.96 light, matching this theme's pre-existing look) untouched, so a
host already themeing it directly in CSS is unaffected either way.
OptionalgesturesDESIGN.md §2.4 — overrides the gesture engine's lockThreshold/
swipeThreshold/swipeVelocity (defaults: 10px, 50px, 0.3px/ms).
Partial: any field left out keeps its default. Momentum easing is not
configurable here — it's the CSS custom property
--shoji-momentum-easing, per CLAUDE.md's "no hardcoded sizes/timings
in JS, everything through --shoji-* custom properties."
OptionalmodeDESIGN.md §2.5 — the slide-to-slide transition for programmatic
navigation (buttons, keyboard, autoplay, goTo()); never affects a
gesture-driven swipe, which always uses its own live-drag/settle
animation regardless of mode (§2.4). Default 'slide'. One of the
built-in preset names (slide, fade, zoom, deck, slideVertical,
push, fadeUp, fadeDown, fadeLeft, fadeRight, zoomOut,
scaleUp, scaleDown, rotate, rotateLeft, rotateRight, flipX,
flipY, cube, coverflow, drop) — or any other string, treated as
a custom CSS class pair (shoji-transition-<mode>-enter/-leave) the
host supplies its own transition/@keyframes animation for; no JS
needed on the host's end.
OptionaltransitionDESIGN.md §2.5 — milliseconds for mode's transition, plus open/close
zoom and Layout's own FLIP reflow (they all key off the same
--shoji-duration). Default 300, matching --shoji-duration's own
CSS default — this option doesn't move timing into JS, it's a
convenience that sets that same CSS custom property for you, the same
way backdropOpacity sets --shoji-backdrop-opacity. Unset leaves
--shoji-duration (and prefers-reduced-motion's own 0ms override
of it) untouched, so a host already theming it directly in CSS is
unaffected either way. Clamped to a minimum of 0.
DOM selector for gallery items when not using dynamic mode.