Skip to content
Draft
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 @@ -86,6 +86,8 @@ type MouseEventProps = Readonly<{

// Experimental/Work in Progress Pointer Event Callbacks (not yet ready for use)
type PointerEventProps = Readonly<{
onAuxClick?: ?(event: PointerEvent) => void,
onAuxClickCapture?: ?(event: PointerEvent) => void,
onClick?: ?(event: PointerEvent) => void,
onClickCapture?: ?(event: PointerEvent) => void,
onPointerEnter?: ?(event: PointerEvent) => void,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ const bubblingEventTypes = {
},

// Experimental/Work in Progress Pointer Events (not yet ready for use)
topAuxClick: {
phasedRegistrationNames: {
captured: 'onAuxClickCapture',
bubbled: 'onAuxClick',
},
},
topPointerCancel: {
phasedRegistrationNames: {
captured: 'onPointerCancelCapture',
Expand Down Expand Up @@ -412,6 +418,8 @@ const validAttributesForEventProps = {
onTouchCancel: true,

// Pointer events
onAuxClick: true,
onAuxClickCapture: true,
onClick: true,
onClickCapture: true,
onPointerEnter: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ const bubblingEventTypes = {
},

// Experimental/Work in Progress Pointer Events (not yet ready for use)
topAuxClick: {
phasedRegistrationNames: {
captured: 'onAuxClickCapture',
bubbled: 'onAuxClick',
},
},
topClick: {
phasedRegistrationNames: {
captured: 'onClickCapture',
Expand Down Expand Up @@ -409,6 +415,8 @@ const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
onTouchCancel: true,

// Pointer events
onAuxClick: true,
onAuxClickCapture: true,
onClick: true,
onClickCapture: true,
onPointerUp: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -638,8 +638,12 @@ - (void)_dispatchActivePointers:(std::vector<ActivePointer>)activePointers event
}
case RCTPointerEventTypeEnd: {
eventEmitter->onPointerUp(pointerEvent);
if (pointerEvent.isPrimary && pointerEvent.button == 0 && IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onClick(std::move(pointerEvent));
if (pointerEvent.isPrimary && pointerEvent.button == 0) {
if (IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onClick(std::move(pointerEvent));
}
} else if (IsPointerWithinInitialTree(activePointer)) {
eventEmitter->onAuxClick(std::move(pointerEvent));
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/React/Views/RCTView.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
/**
* (Experimental and unused for Paper) Pointer event handlers.
*/
@property (nonatomic, assign) RCTBubblingEventBlock onAuxClick;
@property (nonatomic, assign) RCTBubblingEventBlock onClick;
@property (nonatomic, assign) RCTBubblingEventBlock onPointerCancel;
@property (nonatomic, assign) RCTBubblingEventBlock onPointerDown;
Expand Down
1 change: 1 addition & 0 deletions packages/react-native/React/Views/RCTViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ - (void)updateAccessibilityTraitsForRole:(RCTView *)view withDefaultView:(RCTVie
RCT_CUSTOM_VIEW_PROPERTY(onTouchCancel, BOOL, RCTView) {}

// Experimental/WIP Pointer Events (not yet ready for use)
RCT_EXPORT_VIEW_PROPERTY(onAuxClick, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onClick, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onPointerCancel, RCTBubblingEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onPointerDown, RCTBubblingEventBlock)
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -3201,6 +3201,8 @@ public abstract class com/facebook/react/uimanager/BaseViewManager : com/faceboo
public fun setAccessibilityLiveRegion (Landroid/view/View;Ljava/lang/String;)V
public fun setAccessibilityRole (Landroid/view/View;Ljava/lang/String;)V
public fun setAccessibilityValue (Landroid/view/View;Lcom/facebook/react/bridge/ReadableMap;)V
public fun setAuxClick (Landroid/view/View;Z)V
public fun setAuxClickCapture (Landroid/view/View;Z)V
public fun setBackgroundColor (Landroid/view/View;I)V
public fun setBorderBottomLeftRadius (Landroid/view/View;F)V
public fun setBorderBottomRightRadius (Landroid/view/View;F)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,11 @@ protected void onAfterUpdateTransaction(@NonNull T view) {
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onPointerOver", "captured", "onPointerOverCapture")))
.put(
"topAuxClick",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onAuxClick", "captured", "onAuxClickCapture")))
.put(
"topClick",
MapBuilder.of(
Expand Down Expand Up @@ -908,6 +913,16 @@ public void setPointerMoveCapture(@NonNull T view, boolean value) {
setPointerEventsFlag(view, PointerEventHelper.EVENT.MOVE_CAPTURE, value);
}

@ReactProp(name = ViewProps.ON_AUXCLICK)
public void setAuxClick(@NonNull T view, boolean value) {
setPointerEventsFlag(view, PointerEventHelper.EVENT.AUXCLICK, value);
}

@ReactProp(name = ViewProps.ON_AUXCLICK_CAPTURE)
public void setAuxClickCapture(@NonNull T view, boolean value) {
setPointerEventsFlag(view, PointerEventHelper.EVENT.AUXCLICK_CAPTURE, value);
}

@ReactProp(name = ViewProps.ON_CLICK)
public void setClick(@NonNull T view, boolean value) {
setPointerEventsFlag(view, PointerEventHelper.EVENT.CLICK, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ public abstract class BaseViewManagerDelegate<
ViewProps.ON_POINTER_MOVE -> mViewManager.setPointerMove(view, value as Boolean? ?: false)
ViewProps.ON_POINTER_MOVE_CAPTURE ->
mViewManager.setPointerMoveCapture(view, value as Boolean? ?: false)
ViewProps.ON_AUXCLICK -> mViewManager.setAuxClick(view, value as Boolean? ?: false)
ViewProps.ON_AUXCLICK_CAPTURE -> mViewManager.setAuxClickCapture(view, value as Boolean? ?: false)
ViewProps.ON_CLICK -> mViewManager.setClick(view, value as Boolean? ?: false)
ViewProps.ON_CLICK_CAPTURE -> mViewManager.setClickCapture(view, value as Boolean? ?: false)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,30 @@ private void onUp(
eventDispatcher);
}

boolean primaryClick = eventState.primaryPointerId == activePointerId && eventState.supportsHover(pointerId);
List<ViewTarget> hitPathDown = mCurrentlyDownPointerIdsToHitPath.remove(activePointerId);
if (hitPathDown != null
&& isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.CLICK, EVENT.CLICK_CAPTURE)) {
List<ViewTarget> hitPathForClick = findHitPathIntersection(hitPathDown, activeHitPath);
if (!hitPathForClick.isEmpty()) {
final ViewTarget clickTarget = hitPathForClick.get(0);
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.CLICK, clickTarget.getViewId(), eventState, motionEvent));

if (primaryClick) {
if (hitPathDown != null
&& isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.CLICK, EVENT.CLICK_CAPTURE)) {
List<ViewTarget> hitPathForClick = findHitPathIntersection(hitPathDown, activeHitPath);
if (!hitPathForClick.isEmpty()) {
final ViewTarget clickTarget = hitPathForClick.get(0);
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.CLICK, clickTarget.getViewId(), eventState, motionEvent));
}
}
} else {
if (hitPathDown != null
&& isAnyoneListeningForBubblingEvent(activeHitPath, EVENT.AUXCLICK, EVENT.AUXCLICK_CAPTURE)) {
List<ViewTarget> hitPathForClick = findHitPathIntersection(hitPathDown, activeHitPath);
if (!hitPathForClick.isEmpty()) {
final ViewTarget clickTarget = hitPathForClick.get(0);
eventDispatcher.dispatchEvent(
PointerEvent.obtain(
PointerEventHelper.AUXCLICK, clickTarget.getViewId(), eventState, motionEvent));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ public object ViewProps {
internal const val ON_POINTER_LEAVE_CAPTURE: String = "onPointerLeaveCapture"
internal const val ON_POINTER_MOVE: String = "onPointerMove"
internal const val ON_POINTER_MOVE_CAPTURE: String = "onPointerMoveCapture"
internal const val ON_AUXCLICK: String = "onAuxClick"
internal const val ON_AUXCLICK_CAPTURE: String = "onAuxClickCapture"
internal const val ON_CLICK: String = "onClick"
internal const val ON_CLICK_CAPTURE: String = "onClickCapture"
@JvmField
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ internal class PointerEvent private constructor() : Event<PointerEvent>() {
PointerEventHelper.POINTER_LEAVE,
PointerEventHelper.POINTER_OUT,
PointerEventHelper.POINTER_OVER,
PointerEventHelper.AUXCLICK -> {
PointerEventHelper.CLICK -> {
pointersEventData = listOf(createW3CPointerEvent(activePointerIndex))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ internal object PointerEventHelper {
const val POINTER_UP: String = "topPointerUp"
const val POINTER_OVER: String = "topPointerOver"
const val POINTER_OUT: String = "topPointerOut"
const val AUXCLICK: String = "topAuxClick"
const val CLICK: String = "topClick"

enum class EVENT {
AUXCLICK,
AUXCLICK_CAPTURE,
CANCEL,
CANCEL_CAPTURE,
CLICK,
Expand Down Expand Up @@ -110,6 +113,8 @@ internal object PointerEventHelper {
EVENT.UP_CAPTURE,
EVENT.CANCEL,
EVENT.CANCEL_CAPTURE,
EVENT.AUXCLICK,
EVENT.AUXCLICK_CAPTURE,
EVENT.CLICK,
EVENT.CLICK_CAPTURE -> true
else -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ void TouchEventEmitter::onTouchCancel(TouchEvent event) const {
"touchCancel", std::move(event), RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onAuxClick(PointerEvent event) const {
dispatchPointerEvent("auxClick", std::move(event), RawEvent::Category::Discrete);
}

void TouchEventEmitter::onClick(PointerEvent event) const {
dispatchPointerEvent("click", std::move(event), RawEvent::Category::Discrete);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class TouchEventEmitter : public EventEmitter {
void onTouchEnd(TouchEvent event) const;
void onTouchCancel(TouchEvent event) const;

void onAuxClick(PointerEvent event) const;
void onClick(PointerEvent event) const;
void onPointerCancel(PointerEvent event) const;
void onPointerDown(PointerEvent event) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,14 @@ folly::dynamic HostPlatformViewProps::getDiffProps(
oldProps->events,
ViewEvents::Offset::PointerOutCapture,
"onPointerOutCapture");
updateEventProp(
result, events, oldProps->events, ViewEvents::Offset::AuxClick, "onAuxClick");
updateEventProp(
result,
events,
oldProps->events,
ViewEvents::Offset::AuxClickCapture,
"onAuxClickCapture");
updateEventProp(
result, events, oldProps->events, ViewEvents::Offset::Click, "onClick");
updateEventProp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,10 @@ static inline ViewEvents convertRawProp(
"onPointerOutCapture",
sourceValue[Offset::PointerOutCapture],
defaultValue[Offset::PointerOutCapture]);
result[Offset::AuxClick] =
convertRawProp(context, rawProps, "onAuxClick", sourceValue[Offset::AuxClick], defaultValue[Offset::AuxClick]);
result[Offset::AuxClickCapture] = convertRawProp(
context, rawProps, "onAuxClickCapture", sourceValue[Offset::AuxClickCapture], defaultValue[Offset::AuxClickCapture]);
result[Offset::Click] =
convertRawProp(context, rawProps, "onClick", sourceValue[Offset::Click], defaultValue[Offset::Click]);
result[Offset::ClickCapture] = convertRawProp(
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native/ReactNativeApi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3711,6 +3711,8 @@ declare type PlatformType =
| WindowsPlatform
declare type PointerEvent = NativeSyntheticEvent<NativePointerEvent>
declare type PointerEventProps = {
readonly onAuxClick?: (event: PointerEvent) => void
readonly onAuxClickCapture?: (event: PointerEvent) => void
readonly onClick?: (event: PointerEvent) => void
readonly onClickCapture?: (event: PointerEvent) => void
readonly onGotPointerCapture?: (e: PointerEvent) => void
Expand Down
1 change: 1 addition & 0 deletions scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -5048,6 +5048,7 @@ class facebook::react::TimerManager {

class facebook::react::TouchEventEmitter : public facebook::react::EventEmitter {
public TouchEventEmitter(facebook::react::SharedEventTarget eventTarget, facebook::react::EventDispatcher::Weak eventDispatcher);
public void onAuxClick(facebook::react::PointerEvent event) const;
public void onClick(facebook::react::PointerEvent event) const;
public void onGotPointerCapture(facebook::react::PointerEvent event) const;
public void onLostPointerCapture(facebook::react::PointerEvent event) const;
Expand Down
1 change: 1 addition & 0 deletions scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -5039,6 +5039,7 @@ class facebook::react::TimerManager {

class facebook::react::TouchEventEmitter : public facebook::react::EventEmitter {
public TouchEventEmitter(facebook::react::SharedEventTarget eventTarget, facebook::react::EventDispatcher::Weak eventDispatcher);
public void onAuxClick(facebook::react::PointerEvent event) const;
public void onClick(facebook::react::PointerEvent event) const;
public void onGotPointerCapture(facebook::react::PointerEvent event) const;
public void onLostPointerCapture(facebook::react::PointerEvent event) const;
Expand Down
1 change: 1 addition & 0 deletions scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -2462,6 +2462,7 @@ interface RCTView : public UIView {
public @property (assign) CGFloat borderWidth;
public @property (assign) RCTBorderCurve borderCurve;
public @property (assign) RCTBorderStyle borderStyle;
public @property (assign) RCTBubblingEventBlock onAuxClick;
public @property (assign) RCTBubblingEventBlock onClick;
public @property (assign) RCTBubblingEventBlock onGotPointerCapture;
public @property (assign) RCTBubblingEventBlock onLostPointerCapture;
Expand Down
1 change: 1 addition & 0 deletions scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -2462,6 +2462,7 @@ interface RCTView : public UIView {
public @property (assign) CGFloat borderWidth;
public @property (assign) RCTBorderCurve borderCurve;
public @property (assign) RCTBorderStyle borderStyle;
public @property (assign) RCTBubblingEventBlock onAuxClick;
public @property (assign) RCTBubblingEventBlock onClick;
public @property (assign) RCTBubblingEventBlock onGotPointerCapture;
public @property (assign) RCTBubblingEventBlock onLostPointerCapture;
Expand Down
1 change: 1 addition & 0 deletions scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -3543,6 +3543,7 @@ class facebook::react::TimerManager {

class facebook::react::TouchEventEmitter : public facebook::react::EventEmitter {
public TouchEventEmitter(facebook::react::SharedEventTarget eventTarget, facebook::react::EventDispatcher::Weak eventDispatcher);
public void onAuxClick(facebook::react::PointerEvent event) const;
public void onClick(facebook::react::PointerEvent event) const;
public void onGotPointerCapture(facebook::react::PointerEvent event) const;
public void onLostPointerCapture(facebook::react::PointerEvent event) const;
Expand Down
Loading