react-native-gesture-image-viewer 2.0.0-beta.3 → 2.0.0-beta.5
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 +43 -19
- package/lib/module/GestureTrigger.js +82 -0
- package/lib/module/GestureTrigger.js.map +1 -0
- package/lib/module/GestureViewer.js +14 -8
- package/lib/module/GestureViewer.js.map +1 -1
- package/lib/module/GestureViewerManager.js +5 -5
- package/lib/module/GestureViewerManager.js.map +1 -1
- package/lib/module/GestureViewerRegistry.js +11 -0
- package/lib/module/GestureViewerRegistry.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/useGestureViewer.js +140 -71
- package/lib/module/useGestureViewer.js.map +1 -1
- package/lib/module/useGestureViewerController.js +17 -66
- package/lib/module/useGestureViewerController.js.map +1 -1
- package/lib/module/useGestureViewerState.js +78 -0
- package/lib/module/useGestureViewerState.js.map +1 -0
- package/lib/typescript/src/GestureTrigger.d.ts +55 -0
- package/lib/typescript/src/GestureTrigger.d.ts.map +1 -0
- package/lib/typescript/src/GestureViewer.d.ts +2 -2
- package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/GestureViewerManager.d.ts +5 -8
- package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
- package/lib/typescript/src/GestureViewerRegistry.d.ts +5 -0
- package/lib/typescript/src/GestureViewerRegistry.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +4 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +116 -58
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts +9 -8
- package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerController.d.ts +10 -21
- package/lib/typescript/src/useGestureViewerController.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerState.d.ts +35 -0
- package/lib/typescript/src/useGestureViewerState.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/GestureTrigger.tsx +86 -0
- package/src/GestureViewer.tsx +15 -9
- package/src/GestureViewerManager.ts +9 -9
- package/src/GestureViewerRegistry.ts +16 -0
- package/src/index.tsx +4 -1
- package/src/types.ts +116 -60
- package/src/useGestureViewer.ts +180 -77
- package/src/useGestureViewerController.ts +19 -76
- package/src/useGestureViewerState.ts +85 -0
|
@@ -3,7 +3,7 @@ import type { GestureViewerController } from './types';
|
|
|
3
3
|
* Hook to control the gesture viewer programmatically.
|
|
4
4
|
*
|
|
5
5
|
* @param id - Viewer instance identifier (default: 'default')
|
|
6
|
-
* @returns Methods
|
|
6
|
+
* @returns Methods for controlling the viewer
|
|
7
7
|
*
|
|
8
8
|
* **Available methods:**
|
|
9
9
|
* - `goToIndex(index: number)` - Navigate to specific index (0 to totalCount-1)
|
|
@@ -12,43 +12,32 @@ import type { GestureViewerController } from './types';
|
|
|
12
12
|
* - `zoomIn(multiplier?: number)` - Zoom in (default: 0.25)
|
|
13
13
|
* - `zoomOut(multiplier?: number)` - Zoom out (default: 0.25)
|
|
14
14
|
* - `resetZoom(scale?: number)` - Reset zoom level (default: 1.0)
|
|
15
|
-
* - `rotate(angle?:
|
|
16
|
-
*
|
|
17
|
-
* **Available state:**
|
|
18
|
-
* - `currentIndex: number` - Current active index (read-only)
|
|
19
|
-
* - `totalCount: number` - Total number of items (read-only)
|
|
15
|
+
* - `rotate(angle?: RotationAngle, clockwise?: boolean)` - Rotate content (default: 90° clockwise)
|
|
20
16
|
*
|
|
21
17
|
* @example
|
|
22
18
|
* ```tsx
|
|
23
|
-
* const
|
|
19
|
+
* const controller = useGestureViewerController();
|
|
24
20
|
*
|
|
25
21
|
* // Navigate to specific index
|
|
26
|
-
* goToIndex(2);
|
|
22
|
+
* controller.goToIndex(2);
|
|
27
23
|
*
|
|
28
24
|
* // Go to next image
|
|
29
|
-
* goToNext();
|
|
25
|
+
* controller.goToNext();
|
|
30
26
|
*
|
|
31
27
|
* // Zoom in by 25%
|
|
32
|
-
* zoomIn();
|
|
28
|
+
* controller.zoomIn();
|
|
33
29
|
*
|
|
34
30
|
* // Zoom out by 50%
|
|
35
|
-
* zoomOut(0.5);
|
|
31
|
+
* controller.zoomOut(0.5);
|
|
36
32
|
*
|
|
37
33
|
* // Reset to original size
|
|
38
|
-
* resetZoom();
|
|
34
|
+
* controller.resetZoom();
|
|
39
35
|
*
|
|
40
36
|
* // Rotate 90 degrees clockwise
|
|
41
|
-
* rotate();
|
|
37
|
+
* controller.rotate();
|
|
42
38
|
*
|
|
43
39
|
* // Rotate 180 degrees
|
|
44
|
-
* rotate(180);
|
|
45
|
-
*
|
|
46
|
-
* // Check current state
|
|
47
|
-
* console.log(`Image ${currentIndex + 1} of ${totalCount}`);
|
|
48
|
-
*
|
|
49
|
-
* // Check navigation availability
|
|
50
|
-
* const canGoNext = currentIndex < totalCount - 1;
|
|
51
|
-
* const canGoPrevious = currentIndex > 0;
|
|
40
|
+
* controller.rotate(180);
|
|
52
41
|
* ```
|
|
53
42
|
*/
|
|
54
43
|
export declare const useGestureViewerController: (id?: string) => GestureViewerController;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGestureViewerController.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"useGestureViewerController.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerController.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,eAAO,MAAM,0BAA0B,GAAI,WAAc,KAAG,uBAqC3D,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { GestureViewerState } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook to access the current state of the gesture viewer.
|
|
4
|
+
*
|
|
5
|
+
* @param id - Viewer instance identifier (default: 'default')
|
|
6
|
+
* @returns Current state of the viewer
|
|
7
|
+
*
|
|
8
|
+
* **Available state:**
|
|
9
|
+
* - `currentIndex: number` - Current active index (read-only)
|
|
10
|
+
* - `totalCount: number` - Total number of items (read-only)
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { currentIndex, totalCount } = useGestureViewerState();
|
|
15
|
+
*
|
|
16
|
+
* // Display current position
|
|
17
|
+
* return (
|
|
18
|
+
* <Text>
|
|
19
|
+
* {currentIndex + 1} / {totalCount}
|
|
20
|
+
* </Text>
|
|
21
|
+
* );
|
|
22
|
+
*
|
|
23
|
+
* // React to index changes
|
|
24
|
+
* useEffect(() => {
|
|
25
|
+
* console.log(`Moved to image ${currentIndex + 1}`);
|
|
26
|
+
* trackPageView(currentIndex);
|
|
27
|
+
* }, [currentIndex]);
|
|
28
|
+
*
|
|
29
|
+
* // Check navigation availability
|
|
30
|
+
* const canGoNext = currentIndex < totalCount - 1;
|
|
31
|
+
* const canGoPrevious = currentIndex > 0;
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare const useGestureViewerState: (id?: string) => GestureViewerState;
|
|
35
|
+
//# sourceMappingURL=useGestureViewerState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGestureViewerState.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerState.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAc,KAAG,kBAgDtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gesture-image-viewer",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.5",
|
|
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",
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { Children, cloneElement, isValidElement, useMemo, useRef } from 'react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { registry } from './GestureViewerRegistry';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Minimal contract for a pressable child's props.
|
|
8
|
+
* The child must optionally accept an `onPress` handler.
|
|
9
|
+
*/
|
|
10
|
+
type WithOnPress = { onPress?: (...args: unknown[]) => void };
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Props for `GestureTrigger`.
|
|
14
|
+
*
|
|
15
|
+
* @typeParam T - The child's props type. Must include an optional `onPress` handler.
|
|
16
|
+
*
|
|
17
|
+
* @property id - Optional identifier to associate this trigger with a `GestureViewer`.
|
|
18
|
+
* @property children - A single React element whose props include `onPress` (e.g., `Pressable`, `Touchable*`).
|
|
19
|
+
* @property onPress - Optional handler invoked after the child's own `onPress`.
|
|
20
|
+
*/
|
|
21
|
+
export type GestureTriggerProps<T extends WithOnPress> = {
|
|
22
|
+
id?: string;
|
|
23
|
+
children: ReactElement<T>;
|
|
24
|
+
onPress?: (...args: unknown[]) => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Wraps a pressable child element and registers its native view as a trigger for `GestureViewer`.
|
|
29
|
+
*
|
|
30
|
+
* @remark
|
|
31
|
+
* Behavior on press:
|
|
32
|
+
* - Registers the child's native node to the internal registry under the given `id`.
|
|
33
|
+
* - Invokes the child's own `onPress` first (if provided).
|
|
34
|
+
* - Invokes the `onPress` passed to `GestureTrigger` next (if provided).
|
|
35
|
+
*
|
|
36
|
+
* Type parameters:
|
|
37
|
+
* - `T` — The child's props type. Must include an optional `onPress` handler, ensuring the child is pressable.
|
|
38
|
+
*
|
|
39
|
+
* Props:
|
|
40
|
+
* - `id` — Optional identifier to associate this trigger with a `GestureViewer`. Defaults to `"default"`.
|
|
41
|
+
* - `children` — A single React element whose props include `onPress` (e.g., `Pressable`, `Touchable*`, custom button).
|
|
42
|
+
* - `onPress` — Optional handler invoked after the child's `onPress`. Receives the same arguments as the child's handler.
|
|
43
|
+
*
|
|
44
|
+
* Notes:
|
|
45
|
+
* - If neither the child nor this component provides `onPress`, a dev warning is logged and nothing happens on press.
|
|
46
|
+
* - Only a single child is allowed; wrap lists using `React.Children.map` when needed.
|
|
47
|
+
*
|
|
48
|
+
* Example:
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <GestureTrigger id="gallery" onPress={() => openModal(index)}>
|
|
51
|
+
* <Pressable style={styles.thumb}>
|
|
52
|
+
* <Image source={{ uri }} style={styles.thumbImage} />
|
|
53
|
+
* </Pressable>
|
|
54
|
+
* </GestureTrigger>
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function GestureTrigger<T extends WithOnPress>({ id = 'default', children, onPress }: GestureTriggerProps<T>) {
|
|
58
|
+
const ref = useRef<View>(null);
|
|
59
|
+
|
|
60
|
+
const wrapped = useMemo(() => {
|
|
61
|
+
const child = Children.only(children);
|
|
62
|
+
|
|
63
|
+
if (!isValidElement(child)) {
|
|
64
|
+
return children;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const originalOnPress = child.props?.onPress;
|
|
68
|
+
|
|
69
|
+
const handlePress = (...args: unknown[]) => {
|
|
70
|
+
registry.setTriggerNode(id, ref.current);
|
|
71
|
+
originalOnPress?.(...args);
|
|
72
|
+
onPress?.(...args);
|
|
73
|
+
|
|
74
|
+
if (__DEV__ && !originalOnPress && !onPress) {
|
|
75
|
+
console.warn('[GestureTrigger] No onPress found on child or props. Nothing will happen on press.');
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return cloneElement(child, {
|
|
80
|
+
...child.props,
|
|
81
|
+
onPress: handlePress,
|
|
82
|
+
});
|
|
83
|
+
}, [id, onPress, children]);
|
|
84
|
+
|
|
85
|
+
return <View ref={ref}>{wrapped}</View>;
|
|
86
|
+
}
|
package/src/GestureViewer.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
2
|
-
import { type
|
|
2
|
+
import { Platform, type ScrollView, type ScrollViewProps, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
3
3
|
import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
4
|
import Animated from 'react-native-reanimated';
|
|
5
5
|
import { registry } from './GestureViewerRegistry';
|
|
@@ -8,7 +8,7 @@ import { useGestureViewer } from './useGestureViewer';
|
|
|
8
8
|
import { createLoopData, isFlashListLike, isFlatListLike, isScrollViewLike } from './utils';
|
|
9
9
|
import WebPagingFixStyle from './WebPagingFixStyle';
|
|
10
10
|
|
|
11
|
-
export function GestureViewer<T = any, LC = typeof
|
|
11
|
+
export function GestureViewer<T = any, LC = typeof ScrollView>({
|
|
12
12
|
id = 'default',
|
|
13
13
|
data,
|
|
14
14
|
renderItem: renderItemProp,
|
|
@@ -20,18 +20,17 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
20
20
|
containerStyle,
|
|
21
21
|
initialIndex = 0,
|
|
22
22
|
itemSpacing = 0,
|
|
23
|
-
|
|
23
|
+
enableSnapMode = false,
|
|
24
24
|
enableLoop = false,
|
|
25
25
|
...props
|
|
26
26
|
}: GestureViewerProps<T, LC>) {
|
|
27
27
|
const Component = ListComponent as React.ComponentType<any>;
|
|
28
28
|
|
|
29
29
|
const dataRef = useRef(data);
|
|
30
|
-
dataRef.current = data;
|
|
31
30
|
|
|
32
31
|
const { width: screenWidth } = useWindowDimensions();
|
|
33
32
|
|
|
34
|
-
const width =
|
|
33
|
+
const width = enableSnapMode ? customWidth || screenWidth : screenWidth;
|
|
35
34
|
|
|
36
35
|
const loopData = useMemo(() => createLoopData(dataRef, enableLoop), [enableLoop]);
|
|
37
36
|
|
|
@@ -47,13 +46,14 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
47
46
|
onScrollBeginDrag,
|
|
48
47
|
animatedStyle,
|
|
49
48
|
backdropStyle,
|
|
49
|
+
handleDismiss,
|
|
50
50
|
} = useGestureViewer({
|
|
51
51
|
id,
|
|
52
52
|
data,
|
|
53
53
|
width,
|
|
54
54
|
initialIndex,
|
|
55
55
|
itemSpacing,
|
|
56
|
-
|
|
56
|
+
enableSnapMode,
|
|
57
57
|
enableLoop,
|
|
58
58
|
...props,
|
|
59
59
|
});
|
|
@@ -104,6 +104,10 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
104
104
|
return Gesture.Race(dismissGesture, zoomGesture);
|
|
105
105
|
}, [zoomGesture, dismissGesture]);
|
|
106
106
|
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
dataRef.current = data;
|
|
109
|
+
}, [data]);
|
|
110
|
+
|
|
107
111
|
useEffect(() => {
|
|
108
112
|
registry.createManager(id);
|
|
109
113
|
|
|
@@ -118,7 +122,7 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
118
122
|
showsHorizontalScrollIndicator: false,
|
|
119
123
|
onMomentumScrollEnd: onMomentumScrollEnd,
|
|
120
124
|
onScrollBeginDrag,
|
|
121
|
-
...(
|
|
125
|
+
...(enableSnapMode
|
|
122
126
|
? {
|
|
123
127
|
snapToInterval: width + itemSpacing,
|
|
124
128
|
snapToAlignment: 'center',
|
|
@@ -130,9 +134,11 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
130
134
|
scrollEventThrottle: 16,
|
|
131
135
|
removeClippedSubviews: true,
|
|
132
136
|
}) satisfies ScrollViewProps,
|
|
133
|
-
[width, itemSpacing, isZoomed, isRotated, onMomentumScrollEnd, onScrollBeginDrag,
|
|
137
|
+
[width, itemSpacing, isZoomed, isRotated, onMomentumScrollEnd, onScrollBeginDrag, enableSnapMode],
|
|
134
138
|
);
|
|
135
139
|
|
|
140
|
+
const control = useMemo(() => ({ dismiss: handleDismiss }), [handleDismiss]);
|
|
141
|
+
|
|
136
142
|
const listComponent = (
|
|
137
143
|
<GestureHandlerRootView>
|
|
138
144
|
<GestureDetector gesture={gesture}>
|
|
@@ -174,7 +180,7 @@ export function GestureViewer<T = any, LC = typeof FlatList>({
|
|
|
174
180
|
</GestureHandlerRootView>
|
|
175
181
|
);
|
|
176
182
|
|
|
177
|
-
return renderContainer ? renderContainer(listComponent) : listComponent;
|
|
183
|
+
return renderContainer ? renderContainer(listComponent, control) : listComponent;
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
const styles = StyleSheet.create({
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { type SharedValue, withTiming } from 'react-native-reanimated';
|
|
2
2
|
import type {
|
|
3
|
-
GestureViewerControllerState,
|
|
4
3
|
GestureViewerEventCallback,
|
|
5
4
|
GestureViewerEventData,
|
|
6
5
|
GestureViewerEventType,
|
|
6
|
+
GestureViewerState,
|
|
7
7
|
} from './types';
|
|
8
8
|
import { createBoundsConstraint, createScrollAction } from './utils';
|
|
9
9
|
|
|
@@ -13,7 +13,7 @@ class GestureViewerManager {
|
|
|
13
13
|
private width = 0;
|
|
14
14
|
private height = 0;
|
|
15
15
|
private maxZoomScale = 2;
|
|
16
|
-
private
|
|
16
|
+
private enableHorizontalSwipe = true;
|
|
17
17
|
private enableLoop = false;
|
|
18
18
|
private listRef: any | null = null;
|
|
19
19
|
|
|
@@ -24,7 +24,7 @@ class GestureViewerManager {
|
|
|
24
24
|
|
|
25
25
|
private loopCallback: (() => void) | null = null;
|
|
26
26
|
|
|
27
|
-
private listeners = new Set<(state:
|
|
27
|
+
private listeners = new Set<(state: GestureViewerState) => void>();
|
|
28
28
|
private eventListeners = new Map<GestureViewerEventType, Set<(data: any) => void>>();
|
|
29
29
|
|
|
30
30
|
private notifyListeners() {
|
|
@@ -33,7 +33,7 @@ class GestureViewerManager {
|
|
|
33
33
|
this.listeners.forEach((listener) => listener(state));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
subscribe(listener: (state:
|
|
36
|
+
subscribe(listener: (state: GestureViewerState) => void) {
|
|
37
37
|
this.listeners.add(listener);
|
|
38
38
|
|
|
39
39
|
return () => {
|
|
@@ -77,7 +77,7 @@ class GestureViewerManager {
|
|
|
77
77
|
this.emitEvent('rotationChange', { rotation, previousRotation });
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
getState() {
|
|
80
|
+
getState(): GestureViewerState {
|
|
81
81
|
return {
|
|
82
82
|
currentIndex: this.currentIndex,
|
|
83
83
|
totalCount: this.dataLength,
|
|
@@ -104,8 +104,8 @@ class GestureViewerManager {
|
|
|
104
104
|
this.dataLength = length;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
|
|
108
|
-
this.
|
|
107
|
+
setEnableHorizontalSwipe(enabled: boolean) {
|
|
108
|
+
this.enableHorizontalSwipe = enabled;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
setCurrentIndex(index: number) {
|
|
@@ -224,7 +224,7 @@ class GestureViewerManager {
|
|
|
224
224
|
};
|
|
225
225
|
|
|
226
226
|
goToIndex = (index: number) => {
|
|
227
|
-
if (!this.
|
|
227
|
+
if (!this.enableHorizontalSwipe || !this.listRef) {
|
|
228
228
|
return;
|
|
229
229
|
}
|
|
230
230
|
|
|
@@ -299,7 +299,7 @@ class GestureViewerManager {
|
|
|
299
299
|
this.loopCallback = null;
|
|
300
300
|
this.listeners.clear();
|
|
301
301
|
this.listRef = null;
|
|
302
|
-
this.
|
|
302
|
+
this.enableHorizontalSwipe = true;
|
|
303
303
|
this.currentIndex = 0;
|
|
304
304
|
this.dataLength = 0;
|
|
305
305
|
this.maxZoomScale = 2;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { View } from 'react-native';
|
|
1
2
|
import GestureViewerManager from './GestureViewerManager';
|
|
2
3
|
|
|
3
4
|
class GestureViewerRegistry {
|
|
4
5
|
private managers = new Map<string, GestureViewerManager>();
|
|
5
6
|
private subscribers = new Map<string, Set<(manager: GestureViewerManager | null) => void>>();
|
|
7
|
+
private triggers = new Map<string, View | null>();
|
|
6
8
|
|
|
7
9
|
subscribeToManager(id: string, callback: (manager: GestureViewerManager | null) => void) {
|
|
8
10
|
if (!this.subscribers.has(id)) {
|
|
@@ -51,6 +53,8 @@ class GestureViewerRegistry {
|
|
|
51
53
|
this.managers.delete(id);
|
|
52
54
|
|
|
53
55
|
this.notifySubscribers(id, null);
|
|
56
|
+
|
|
57
|
+
this.triggers.delete(id);
|
|
54
58
|
}
|
|
55
59
|
}
|
|
56
60
|
|
|
@@ -61,6 +65,18 @@ class GestureViewerRegistry {
|
|
|
61
65
|
[...listeners].forEach((callback) => callback(manager));
|
|
62
66
|
}
|
|
63
67
|
}
|
|
68
|
+
|
|
69
|
+
setTriggerNode(id: string, node: View | null) {
|
|
70
|
+
this.triggers.set(id, node);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
getTriggerNode(id: string): View | null {
|
|
74
|
+
return this.triggers.get(id) ?? null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
clearTriggerNode(id: string) {
|
|
78
|
+
this.triggers.delete(id);
|
|
79
|
+
}
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
export const registry = new GestureViewerRegistry();
|
package/src/index.tsx
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
export type { GestureTriggerProps } from './GestureTrigger';
|
|
2
|
+
export { GestureTrigger } from './GestureTrigger';
|
|
1
3
|
export { GestureViewer } from './GestureViewer';
|
|
2
4
|
export type {
|
|
3
5
|
GestureViewerController,
|
|
4
|
-
GestureViewerControllerState,
|
|
5
6
|
GestureViewerEventCallback,
|
|
6
7
|
GestureViewerEventData,
|
|
7
8
|
GestureViewerEventType,
|
|
8
9
|
GestureViewerProps,
|
|
10
|
+
GestureViewerState,
|
|
9
11
|
} from './types';
|
|
10
12
|
export { useGestureViewerController } from './useGestureViewerController';
|
|
11
13
|
export { useGestureViewerEvent } from './useGestureViewerEvent';
|
|
14
|
+
export { useGestureViewerState } from './useGestureViewerState';
|