Important!
The library uses Reanimated 2 alpha. It means that it may be unstable. Also, the library itself is in the alpha testing stage and may contain bugs.
Use npm or yarn to install the library
npm i --save react-native-gallery-toolkitAlso, you need to install [email protected] (the new 2 version) and react-native-gesture-handler, and follow their installation instructions.
Expo is supported since SDK 40.
npm install [email protected]More information is available https://docs.expo.io/versions/latest/sdk/reanimated/
Standalone gallery renders Pager which supports thousands of images thanks to virtualization. Each page renders ImageTransformer component which gives ability to pinch-to-zoom, double tap to zoom, also you can run custom callbacks and worklets on on tab, double tap, pan.
import {
  StandaloneGallery,
  GalleryItemType,
  StandaloneGalleryHandler,
} from 'react-native-gallery-toolkit';
const images: GalleryItemType[] = [
  {
    id: '1',
    width: 300,
    height: 300,
    uri: 'https://placekitten.com/300/300',
  },
  {
    id: '2',
    width: 400,
    height: 200,
    uri: 'https://placekitten.com/400/200',
  },
];
export default function App() {
  return <StandaloneGallery items={images} />;
}See Full featured example for example of usage of all the props.
- Only portrait orientation currently supported
 - There is no way to change dimensions without full re-render of the gallery
 - Debugging is not supported because of Reanimated v2 uses TurboModules. Use flipper to debug your JS Context.
 - On Android tap on hold on the screen while page changes doesn't trigger animation to stop due to bug in Gesture Handler.
 
| Prop | Description | Type | Default | 
|---|---|---|---|
items | 
The array of items to render. But can also accept Map, Set, or Object with keys. If the type is not array, then getTotalCount and getItem should be defined too. | 
Array<{ width: number, height: number, id: string, uri: string  }> | 
undefined | 
width? | 
Viewport width | number | 
Dimensions.get('window').width | 
height? | 
Viewport height | number | 
Dimensions.get('window').height | 
numToRender? | 
How many pages should be rendered at the same time | number | 
2 | 
gutterWidth? | 
The width of the gutter between pages | number | 
0 | 
initialIndex? | 
The initial page index | number | 
0 | 
keyExtractor? | 
Callback which extract the key of the page. Receives current item of the provided items as well as current index | 
(item: T, index: number) => string | 
Uses index as a key by default | 
| Prop | Description | Type | Default | 
|---|---|---|---|
getTotalCount? | 
If the type of items is not an array, then this method should be defined to provide the total count of items | 
(data: T) => number | 
Required when items is not an array | 
getItem? | 
If the type of items is not an array, then this method should be defined to provide the current item based on the index. Can return either the item or undefined. | 
(data: T, index: number) => ItemT or undefined | 
Required when items is not an array | 
renderImage? | 
Callback that can be used to render custom image component. As an example, it can be used to render custom loading/error states | (props: RenderImageProps, item: ItemT, index: number) => JSX.Element | 
() => Image | 
renderPage? | 
Callback that can be used to render custom page. Can be used to display some non-image pages such as Video, for instance | (props: ImageRendererProps<T>, index: number) => JSX.Element | 
ImageTransformer | 
| Prop | Description | Type | Is worklet? | Default | 
|---|---|---|---|---|
onIndexChange? | 
Fires when active index changes | (nextIndex: number) => void | 
Function or Worklet | 
undefined | 
onTap? | 
Executes when tap image transformer receives tap | () => void | 
Function or Worklet | 
undefined | 
onDoubleTap? | 
Executes when tap image transformer receives double-tap | () => void | 
Function or Worklet | 
undefined | 
onInteraction? | 
Is called when either pan or scale has happened. | (type: 'scale' or 'pan') => void | 
Function or Worklet | 
undefined | 
onPagerTranslateChange? | 
Executes on pager's horizontal pan | (translateX: number) => void | 
Function or Worklet | 
undefined | 
onGesture? | 
Executes on pager's gesture | (event: PanGestureHandlerGestureEvent, isActive: SharedValue<boolean>) => void | 
Function or Worklet | 
undefined | 
shouldPagerHandleGestureEvent? | 
Worklet that will be passed to pager's shouldHandleEvent to determine should pager handle this event. Can be used to handle "swipe down to close". | 
(event: PanGestureHandlerGestureEvent) => boolean | 
Only Worklet | 
undefined | 
| Name | Description | Type | 
|---|---|---|
goNext | 
Changes the active index forward | () => void | 
goBack | 
Changes the active index backward | () => void | 
setIndex | 
Sets the active index | (nextIndex: number) => void | 
TODO
TODO
TODO
The source code for the example (showcase) app is under the Example/ directory.
Clone the repo, go to the Example/ folder and run:
npm installBefore running the app, install the cocoapods dependencies:
npx pod-installNow, you can start the app:
npm run iosnpm run android- Add invariants to all the required props
 - Finish documentation
 - Lightbox with examples
 - Lightbox Gallery with examples
 - Try to use react-native-shared-element
 

