react-native-gesture-image-viewer 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -5
- package/lib/module/GestureImageViewer.js +10 -9
- package/lib/module/GestureImageViewer.js.map +1 -1
- package/lib/module/utils.js +6 -3
- package/lib/module/utils.js.map +1 -1
- package/lib/typescript/src/GestureImageViewer.d.ts +2 -1
- package/lib/typescript/src/GestureImageViewer.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +11 -13
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils.d.ts +4 -3
- package/lib/typescript/src/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/GestureImageViewer.tsx +15 -13
- package/src/types.ts +19 -14
- package/src/utils.ts +11 -6
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Existing libraries often have limited customization options or performance issue
|
|
|
16
16
|
- ✅ **External Control API** - Programmatic control from buttons or other components
|
|
17
17
|
- ✅ **Multi-Instance Management** - ID-based independent management of multiple viewers
|
|
18
18
|
- ✅ **Flexible Integration** - Use with FlatList, FlashList, Expo Image, FastImage, and more
|
|
19
|
-
- ✅ **Full TypeScript Support** -
|
|
19
|
+
- ✅ **Full TypeScript Support** - Enhanced developer experience with smart type inference
|
|
20
20
|
- ✅ **Cross-Platform** - iOS, Android, and Web support
|
|
21
21
|
- ✅ **Easy-to-Use API** - Intuitive and simple implementation without complex setup
|
|
22
22
|
- ✅ **Various Environment Support** - Expo Go and New Architecture support
|
|
@@ -168,17 +168,19 @@ function App() {
|
|
|
168
168
|
|
|
169
169
|
#### List Components
|
|
170
170
|
|
|
171
|
-
Support for `ScrollView`, `FlatList`, `FlashList
|
|
172
|
-
|
|
171
|
+
Support for any list component like `ScrollView`, `FlatList`, `FlashList` through the `ListComponent` prop.
|
|
172
|
+
The `listProps` provides **type inference based on the selected list component**, ensuring accurate autocompletion and type safety in your IDE.
|
|
173
173
|
|
|
174
174
|
```tsx
|
|
175
|
+
import { FlashList } from '@shopify/flash-list';
|
|
176
|
+
|
|
175
177
|
function App() {
|
|
176
178
|
return (
|
|
177
179
|
<GestureImageViewer
|
|
178
180
|
data={images}
|
|
179
|
-
ListComponent={
|
|
181
|
+
ListComponent={FlashList}
|
|
180
182
|
listProps={{
|
|
181
|
-
//
|
|
183
|
+
// ✅ FlashList props autocompletion
|
|
182
184
|
}}
|
|
183
185
|
/>
|
|
184
186
|
);
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
4
4
|
import { Platform, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
5
|
-
import {
|
|
5
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
6
6
|
import Animated from 'react-native-reanimated';
|
|
7
7
|
import { registry } from "./ImageViewerRegistry.js";
|
|
8
8
|
import { useGestureImageViewer } from "./useGestureImageViewer.js";
|
|
9
|
-
import { isFlatListLike, isScrollViewLike } from "./utils.js";
|
|
9
|
+
import { isFlashListLike, isFlatListLike, isScrollViewLike } from "./utils.js";
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
11
|
const WebPagingFix = () => {
|
|
12
12
|
if (Platform.OS !== 'web') {
|
|
@@ -21,7 +21,7 @@ export function GestureImageViewer({
|
|
|
21
21
|
data,
|
|
22
22
|
renderImage,
|
|
23
23
|
renderContainer,
|
|
24
|
-
ListComponent
|
|
24
|
+
ListComponent,
|
|
25
25
|
width: customWidth,
|
|
26
26
|
listProps,
|
|
27
27
|
backdropStyle: backdropStyleProps,
|
|
@@ -30,6 +30,7 @@ export function GestureImageViewer({
|
|
|
30
30
|
itemSpacing = 0,
|
|
31
31
|
...props
|
|
32
32
|
}) {
|
|
33
|
+
const Component = ListComponent;
|
|
33
34
|
const {
|
|
34
35
|
width: screenWidth
|
|
35
36
|
} = useWindowDimensions();
|
|
@@ -98,7 +99,7 @@ export function GestureImageViewer({
|
|
|
98
99
|
style: [styles.background, backdropStyleProps, backdropStyle]
|
|
99
100
|
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
100
101
|
style: [styles.content, animatedStyle],
|
|
101
|
-
children: isScrollViewLike(
|
|
102
|
+
children: isScrollViewLike(Component) ? /*#__PURE__*/_jsx(Component, {
|
|
102
103
|
ref: listRef,
|
|
103
104
|
...commonProps,
|
|
104
105
|
...listProps,
|
|
@@ -106,19 +107,19 @@ export function GestureImageViewer({
|
|
|
106
107
|
item,
|
|
107
108
|
index
|
|
108
109
|
}))
|
|
109
|
-
}) : isFlatListLike(
|
|
110
|
+
}) : isFlatListLike(Component) && /*#__PURE__*/_jsx(Component, {
|
|
110
111
|
ref: listRef,
|
|
111
112
|
...commonProps,
|
|
112
113
|
data: data,
|
|
113
114
|
renderItem: renderItem,
|
|
114
115
|
initialScrollIndex: initialIndex,
|
|
115
116
|
keyExtractor: keyExtractor,
|
|
116
|
-
estimatedItemSize: width + itemSpacing,
|
|
117
117
|
windowSize: 3,
|
|
118
118
|
maxToRenderPerBatch: 3,
|
|
119
|
-
getItemLayout: getItemLayout
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
getItemLayout: getItemLayout,
|
|
120
|
+
...(isFlashListLike(Component) && {
|
|
121
|
+
estimatedItemSize: width + itemSpacing
|
|
122
|
+
}),
|
|
122
123
|
...(Platform.OS === 'web' && {
|
|
123
124
|
dataSet: {
|
|
124
125
|
'paging-enabled-fix': true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useMemo","Platform","StyleSheet","useWindowDimensions","View","
|
|
1
|
+
{"version":3,"names":["useCallback","useEffect","useMemo","Platform","StyleSheet","useWindowDimensions","View","Gesture","GestureDetector","GestureHandlerRootView","Animated","registry","useGestureImageViewer","isFlashListLike","isFlatListLike","isScrollViewLike","jsx","_jsx","jsxs","_jsxs","WebPagingFix","OS","children","GestureImageViewer","id","data","renderImage","renderContainer","ListComponent","width","customWidth","listProps","backdropStyle","backdropStyleProps","containerStyle","initialIndex","itemSpacing","props","Component","screenWidth","listRef","isZoomed","dismissGesture","zoomGesture","onMomentumScrollEnd","animatedStyle","renderItem","item","index","style","height","justifyContent","alignItems","marginHorizontal","getItemLayout","_","length","offset","keyExtractor","gesture","Race","createManager","deleteManager","commonProps","horizontal","scrollEnabled","showsHorizontalScrollIndicator","snapToInterval","snapToAlignment","decelerationRate","scrollEventThrottle","removeClippedSubviews","listComponent","styles","container","background","content","ref","map","initialScrollIndex","windowSize","maxToRenderPerBatch","estimatedItemSize","dataSet","create","flex","position","top","left","right","bottom","backgroundColor"],"sourceRoot":"../../src","sources":["GestureImageViewer.tsx"],"mappings":"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","ignoreList":[]}
|
package/lib/module/utils.js
CHANGED
|
@@ -6,6 +6,12 @@ export const isScrollViewLike = component => {
|
|
|
6
6
|
return component === RNScrollView || component === GestureScrollView;
|
|
7
7
|
};
|
|
8
8
|
export const isFlatListLike = component => {
|
|
9
|
+
if (component === RNFlatList || component === GestureFlatList || isFlashListLike(component)) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
return false;
|
|
13
|
+
};
|
|
14
|
+
export const isFlashListLike = component => {
|
|
9
15
|
try {
|
|
10
16
|
const FlashList = require('@shopify/flash-list')?.FlashList;
|
|
11
17
|
if (FlashList && component === FlashList) {
|
|
@@ -14,9 +20,6 @@ export const isFlatListLike = component => {
|
|
|
14
20
|
} catch {
|
|
15
21
|
// do nothing
|
|
16
22
|
}
|
|
17
|
-
if (component === RNFlatList || component === GestureFlatList) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
23
|
return component?.name === 'FlashList';
|
|
21
24
|
};
|
|
22
25
|
//# sourceMappingURL=utils.js.map
|
package/lib/module/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["FlatList","RNFlatList","ScrollView","RNScrollView","GestureFlatList","GestureScrollView","isScrollViewLike","component","isFlatListLike","FlashList","require","name"],"sourceRoot":"../../src","sources":["utils.ts"],"mappings":";;AAAA,SAASA,QAAQ,IAAIC,UAAU,EAAEC,UAAU,IAAIC,YAAY,QAAQ,cAAc;AACjF,SAASH,QAAQ,IAAII,eAAe,EAAEF,UAAU,IAAIG,iBAAiB,QAAQ,8BAA8B;
|
|
1
|
+
{"version":3,"names":["FlatList","RNFlatList","ScrollView","RNScrollView","GestureFlatList","GestureScrollView","isScrollViewLike","component","isFlatListLike","isFlashListLike","FlashList","require","name"],"sourceRoot":"../../src","sources":["utils.ts"],"mappings":";;AAAA,SAASA,QAAQ,IAAIC,UAAU,EAAEC,UAAU,IAAIC,YAAY,QAAQ,cAAc;AACjF,SAASH,QAAQ,IAAII,eAAe,EAAEF,UAAU,IAAIG,iBAAiB,QAAQ,8BAA8B;AAG3G,OAAO,MAAMC,gBAAgB,GAAIC,SAAc,IAAuC;EACpF,OAAOA,SAAS,KAAKJ,YAAY,IAAII,SAAS,KAAKF,iBAAiB;AACtE,CAAC;AAED,OAAO,MAAMG,cAAc,GAAID,SAAc,IAAqC;EAChF,IAAIA,SAAS,KAAKN,UAAU,IAAIM,SAAS,KAAKH,eAAe,IAAIK,eAAe,CAACF,SAAS,CAAC,EAAE;IAC3F,OAAO,IAAI;EACb;EAEA,OAAO,KAAK;AACd,CAAC;AAED,OAAO,MAAME,eAAe,GAAIF,SAAc,IAAuB;EACnE,IAAI;IACF,MAAMG,SAAS,GAAGC,OAAO,CAAC,qBAAqB,CAAC,EAAED,SAAS;IAE3D,IAAIA,SAAS,IAAIH,SAAS,KAAKG,SAAS,EAAE;MACxC,OAAO,IAAI;IACb;EACF,CAAC,CAAC,MAAM;IACN;EAAA;EAGF,OAAOH,SAAS,EAAEK,IAAI,KAAK,WAAW;AACxC,CAAC","ignoreList":[]}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FlatList } from 'react-native';
|
|
1
2
|
import type { GestureImageViewerProps } from './types';
|
|
2
|
-
export declare function GestureImageViewer<T = any>({ id, data, renderImage, renderContainer, ListComponent, width: customWidth, listProps, backdropStyle: backdropStyleProps, containerStyle, initialIndex, itemSpacing, ...props }: GestureImageViewerProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare function GestureImageViewer<T = any, LC = typeof FlatList>({ id, data, renderImage, renderContainer, ListComponent, width: customWidth, listProps, backdropStyle: backdropStyleProps, containerStyle, initialIndex, itemSpacing, ...props }: GestureImageViewerProps<T, LC>): import("react/jsx-runtime").JSX.Element;
|
|
3
4
|
//# sourceMappingURL=GestureImageViewer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GestureImageViewer.d.ts","sourceRoot":"","sources":["../../../src/GestureImageViewer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GestureImageViewer.d.ts","sourceRoot":"","sources":["../../../src/GestureImageViewer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAyE,MAAM,cAAc,CAAC;AAIpH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAYvD,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,QAAQ,EAAE,EAChE,EAAc,EACd,IAAI,EACJ,WAAW,EACX,eAAe,EACf,aAAa,EACb,KAAK,EAAE,WAAW,EAClB,SAAS,EACT,aAAa,EAAE,kBAAkB,EACjC,cAAc,EACd,YAAgB,EAChB,WAAe,EACf,GAAG,KAAK,EACT,EAAE,uBAAuB,CAAC,CAAC,EAAE,EAAE,CAAC,2CAmHhC"}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type {
|
|
3
|
-
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { FlatList as RNFlatList, ScrollView as RNScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import type { FlatList as GHFlatList, ScrollView as GHScrollView } from 'react-native-gesture-handler';
|
|
4
|
+
export type FlatListComponent = typeof RNFlatList | typeof GHFlatList;
|
|
5
|
+
export type ScrollViewComponent = typeof RNScrollView | typeof GHScrollView;
|
|
6
|
+
type GetComponentProps<T> = T extends React.ComponentType<infer P> ? P : never;
|
|
7
|
+
type ConditionalListProps<LC> = LC extends FlatListComponent ? React.ComponentProps<LC> : LC extends ScrollViewComponent ? React.ComponentProps<LC> : GetComponentProps<LC>;
|
|
8
|
+
export interface GestureImageViewerProps<T = any, LC = typeof RNFlatList> {
|
|
4
9
|
id?: string;
|
|
5
10
|
data: T[];
|
|
6
11
|
initialIndex?: number;
|
|
@@ -8,15 +13,13 @@ export interface GestureImageViewerProps<T = any> {
|
|
|
8
13
|
onDismiss?: () => void;
|
|
9
14
|
renderImage: (item: T, index: number) => React.ReactElement;
|
|
10
15
|
renderContainer?: (children: React.ReactElement) => React.ReactElement;
|
|
11
|
-
ListComponent
|
|
16
|
+
ListComponent: LC;
|
|
12
17
|
width?: number;
|
|
13
18
|
dismissThreshold?: number;
|
|
14
|
-
swipeThreshold?: number;
|
|
15
|
-
velocityThreshold?: number;
|
|
16
19
|
enableDismissGesture?: boolean;
|
|
17
20
|
enableSwipeGesture?: boolean;
|
|
18
21
|
resistance?: number;
|
|
19
|
-
listProps?:
|
|
22
|
+
listProps?: Partial<ConditionalListProps<LC>>;
|
|
20
23
|
backdropStyle?: StyleProp<ViewStyle>;
|
|
21
24
|
containerStyle?: StyleProp<ViewStyle>;
|
|
22
25
|
animateBackdrop?: boolean;
|
|
@@ -26,10 +29,5 @@ export interface GestureImageViewerProps<T = any> {
|
|
|
26
29
|
maxZoomScale?: number;
|
|
27
30
|
itemSpacing?: number;
|
|
28
31
|
}
|
|
29
|
-
export
|
|
30
|
-
currentIndex: number;
|
|
31
|
-
translateY: SharedValue<number>;
|
|
32
|
-
isGestureActive: boolean;
|
|
33
|
-
lockDirection: 'horizontal' | 'vertical' | null;
|
|
34
|
-
}
|
|
32
|
+
export {};
|
|
35
33
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,IAAI,UAAU,EAAE,UAAU,IAAI,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC7G,OAAO,KAAK,EAAE,QAAQ,IAAI,UAAU,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAEvG,MAAM,MAAM,iBAAiB,GAAG,OAAO,UAAU,GAAG,OAAO,UAAU,CAAC;AACtE,MAAM,MAAM,mBAAmB,GAAG,OAAO,YAAY,GAAG,OAAO,YAAY,CAAC;AAE5E,KAAK,iBAAiB,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE/E,KAAK,oBAAoB,CAAC,EAAE,IAAI,EAAE,SAAS,iBAAiB,GACxD,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,GACxB,EAAE,SAAS,mBAAmB,GAC5B,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,GACxB,iBAAiB,CAAC,EAAE,CAAC,CAAC;AAE5B,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,GAAG,EAAE,EAAE,GAAG,OAAO,UAAU;IACtE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC,YAAY,CAAC;IAC5D,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY,CAAC;IACvE,aAAa,EAAE,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAG1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const isScrollViewLike: (component: any) => component is
|
|
3
|
-
export declare const isFlatListLike: (component: any) => component is
|
|
1
|
+
import type { FlatListComponent, ScrollViewComponent } from './types';
|
|
2
|
+
export declare const isScrollViewLike: (component: any) => component is ScrollViewComponent;
|
|
3
|
+
export declare const isFlatListLike: (component: any) => component is FlatListComponent;
|
|
4
|
+
export declare const isFlashListLike: (component: any) => component is any;
|
|
4
5
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEtE,eAAO,MAAM,gBAAgB,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,mBAE9D,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,iBAM5D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,GAAG,KAAG,SAAS,IAAI,GAY7D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gesture-image-viewer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "🖼️ A highly customizable and easy-to-use React Native image viewer with gesture support and external controls",
|
|
5
5
|
"main": "./lib/module/index.js",
|
|
6
6
|
"types": "./lib/typescript/src/index.d.ts",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
2
|
-
import { Platform, type ScrollViewProps, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
|
-
import {
|
|
2
|
+
import { type FlatList, Platform, type ScrollViewProps, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
|
+
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
4
|
import Animated from 'react-native-reanimated';
|
|
5
5
|
import { registry } from './ImageViewerRegistry';
|
|
6
6
|
import type { GestureImageViewerProps } from './types';
|
|
7
7
|
import { useGestureImageViewer } from './useGestureImageViewer';
|
|
8
|
-
import { isFlatListLike, isScrollViewLike } from './utils';
|
|
8
|
+
import { isFlashListLike, isFlatListLike, isScrollViewLike } from './utils';
|
|
9
9
|
|
|
10
10
|
const WebPagingFix = () => {
|
|
11
11
|
if (Platform.OS !== 'web') {
|
|
@@ -15,12 +15,12 @@ const WebPagingFix = () => {
|
|
|
15
15
|
return <style>{`[data-paging-enabled-fix] > div > div > div {height: 100%;}`}</style>;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
export function GestureImageViewer<T = any>({
|
|
18
|
+
export function GestureImageViewer<T = any, LC = typeof FlatList>({
|
|
19
19
|
id = 'default',
|
|
20
20
|
data,
|
|
21
21
|
renderImage,
|
|
22
22
|
renderContainer,
|
|
23
|
-
ListComponent
|
|
23
|
+
ListComponent,
|
|
24
24
|
width: customWidth,
|
|
25
25
|
listProps,
|
|
26
26
|
backdropStyle: backdropStyleProps,
|
|
@@ -28,7 +28,9 @@ export function GestureImageViewer<T = any>({
|
|
|
28
28
|
initialIndex = 0,
|
|
29
29
|
itemSpacing = 0,
|
|
30
30
|
...props
|
|
31
|
-
}: GestureImageViewerProps<T>) {
|
|
31
|
+
}: GestureImageViewerProps<T, LC>) {
|
|
32
|
+
const Component = ListComponent as React.ComponentType<any>;
|
|
33
|
+
|
|
32
34
|
const { width: screenWidth } = useWindowDimensions();
|
|
33
35
|
|
|
34
36
|
const width = customWidth || screenWidth;
|
|
@@ -66,7 +68,7 @@ export function GestureImageViewer<T = any>({
|
|
|
66
68
|
);
|
|
67
69
|
|
|
68
70
|
const getItemLayout = useCallback(
|
|
69
|
-
(_:
|
|
71
|
+
(_: ArrayLike<T> | null | undefined, index: number) => ({
|
|
70
72
|
length: width + itemSpacing,
|
|
71
73
|
offset: (width + itemSpacing) * index,
|
|
72
74
|
index,
|
|
@@ -110,23 +112,23 @@ export function GestureImageViewer<T = any>({
|
|
|
110
112
|
<View style={[styles.container, containerStyle]}>
|
|
111
113
|
<Animated.View style={[styles.background, backdropStyleProps, backdropStyle]} />
|
|
112
114
|
<Animated.View style={[styles.content, animatedStyle]}>
|
|
113
|
-
{isScrollViewLike(
|
|
114
|
-
<
|
|
115
|
+
{isScrollViewLike(Component) ? (
|
|
116
|
+
<Component ref={listRef} {...commonProps} {...listProps}>
|
|
115
117
|
{data.map((item, index) => renderItem({ item, index }))}
|
|
116
|
-
</
|
|
118
|
+
</Component>
|
|
117
119
|
) : (
|
|
118
|
-
isFlatListLike(
|
|
119
|
-
<
|
|
120
|
+
isFlatListLike(Component) && (
|
|
121
|
+
<Component
|
|
120
122
|
ref={listRef}
|
|
121
123
|
{...commonProps}
|
|
122
124
|
data={data}
|
|
123
125
|
renderItem={renderItem}
|
|
124
126
|
initialScrollIndex={initialIndex}
|
|
125
127
|
keyExtractor={keyExtractor}
|
|
126
|
-
estimatedItemSize={width + itemSpacing}
|
|
127
128
|
windowSize={3}
|
|
128
129
|
maxToRenderPerBatch={3}
|
|
129
130
|
getItemLayout={getItemLayout}
|
|
131
|
+
{...(isFlashListLike(Component) && { estimatedItemSize: width + itemSpacing })}
|
|
130
132
|
// NOTE - https://github.com/necolas/react-native-web/issues/1299
|
|
131
133
|
{...(Platform.OS === 'web' && { dataSet: { 'paging-enabled-fix': true } })}
|
|
132
134
|
{...listProps}
|
package/src/types.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type {
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { FlatList as RNFlatList, ScrollView as RNScrollView, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import type { FlatList as GHFlatList, ScrollView as GHScrollView } from 'react-native-gesture-handler';
|
|
3
4
|
|
|
4
|
-
export
|
|
5
|
+
export type FlatListComponent = typeof RNFlatList | typeof GHFlatList;
|
|
6
|
+
export type ScrollViewComponent = typeof RNScrollView | typeof GHScrollView;
|
|
7
|
+
|
|
8
|
+
type GetComponentProps<T> = T extends React.ComponentType<infer P> ? P : never;
|
|
9
|
+
|
|
10
|
+
type ConditionalListProps<LC> = LC extends FlatListComponent
|
|
11
|
+
? React.ComponentProps<LC>
|
|
12
|
+
: LC extends ScrollViewComponent
|
|
13
|
+
? React.ComponentProps<LC>
|
|
14
|
+
: GetComponentProps<LC>;
|
|
15
|
+
|
|
16
|
+
export interface GestureImageViewerProps<T = any, LC = typeof RNFlatList> {
|
|
5
17
|
id?: string;
|
|
6
18
|
data: T[];
|
|
7
19
|
initialIndex?: number;
|
|
@@ -9,15 +21,15 @@ export interface GestureImageViewerProps<T = any> {
|
|
|
9
21
|
onDismiss?: () => void;
|
|
10
22
|
renderImage: (item: T, index: number) => React.ReactElement;
|
|
11
23
|
renderContainer?: (children: React.ReactElement) => React.ReactElement;
|
|
12
|
-
ListComponent
|
|
24
|
+
ListComponent: LC;
|
|
13
25
|
width?: number;
|
|
14
26
|
dismissThreshold?: number;
|
|
15
|
-
swipeThreshold?: number;
|
|
16
|
-
velocityThreshold?: number;
|
|
27
|
+
// swipeThreshold?: number;
|
|
28
|
+
// velocityThreshold?: number;
|
|
17
29
|
enableDismissGesture?: boolean;
|
|
18
30
|
enableSwipeGesture?: boolean;
|
|
19
31
|
resistance?: number;
|
|
20
|
-
listProps?:
|
|
32
|
+
listProps?: Partial<ConditionalListProps<LC>>;
|
|
21
33
|
backdropStyle?: StyleProp<ViewStyle>;
|
|
22
34
|
containerStyle?: StyleProp<ViewStyle>;
|
|
23
35
|
animateBackdrop?: boolean;
|
|
@@ -27,10 +39,3 @@ export interface GestureImageViewerProps<T = any> {
|
|
|
27
39
|
maxZoomScale?: number;
|
|
28
40
|
itemSpacing?: number;
|
|
29
41
|
}
|
|
30
|
-
|
|
31
|
-
export interface GestureState {
|
|
32
|
-
currentIndex: number;
|
|
33
|
-
translateY: SharedValue<number>;
|
|
34
|
-
isGestureActive: boolean;
|
|
35
|
-
lockDirection: 'horizontal' | 'vertical' | null;
|
|
36
|
-
}
|
package/src/utils.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import { FlatList as RNFlatList, ScrollView as RNScrollView } from 'react-native';
|
|
2
2
|
import { FlatList as GestureFlatList, ScrollView as GestureScrollView } from 'react-native-gesture-handler';
|
|
3
|
+
import type { FlatListComponent, ScrollViewComponent } from './types';
|
|
3
4
|
|
|
4
|
-
export const isScrollViewLike = (component: any): component is
|
|
5
|
+
export const isScrollViewLike = (component: any): component is ScrollViewComponent => {
|
|
5
6
|
return component === RNScrollView || component === GestureScrollView;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
|
-
export const isFlatListLike = (component: any): component is
|
|
9
|
+
export const isFlatListLike = (component: any): component is FlatListComponent => {
|
|
10
|
+
if (component === RNFlatList || component === GestureFlatList || isFlashListLike(component)) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const isFlashListLike = (component: any): component is any => {
|
|
9
18
|
try {
|
|
10
19
|
const FlashList = require('@shopify/flash-list')?.FlashList;
|
|
11
20
|
|
|
@@ -16,9 +25,5 @@ export const isFlatListLike = (component: any): component is typeof RNFlatList =
|
|
|
16
25
|
// do nothing
|
|
17
26
|
}
|
|
18
27
|
|
|
19
|
-
if (component === RNFlatList || component === GestureFlatList) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
28
|
return component?.name === 'FlashList';
|
|
24
29
|
};
|