react-native-gallery-toolkit
React Native Gallery Toolkit
Reanimated 2 and Gesturer Handler powered Gallery implementation
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.
Installation
Use npm or yarn to install the library
npm i --save react-native-gallery-toolkit
Also, you need to install react-native-reanimated@2.0.0-alpha.7 (the new 2 version) and react-native-gesture-handler, and follow their installation instructions.
Expo is supported since SDK 40.
npm install react-native-reanimated@2.0.0-rc.0
More information is available https://docs.expo.io/versions/latest/sdk/reanimated/
Standalone gallery
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.
Limitations
- 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.
Base props
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
initialIndex?
The initial page index
number
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
Advance props
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
Handlers
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
Methods
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
Pager
TODO
Transformer
TODO
Scalable Image
TODO
Examples
The source code for the example (showcase) app is under the Example/
directory.
Clone the repo, go to the Example/ folder and run:
npm install
Running on iOS
Before running the app, install the cocoapods dependencies:
npx pod-install
Now, you can start the app:
npm run ios
Running on Android
npm run android
TODOs
- Add invariants to all the required props
- Finish documentation
- Lightbox with examples
- Lightbox Gallery with examples
- Try to use react-native-shared-element
LICENSE
MIT