Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import type { ActionType } from './ActionType';
import type { GestureRelations } from './v3/types';
import { Gestures } from './web/Gestures';
import type { Config, PropsRef } from './web/interfaces';
import type { Config, HostDetector, PropsRef } from './web/interfaces';
import { GestureHandlerWebDelegate } from './web/tools/GestureHandlerWebDelegate';
import InteractionManager from './web/tools/InteractionManager';
import NodeManager from './web/tools/NodeManager';
Expand Down Expand Up @@ -39,7 +39,8 @@ export default {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
newView: any,
actionType: ActionType,
propsRef: React.RefObject<PropsRef>
propsRef: React.RefObject<PropsRef>,
hostDetector?: HostDetector | null
) {
if (!(newView instanceof Element || newView instanceof React.Component)) {
shouldPreventDrop = true;
Expand All @@ -53,16 +54,21 @@ export default {
);
}

// @ts-ignore Types should be HTMLElement or React.Component
NodeManager.getHandler(handlerTag).init(newView, propsRef, actionType);
NodeManager.getHandler(handlerTag).init(
// @ts-expect-error view ref type differs between web and native
newView,
propsRef,
actionType,
hostDetector ?? null
);
},
detachGestureHandler(handlerTag: number) {
detachGestureHandler(handlerTag: number, hostDetector?: HostDetector | null) {
if (shouldPreventDrop) {
shouldPreventDrop = false;
return;
}

NodeManager.detachGestureHandler(handlerTag);
NodeManager.detachGestureHandler(handlerTag, hostDetector);
},
setGestureHandlerConfig(handlerTag: number, newConfig: Config) {
NodeManager.getHandler(handlerTag).setGestureConfig(newConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export interface VirtualChildrenWeb {
// one stable object keeps the helpers pure (no closures over component-render-scoped values),
// which means the useEffects don't need them in their deps lists.
type DetectorRefs = {
owner: object;
viewRef: RefObject<Element | null>;
propsRef: RefObject<GestureHandlerDetectorProps>;
// Tags observed for the detector view (top-level).
Expand Down Expand Up @@ -94,7 +93,8 @@ function attachReadyHandler(
tag,
child.viewRef.current,
actionType,
refs.propsRef
refs.propsRef,
refs.viewRef
);
refs.attachedHandlers.add(tag);
}
Expand All @@ -116,7 +116,8 @@ function attachReadyHandler(
tag,
refs.viewRef.current,
actionType,
refs.propsRef
refs.propsRef,
refs.viewRef
);
refs.attachedHandlers.add(tag);
}
Expand Down Expand Up @@ -164,7 +165,8 @@ function tryAttachNativeHandlersToChildView(refs: DetectorRefs) {
tag,
target,
ActionType.NATIVE_DETECTOR,
refs.propsRef
refs.propsRef,
refs.viewRef
);
refs.attachedHandlers.add(tag);
RNGestureHandlerModule.updateGestureHandlerConfig(tag, {
Expand All @@ -191,16 +193,16 @@ function syncSubscriptions(
if (subscribedSet.has(tag)) {
continue;
}
NodeManager.observeHandler(tag, refs.owner, () => {
NodeManager.observeHandler(tag, refs.viewRef, () => {
attachReadyHandler(refs, tag, actionType, virtualViewTag);
});
subscribedSet.add(tag);
}

for (const tag of toUnsubscribe) {
NodeManager.cancelObservation(tag, refs.owner);
NodeManager.cancelObservation(tag, refs.viewRef);
if (refs.attachedHandlers.has(tag)) {
RNGestureHandlerModule.detachGestureHandler(tag);
RNGestureHandlerModule.detachGestureHandler(tag, refs.viewRef);
refs.attachedHandlers.delete(tag);
}
subscribedSet.delete(tag);
Expand All @@ -209,9 +211,9 @@ function syncSubscriptions(
}

function teardown(refs: DetectorRefs) {
NodeManager.cancelAllObservationsForOwner(refs.owner);
NodeManager.cancelAllObservationsForOwner(refs.viewRef);
for (const tag of refs.attachedHandlers) {
RNGestureHandlerModule.detachGestureHandler(tag);
RNGestureHandlerModule.detachGestureHandler(tag, refs.viewRef);
}
refs.attachedHandlers.clear();
refs.subscribedHandlers.clear();
Expand All @@ -232,7 +234,6 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => {
const refsRef = useRef<DetectorRefs | null>(null);
if (refsRef.current === null) {
refsRef.current = {
owner: {},
viewRef,
propsRef,
subscribedHandlers: new Set<number>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
Config,
GestureHandlerNativeEvent,
HitSlop,
HostDetector,
PointerData,
PropsRef,
ResultEvent,
Expand All @@ -45,6 +46,7 @@ export default abstract class GestureHandler implements IGestureHandler {
private _enabled: boolean | null = null;

private viewRef: number | null = null;
private _hostDetectorView: HostDetector | null = null;
private propsRef: React.RefObject<PropsRef> | null = null;
protected actionType: ActionType | null = null;
private forAnimated: boolean = false;
Expand Down Expand Up @@ -84,15 +86,21 @@ export default abstract class GestureHandler implements IGestureHandler {
// Initializing handler
//

protected init(
public init(
viewRef: number,
propsRef: React.RefObject<PropsRef>,
actionType: ActionType
actionType: ActionType,
hostDetector: HostDetector | null = null
) {
if (this.attached) {
this.detach();
}

this.attached = true;
this.propsRef = propsRef;
this.viewRef = viewRef;
this.actionType = actionType;
this.hostDetectorView = hostDetector;
this.state = State.UNDETERMINED;

this.delegate.init(viewRef, this);
Expand Down Expand Up @@ -1061,6 +1069,13 @@ export default abstract class GestureHandler implements IGestureHandler {
this._attached = value;
}

public get hostDetectorView() {
return this._hostDetectorView;
}
protected set hostDetectorView(value) {
this._hostDetectorView = value;
}

public get activationIndex() {
return this._activationIndex;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import type { RefObject } from 'react';

import type { ActionType } from '../../ActionType';
import type {
ActiveCursor,
MouseButton,
Expand All @@ -7,13 +10,14 @@ import type {
import type { PointerType } from '../../PointerType';
import type { State } from '../../State';
import type { SingleGestureName } from '../../v3/types';
import type { Config } from '../interfaces';
import type { Config, HostDetector, PropsRef } from '../interfaces';
import type EventManager from '../tools/EventManager';
import type { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
import type PointerTracker from '../tools/PointerTracker';

export default interface IGestureHandler {
attached: boolean;
hostDetectorView: HostDetector | null;
active: boolean;
activationIndex: number;
awaiting: boolean;
Expand Down Expand Up @@ -49,6 +53,12 @@ export default interface IGestureHandler {
fail: () => void;
cancel: () => void;

init: (
viewRef: number,
propsRef: RefObject<PropsRef>,
actionType: ActionType,
hostDetector?: HostDetector | null
) => void;
reset: () => void;
detach: () => void;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { ActionType } from '../../ActionType';
import { State } from '../../State';
import { SingleGestureName } from '../../v3/types';
import type { AdaptedEvent, Config, PropsRef } from '../interfaces';
import type {
AdaptedEvent,
Config,
HostDetector,
PropsRef,
} from '../interfaces';
import type { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
import GestureHandler from './GestureHandler';
import type IGestureHandler from './IGestureHandler';
Expand Down Expand Up @@ -35,13 +40,14 @@ export default class LongPressGestureHandler extends GestureHandler {
public override init(
ref: number,
propsRef: React.RefObject<PropsRef>,
actionType: ActionType
actionType: ActionType,
hostDetector: HostDetector | null = null
) {
if (this.enableContextMenu === undefined) {
this.enableContextMenu = false;
}

super.init(ref, propsRef, actionType);
super.init(ref, propsRef, actionType, hostDetector);
}

protected override transformNativeEvent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import {
DEFAULT_TOUCH_SLOP,
NATIVE_GESTURE_ROLE_ATTRIBUTE,
} from '../constants';
import type { AdaptedEvent, Config, PropsRef } from '../interfaces';
import type {
AdaptedEvent,
Config,
HostDetector,
PropsRef,
} from '../interfaces';
import { NativeGestureRole } from '../interfaces';
import type { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
import {
Expand Down Expand Up @@ -45,9 +50,10 @@ export default class NativeViewGestureHandler extends GestureHandler {
public override init(
ref: number,
propsRef: React.RefObject<PropsRef>,
actionType: ActionType
actionType: ActionType,
hostDetector: HostDetector | null = null
): void {
super.init(ref, propsRef, actionType);
super.init(ref, propsRef, actionType, hostDetector);

this.shouldCancelWhenOutside = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SingleGestureName } from '../../v3/types';
import { DEFAULT_TOUCH_SLOP } from '../constants';
import type { ScaleGestureListener } from '../detectors/ScaleGestureDetector';
import ScaleGestureDetector from '../detectors/ScaleGestureDetector';
import type { AdaptedEvent, PropsRef } from '../interfaces';
import type { AdaptedEvent, HostDetector, PropsRef } from '../interfaces';
import type { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
import GestureHandler from './GestureHandler';
import type IGestureHandler from './IGestureHandler';
Expand Down Expand Up @@ -62,9 +62,10 @@ export default class PinchGestureHandler extends GestureHandler {
public override init(
ref: number,
propsRef: React.RefObject<PropsRef>,
actionType: ActionType
actionType: ActionType,
hostDetector: HostDetector | null = null
) {
super.init(ref, propsRef, actionType);
super.init(ref, propsRef, actionType, hostDetector);

this.shouldCancelWhenOutside = false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { State } from '../../State';
import { SingleGestureName } from '../../v3/types';
import type { RotationGestureListener } from '../detectors/RotationGestureDetector';
import RotationGestureDetector from '../detectors/RotationGestureDetector';
import type { AdaptedEvent, PropsRef } from '../interfaces';
import type { AdaptedEvent, HostDetector, PropsRef } from '../interfaces';
import type { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
import GestureHandler from './GestureHandler';
import type IGestureHandler from './IGestureHandler';
Expand Down Expand Up @@ -62,9 +62,10 @@ export default class RotationGestureHandler extends GestureHandler {
public override init(
ref: number,
propsRef: React.RefObject<PropsRef>,
actionType: ActionType
actionType: ActionType,
hostDetector: HostDetector | null = null
): void {
super.init(ref, propsRef, actionType);
super.init(ref, propsRef, actionType, hostDetector);

this.shouldCancelWhenOutside = false;
}
Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-gesture-handler/src/web/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { RefObject } from 'react';

import type { Directions } from '../Directions';
import type {
ActiveCursor,
Expand Down Expand Up @@ -179,6 +181,8 @@ export type SVGRef = {
elementRef: { current: SVGElement };
};

export type HostDetector = RefObject<Element | null>;

export enum NativeGestureRole {
Button = 'GestureHandlerButton',
Switch = 'Switch',
Expand Down
17 changes: 15 additions & 2 deletions packages/react-native-gesture-handler/src/web/tools/NodeManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ValueOf } from '../../typeUtils';
import type { Gestures } from '../Gestures';
import type IGestureHandler from '../handlers/IGestureHandler';
import type { HostDetector } from '../interfaces';

type HandlerReadyCallback = (handler: IGestureHandler) => void;

Expand Down Expand Up @@ -60,12 +61,24 @@ export default abstract class NodeManager {
delete this.gestures[handlerTag];
}

public static detachGestureHandler(handlerTag: number): void {
public static detachGestureHandler(
handlerTag: number,
hostDetector?: HostDetector | null
): void {
if (!(handlerTag in this.gestures)) {
return;
}

this.gestures[handlerTag].detach();
const handler = this.gestures[handlerTag] as IGestureHandler;

if (
!handler.attached ||
(hostDetector !== undefined && handler.hostDetectorView !== hostDetector)
) {
return;
}

handler.detach();
}
Comment thread
m-bert marked this conversation as resolved.

// Invokes `callback` every time a handler with `tag` is created and, if the handler already exists,
Expand Down
Loading