@office-iss/react-native-win32 0.68.0-preview.2 → 0.69.0-preview.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.flowconfig +3 -3
  2. package/CHANGELOG.json +386 -14
  3. package/CHANGELOG.md +159 -9
  4. package/IntegrationTests/BUCK +4 -1
  5. package/Libraries/ActionSheetIOS/ActionSheetIOS.js +7 -0
  6. package/Libraries/ActionSheetIOS/NativeActionSheetManager.js +1 -0
  7. package/Libraries/Alert/Alert.win32.js +1 -1
  8. package/Libraries/Animated/AnimatedImplementation.js +1 -1
  9. package/Libraries/Animated/NativeAnimatedHelper.js +55 -9
  10. package/Libraries/Animated/NativeAnimatedModule.js +1 -0
  11. package/Libraries/Animated/NativeAnimatedTurboModule.js +1 -0
  12. package/Libraries/Animated/animations/TimingAnimation.js +6 -11
  13. package/Libraries/Animated/createAnimatedComponent.js +2 -2
  14. package/Libraries/Animated/nodes/AnimatedColor.js +95 -29
  15. package/Libraries/Animated/nodes/AnimatedInterpolation.js +19 -22
  16. package/Libraries/Animated/nodes/AnimatedNode.js +2 -2
  17. package/Libraries/Animated/nodes/AnimatedValue.js +1 -1
  18. package/Libraries/AppState/AppState.js +1 -1
  19. package/Libraries/Blob/URL.js +7 -1
  20. package/Libraries/Components/Button.js +3 -0
  21. package/Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js +5 -0
  22. package/Libraries/Components/Pressable/Pressable.js +3 -3
  23. package/Libraries/Components/Pressable/Pressable.win32.js +3 -3
  24. package/Libraries/Components/ScrollView/AndroidHorizontalScrollViewNativeComponent.js +47 -38
  25. package/Libraries/Components/ScrollView/ScrollContentViewNativeComponent.js +15 -7
  26. package/Libraries/Components/ScrollView/ScrollView.js +1 -1
  27. package/Libraries/Components/ScrollView/ScrollViewNativeComponent.js +16 -3
  28. package/Libraries/Components/ScrollView/ScrollViewStickyHeader.js +3 -1
  29. package/Libraries/Components/Slider/Slider.js +0 -2
  30. package/Libraries/Components/Slider/SliderNativeComponent.js +0 -1
  31. package/Libraries/Components/StatusBar/StatusBar.js +6 -1
  32. package/Libraries/Components/Switch/Switch.js +13 -2
  33. package/Libraries/Components/TextInput/AndroidTextInputNativeComponent.js +114 -109
  34. package/Libraries/Components/TextInput/RCTMultilineTextInputNativeComponent.js +17 -9
  35. package/Libraries/Components/TextInput/RCTSingelineTextInputNativeComponent.js +13 -5
  36. package/Libraries/Components/TextInput/RCTTextInputViewConfig.js +10 -0
  37. package/Libraries/Components/TextInput/TextInput.js +1 -8
  38. package/Libraries/Components/TextInput/TextInputState.js +10 -2
  39. package/Libraries/Components/TextInput/TextInputState.win32.js +10 -2
  40. package/Libraries/Components/Touchable/Tests/TouchableWin32Test.js.map +1 -1
  41. package/Libraries/Components/Touchable/TouchableBounce.js +1 -0
  42. package/Libraries/Components/Touchable/TouchableHighlight.js +1 -0
  43. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +1 -0
  44. package/Libraries/Components/Touchable/TouchableOpacity.js +7 -1
  45. package/Libraries/Components/Touchable/TouchableWin32.Props.d.ts +3 -1
  46. package/Libraries/Components/Touchable/TouchableWin32.Props.js.map +1 -1
  47. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +2 -0
  48. package/Libraries/Components/View/ReactNativeViewAttributes.js +1 -0
  49. package/Libraries/Components/View/ReactNativeViewAttributes.win32.js +1 -0
  50. package/Libraries/Components/View/View.win32.js +33 -1
  51. package/Libraries/Components/View/ViewNativeComponent.js +68 -8
  52. package/Libraries/Components/View/ViewPropTypes.js +36 -4
  53. package/Libraries/Components/View/ViewPropTypes.win32.js +36 -4
  54. package/Libraries/Components/View/ViewWin32.Props.d.ts +1 -1
  55. package/Libraries/Components/View/ViewWin32.Props.js.map +1 -1
  56. package/Libraries/Core/Devtools/parseHermesStack.js +1 -1
  57. package/Libraries/Core/ExceptionsManager.js +1 -1
  58. package/Libraries/Core/RawEventEmitter.js +38 -0
  59. package/Libraries/Core/ReactNativeVersion.js +2 -2
  60. package/Libraries/Core/polyfillPromise.js +32 -0
  61. package/Libraries/Core/setUpReactDevTools.js +3 -2
  62. package/Libraries/EventEmitter/NativeEventEmitter.js +3 -3
  63. package/Libraries/EventEmitter/RCTDeviceEventEmitter.js +2 -1
  64. package/Libraries/EventEmitter/__mocks__/NativeEventEmitter.js +3 -3
  65. package/Libraries/Events/CustomEvent.js +32 -0
  66. package/Libraries/Events/EventPolyfill.js +239 -0
  67. package/Libraries/Image/Image.android.js +0 -6
  68. package/Libraries/Image/Image.ios.js +0 -6
  69. package/Libraries/Image/Image.win32.js +2 -8
  70. package/Libraries/Image/ImageViewNativeComponent.js +18 -3
  71. package/Libraries/Image/TextInlineImageNativeComponent.js +23 -15
  72. package/Libraries/Image/resolveAssetSource.win32.js +1 -1
  73. package/Libraries/Inspector/Inspector.js +2 -4
  74. package/Libraries/Inspector/Inspector.win32.js +7 -9
  75. package/Libraries/Interaction/BridgeSpyStallHandler.js +4 -3
  76. package/Libraries/Interaction/InteractionManager.js +1 -12
  77. package/Libraries/Interaction/TaskQueue.js +5 -4
  78. package/Libraries/LayoutAnimation/LayoutAnimation.js +13 -0
  79. package/Libraries/Linking/Linking.js +1 -1
  80. package/Libraries/Lists/FlatList.js +27 -6
  81. package/Libraries/Lists/VirtualizedList.js +71 -55
  82. package/Libraries/Lists/VirtualizedListContext.js +7 -3
  83. package/Libraries/Lists/VirtualizedSectionList.js +2 -2
  84. package/Libraries/Lists/__tests__/{FillRateHelper-test.windows.js → FillRateHelper-test.js} +2 -2
  85. package/Libraries/Lists/__tests__/{FlatList-test.windows.js → FlatList-test.js} +2 -2
  86. package/Libraries/Lists/__tests__/{SectionList-test.windows.js → SectionList-test.js} +14 -14
  87. package/Libraries/Lists/__tests__/{VirtualizeUtils-test.windows.js → VirtualizeUtils-test.js} +3 -3
  88. package/Libraries/Lists/__tests__/{VirtualizedList-test.windows.js → VirtualizedList-test.js} +92 -43
  89. package/Libraries/Lists/__tests__/{VirtualizedSectionList-test.windows.js → VirtualizedSectionList-test.js} +16 -14
  90. package/Libraries/LogBox/Data/LogBoxData.js +2 -2
  91. package/Libraries/LogBox/Data/LogBoxLog.js +1 -1
  92. package/Libraries/LogBox/Data/LogBoxSymbolication.js +1 -1
  93. package/Libraries/LogBox/Data/parseLogBoxLog.js +1 -1
  94. package/Libraries/LogBox/LogBox.js +2 -21
  95. package/Libraries/LogBox/UI/LogBoxInspectorFooter.js +1 -0
  96. package/Libraries/LogBox/UI/LogBoxInspectorHeader.js +2 -1
  97. package/Libraries/NativeComponent/BaseViewConfig.android.js +295 -0
  98. package/Libraries/NativeComponent/BaseViewConfig.ios.js +333 -0
  99. package/Libraries/NativeComponent/BaseViewConfig.win32.js +334 -0
  100. package/Libraries/NativeComponent/NativeComponentRegistry.js +0 -2
  101. package/Libraries/NativeComponent/PlatformBaseViewConfig.js +24 -0
  102. package/Libraries/NativeComponent/StaticViewConfigValidator.js +7 -42
  103. package/Libraries/NativeComponent/ViewConfig.js +4 -4
  104. package/Libraries/NativeComponent/ViewConfigIgnore.js +54 -0
  105. package/Libraries/Network/FormData.js +7 -1
  106. package/Libraries/Network/RCTNetworking.win32.js +1 -1
  107. package/Libraries/Pressability/Pressability.js +115 -46
  108. package/Libraries/Pressability/Pressability.win32.js +174 -69
  109. package/Libraries/Pressability/PressabilityDebug.js +5 -9
  110. package/Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js +1 -0
  111. package/Libraries/ReactNative/AppContainer.js +1 -1
  112. package/Libraries/ReactNative/{DummyUIManager.js → BridgelessUIManager.js} +62 -40
  113. package/Libraries/ReactNative/PaperUIManager.win32.js +5 -5
  114. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +39 -0
  115. package/Libraries/ReactNative/UIManager.js +2 -3
  116. package/Libraries/ReactNative/renderApplication.js +4 -0
  117. package/Libraries/ReactPrivate/ReactNativePrivateInterface.js +8 -0
  118. package/Libraries/Renderer/implementations/ReactFabric-dev.js +5908 -4906
  119. package/Libraries/Renderer/implementations/ReactFabric-prod.js +2100 -1918
  120. package/Libraries/Renderer/implementations/ReactFabric-profiling.js +2567 -2352
  121. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js +5610 -4844
  122. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.js +1710 -1556
  123. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.js +1830 -1639
  124. package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
  125. package/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +2 -1
  126. package/Libraries/StyleSheet/EdgeInsetsPropType.js +4 -1
  127. package/Libraries/StyleSheet/StyleSheetTypes.js +59 -66
  128. package/Libraries/StyleSheet/normalizeColor.js +1 -1
  129. package/Libraries/StyleSheet/private/_StyleSheetTypesOverrides.js +15 -0
  130. package/Libraries/StyleSheet/private/_TransformStyle.js +53 -0
  131. package/Libraries/Text/Text.js +13 -7
  132. package/Libraries/Text/TextNativeComponent.js +2 -0
  133. package/Libraries/Text/TextNativeComponent.win32.js +2 -0
  134. package/Libraries/Text/TextProps.js +10 -0
  135. package/Libraries/Types/CoreEventTypes.js +13 -1
  136. package/Libraries/Types/CoreEventTypes.win32.js +26 -1
  137. package/Libraries/Utilities/Appearance.js +0 -8
  138. package/Libraries/Utilities/HMRClient.js +1 -1
  139. package/Libraries/Utilities/ReactNativeTestTools.js +1 -0
  140. package/Libraries/Utilities/codegenNativeComponent.js +17 -6
  141. package/Libraries/Utilities/stringifySafe.js +4 -1
  142. package/Libraries/Utilities/verifyComponentAttributeEquivalence.js +3 -3
  143. package/Libraries/WebSocket/WebSocket.js +1 -1
  144. package/Libraries/vendor/emitter/_EmitterSubscription.js +1 -1
  145. package/Libraries/vendor/emitter/_EventEmitter.js +1 -1
  146. package/Libraries/vendor/emitter/_EventSubscription.js +1 -1
  147. package/index.js +30 -25
  148. package/index.win32.js +30 -25
  149. package/jest/preprocessor.js +24 -107
  150. package/jest/preprocessor_DO_NOT_USE.js +122 -0
  151. package/metro.config.js +3 -47
  152. package/overrides.json +39 -46
  153. package/package.json +28 -26
  154. package/rntypes/index.d.ts +19 -7
  155. package/src/Libraries/Components/Touchable/Tests/TouchableWin32Test.tsx +1 -1
  156. package/src/Libraries/Components/Touchable/TouchableWin32.Props.tsx +3 -1
  157. package/src/Libraries/Components/View/ViewWin32.Props.ts +1 -0
  158. package/src/Libraries/Lists/__tests__/__snapshots__/FlatList-test.js.snap +427 -0
  159. package/src/Libraries/Lists/__tests__/__snapshots__/SectionList-test.js.snap +391 -0
  160. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizeUtils-test.js.snap +3 -0
  161. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizedList-test.js.snap +4565 -0
  162. package/src/Libraries/Lists/__tests__/__snapshots__/VirtualizedSectionList-test.js.snap +1153 -0
  163. package/src/rntypes/index.d.ts +19 -7
  164. package/typings-index.js +5 -1
  165. package/typings-index.js.map +1 -1
  166. package/Libraries/Components/SegmentedControlIOS/RCTSegmentedControlNativeComponent.js +0 -44
  167. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.android.js +0 -45
  168. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +0 -123
  169. package/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.js +0 -45
  170. package/Libraries/Components/View/ReactNativeViewViewConfig.js +0 -360
  171. package/Libraries/Components/View/ReactNativeViewViewConfig.win32.js +0 -401
  172. package/Libraries/Components/View/ReactNativeViewViewConfigAndroid.js +0 -83
  173. package/Libraries/ReactNative/UIManagerInjection.js +0 -15
  174. package/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +0 -24527
  175. package/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +0 -8309
  176. package/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +0 -8961
  177. package/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +0 -24948
  178. package/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +0 -8400
  179. package/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +0 -9049
  180. package/flow/Promise.js +0 -47
@@ -9,12 +9,9 @@
9
9
  */
10
10
 
11
11
  import {type ViewConfig} from '../Renderer/shims/ReactNativeTypes';
12
- // $FlowFixMe[nonstrict-import]
13
- import getNativeComponentAttributes from '../ReactNative/getNativeComponentAttributes';
14
- // $FlowFixMe[nonstrict-import]
15
- import {createViewConfig} from './ViewConfig';
12
+ import {isIgnored} from './ViewConfigIgnore';
16
13
 
17
- type Difference =
14
+ export type Difference =
18
15
  | {
19
16
  type: 'missing',
20
17
  path: Array<string>,
@@ -32,7 +29,7 @@ type Difference =
32
29
  staticValue: mixed,
33
30
  };
34
31
 
35
- type ValidationResult = ValidResult | InvalidResult;
32
+ export type ValidationResult = ValidResult | InvalidResult;
36
33
  type ValidResult = {
37
34
  type: 'valid',
38
35
  };
@@ -41,41 +38,6 @@ type InvalidResult = {
41
38
  differences: Array<Difference>,
42
39
  };
43
40
 
44
- type ViewConfigValidationResult = {
45
- componentName: string,
46
- nativeViewConfig?: ?ViewConfig,
47
- staticViewConfig?: ?ViewConfig,
48
- validationResult?: ?ValidationResult,
49
- };
50
-
51
- // e.g. require('MyNativeComponent') where MyNativeComponent.js exports a HostComponent
52
- type JSModule = $FlowFixMe;
53
-
54
- export function validateStaticViewConfigs(
55
- nativeComponent: JSModule,
56
- ): ViewConfigValidationResult {
57
- const nativeViewConfig = getNativeComponentAttributes(
58
- nativeComponent.default || nativeComponent,
59
- );
60
-
61
- const generatedPartialViewConfig = nativeComponent.__INTERNAL_VIEW_CONFIG;
62
- const staticViewConfig: ?ViewConfig =
63
- generatedPartialViewConfig && createViewConfig(generatedPartialViewConfig);
64
-
65
- const componentName: string = nativeComponent.default || nativeComponent;
66
- const validationResult: ?ValidationResult =
67
- nativeViewConfig &&
68
- staticViewConfig &&
69
- validate(componentName, nativeViewConfig, staticViewConfig);
70
-
71
- return {
72
- componentName,
73
- nativeViewConfig,
74
- staticViewConfig,
75
- validationResult,
76
- };
77
- }
78
-
79
41
  /**
80
42
  * During the migration from native view configs to static view configs, this is
81
43
  * used to validate that the two are equivalent.
@@ -183,7 +145,10 @@ function accumulateDifferences(
183
145
  }
184
146
 
185
147
  for (const staticKey in staticObject) {
186
- if (!nativeObject.hasOwnProperty(staticKey)) {
148
+ if (
149
+ !nativeObject.hasOwnProperty(staticKey) &&
150
+ !isIgnored(staticObject[staticKey])
151
+ ) {
187
152
  differences.push({
188
153
  path: [...path, staticKey],
189
154
  type: 'unexpected',
@@ -8,11 +8,11 @@
8
8
  * @format
9
9
  */
10
10
 
11
- import ReactNativeViewViewConfig from '../Components/View/ReactNativeViewViewConfig';
12
11
  import type {
13
12
  PartialViewConfig,
14
13
  ViewConfig,
15
14
  } from '../Renderer/shims/ReactNativeTypes';
15
+ import PlatformBaseViewConfig from './PlatformBaseViewConfig';
16
16
 
17
17
  /**
18
18
  * Creates a complete `ViewConfig` from a `PartialViewConfig`.
@@ -24,16 +24,16 @@ export function createViewConfig(
24
24
  uiViewClassName: partialViewConfig.uiViewClassName,
25
25
  Commands: {},
26
26
  bubblingEventTypes: composeIndexers(
27
- ReactNativeViewViewConfig.bubblingEventTypes,
27
+ PlatformBaseViewConfig.bubblingEventTypes,
28
28
  partialViewConfig.bubblingEventTypes,
29
29
  ),
30
30
  directEventTypes: composeIndexers(
31
- ReactNativeViewViewConfig.directEventTypes,
31
+ PlatformBaseViewConfig.directEventTypes,
32
32
  partialViewConfig.directEventTypes,
33
33
  ),
34
34
  validAttributes: composeIndexers(
35
35
  // $FlowFixMe[incompatible-call] `style` property confuses Flow.
36
- ReactNativeViewViewConfig.validAttributes,
36
+ PlatformBaseViewConfig.validAttributes,
37
37
  // $FlowFixMe[incompatible-call] `style` property confuses Flow.
38
38
  partialViewConfig.validAttributes,
39
39
  ),
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ * @format
9
+ */
10
+
11
+ import Platform from '../Utilities/Platform';
12
+
13
+ const ignoredViewConfigProps = new WeakSet<{...}>();
14
+
15
+ /**
16
+ * Decorates ViewConfig values that are dynamically injected by the library,
17
+ * react-native-gesture-handler. (T45765076)
18
+ */
19
+ export function DynamicallyInjectedByGestureHandler<T: {...}>(object: T): T {
20
+ ignoredViewConfigProps.add(object);
21
+ return object;
22
+ }
23
+
24
+ /**
25
+ * On iOS, ViewManager event declarations generate {eventName}: true entries
26
+ * in ViewConfig valueAttributes. These entries aren't generated for Android.
27
+ * This annotation allows Static ViewConfigs to insert these entries into
28
+ * iOS but not Android.
29
+ *
30
+ * In the future, we want to remove this platform-inconsistency. We want
31
+ * to set RN$ViewConfigEventValidAttributesDisabled = true server-side,
32
+ * so that iOS does not generate validAttributes from event props in iOS RCTViewManager,
33
+ * since Android does not generate validAttributes from events props in Android ViewManager.
34
+ *
35
+ * TODO(T110872225): Remove this logic, after achieving platform-consistency
36
+ */
37
+ export function ConditionallyIgnoredEventHandlers<T: {[name: string]: true}>(
38
+ value: T,
39
+ ): T | void {
40
+ if (
41
+ Platform.OS === 'ios' &&
42
+ !(global.RN$ViewConfigEventValidAttributesDisabled === true)
43
+ ) {
44
+ return value;
45
+ }
46
+ return undefined;
47
+ }
48
+
49
+ export function isIgnored(value: mixed): boolean {
50
+ if (typeof value === 'object' && value != null) {
51
+ return ignoredViewConfigProps.has(value);
52
+ }
53
+ return false;
54
+ }
@@ -64,6 +64,12 @@ class FormData {
64
64
  this._parts.push([key, value]);
65
65
  }
66
66
 
67
+ getAll(key: string): Array<FormDataValue> {
68
+ return this._parts
69
+ .filter(([name]) => name === key)
70
+ .map(([, value]) => value);
71
+ }
72
+
67
73
  getParts(): Array<FormDataPart> {
68
74
  return this._parts.map(([name, value]) => {
69
75
  const contentDisposition = 'form-data; name="' + name + '"';
@@ -74,7 +80,7 @@ class FormData {
74
80
  // an object with a `uri` attribute. Optionally, it can also
75
81
  // have a `name` and `type` attribute to specify filename and
76
82
  // content type (cf. web Blob interface.)
77
- if (typeof value === 'object' && value) {
83
+ if (typeof value === 'object' && !Array.isArray(value) && value) {
78
84
  if (typeof value.name === 'string') {
79
85
  headers['content-disposition'] += '; filename="' + value.name + '"';
80
86
  }
@@ -60,7 +60,7 @@ class RCTNetworking extends NativeEventEmitter<$FlowFixMe> {
60
60
  ) {
61
61
  const body = convertRequestBody(data);
62
62
  if (body && body.formData) {
63
- body.formData = body.formData.map((part) => ({
63
+ body.formData = body.formData.map(part => ({
64
64
  ...part,
65
65
  headers: convertHeadersMapToArray(part.headers),
66
66
  }));
@@ -24,6 +24,8 @@ import Platform from '../Utilities/Platform';
24
24
  import UIManager from '../ReactNative/UIManager';
25
25
  import type {HostComponent} from '../Renderer/shims/ReactNativeTypes';
26
26
  import * as React from 'react';
27
+ import ReactNativeFeatureFlags from '../ReactNative/ReactNativeFeatureFlags';
28
+ import {type PointerEvent} from '../Types/CoreEventTypes';
27
29
 
28
30
  export type PressabilityConfig = $ReadOnly<{|
29
31
  /**
@@ -158,6 +160,8 @@ export type EventHandlers = $ReadOnly<{|
158
160
  onFocus: (event: FocusEvent) => void,
159
161
  onMouseEnter?: (event: MouseEvent) => void,
160
162
  onMouseLeave?: (event: MouseEvent) => void,
163
+ onPointerEnter2?: (event: PointerEvent) => void,
164
+ onPointerLeave2?: (event: PointerEvent) => void,
161
165
  onResponderGrant: (event: PressEvent) => void,
162
166
  onResponderMove: (event: PressEvent) => void,
163
167
  onResponderRelease: (event: PressEvent) => void,
@@ -549,58 +553,108 @@ export default class Pressability {
549
553
  () => this._config;
550
554
  }
551
555
 
552
- const mouseEventHandlers =
553
- Platform.OS === 'ios' || Platform.OS === 'android'
554
- ? null
555
- : {
556
- onMouseEnter: (event: MouseEvent): void => {
557
- if (isHoverEnabled()) {
558
- this._isHovered = true;
559
- this._cancelHoverOutDelayTimeout();
560
- const {onHoverIn} = this._config;
561
- if (onHoverIn != null) {
562
- const delayHoverIn = normalizeDelay(
563
- this._config.delayHoverIn,
564
- );
565
- if (delayHoverIn > 0) {
566
- event.persist();
567
- this._hoverInDelayTimeout = setTimeout(() => {
556
+ if (
557
+ ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover()
558
+ ) {
559
+ const hoverPointerEvents = {
560
+ onPointerEnter2: undefined,
561
+ onPointerLeave2: undefined,
562
+ };
563
+ const {onHoverIn, onHoverOut} = this._config;
564
+ if (onHoverIn != null) {
565
+ hoverPointerEvents.onPointerEnter2 = (event: PointerEvent) => {
566
+ this._isHovered = true;
567
+ this._cancelHoverOutDelayTimeout();
568
+ if (onHoverIn != null) {
569
+ const delayHoverIn = normalizeDelay(this._config.delayHoverIn);
570
+ if (delayHoverIn > 0) {
571
+ event.persist();
572
+ this._hoverInDelayTimeout = setTimeout(() => {
573
+ onHoverIn(convertPointerEventToMouseEvent(event));
574
+ }, delayHoverIn);
575
+ } else {
576
+ onHoverIn(convertPointerEventToMouseEvent(event));
577
+ }
578
+ }
579
+ };
580
+ }
581
+ if (onHoverOut != null) {
582
+ hoverPointerEvents.onPointerLeave2 = (event: PointerEvent) => {
583
+ if (this._isHovered) {
584
+ this._isHovered = false;
585
+ this._cancelHoverInDelayTimeout();
586
+ if (onHoverOut != null) {
587
+ const delayHoverOut = normalizeDelay(this._config.delayHoverOut);
588
+ if (delayHoverOut > 0) {
589
+ event.persist();
590
+ this._hoverOutDelayTimeout = setTimeout(() => {
591
+ onHoverOut(convertPointerEventToMouseEvent(event));
592
+ }, delayHoverOut);
593
+ } else {
594
+ onHoverOut(convertPointerEventToMouseEvent(event));
595
+ }
596
+ }
597
+ }
598
+ };
599
+ }
600
+ return {
601
+ ...focusEventHandlers,
602
+ ...responderEventHandlers,
603
+ ...hoverPointerEvents,
604
+ };
605
+ } else {
606
+ const mouseEventHandlers =
607
+ Platform.OS === 'ios' || Platform.OS === 'android'
608
+ ? null
609
+ : {
610
+ onMouseEnter: (event: MouseEvent): void => {
611
+ if (isHoverEnabled()) {
612
+ this._isHovered = true;
613
+ this._cancelHoverOutDelayTimeout();
614
+ const {onHoverIn} = this._config;
615
+ if (onHoverIn != null) {
616
+ const delayHoverIn = normalizeDelay(
617
+ this._config.delayHoverIn,
618
+ );
619
+ if (delayHoverIn > 0) {
620
+ event.persist();
621
+ this._hoverInDelayTimeout = setTimeout(() => {
622
+ onHoverIn(event);
623
+ }, delayHoverIn);
624
+ } else {
568
625
  onHoverIn(event);
569
- }, delayHoverIn);
570
- } else {
571
- onHoverIn(event);
626
+ }
572
627
  }
573
628
  }
574
- }
575
- },
576
-
577
- onMouseLeave: (event: MouseEvent): void => {
578
- if (this._isHovered) {
579
- this._isHovered = false;
580
- this._cancelHoverInDelayTimeout();
581
- const {onHoverOut} = this._config;
582
- if (onHoverOut != null) {
583
- const delayHoverOut = normalizeDelay(
584
- this._config.delayHoverOut,
585
- );
586
- if (delayHoverOut > 0) {
587
- event.persist();
588
- this._hoverInDelayTimeout = setTimeout(() => {
629
+ },
630
+
631
+ onMouseLeave: (event: MouseEvent): void => {
632
+ if (this._isHovered) {
633
+ this._isHovered = false;
634
+ this._cancelHoverInDelayTimeout();
635
+ const {onHoverOut} = this._config;
636
+ if (onHoverOut != null) {
637
+ const delayHoverOut = normalizeDelay(
638
+ this._config.delayHoverOut,
639
+ );
640
+ if (delayHoverOut > 0) {
641
+ event.persist();
642
+ this._hoverInDelayTimeout = setTimeout(() => {
643
+ onHoverOut(event);
644
+ }, delayHoverOut);
645
+ } else {
589
646
  onHoverOut(event);
590
- }, delayHoverOut);
591
- } else {
592
- onHoverOut(event);
647
+ }
593
648
  }
594
649
  }
595
- }
596
- },
597
- };
598
-
599
- return {
600
- ...focusEventHandlers,
601
- ...responderEventHandlers,
602
- ...mouseEventHandlers,
603
- };
650
+ },
651
+ };
652
+ return {
653
+ ...focusEventHandlers,
654
+ ...responderEventHandlers,
655
+ ...mouseEventHandlers,
656
+ };
657
+ }
604
658
  }
605
659
 
606
660
  /**
@@ -879,3 +933,18 @@ const getTouchFromPressEvent = (event: PressEvent) => {
879
933
  }
880
934
  return event.nativeEvent;
881
935
  };
936
+
937
+ function convertPointerEventToMouseEvent(input: PointerEvent): MouseEvent {
938
+ const {touchHistory: _, ...synthEvent} = input;
939
+ const {clientX, clientY, timestamp} = input.nativeEvent;
940
+ return {
941
+ ...synthEvent,
942
+ nativeEvent: {
943
+ clientX,
944
+ clientY,
945
+ pageX: clientX,
946
+ pageY: clientY,
947
+ timestamp,
948
+ },
949
+ };
950
+ }
@@ -25,6 +25,8 @@ import Platform from '../Utilities/Platform';
25
25
  import {isHoverEnabled} from './HoverState';
26
26
  import PressabilityPerformanceEventEmitter from './PressabilityPerformanceEventEmitter.js';
27
27
  import {type PressabilityTouchSignal as TouchSignal} from './PressabilityTypes.js';
28
+ import ReactNativeFeatureFlags from '../ReactNative/ReactNativeFeatureFlags';
29
+ import {type PointerEvent} from '../Types/CoreEventTypes';
28
30
 
29
31
  export type PressabilityConfig = $ReadOnly<{|
30
32
  /**
@@ -185,6 +187,8 @@ export type EventHandlers = $ReadOnly<{|
185
187
  onFocus: (event: FocusEvent) => void,
186
188
  onMouseEnter?: (event: MouseEvent) => void,
187
189
  onMouseLeave?: (event: MouseEvent) => void,
190
+ onPointerEnter2?: (event: PointerEvent) => void,
191
+ onPointerLeave2?: (event: PointerEvent) => void,
188
192
  onResponderGrant: (event: PressEvent) => void,
189
193
  onResponderMove: (event: PressEvent) => void,
190
194
  onResponderRelease: (event: PressEvent) => void,
@@ -282,20 +286,20 @@ const Transitions = Object.freeze({
282
286
  },
283
287
  });
284
288
 
285
- const isActiveSignal = (signal) =>
289
+ const isActiveSignal = signal =>
286
290
  signal === 'RESPONDER_ACTIVE_PRESS_IN' ||
287
291
  signal === 'RESPONDER_ACTIVE_LONG_PRESS_IN';
288
292
 
289
- const isActivationSignal = (signal) =>
293
+ const isActivationSignal = signal =>
290
294
  signal === 'RESPONDER_ACTIVE_PRESS_OUT' ||
291
295
  signal === 'RESPONDER_ACTIVE_PRESS_IN';
292
296
 
293
- const isPressInSignal = (signal) =>
297
+ const isPressInSignal = signal =>
294
298
  signal === 'RESPONDER_INACTIVE_PRESS_IN' ||
295
299
  signal === 'RESPONDER_ACTIVE_PRESS_IN' ||
296
300
  signal === 'RESPONDER_ACTIVE_LONG_PRESS_IN';
297
301
 
298
- const isTerminalSignal = (signal) =>
302
+ const isTerminalSignal = signal =>
299
303
  signal === 'RESPONDER_TERMINATED' || signal === 'RESPONDER_RELEASE';
300
304
 
301
305
  const DEFAULT_LONG_PRESS_DELAY_MS = 500;
@@ -580,65 +584,6 @@ export default class Pressability {
580
584
  () => this._config;
581
585
  }
582
586
 
583
- const mouseEventHandlers =
584
- Platform.OS === 'ios' || Platform.OS === 'android'
585
- ? null
586
- : {
587
- onMouseEnter: (event: MouseEvent): void => {
588
- // [Windows Add attached raw mouse event handler for compat
589
- if (this._config.onMouseEnter) {
590
- this._config.onMouseEnter(event);
591
- }
592
- // Windows]
593
-
594
- if (isHoverEnabled()) {
595
- this._isHovered = true;
596
- this._cancelHoverOutDelayTimeout();
597
- const {onHoverIn} = this._config;
598
- if (onHoverIn != null) {
599
- const delayHoverIn = normalizeDelay(
600
- this._config.delayHoverIn,
601
- );
602
- if (delayHoverIn > 0) {
603
- event.persist();
604
- this._hoverInDelayTimeout = setTimeout(() => {
605
- onHoverIn(event);
606
- }, delayHoverIn);
607
- } else {
608
- onHoverIn(event);
609
- }
610
- }
611
- }
612
- },
613
-
614
- onMouseLeave: (event: MouseEvent): void => {
615
- // [Windows Add attached raw mouse event handler for compat
616
- if (this._config.onMouseLeave) {
617
- this._config.onMouseLeave(event);
618
- }
619
- // Windows]
620
-
621
- if (this._isHovered) {
622
- this._isHovered = false;
623
- this._cancelHoverInDelayTimeout();
624
- const {onHoverOut} = this._config;
625
- if (onHoverOut != null) {
626
- const delayHoverOut = normalizeDelay(
627
- this._config.delayHoverOut,
628
- );
629
- if (delayHoverOut > 0) {
630
- event.persist();
631
- this._hoverInDelayTimeout = setTimeout(() => {
632
- onHoverOut(event);
633
- }, delayHoverOut);
634
- } else {
635
- onHoverOut(event);
636
- }
637
- }
638
- }
639
- },
640
- };
641
-
642
587
  // [Windows
643
588
  const keyboardEventHandlers = {
644
589
  onKeyUp: (event: KeyEvent): void => {
@@ -676,12 +621,123 @@ export default class Pressability {
676
621
  };
677
622
  // Windows]
678
623
 
679
- return {
680
- ...focusEventHandlers,
681
- ...responderEventHandlers,
682
- ...mouseEventHandlers,
683
- ...keyboardEventHandlers, // [Windows]
684
- };
624
+ if (
625
+ ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover()
626
+ ) {
627
+ const hoverPointerEvents = {
628
+ onPointerEnter2: undefined,
629
+ onPointerLeave2: undefined,
630
+ };
631
+ const {onHoverIn, onHoverOut} = this._config;
632
+ if (onHoverIn != null) {
633
+ hoverPointerEvents.onPointerEnter2 = (event: PointerEvent) => {
634
+ this._isHovered = true;
635
+ this._cancelHoverOutDelayTimeout();
636
+ if (onHoverIn != null) {
637
+ const delayHoverIn = normalizeDelay(this._config.delayHoverIn);
638
+ if (delayHoverIn > 0) {
639
+ event.persist();
640
+ this._hoverInDelayTimeout = setTimeout(() => {
641
+ onHoverIn(convertPointerEventToMouseEvent(event));
642
+ }, delayHoverIn);
643
+ } else {
644
+ onHoverIn(convertPointerEventToMouseEvent(event));
645
+ }
646
+ }
647
+ };
648
+ }
649
+ if (onHoverOut != null) {
650
+ hoverPointerEvents.onPointerLeave2 = (event: PointerEvent) => {
651
+ if (this._isHovered) {
652
+ this._isHovered = false;
653
+ this._cancelHoverInDelayTimeout();
654
+ if (onHoverOut != null) {
655
+ const delayHoverOut = normalizeDelay(this._config.delayHoverOut);
656
+ if (delayHoverOut > 0) {
657
+ event.persist();
658
+ this._hoverOutDelayTimeout = setTimeout(() => {
659
+ onHoverOut(convertPointerEventToMouseEvent(event));
660
+ }, delayHoverOut);
661
+ } else {
662
+ onHoverOut(convertPointerEventToMouseEvent(event));
663
+ }
664
+ }
665
+ }
666
+ };
667
+ }
668
+ return {
669
+ ...focusEventHandlers,
670
+ ...responderEventHandlers,
671
+ ...hoverPointerEvents,
672
+ ...keyboardEventHandlers, // [Windows]
673
+ };
674
+ } else {
675
+ const mouseEventHandlers =
676
+ Platform.OS === 'ios' || Platform.OS === 'android'
677
+ ? null
678
+ : {
679
+ onMouseEnter: (event: MouseEvent): void => {
680
+ // [Windows Add attached raw mouse event handler for compat
681
+ if (this._config.onMouseEnter) {
682
+ this._config.onMouseEnter(event);
683
+ }
684
+ // Windows]
685
+
686
+ if (isHoverEnabled()) {
687
+ this._isHovered = true;
688
+ this._cancelHoverOutDelayTimeout();
689
+ const {onHoverIn} = this._config;
690
+ if (onHoverIn != null) {
691
+ const delayHoverIn = normalizeDelay(
692
+ this._config.delayHoverIn,
693
+ );
694
+ if (delayHoverIn > 0) {
695
+ event.persist();
696
+ this._hoverInDelayTimeout = setTimeout(() => {
697
+ onHoverIn(event);
698
+ }, delayHoverIn);
699
+ } else {
700
+ onHoverIn(event);
701
+ }
702
+ }
703
+ }
704
+ },
705
+
706
+ onMouseLeave: (event: MouseEvent): void => {
707
+ // [Windows Add attached raw mouse event handler for compat
708
+ if (this._config.onMouseLeave) {
709
+ this._config.onMouseLeave(event);
710
+ }
711
+ // Windows]
712
+
713
+ if (this._isHovered) {
714
+ this._isHovered = false;
715
+ this._cancelHoverInDelayTimeout();
716
+ const {onHoverOut} = this._config;
717
+ if (onHoverOut != null) {
718
+ const delayHoverOut = normalizeDelay(
719
+ this._config.delayHoverOut,
720
+ );
721
+ if (delayHoverOut > 0) {
722
+ event.persist();
723
+ this._hoverInDelayTimeout = setTimeout(() => {
724
+ onHoverOut(event);
725
+ }, delayHoverOut);
726
+ } else {
727
+ onHoverOut(event);
728
+ }
729
+ }
730
+ }
731
+ },
732
+ };
733
+
734
+ return {
735
+ ...focusEventHandlers,
736
+ ...responderEventHandlers,
737
+ ...mouseEventHandlers,
738
+ ...keyboardEventHandlers, // [Windows]
739
+ };
740
+ }
685
741
  }
686
742
 
687
743
  /**
@@ -960,3 +1016,52 @@ const getTouchFromPressEvent = (event: PressEvent) => {
960
1016
  }
961
1017
  return event.nativeEvent;
962
1018
  };
1019
+
1020
+ function convertPointerEventToMouseEvent(input: PointerEvent): MouseEvent {
1021
+ const {touchHistory: _, ...synthEvent} = input;
1022
+ const {clientX, clientY, timestamp} = input.nativeEvent;
1023
+ // [Windows
1024
+ const {
1025
+ pointerType,
1026
+ pressure,
1027
+ isLeftButton,
1028
+ isRightButton,
1029
+ isMiddleButton,
1030
+ isBarrelButtonPressed,
1031
+ isHorizontalScrollWheel,
1032
+ isEraser,
1033
+ shiftKey,
1034
+ ctrlKey,
1035
+ altKey,
1036
+ } = input.nativeEvent;
1037
+ // Windows]
1038
+ return {
1039
+ ...synthEvent,
1040
+ nativeEvent: {
1041
+ clientX,
1042
+ clientY,
1043
+ pageX: clientX,
1044
+ pageY: clientY,
1045
+ timestamp,
1046
+ // [Windows
1047
+ target:
1048
+ input.nativeEvent.target ??
1049
+ (typeof input.target === 'number' ? input.target : -1),
1050
+ identifier: input.nativeEvent.pointerId,
1051
+ locationX: clientX,
1052
+ locationY: clientY,
1053
+ pointerType,
1054
+ force: pressure,
1055
+ isLeftButton,
1056
+ isRightButton,
1057
+ isMiddleButton,
1058
+ isBarrelButtonPressed,
1059
+ isHorizontalScrollWheel,
1060
+ isEraser,
1061
+ shiftKey,
1062
+ ctrlKey,
1063
+ altKey,
1064
+ // Windows]
1065
+ },
1066
+ };
1067
+ }