Skip to content

Commit 9172dc9

Browse files
committed
a
1 parent 98eb33d commit 9172dc9

File tree

15 files changed

+138
-81
lines changed

15 files changed

+138
-81
lines changed

packages/react-native/Libraries/Components/View/ReactNativeViewAttributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const UIView = {
4646
focusable: true,
4747
onMouseEnter: true,
4848
onMouseLeave: true,
49+
onDoubleClick: true,
4950
onDragEnter: true,
5051
onDragLeave: true,
5152
onDrop: true,

packages/react-native/Libraries/Components/View/ViewPropTypes.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ export interface ViewPropsMacOS {
119119
enableFocusRing?: boolean | undefined;
120120
onMouseEnter?: ((event: MouseEvent) => void) | undefined;
121121
onMouseLeave?: ((event: MouseEvent) => void) | undefined;
122+
onDoubleClick?: ((event: MouseEvent) => void) | undefined;
122123
onDragEnter?: ((event: DragEvent) => void) | undefined;
123124
onDragLeave?: ((event: DragEvent) => void) | undefined;
124125
onDrop?: ((event: DragEvent) => void) | undefined;

packages/react-native/Libraries/Components/View/ViewPropTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export type KeyboardEventProps = $ReadOnly<{|
127127
type MouseEventProps = $ReadOnly<{
128128
onMouseEnter?: ?(event: MouseEvent) => void,
129129
onMouseLeave?: ?(event: MouseEvent) => void,
130+
onDoubleClick?: ?(event: MouseEvent) => void, // [macOS]
130131
}>;
131132

132133
// Experimental/Work in Progress Pointer Event Callbacks (not yet ready for use)

packages/react-native/Libraries/NativeComponent/BaseViewConfig.macos.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const bubblingEventTypes = {
3434

3535
const directEventTypes = {
3636
...PlatformBaseViewConfigIos.directEventTypes,
37+
topDoubleClick: {
38+
registrationName: 'onDoubleClick',
39+
},
3740
topDragEnter: {
3841
registrationName: 'onDragEnter',
3942
},
@@ -68,6 +71,7 @@ const validAttributesForNonEventProps = {
6871
// Props for bubbling and direct events
6972
const validAttributesForEventProps = ConditionallyIgnoredEventHandlers({
7073
onBlur: true,
74+
onDoubleClick: true,
7175
onDragEnter: true,
7276
onDragLeave: true,
7377
onDrop: true,

packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3866,6 +3866,7 @@ exports[`public API should not change unintentionally Libraries/Components/View/
38663866
focusable: true,
38673867
onMouseEnter: true,
38683868
onMouseLeave: true,
3869+
onDoubleClick: true,
38693870
onDragEnter: true,
38703871
onDragLeave: true,
38713872
onDrop: true,
@@ -4106,6 +4107,7 @@ export type KeyboardEventProps = $ReadOnly<{|
41064107
type MouseEventProps = $ReadOnly<{
41074108
onMouseEnter?: ?(event: MouseEvent) => void,
41084109
onMouseLeave?: ?(event: MouseEvent) => void,
4110+
onDoubleClick?: ?(event: MouseEvent) => void,
41094111
}>;
41104112
type PointerEventProps = $ReadOnly<{
41114113
onClick?: ?(event: PointerEvent) => void,

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,7 +1875,14 @@ - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
18751875

18761876
#pragma mark - Mouse Events
18771877

1878-
- (void)emitMouseEvent {
1878+
enum MouseEventType {
1879+
MouseEnter,
1880+
MouseLeave,
1881+
DoubleClick,
1882+
};
1883+
1884+
- (void)emitMouseEvent:(MouseEventType)eventType
1885+
{
18791886
if (!_eventEmitter) {
18801887
return;
18811888
}
@@ -1896,10 +1903,18 @@ - (void)emitMouseEvent {
18961903
.metaKey = static_cast<bool>(modifierFlags & NSEventModifierFlagCommand),
18971904
};
18981905

1899-
if (_hasMouseOver) {
1900-
_eventEmitter->onMouseEnter(mouseEvent);
1901-
} else {
1902-
_eventEmitter->onMouseLeave(mouseEvent);
1906+
switch (eventType) {
1907+
case MouseEnter:
1908+
_eventEmitter->onMouseEnter(mouseEvent);
1909+
break;
1910+
1911+
case MouseLeave:
1912+
_eventEmitter->onMouseLeave(mouseEvent);
1913+
break;
1914+
1915+
case DoubleClick:
1916+
_eventEmitter->onDoubleClick(mouseEvent);
1917+
break;
19031918
}
19041919
}
19051920

@@ -1928,7 +1943,7 @@ - (void)updateMouseOverIfNeeded
19281943

19291944
if (hasMouseOver != _hasMouseOver) {
19301945
_hasMouseOver = hasMouseOver;
1931-
[self emitMouseEvent];
1946+
[self emitMouseEvent:hasMouseOver ? MouseEnter : MouseLeave];
19321947
}
19331948
}
19341949

@@ -2001,7 +2016,7 @@ - (void)mouseEntered:(NSEvent *)event
20012016
}
20022017

20032018
_hasMouseOver = YES;
2004-
[self emitMouseEvent];
2019+
[self emitMouseEvent:MouseEnter];
20052020
}
20062021

20072022
- (void)mouseExited:(NSEvent *)event
@@ -2011,7 +2026,17 @@ - (void)mouseExited:(NSEvent *)event
20112026
}
20122027

20132028
_hasMouseOver = NO;
2014-
[self emitMouseEvent];
2029+
[self emitMouseEvent:MouseLeave];
2030+
}
2031+
2032+
- (void)mouseUp:(NSEvent *)event
2033+
{
2034+
BOOL hasDoubleClickEventHandler = _props->hostPlatformEvents[HostPlatformViewEvents::Offset::DoubleClick];
2035+
if (hasDoubleClickEventHandler && event.clickCount == 2) {
2036+
[self emitMouseEvent :DoubleClick];
2037+
} else {
2038+
[super mouseUp:event];
2039+
}
20152040
}
20162041
#endif // macOS]
20172042

packages/react-native/React/Views/RCTView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
174174
@property (nonatomic, copy) RCTDirectEventBlock onDragEnter;
175175
@property (nonatomic, copy) RCTDirectEventBlock onDragLeave;
176176
@property (nonatomic, copy) RCTDirectEventBlock onDrop;
177+
@property (nonatomic, copy) RCTDirectEventBlock onDoubleClick;
177178

178179
// Keyboarding events
179180
// NOTE does not properly work with single line text inputs (most key downs). This is because those are

packages/react-native/React/Views/RCTView.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,15 @@ - (void)mouseExited:(NSEvent *)event
15521552
additionalData:nil];
15531553
}
15541554

1555+
- (void)mouseUp:(NSEvent *)event
1556+
{
1557+
if (_onDoubleClick && event.clickCount == 2){
1558+
_onDoubleClick(nil);
1559+
} else {
1560+
[super mouseUp:event];
1561+
}
1562+
}
1563+
15551564
- (BOOL)mouseDownCanMoveWindow
15561565
{
15571566
return _mouseDownCanMoveWindow;

packages/react-native/React/Views/RCTViewManager.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ - (void) updateAccessibilityRole:(RCTView *)view withDefaultView:(RCTView *)defa
641641
RCT_EXPORT_VIEW_PROPERTY(onFocus, RCTBubblingEventBlock)
642642
RCT_EXPORT_VIEW_PROPERTY(onBlur, RCTBubblingEventBlock)
643643

644+
RCT_EXPORT_VIEW_PROPERTY(onDoubleClick, RCTDirectEventBlock)
644645
RCT_EXPORT_VIEW_PROPERTY(onMouseEnter, RCTDirectEventBlock)
645646
RCT_EXPORT_VIEW_PROPERTY(onMouseLeave, RCTDirectEventBlock)
646647
RCT_EXPORT_VIEW_PROPERTY(onDragEnter, RCTDirectEventBlock)

packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,23 @@ static jsi::Object mouseEventPayload(jsi::Runtime& runtime, const MouseEvent& ev
6767
};
6868

6969
void HostPlatformViewEventEmitter::onMouseEnter(const MouseEvent& mouseEvent) const {
70-
dispatchEvent("mouseEnter", [mouseEvent](jsi::Runtime &runtime) {
70+
dispatchEvent("mouseEnter", [mouseEvent](jsi::Runtime& runtime) {
7171
return mouseEventPayload(runtime, mouseEvent);
7272
});
7373
}
7474

7575
void HostPlatformViewEventEmitter::onMouseLeave(const MouseEvent& mouseEvent) const {
76-
dispatchEvent("mouseLeave", [mouseEvent](jsi::Runtime &runtime) {
76+
dispatchEvent("mouseLeave", [mouseEvent](jsi::Runtime& runtime) {
7777
return mouseEventPayload(runtime, mouseEvent);
7878
});
7979
}
8080

81+
void HostPlatformViewEventEmitter::onDoubleClick(const MouseEvent& mouseEvent) const {
82+
dispatchEvent("doubleClick", [mouseEvent](jsi::Runtime& runtime) {
83+
return mouseEventPayload(runtime, mouseEvent);
84+
});
85+
}
86+
8187
#pragma mark - Drag and Drop Events
8288

8389
jsi::Value HostPlatformViewEventEmitter::dataTransferPayload(
@@ -170,20 +176,20 @@ static jsi::Value dragEventPayload(
170176
return payload;
171177
}
172178

173-
void HostPlatformViewEventEmitter::onDragEnter(DragEvent const& dragEvent) const {
174-
dispatchEvent("dragEnter", [dragEvent](jsi::Runtime &runtime) {
179+
void HostPlatformViewEventEmitter::onDragEnter(const DragEvent& dragEvent) const {
180+
dispatchEvent("dragEnter", [dragEvent](jsi::Runtime& runtime) {
175181
return dragEventPayload(runtime, dragEvent);
176182
});
177183
}
178184

179-
void HostPlatformViewEventEmitter::onDragLeave(DragEvent const& dragEvent) const {
180-
dispatchEvent("dragLeave", [dragEvent](jsi::Runtime &runtime) {
185+
void HostPlatformViewEventEmitter::onDragLeave(const DragEvent& dragEvent) const {
186+
dispatchEvent("dragLeave", [dragEvent](jsi::Runtime& runtime) {
181187
return dragEventPayload(runtime, dragEvent);
182188
});
183189
}
184190

185-
void HostPlatformViewEventEmitter::onDrop(DragEvent const& dragEvent) const {
186-
dispatchEvent("drop", [dragEvent](jsi::Runtime &runtime) {
191+
void HostPlatformViewEventEmitter::onDrop(const DragEvent& dragEvent) const {
192+
dispatchEvent("drop", [dragEvent](jsi::Runtime& runtime) {
187193
return dragEventPayload(runtime, dragEvent);
188194
});
189195
}

0 commit comments

Comments
 (0)