Skip to content

v0.1.0

Choose a tag to compare

@github-actions github-actions released this 09 Apr 17:58
· 20 commits to main since this release

First tagged release. pencere is a modern, accessible, framework-agnostic
lightbox — pure TypeScript, zero runtime dependencies, ESM, tree-shakeable.

Live demo: pencere.productdevbook.com

npm install pencere

Highlights

  • Core engine — typed event emitter, Pencere<T> state machine, next/prev/goTo/open/close, optional looping.
  • Renderers — first-class image, <video>, sandboxed <iframe>, and a user-extensible Renderer registry (#8) for custom item types.
  • View Transitions API morph (#12) — pass the clicked thumbnail as the trigger and the UA animates thumb → lightbox natively. Symmetric fade on close.
  • Hash-based deep linking (#75)/page#p3 opens slide 3 on reload; browser Back + Safari / Firefox edge-swipe dismiss via popstate.
  • Fullscreen API (#14) — real requestFullscreen where supported, CSS faux-fullscreen fallback on iOS Safari.
  • Declarative DOM scanner (#7)bindPencere("[data-pencere]") wires <a data-pencere> anchors into a grouped gallery with zero JS glue.
  • Lifecycle hooks (Phase 2)willOpen, didOpen, willClose, didClose, willRender, didRender, didNavigate. will* is awaited and may abort the transition.
  • Plugin architecture (#4) — narrow PencereContext { core, events, dom, registerHook, registerRenderer }. Includes a reference slideshowPlugin({ intervalMs, autoStart, pauseOnHover }).
  • Controlled mode (#6)new Pencere({ controlled: true }) emits requestOpen / requestChange / requestClose; consumer commits state via commitOpen / commitChange / commitClose. Drop-in for React / Vue router sync.
  • ImageLoader DI (#9)interface ImageLoader { load(item, signal, options) } lets you inject CDN signing, blur-up previews, service-worker caching, or a custom AVIF fallback.

Gestures & keyboard

  • Pinch, wheel, double-tap zoom (1×–8×), pan once zoomed.
  • Swipe left/right to navigate at fit scale; swipe down to dismiss with backdrop fade.
  • Full keyboard map (Arrow, Home/End, +/-/0, Esc) with IME-safe composition guard.
  • WCAG 2.5.7 arrow-key pan alternative while zoomed (#25).
  • Opt-in haptic feedback on coarse pointers.

Accessibility (WCAG 2.2 AA)

  • APG Dialog + Carousel patterns, focus trap with shadow-DOM-aware tabbable detection.
  • 44×44 min targets, prefers-reduced-motion honored, forced-colors mapping, live-region announcements.
  • ImageItem.longDescription wired to aria-describedby (#26), per-slide lang font stacks (#65).

Security

  • URL protocol allowlist — rejects javascript:, vbscript:, file:, data:text/html, data:image/svg+xml (script-bearing SVG). Raster-only data: images pass.
  • textContent for captions by default; opt into HTML via the Trusted Types helper.
  • iframe renderer sets sandbox before src, strict referrer policy everywhere.
  • npm releases published with OIDC --provenance from GitHub Actions. Verify with npm audit signatures pencere.
  • OSSF Scorecard workflow, Dependabot, SHA-pinned actions.

Adapters

Sub-path exports: pencere/react, pencere/vue, pencere/svelte, pencere/solid, pencere/element. All SSR-safe: no document / window access at import time.

Refactor + bug hunt

Architecture Phase 1 — viewer.ts decomposed from a 1003-LOC god file into five focused controllers: routing-controller, fullscreen-controller, view-transition-controller, motion-controller, render-pipeline. Three rounds of parallel bug hunts (concurrency, security, async races, real-browser smoke test) landed 29 fixes before this tag.

Links