diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h index ef3b407272250e..11ef6cf03c4d53 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h @@ -12,5 +12,65 @@ #include namespace facebook::react { -using HostPlatformTouch = BaseTouch; + +class HostPlatformTouch : public BaseTouch { + public: + /* + * The button indicating which pointer is used. + */ + int button; + + /* + * The pointer type indicating the device type (e.g., mouse, pen, touch) + */ + std::string pointerType; + + /* + * A flag indicating if the alt key is pressed. + */ + bool altKey; + + /* + * A flag indicating if the control key is pressed. + */ + bool ctrlKey; + + /* + * A flag indicating if the shift key is pressed. + */ + bool shiftKey; + + /* + * A flag indicating if the shift key is pressed. + */ + bool metaKey; + + /* + * Windows-specific timestamp field. We can't use the shared BaseTouch + * timestamp field beacuse it's a float and lacks sufficient resolution. + */ + double pointerTimestamp; +}; + +inline static void setTouchPayloadOnObject( + jsi::Object& object, + jsi::Runtime& runtime, + const HostPlatformTouch& touch) { + object.setProperty(runtime, "locationX", touch.offsetPoint.x); + object.setProperty(runtime, "locationY", touch.offsetPoint.y); + object.setProperty(runtime, "pageX", touch.pagePoint.x); + object.setProperty(runtime, "pageY", touch.pagePoint.y); + object.setProperty(runtime, "screenX", touch.screenPoint.x); + object.setProperty(runtime, "screenY", touch.screenPoint.y); + object.setProperty(runtime, "identifier", touch.identifier); + object.setProperty(runtime, "target", touch.target); + object.setProperty(runtime, "timestamp", touch.pointerTimestamp); + object.setProperty(runtime, "force", touch.force); + object.setProperty(runtime, "button", touch.button); + object.setProperty(runtime, "altKey", touch.altKey); + object.setProperty(runtime, "ctrlKey", touch.ctrlKey); + object.setProperty(runtime, "shiftKey", touch.shiftKey); + object.setProperty(runtime, "metaKey", touch.metaKey); +}; + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp index 6ad5d85108777b..5a8c6e512e3539 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp @@ -7,7 +7,8 @@ // [macOS] -#include + +#include "HostPlatformViewEventEmitter.h" namespace facebook::react { @@ -21,4 +22,145 @@ void HostPlatformViewEventEmitter::onBlur() const { dispatchEvent("blur"); } +#pragma mark - Keyboard Events + +static jsi::Value keyEventPayload( + jsi::Runtime& runtime, + const KeyEvent& event) { + auto payload = jsi::Object(runtime); + payload.setProperty( + runtime, "key", jsi::String::createFromUtf8(runtime, event.key)); + payload.setProperty(runtime, "ctrlKey", event.ctrlKey); + payload.setProperty(runtime, "shiftKey", event.shiftKey); + payload.setProperty(runtime, "altKey", event.altKey); + payload.setProperty(runtime, "metaKey", event.metaKey); + payload.setProperty(runtime, "capsLockKey", event.capsLockKey); + payload.setProperty(runtime, "numericPadKey", event.numericPadKey); + payload.setProperty(runtime, "helpKey", event.helpKey); + payload.setProperty(runtime, "functionKey", event.functionKey); + return payload; +}; + +void HostPlatformViewEventEmitter::onKeyDown(const KeyEvent& keyEvent) const { + dispatchEvent("keyDown", [keyEvent](jsi::Runtime& runtime) { + return keyEventPayload(runtime, keyEvent); + }); +} + +void HostPlatformViewEventEmitter::onKeyUp(const KeyEvent& keyEvent) const { + dispatchEvent("keyUp", [keyEvent](jsi::Runtime& runtime) { + return keyEventPayload(runtime, keyEvent); + }); +} + +#pragma mark - Mouse Events + +static jsi::Object mouseEventPayload( + jsi::Runtime& runtime, + const MouseEvent& event) { + auto payload = jsi::Object(runtime); + payload.setProperty(runtime, "clientX", event.clientX); + payload.setProperty(runtime, "clientY", event.clientY); + payload.setProperty(runtime, "screenX", event.screenX); + payload.setProperty(runtime, "screenY", event.screenY); + payload.setProperty(runtime, "altKey", event.altKey); + payload.setProperty(runtime, "ctrlKey", event.ctrlKey); + payload.setProperty(runtime, "shiftKey", event.shiftKey); + payload.setProperty(runtime, "metaKey", event.metaKey); + return payload; +}; + +void HostPlatformViewEventEmitter::onMouseEnter( + const MouseEvent& mouseEvent) const { + dispatchEvent("mouseEnter", [mouseEvent](jsi::Runtime& runtime) { + return mouseEventPayload(runtime, mouseEvent); + }); +} + +void HostPlatformViewEventEmitter::onMouseLeave( + const MouseEvent& mouseEvent) const { + dispatchEvent("mouseLeave", [mouseEvent](jsi::Runtime& runtime) { + return mouseEventPayload(runtime, mouseEvent); + }); +} + +void HostPlatformViewEventEmitter::onDoubleClick( + const MouseEvent& mouseEvent) const { + dispatchEvent("doubleClick", [mouseEvent](jsi::Runtime& runtime) { + return mouseEventPayload(runtime, mouseEvent); + }); +} + +#pragma mark - Drag and Drop Events + +static jsi::Value dataTransferPayload( + jsi::Runtime& runtime, + const std::vector& dataTransferItems) { + auto filesArray = jsi::Array(runtime, dataTransferItems.size()); + auto itemsArray = jsi::Array(runtime, dataTransferItems.size()); + auto typesArray = jsi::Array(runtime, dataTransferItems.size()); + int i = 0; + for (const auto& transferItem : dataTransferItems) { + auto fileObject = jsi::Object(runtime); + fileObject.setProperty(runtime, "name", transferItem.name); + fileObject.setProperty(runtime, "type", transferItem.type); + fileObject.setProperty(runtime, "uri", transferItem.uri); + if (transferItem.size.has_value()) { + fileObject.setProperty(runtime, "size", *transferItem.size); + } + if (transferItem.width.has_value()) { + fileObject.setProperty(runtime, "width", *transferItem.width); + } + if (transferItem.height.has_value()) { + fileObject.setProperty(runtime, "height", *transferItem.height); + } + filesArray.setValueAtIndex(runtime, i, fileObject); + + auto itemObject = jsi::Object(runtime); + itemObject.setProperty(runtime, "kind", transferItem.kind); + itemObject.setProperty(runtime, "type", transferItem.type); + itemsArray.setValueAtIndex(runtime, i, itemObject); + + typesArray.setValueAtIndex(runtime, i, transferItem.type); + i++; + } + + auto dataTransferObject = jsi::Object(runtime); + dataTransferObject.setProperty(runtime, "files", filesArray); + dataTransferObject.setProperty(runtime, "items", itemsArray); + dataTransferObject.setProperty(runtime, "types", typesArray); + + return dataTransferObject; +} + +static jsi::Value dragEventPayload( + jsi::Runtime& runtime, + const DragEvent& event) { + auto payload = mouseEventPayload(runtime, event); + auto dataTransferObject = + dataTransferPayload(runtime, event.dataTransferItems); + payload.setProperty(runtime, "dataTransfer", dataTransferObject); + return payload; +} + +void HostPlatformViewEventEmitter::onDragEnter( + const DragEvent& dragEvent) const { + dispatchEvent("dragEnter", [dragEvent](jsi::Runtime& runtime) { + return dragEventPayload(runtime, dragEvent); + }); +} + +void HostPlatformViewEventEmitter::onDragLeave( + const DragEvent& dragEvent) const { + dispatchEvent("dragLeave", [dragEvent](jsi::Runtime& runtime) { + return dragEventPayload(runtime, dragEvent); + }); +} + +void HostPlatformViewEventEmitter::onDrop(const DragEvent& dragEvent) const { + dispatchEvent("drop", [dragEvent](jsi::Runtime& runtime) { + return dragEventPayload(runtime, dragEvent); + }); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h index 132f1563e5a8ea..7231f9d4a3f91e 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h @@ -10,6 +10,8 @@ #pragma once #include +#include "KeyEvent.h" +#include "MouseEvent.h" namespace facebook::react { @@ -21,6 +23,23 @@ class HostPlatformViewEventEmitter : public BaseViewEventEmitter { void onFocus() const; void onBlur() const; + +#pragma mark - Keyboard Events + + void onKeyDown(const KeyEvent& keyEvent) const; + void onKeyUp(const KeyEvent& keyEvent) const; + +#pragma mark - Mouse Events + + void onMouseEnter(const MouseEvent& mouseEvent) const; + void onMouseLeave(const MouseEvent& mouseEvent) const; + void onDoubleClick(const MouseEvent& mouseEvent) const; + +#pragma mark - Drag and Drop Events + + void onDragEnter(const DragEvent& dragEvent) const; + void onDragLeave(const DragEvent& dragEvent) const; + void onDrop(const DragEvent& dragEvent) const; }; -} // namespace facebook::react \ No newline at end of file +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h new file mode 100644 index 00000000000000..733c3d02728f29 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace facebook::react { + +struct HostPlatformViewEvents { + std::bitset<64> bits{}; + + enum class Offset : std::size_t { + // Focus Events + Focus = 0, + Blur = 1, + + // Keyboard Events + KeyDown = 1, + KeyUp = 2, + + // Mouse Events + MouseEnter = 3, + MouseLeave = 4, + DoubleClick = 5, + }; + + constexpr bool operator[](const Offset offset) const { + return bits[static_cast(offset)]; + } + + std::bitset<64>::reference operator[](const Offset offset) { + return bits[static_cast(offset)]; + } +}; + +inline static bool operator==( + const HostPlatformViewEvents& lhs, + const HostPlatformViewEvents& rhs) { + return lhs.bits == rhs.bits; +} + +inline static bool operator!=( + const HostPlatformViewEvents& lhs, + const HostPlatformViewEvents& rhs) { + return lhs.bits != rhs.bits; +} + +static inline HostPlatformViewEvents convertRawProp( + const PropsParserContext& context, + const RawProps& rawProps, + const HostPlatformViewEvents& sourceValue, + const HostPlatformViewEvents& defaultValue) { + HostPlatformViewEvents result{}; + using Offset = HostPlatformViewEvents::Offset; + + // Focus Events + result[Offset::Focus] = convertRawProp( + context, + rawProps, + "onFocus", + sourceValue[Offset::Focus], + defaultValue[Offset::Focus]); + result[Offset::Blur] = convertRawProp( + context, + rawProps, + "onBlur", + sourceValue[Offset::Blur], + defaultValue[Offset::Blur]); + + // Keyboard Events + result[Offset::KeyDown] = convertRawProp( + context, + rawProps, + "onKeyDown", + sourceValue[Offset::KeyDown], + defaultValue[Offset::KeyDown]); + result[Offset::KeyUp] = convertRawProp( + context, + rawProps, + "onKeyUp", + sourceValue[Offset::KeyUp], + defaultValue[Offset::KeyUp]); + + // Mouse Events + result[Offset::MouseEnter] = convertRawProp( + context, + rawProps, + "onMouseEnter", + sourceValue[Offset::MouseEnter], + defaultValue[Offset::MouseEnter]); + result[Offset::MouseLeave] = convertRawProp( + context, + rawProps, + "onMouseLeave", + sourceValue[Offset::MouseLeave], + defaultValue[Offset::MouseLeave]); + + result[Offset::DoubleClick] = convertRawProp( + context, + rawProps, + "onDoubleClick", + sourceValue[Offset::DoubleClick], + defaultValue[Offset::DoubleClick]); + + return result; +} + +} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp index ad224e03eb1c30..e99f2614d3a320 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp @@ -1,17 +1,16 @@ /* - * Copyright (c) Meta Platforms, Inc. and affiliates. + * Copyright (c) Microsoft Corporation. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -#include "HostPlatformViewProps.h" + // [macOS] -#include +#include "HostPlatformViewProps.h" #include #include -#include #include #include @@ -22,14 +21,23 @@ HostPlatformViewProps::HostPlatformViewProps( const HostPlatformViewProps& sourceProps, const RawProps& rawProps) : BaseViewProps(context, sourceProps, rawProps), - macOSViewEvents( + hostPlatformEvents( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() - ? sourceProps.macOSViewEvents + ? sourceProps.hostPlatformEvents : convertRawProp( - context, + context, rawProps, - sourceProps.macOSViewEvents, + sourceProps.hostPlatformEvents, {})), + enableFocusRing( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.enableFocusRing + : convertRawProp( + context, + rawProps, + "enableFocusRing", + sourceProps.enableFocusRing, + true)), focusable( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() ? sourceProps.focusable @@ -39,27 +47,54 @@ HostPlatformViewProps::HostPlatformViewProps( "focusable", sourceProps.focusable, {})), - enableFocusRing( + draggedTypes( ReactNativeFeatureFlags::enableCppPropsIteratorSetter() - ? sourceProps.enableFocusRing + ? sourceProps.draggedTypes : convertRawProp( context, rawProps, - "enableFocusRing", - sourceProps.enableFocusRing, - {})) {} + "draggedTypes", + sourceProps.draggedTypes, + {})), + tooltip( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.tooltip + : convertRawProp( + context, + rawProps, + "tooltip", + sourceProps.tooltip, + {})), + keyDownEvents( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.keyDownEvents + : convertRawProp( + context, + rawProps, + "keyDownEvents", + sourceProps.keyDownEvents, + {})), + keyUpEvents( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.keyUpEvents + : convertRawProp( + context, + rawProps, + "keyUpEvents", + sourceProps.keyUpEvents, + {})){}; -#define MACOS_VIEW_EVENT_CASE(eventType) \ -case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \ - const auto offset = MacOSViewEvents::Offset::eventType; \ - MacOSViewEvents defaultViewEvents{}; \ - bool res = defaultViewEvents[offset]; \ - if (value.hasValue()) { \ - fromRawValue(context, value, res); \ - } \ - macOSViewEvents[offset] = res; \ - return; \ -} +#define VIEW_EVENT_CASE_MACOS(eventType) \ + case CONSTEXPR_RAW_PROPS_KEY_HASH("on" #eventType): { \ + const auto offset = HostPlatformViewEvents::Offset::eventType; \ + HostPlatformViewEvents defaultViewEvents{}; \ + bool res = defaultViewEvents[offset]; \ + if (value.hasValue()) { \ + fromRawValue(context, value, res); \ + } \ + hostPlatformEvents[offset] = res; \ + return; \ + } void HostPlatformViewProps::setProp( const PropsParserContext& context, @@ -70,17 +105,24 @@ void HostPlatformViewProps::setProp( // call all super::setProp methods, since multiple structs may // reuse the same values. BaseViewProps::setProp(context, hash, propName, value); - + static auto defaults = HostPlatformViewProps{}; - + switch (hash) { - RAW_SET_PROP_SWITCH_CASE_BASIC(focusable); + VIEW_EVENT_CASE_MACOS(Focus); + VIEW_EVENT_CASE_MACOS(Blur); + VIEW_EVENT_CASE_MACOS(KeyDown); + VIEW_EVENT_CASE_MACOS(KeyUp); + VIEW_EVENT_CASE_MACOS(MouseEnter); + VIEW_EVENT_CASE_MACOS(MouseLeave); + VIEW_EVENT_CASE_MACOS(DoubleClick); RAW_SET_PROP_SWITCH_CASE_BASIC(enableFocusRing); - MACOS_VIEW_EVENT_CASE(Focus); - MACOS_VIEW_EVENT_CASE(Blur); - + RAW_SET_PROP_SWITCH_CASE_BASIC(focusable); + RAW_SET_PROP_SWITCH_CASE_BASIC(draggedTypes); + RAW_SET_PROP_SWITCH_CASE_BASIC(tooltip); + RAW_SET_PROP_SWITCH_CASE_BASIC(keyDownEvents); + RAW_SET_PROP_SWITCH_CASE_BASIC(keyUpEvents); } } - } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h index b60a690aa5eb35..17eaabde9f1445 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h @@ -10,14 +10,11 @@ #pragma once #include -#include -#include #include - -#include "MacOSViewEvents.h" +#include "HostPlatformViewEvents.h" +#include "KeyEvent.h" namespace facebook::react { - class HostPlatformViewProps : public BaseViewProps { public: HostPlatformViewProps() = default; @@ -32,12 +29,14 @@ class HostPlatformViewProps : public BaseViewProps { const char* propName, const RawValue& value); - MacOSViewEvents macOSViewEvents{}; - -#pragma mark - Props + HostPlatformViewEvents hostPlatformEvents{}; - bool focusable{false}; bool enableFocusRing{true}; + bool focusable{false}; + std::vector draggedTypes{}; + std::optional tooltip{}; + std::vector keyDownEvents{}; + std::vector keyUpEvents{}; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h index 4f678feeb24c1f..4cf35bb339f6a1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h @@ -1,10 +1,12 @@ /* - * Copyright (c) Meta Platforms, Inc. and affiliates. + * Copyright (c) Microsoft Corporation. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ + // [macOS] + #pragma once #include @@ -13,7 +15,12 @@ namespace facebook::react::HostPlatformViewTraitsInitializer { inline bool formsStackingContext(const ViewProps& props) { - return false; + constexpr decltype(HostPlatformViewEvents::bits) mouseEventMask = { + (1 << (int)HostPlatformViewEvents::Offset::MouseEnter) | + (1 << (int)HostPlatformViewEvents::Offset::MouseLeave) | + (1 << (int)HostPlatformViewEvents::Offset::DoubleClick)}; + return (props.hostPlatformEvents.bits & mouseEventMask).any() || + props.tooltip; } inline bool formsView(const ViewProps& props) { diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h new file mode 100644 index 00000000000000..8f1bbcda9cbc77 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) Microsoft Corporation. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + // [macOS] + +#pragma once + +#include +#include +#include +#include + +namespace facebook::react { + +/* + * Describes an individual key event. + */ +struct BaseKeyEvent { + /** + * The code for the event aligned to https://www.w3.org/TR/uievents-code/. + */ + std::string code{}; + + /* + * A flag indicating if the alt key is pressed. + */ + bool altKey{false}; + + /* + * A flag indicating if the control key is pressed. + */ + bool ctrlKey{false}; + + /* + * A flag indicating if the shift key is pressed. + */ + bool shiftKey{false}; + + /* + * A flag indicating if the meta key is pressed. + */ + bool metaKey{false}; +}; + +inline static bool operator==(const BaseKeyEvent &lhs, const BaseKeyEvent &rhs) { + return lhs.code == rhs.code && lhs.altKey == rhs.altKey && lhs.ctrlKey == rhs.ctrlKey && + lhs.shiftKey == rhs.shiftKey && lhs.metaKey == rhs.metaKey; +} + +/** + * Event phase indicator matching the EventPhase in React. + * EventPhase includes None, Capturing, AtTarget, Bubbling. + */ +enum class HandledEventPhase { Capturing = 1, Bubbling = 3 }; + +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, HandledEventPhase &result) { + if (value.hasType()) { + result = static_cast((int)value); + return; + } + + LOG(ERROR) << "Unsupported HandledKeyEvent::EventPhase type"; +} + +/** + * Describes a handled key event declaration. + */ +struct HandledKeyEvent : BaseKeyEvent { + /** + * The phase at which the event should be marked as handled. + */ + HandledEventPhase handledEventPhase{HandledEventPhase::Bubbling}; +}; + +inline void fromRawValue(const PropsParserContext &context, const RawValue &value, HandledKeyEvent &result) { + if (value.hasType>()) { + auto map = (std::unordered_map)value; + + auto attrIterator = map.find("handledEventPhase"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.handledEventPhase); + attrIterator = map.find("altKey"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.altKey); + attrIterator = map.find("ctrlKey"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.ctrlKey); + attrIterator = map.find("metaKey"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.metaKey); + attrIterator = map.find("shiftKey"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.shiftKey); + attrIterator = map.find("code"); + if (attrIterator != map.end()) + fromRawValue(context, attrIterator->second, result.code); + return; + } + + LOG(ERROR) << "Unsupported HandledKeyEvent type"; +} + +inline static bool operator==(const HandledKeyEvent &lhs, const HandledKeyEvent &rhs) { + return lhs.handledEventPhase == rhs.handledEventPhase && + static_cast(lhs) == static_cast(rhs); +} + +struct KeyEvent : BaseKeyEvent { + /** + * The key for the event aligned to https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values. + */ + std::string key{}; +}; + +} // namespace facebook::react \ No newline at end of file diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h new file mode 100644 index 00000000000000..4edc571b707949 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +namespace facebook::react { + +/* + * Describes a mouse enter/leave event. + */ +struct MouseEvent { + /** + * Pointer horizontal location in target view. + */ + Float clientX{0}; + + /** + * Pointer vertical location in target view. + */ + Float clientY{0}; + + /** + * Pointer horizontal location in window. + */ + Float screenX{0}; + + /** + * Pointer vertical location in window. + */ + Float screenY{0}; + + /* + * A flag indicating if the alt key is pressed. + */ + bool altKey{false}; + + /* + * A flag indicating if the control key is pressed. + */ + bool ctrlKey{false}; + + /* + * A flag indicating if the shift key is pressed. + */ + bool shiftKey{false}; + + /* + * A flag indicating if the meta key is pressed. + */ + bool metaKey{false}; +}; + +struct DataTransferItem { + std::string name{}; + std::string kind{}; + std::string type{}; + std::string uri{}; + std::optional size{}; + std::optional width{}; + std::optional height{}; +}; + +struct DragEvent : MouseEvent { + std::vector dataTransferItems; +}; + +} // namespace facebook::react