From 189d88eb14e2d579f0e33b03f5ed2b0e17c93d4a Mon Sep 17 00:00:00 2001 From: devan Date: Mon, 3 Feb 2025 10:36:35 -0800 Subject: [PATCH] Fabric view props --- .../components/view/HostPlatformTouch.h | 70 ++++++++ .../view/HostPlatformViewEventEmitter.cpp | 163 ++++++++++++++++++ .../view/HostPlatformViewEventEmitter.h | 43 +++++ .../components/view/HostPlatformViewEvents.h | 98 +++++++++++ .../components/view/HostPlatformViewProps.cpp | 124 +++++++++++++ .../components/view/HostPlatformViewProps.h | 40 +++++ .../view/HostPlatformViewTraitsInitializer.h | 28 +++ .../react/renderer/components/view/KeyEvent.h | 135 +++++++++++++++ .../renderer/components/view/MouseEvent.h | 73 ++++++++ 9 files changed, 774 insertions(+) create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h create mode 100644 packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h 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 new file mode 100644 index 00000000000000..bd5029f53f11ca --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#pragma once + +#include + +namespace facebook::react { + +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 new file mode 100644 index 00000000000000..425b4bb2120f8f --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.cpp @@ -0,0 +1,163 @@ +/* + * 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. + */ + +#include "HostPlatformViewEventEmitter.h" + +namespace facebook::react { + +#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); + }); +} + +#pragma mark - Focus Events + +void HostPlatformViewEventEmitter::onFocus() const { + dispatchEvent("focus"); +} + +void HostPlatformViewEventEmitter::onBlur() const { + dispatchEvent("blur"); +} + +} // 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 new file mode 100644 index 00000000000000..ced8f8b5e4d747 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h @@ -0,0 +1,43 @@ +/* + * 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 "KeyEvent.h" +#include "MouseEvent.h" + +namespace facebook::react { + +class HostPlatformViewEventEmitter : public BaseViewEventEmitter { + public: + using BaseViewEventEmitter::BaseViewEventEmitter; + +#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; + +#pragma mark - Focus Events + + void onFocus() const; + void onBlur() const; +}; + +} // 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..1f666ae86cf269 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h @@ -0,0 +1,98 @@ +/* + * 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<32> bits{}; + + enum class Offset : std::size_t { + // 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<32>::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; + + 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]); + + 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 new file mode 100644 index 00000000000000..f53647a1daef23 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.cpp @@ -0,0 +1,124 @@ +/* + * 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. + */ + +#include "HostPlatformViewProps.h" + +#include +#include +#include +#include + +namespace facebook::react { + +HostPlatformViewProps::HostPlatformViewProps( + const PropsParserContext& context, + const HostPlatformViewProps& sourceProps, + const RawProps& rawProps) + : BaseViewProps(context, sourceProps, rawProps), + hostPlatformEvents( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.hostPlatformEvents + : convertRawProp( + context, + rawProps, + sourceProps.hostPlatformEvents, + {})), + enableFocusRing( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.enableFocusRing + : convertRawProp( + context, + rawProps, + "enableFocusRing", + sourceProps.enableFocusRing, + true)), + focusable( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.focusable + : convertRawProp( + context, + rawProps, + "focusable", + sourceProps.focusable, + {})), + draggedTypes( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.draggedTypes + : convertRawProp( + context, + rawProps, + "draggedTypes", + sourceProps.draggedTypes, + {})), + tooltip( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.tooltip + : convertRawProp( + context, + rawProps, + "tooltip", + sourceProps.tooltip, + {})), + validKeysDown( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.validKeysDown + : convertRawProp( + context, + rawProps, + "validKeysDown", + sourceProps.validKeysDown, + {})), + validKeysUp( + ReactNativeFeatureFlags::enableCppPropsIteratorSetter() + ? sourceProps.validKeysUp + : convertRawProp( + context, + rawProps, + "validKeysUp", + sourceProps.validKeysUp, + {})){}; + +#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, + RawPropsPropNameHash hash, + const char* propName, + const RawValue& value) { + // All Props structs setProp methods must always, unconditionally, + // 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) { + VIEW_EVENT_CASE_MACOS(DoubleClick); + VIEW_EVENT_CASE_MACOS(KeyDown); + VIEW_EVENT_CASE_MACOS(KeyUp); + VIEW_EVENT_CASE_MACOS(MouseEnter); + VIEW_EVENT_CASE_MACOS(MouseLeave); + RAW_SET_PROP_SWITCH_CASE_BASIC(draggedTypes); + RAW_SET_PROP_SWITCH_CASE_BASIC(enableFocusRing); + RAW_SET_PROP_SWITCH_CASE_BASIC(focusable); + RAW_SET_PROP_SWITCH_CASE_BASIC(tooltip); + RAW_SET_PROP_SWITCH_CASE_BASIC(validKeysDown); + RAW_SET_PROP_SWITCH_CASE_BASIC(validKeysUp); + } +} + +} // 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 new file mode 100644 index 00000000000000..4f7322cf8441c5 --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h @@ -0,0 +1,40 @@ +/* + * 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 "HostPlatformViewEvents.h" +#include "KeyEvent.h" + +namespace facebook::react { +class HostPlatformViewProps : public BaseViewProps { + public: + HostPlatformViewProps() = default; + HostPlatformViewProps( + const PropsParserContext& context, + const HostPlatformViewProps& sourceProps, + const RawProps& rawProps); + + void setProp( + const PropsParserContext& context, + RawPropsPropNameHash hash, + const char* propName, + const RawValue& value); + + HostPlatformViewEvents hostPlatformEvents{}; + + bool enableFocusRing{true}; + bool focusable{false}; + + std::vector draggedTypes{}; + std::optional tooltip{}; + std::optional> validKeysDown{}; + std::optional> validKeysUp{}; +}; +} // 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 new file mode 100644 index 00000000000000..195f32d3a403ac --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h @@ -0,0 +1,28 @@ +/* + * 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 + +namespace facebook::react::HostPlatformViewTraitsInitializer { + +inline bool formsStackingContext(const ViewProps& props) { + 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) { + return props.focusable; +} + +} // namespace facebook::react::HostPlatformViewTraitsInitializer 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..5fbb9b735af80c --- /dev/null +++ b/packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h @@ -0,0 +1,135 @@ +/* + * 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 + +namespace facebook::react { + +/* + * Describes a request to handle a key input. + */ +struct HandledKey { + /** + * The key for the event aligned to https://www.w3.org/TR/uievents-key/. + */ + std::string key{}; + + /* + * A flag indicating if the alt key is pressed. + */ + std::optional altKey{}; + + /* + * A flag indicating if the control key is pressed. + */ + std::optional ctrlKey{}; + + /* + * A flag indicating if the shift key is pressed. + */ + std::optional shiftKey{}; + + /* + * A flag indicating if the meta key is pressed. + */ + std::optional metaKey{}; +}; + +inline static bool operator==(const HandledKey& lhs, const HandledKey& rhs) { + return lhs.key == rhs.key && lhs.altKey == rhs.altKey && + lhs.ctrlKey == rhs.ctrlKey && lhs.shiftKey == rhs.shiftKey && + lhs.metaKey == rhs.metaKey; +} + +/** + * Key event emitted by handled key events. + */ +struct KeyEvent { + /** + * The key for the event aligned to https://www.w3.org/TR/uievents-key/. + */ + std::string key{}; + + /* + * 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}; + + /* + * A flag indicating if the caps lock key is pressed. + */ + bool capsLockKey{false}; + + /* + * A flag indicating if the key on the numeric pad is pressed. + */ + bool numericPadKey{false}; + + /* + * A flag indicating if the help key is pressed. + */ + bool helpKey{false}; + + /* + * A flag indicating if a function key is pressed. + */ + bool functionKey{false}; +}; + +inline static bool operator==(const KeyEvent& lhs, const HandledKey& rhs) { + return lhs.key == rhs.key && + (!rhs.altKey.has_value() || lhs.altKey == *rhs.altKey) && + (!rhs.ctrlKey.has_value() || lhs.ctrlKey == *rhs.ctrlKey) && + (!rhs.shiftKey.has_value() || lhs.shiftKey == *rhs.shiftKey) && + (!rhs.metaKey.has_value() || lhs.metaKey == *rhs.metaKey); +} + +inline void fromRawValue( + const PropsParserContext& context, + const RawValue& value, + HandledKey& result) { + if (value.hasType>()) { + auto map = static_cast>(value); + for (const auto& pair : map) { + if (pair.first == "key") { + result.key = static_cast(pair.second); + } else if (pair.first == "altKey") { + result.altKey = static_cast(pair.second); + } else if (pair.first == "ctrlKey") { + result.ctrlKey = static_cast(pair.second); + } else if (pair.first == "shiftKey") { + result.shiftKey = static_cast(pair.second); + } else if (pair.first == "metaKey") { + result.metaKey = static_cast(pair.second); + } + } + } else if (value.hasType()) { + result.key = (std::string)value; + } +} + +} // namespace facebook::react 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