Shoji API Reference
    Preparing search index...

    Interface GalleryEvents

    See DESIGN.md §2.2 — grows as core lifecycle stages and plugins land.

    interface GalleryEvents {
        beforeOpen: { index: number };
        open: { index: number };
        afterOpen: { index: number };
        beforeClose: Record<string, never>;
        close: Record<string, never>;
        afterClose: Record<string, never>;
        destroy: Record<string, never>;
        itemsUpdated: { items: GalleryItem[] };
        beforeSlide: { from: number; to: number };
        afterSlide: { from: number; to: number };
        slideItemLoad: { index: number };
        "controls:hide": Record<string, never>;
        "controls:show": Record<string, never>;
        dragCloseThreshold: { hidden: boolean };
        captionModalChange: { open: boolean };
        autoplayStart: Record<string, never>;
        autoplayStop: Record<string, never>;
        tap: { x: number; y: number; controlsWereHidden: boolean };
        doubleTap: { x: number; y: number };
        pinchStart: { centerX: number; centerY: number };
        pinchMove: { scale: number; centerX: number; centerY: number };
        pinchEnd: Record<string, never>;
        wheelZoom: { deltaScale: number; x: number; y: number };
        fullscreenChange: { fullscreen: boolean };
        rotateFlipChange: {
            index: number;
            flipH: boolean;
            flipV: boolean;
            rotation: number;
        };
        zoomChange: { index: number; scale: number };
        layoutRender: { tiles: { index: number; element: HTMLElement }[] };
        [key: string]: unknown;
    }

    Hierarchy

    • Record<string, unknown>
      • GalleryEvents

    Indexable

    • [key: string]: unknown
    Index
    beforeOpen: { index: number }
    open: { index: number }
    afterOpen: { index: number }
    beforeClose: Record<string, never>
    close: Record<string, never>
    afterClose: Record<string, never>
    destroy: Record<string, never>
    itemsUpdated: { items: GalleryItem[] }

    DESIGN.md §2.1 — fires after the item list changes via updateSlides()/refresh().

    beforeSlide: { from: number; to: number }

    DESIGN.md §2.2 lists these as cancelable; that isn't implemented yet (no plugin needs it yet) — detail is plain {from, to} for now, same as the other lifecycle events, not the event.preventDefault() shape §2.2 describes.

    afterSlide: { from: number; to: number }
    slideItemLoad: { index: number }

    DESIGN.md §2.3 — fires once a slide's media has decoded/settled.

    "controls:hide": Record<string, never>

    DESIGN.md §2.8 — toolbar auto-hide sync points for plugins with their own overlays.

    "controls:show": Record<string, never>
    dragCloseThreshold: { hidden: boolean }

    DESIGN.md §2.4/§2.6a — a vertical drag crossing (true) or un-crossing (false) the same distance a release would close at. Autoplay (§4-autoplay) uses it to pause/resume in step with the drag itself.

    captionModalChange: { open: boolean }

    DESIGN.md §2.3a — fires from openCaptionModal()/closeCaptionModal(), the truncated-caption "read the rest" overlay. Autoplay's onCaptionExpand (§4-autoplay) uses open: true to pause — expanding a caption to read it is a viewer asking for time, not an idle moment to advance past.

    autoplayStart: Record<string, never>

    DESIGN.md §2.2a-autoplay — emitted by the autoplay plugin, not core.

    autoplayStop: Record<string, never>
    tap: { x: number; y: number; controlsWereHidden: boolean }

    controlsWereHidden is a snapshot from before this same gesture's own pointerdown-triggered reveal (Gallery.ts's onActivity) ran — a live read of gallery.controlsHidden at tap time would always say "visible" regardless, since that reveal already happened by then. Lets a consumer tell "this tap was just revealing hidden controls" apart from "this tap landed on an already-visible gallery," rather than treating every tap the same regardless of what it just did.

    doubleTap: { x: number; y: number }
    pinchStart: { centerX: number; centerY: number }
    pinchMove: { scale: number; centerX: number; centerY: number }

    scale is relative to this pinch gesture's own start distance (1 = unchanged), not cumulative across separate pinches.

    pinchEnd: Record<string, never>
    wheelZoom: { deltaScale: number; x: number; y: number }

    deltaScale is a small per-event increment (positive = zoom in); a consumer accumulates it, it isn't an absolute scale.

    fullscreenChange: { fullscreen: boolean }

    DESIGN.md §4-fullscreen — emitted by the fullscreen plugin, not core; fires from the native fullscreenchange event, not the toolbar button's own click, so it reflects reality even when fullscreen was entered/exited by other means (browser Escape handling, a request rejected).

    rotateFlipChange: {
        index: number;
        flipH: boolean;
        flipV: boolean;
        rotation: number;
    }

    DESIGN.md §4-rotate/flip — emitted by the rotateFlip plugin, not core, on every rotate/flip click; the plugin itself never persists this (resets per slide) — a host wanting to keep it stores this event's payload themselves.

    zoomChange: { index: number; scale: number }

    DESIGN.md §4-zoom — emitted by the zoom plugin, not core, on every scale change (gesture or button-driven); resets per slide, not persisted by the plugin itself, same pattern as rotateFlipChange.

    layoutRender: { tiles: { index: number; element: HTMLElement }[] }

    DESIGN.md §5 — emitted by the layout plugin, not core, once a render pass has built and appended tile DOM: after fullRender() (every tile currently in the container — a full rebuild, e.g. from a non-append items change), or after appendRender() (just the newly-created tiles — existing ones are untouched, per the plugin's own incremental-append behavior). tiles is exactly the elements built this pass, in item order — a host injecting custom content into tiles (a badge, a selection checkbox, anything not itself part of the layout plugin) uses element directly and index to look the item back up via gallery.items[index]; element.dataset.shojiIndex (also set on every tile, matching index here) is the same lookup from the DOM side, for code that only has the element itself later (e.g. a click handler on injected content) and needs the index back without having kept this event's payload around.