For AI agents: the complete documentation index is available at /2.x/llms.txt, the full documentation bundle is available at /2.x/llms-full.txt, and this page is available as Markdown at /2.x/guide/usage/gesture-viewer-props.md.
v3 is stable. See what changed
  • English
  • 2.x
  • GestureViewer Props

    renderItem

    renderItem renders each item in data and receives isActive and setItemDimensions through its third argument: renderItem(item, index, { isActive, setItemDimensions }).

    Use isActive for work that should run only on the active item, such as video playback. See renderItem active state (isActive) for behavior and examples.

    Call setItemDimensions({ width, height }) after rendered content dimensions become available. See the item dimensions guide for examples and call timing.

    enableLoop (default: false)

    Enables loop mode. When true, navigating next from the last item goes to the first item, and navigating previous from the first item goes to the last item.

    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      return (
        <GestureViewer
          enableLoop={true} 
        />
      );
    }

    enableSnapMode (default: false)

    Enables snap scrolling mode.

    • false (default): Paging mode (pagingEnabled: true)

      • Scrolls by full screen size increments
    • true: Snap mode (snapToInterval auto-calculated)

      • snapToInterval is automatically calculated based on width and itemSpacing values
      • Use this option when you need item spacing
    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      return (
        <GestureViewer
          data={data}
          renderItem={renderItem}
          enableSnapMode={true} 
        />
      );
    }

    itemSpacing (default: 0)

    Sets the spacing between items in pixels. Only applied when enableSnapMode is true.

    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      return (
        <GestureViewer
          data={data}
          renderItem={renderItem}
          enableSnapMode={true}
          itemSpacing={16} // 16px spacing between items
        />
      );
    }

    autoPlay (default: false)

    Enables auto play mode. When true, the viewer will automatically play the next item after the specified interval.

    • When enableLoop is enabled, the viewer will loop back to the first item after the last item.
    • When enableLoop is disabled, the viewer will stop at the last item.
    • When there is only one item, auto-play is disabled.
    • When zoom or rotate gestures are detected, the auto-play will be paused.
    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      return (
        <GestureViewer
          autoPlay={true}
        />
      );
    }

    autoPlayInterval (default: 3000)

    Sets the interval between auto play in milliseconds.
    Must be a positive integer. Values below 250ms are clamped to 250ms at runtime.

    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      return (
        <GestureViewer
          autoPlay={true}
          autoPlayInterval={3000}
        />
      );
    }

    onSingleTap

    Runs when the viewer confirms a single tap. This is useful for toggling viewer chrome such as headers, footers, captions, and action buttons without overlaying another pressable on top of the viewer.

    • May resolve slightly later when double-tap zoom is enabled because the viewer waits to confirm it is not a double tap
    • Does not fire for swipe, pinch, dismiss, or double-tap zoom gestures
    import { GestureViewer } from 'react-native-gesture-image-viewer';
    
    function App() {
      const [showControls, setShowControls] = useState(true);
    
      return (
        <GestureViewer
          data={images}
          renderItem={renderImage}
          onSingleTap={() => setShowControls((prev) => !prev)} 
        />
      );
    }

    getItemDimensions

    Returns natural/source dimensions for an item when they are already known. Runtime dimensions reported from renderItem with setItemDimensions take precedence. See the item dimensions guide for examples.

    getItemKey

    Returns a stable logical key for an item when the same content may be recreated as a new object in the same slot. Use it with runtime setItemDimensions values. See the item dimensions guide for details.

    initialIndex (default: 0)

    Sets the item index the viewer should display. The value is normalized against the current data length: non-finite and negative values become 0, values above the available range become the last index, and empty data resolves to 0.

    When initialIndex changes after the viewer is already mounted, the viewer repositions to the normalized index.

    maxZoomScale (default: 2)

    Controls the maximum zoom scale multiplier.

    GestureViewerProps interface

    Go to source

    GestureViewerProps
    export type GestureViewerItemDimensions = Readonly<{
      /** Natural/source content width. Must be finite and greater than zero. */
      width: number;
      /** Natural/source content height. Must be finite and greater than zero. */
      height: number;
    }>;
    
    export type GestureViewerItemDimensionsResolver<ItemT> = (
      item: ItemT,
      index: number,
    ) => GestureViewerItemDimensions | undefined;
    
    export type GestureViewerItemKey = string | number;
    
    export type GestureViewerItemKeyResolver<ItemT> = (
      item: ItemT,
      index: number,
    ) => GestureViewerItemKey;
    
    export type GestureViewerRenderItemInfo = {
      /**
       * Whether the rendered item is currently active.
       * @remarks The current item remains active during a page transition. When the transition finishes on another item, that item becomes active.
       */
      readonly isActive: boolean;
      /**
       * Registers natural/source dimensions for the rendered item after they become available.
       * @remarks Call this from an image load or event callback, or from a passive `useEffect` after commit. Do not call it during render or from a descendant layout effect.
       */
      readonly setItemDimensions: (dimensions: GestureViewerItemDimensions) => void;
    };
    
    export interface GestureViewerProps<ItemT, LC> {
      /**
       * When you want to efficiently manage multiple `GestureViewer` instances, you can use the `id` prop to use multiple `GestureViewer` components.
       * @remarks `GestureViewer` automatically removes instances from memory when components are unmounted, so no manual memory management is required.
       * @defaultValue 'default'
       */
      id?: string;
      /**
       * The data to display in the `GestureViewer`.
       */
      data: ItemT[];
      /**
       * The index of the item to display in the `GestureViewer`.
       * @remarks
       * - Normalized against the current data length: non-finite and negative values become 0, values above range become the last index, and empty data resolves to 0.
       * - Prop changes reposition an already-mounted viewer to the normalized index.
       * @defaultValue 0
       */
      initialIndex?: number;
      /**
       * A callback function that is called when the `GestureViewer` is dismissed.
       */
      onDismiss?: () => void;
      /**
       * A callback function that is called when the dismiss interaction starts.
       * @remarks Useful to hide external UI (e.g., headers, buttons) while the dismiss gesture/animation is in progress.
       */
      onDismissStart?: () => void;
      /**
       * A callback function that is called to render the item.
       * @param item - The item to render.
       * @param index - The list index of the rendered item.
       * @param info - Render state for this list cell.
       */
      renderItem: (item: ItemT, index: number, info: GestureViewerRenderItemInfo) => React.ReactElement;
      /**
       * A callback function that is called when a single tap is confirmed on the viewer content.
       * @remarks
       * - The callback runs only after the tap is resolved as a single tap, so it may be slightly delayed when double-tap zoom is enabled.
       * - It is not called for swipe, pinch, dismiss, or double-tap zoom gestures.
       * - Prefer this callback over overlaying a pressable in `renderContainer` for fullscreen tap handling.
       */
      onSingleTap?: (event: GestureViewerSingleTapEvent<ItemT>) => void;
      /**
       * Returns natural/source dimensions for an item when they are already known.
       * @remarks Return `undefined` while dimensions are unavailable. Invalid dimensions fall back to the viewer cell size.
       */
      getItemDimensions?: GestureViewerItemDimensionsResolver<ItemT>;
      /**
       * Returns a stable logical key when the same item can be recreated as a new object in the same slot.
       * @remarks Use this when object identity is not stable across rerenders. The key must identify the same rendered content and change when the rendered source or natural dimensions change. Do not return the array index alone. If the item changes position, the viewer falls back to `getItemDimensions` or the viewer cell size until the new slot reports dimensions again.
       */
      getItemKey?: GestureViewerItemKeyResolver<ItemT>;
      /**
       * A callback function that is called to render the container.
       * @remarks Useful for composing additional UI (e.g., close button, toolbars) around the viewer.
       * Prefer `onSingleTap` for fullscreen tap handling instead of overlaying a pressable over the viewer content.
       * The second argument provides control helpers such as `dismiss()` to close the viewer.
       *
       * @param children - The viewer content to be rendered inside your container.
       * @param helpers - Control helpers for the viewer. Currently includes `dismiss()`.
       * @returns A React element that wraps and renders the provided `children`.
       */
      renderContainer?: (
        children: React.ReactElement,
        helpers: { dismiss: () => void },
      ) => React.ReactElement;
      /**
       * Support for any list component like `ScrollView`, `FlatList`, `FlashList` through the `ListComponent` prop.
       */
      ListComponent: LC;
      /**
       * The width of the `GestureViewer`.
       * @remarks If you don't set this prop, the width of the `GestureViewer` will be the same as the width of the screen.
       * @defaultValue screen width
       */
      width?: number;
      /**
       * The height of the `GestureViewer`.
       * @remarks If you don't set this prop, the height of the `GestureViewer` will be the same as the height of the screen.
       * @defaultValue screen height
       */
      height?: number;
      /**
       * The props to pass to the list component.
       * @remarks The `listProps` provides **type inference based on the selected list component**, ensuring accurate autocompletion and type safety in your IDE.
       */
      listProps?: Partial<ConditionalListProps<ItemT, LC>>;
      /**
       * The style of the backdrop.
       */
      backdropStyle?: StyleProp<ViewStyle>;
      /**
       * The style of the container.
       */
      containerStyle?: StyleProp<ViewStyle>;
      /**
       * Auto play mode.
       * @remarks
       * - When `true`, the viewer will automatically play the next item after the specified interval.
       * - When `enableLoop` is enabled, the viewer will loop back to the first item after the last item.
       * - When `enableLoop` is disabled, the viewer will stop at the last item.
       * - When there is only one item, auto-play is disabled.
       * - When zoom or rotate gestures are detected, the auto-play will be paused.
       * @defaultValue false
       */
      autoPlay?: boolean;
      /**
       * Auto play interval.
       * @remarks
       * - When `autoPlay` is enabled, the viewer advances to the next item after the specified interval (ms).
       * - Must be a positive integer. Values below 250ms are clamped to 250ms at runtime.
       * @defaultValue 3000
       */
      autoPlayInterval?: number;
      /**
       * Dismiss gesture options.
       * @remarks Useful for closing modals with configurable vertical swipe gestures.
       */
      dismiss?: {
        /**
         * When `false`, dismiss gesture is disabled.
         * @defaultValue true
         */
        enabled?: boolean;
        /**
         * Controls which vertical swipe direction can trigger `onDismiss`.
         * @remarks Use `down` for backward-compatible behavior, `up` for upward-only dismiss, or `both` for either direction.
         * @defaultValue 'down'
         */
        direction?: GestureViewerDismissDirection;
        /**
         * `threshold` controls when `onDismiss` is called by applying a threshold value during vertical gestures.
         * @defaultValue 80
         */
        threshold?: number;
        /**
         * `resistance` controls the range of vertical movement by applying resistance during dismiss gestures.
         * @defaultValue 2
         */
        resistance?: number;
        /**
         * By default, the background `opacity` gradually decreases as you drag in the configured dismiss direction.
         * @remarks When `false`, this animation is disabled.
         * @defaultValue true
         */
        fadeBackdrop?: boolean;
      };
      /**
       * Controls left/right swipe gestures.
       * @remarks When `false`, horizontal gestures are disabled.
       * @defaultValue true
       */
      enableHorizontalSwipe?: boolean;
      /**
       * Only works when zoom is active, allows moving item position when zoomed.
       * @remarks When `false`, gesture movement is disabled during zoom.
       * @defaultValue true
       */
      enablePanWhenZoomed?: boolean;
      /**
       * Controls two-finger pinch gestures.
       * @remarks When `false`, two-finger zoom gestures are disabled.
       * @defaultValue true
       */
      enablePinchZoom?: boolean;
      /**
       * Controls double-tap zoom gestures.
       * @remarks When `false`, double-tap zoom gestures are disabled.
       * @defaultValue true
       */
      enableDoubleTapZoom?: boolean;
      /**
       * Enables infinite loop navigation.
       * @defaultValue false
       */
      enableLoop?: boolean;
      /**
       * Enables snap scrolling mode.
       *
       * @remarks
       * **`false` (default)**: Paging mode (`pagingEnabled: true`)
       * - Scrolls by full screen size increments
       *
       * **`true`**: Snap mode (`snapToInterval` auto-calculated)
       * - `snapToInterval` is automatically calculated based on `width` and `itemSpacing` values
       * - Use this option when you need item spacing
       * @defaultValue false
       *
       */
      enableSnapMode?: boolean;
      /**
       * The spacing between items in pixels.
       * @remarks Only applied when `enableSnapMode` is `true`.
       * @defaultValue 0
       */
      itemSpacing?: number;
      /**
       * The maximum zoom scale.
       * @defaultValue 2
       */
      maxZoomScale?: number;
      /**
       * Trigger-based animation settings
       * @remarks You can customize animation duration, easing, and system reduce-motion behavior.
       *
       * @example
       * ```tsx
       * <GestureViewer
       *   triggerAnimation={{
       *     duration: 250,
       *     easing: Easing.out(Easing.cubic),
       *     reduceMotion: 'system',
       *     onAnimationComplete: () => {
       *       console.log('Animation complete');
       *     },
       *   }}
       * />
       * ```
       */
      triggerAnimation?: TriggerAnimationConfig;
    }