react-native-windows 0.0.0-canary.510 → 0.0.0-canary.511

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 (39) hide show
  1. package/.flowconfig +3 -1
  2. package/Libraries/Animated/NativeAnimatedHelper.js +212 -93
  3. package/Libraries/Animated/NativeAnimatedModule.js +3 -0
  4. package/Libraries/Animated/NativeAnimatedTurboModule.js +3 -0
  5. package/Libraries/Animated/nodes/AnimatedColor.js +49 -28
  6. package/Libraries/Animated/nodes/AnimatedProps.js +1 -5
  7. package/Libraries/Animated/nodes/AnimatedStyle.js +1 -5
  8. package/Libraries/Animated/nodes/AnimatedValue.js +11 -4
  9. package/Libraries/Animated/nodes/AnimatedValueXY.js +27 -0
  10. package/Libraries/Animated/useAnimatedProps.js +1 -0
  11. package/Libraries/BatchedBridge/MessageQueue.js +16 -9
  12. package/Libraries/Blob/FileReader.js +0 -6
  13. package/Libraries/Components/ScrollView/ScrollView.js +2 -2
  14. package/Libraries/Components/TextInput/TextInput.js +1 -1
  15. package/Libraries/Components/TextInput/TextInput.windows.js +1 -1
  16. package/Libraries/Core/ReactNativeVersion.js +1 -1
  17. package/Libraries/Lists/VirtualizeUtils.js +27 -18
  18. package/Libraries/Lists/VirtualizedList.js +3 -2
  19. package/Libraries/Lists/__tests__/VirtualizeUtils-test.js +14 -13
  20. package/Libraries/LogBox/UI/LogBoxInspectorCodeFrame.js +3 -0
  21. package/Libraries/Performance/PureComponentDebug.js +1 -0
  22. package/Libraries/PermissionsAndroid/NativePermissionsAndroid.js +7 -1
  23. package/Libraries/PermissionsAndroid/PermissionsAndroid.js +12 -0
  24. package/Libraries/Pressability/Pressability.js +3 -4
  25. package/Libraries/Pressability/Pressability.windows.js +3 -4
  26. package/Libraries/ReactNative/ReactNativeFeatureFlags.js +12 -0
  27. package/Libraries/StyleSheet/splitLayoutProps.js +2 -0
  28. package/Libraries/Types/CoreEventTypes.js +128 -11
  29. package/Libraries/Types/CoreEventTypes.windows.js +138 -22
  30. package/Libraries/Utilities/codegenNativeCommands.js +10 -1
  31. package/Microsoft.ReactNative.Managed/packages.lock.json +4 -4
  32. package/PropertySheets/Generated/PackageVersion.g.props +1 -1
  33. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/RectangleEdges.h +100 -0
  34. package/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/YGValue.h +94 -0
  35. package/Shared/OInstance.cpp +15 -11
  36. package/codegen/NativeAnimatedModuleSpec.g.h +6 -0
  37. package/codegen/NativeAnimatedTurboModuleSpec.g.h +6 -0
  38. package/package.json +8 -8
  39. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +0 -87
@@ -10,11 +10,16 @@
10
10
 
11
11
  'use strict';
12
12
 
13
+ import type {PlatformConfig} from '../AnimatedPlatformConfig';
14
+
13
15
  const AnimatedValue = require('./AnimatedValue');
14
16
  const AnimatedWithChildren = require('./AnimatedWithChildren');
15
17
 
16
18
  const invariant = require('invariant');
17
19
 
20
+ export type AnimatedValueXYConfig = $ReadOnly<{
21
+ useNativeDriver: boolean,
22
+ }>;
18
23
  type ValueXYListenerCallback = (value: {
19
24
  x: number,
20
25
  y: number,
@@ -47,6 +52,7 @@ class AnimatedValueXY extends AnimatedWithChildren {
47
52
  +y: number | AnimatedValue,
48
53
  ...
49
54
  },
55
+ config?: ?AnimatedValueXYConfig,
50
56
  ) {
51
57
  super();
52
58
  const value: any = valueIn || {x: 0, y: 0}; // @flowfixme: shouldn't need `: any`
@@ -63,6 +69,9 @@ class AnimatedValueXY extends AnimatedWithChildren {
63
69
  this.y = value.y;
64
70
  }
65
71
  this._listeners = {};
72
+ if (config && config.useNativeDriver) {
73
+ this.__makeNative();
74
+ }
66
75
  }
67
76
 
68
77
  /**
@@ -221,6 +230,24 @@ class AnimatedValueXY extends AnimatedWithChildren {
221
230
  getTranslateTransform(): Array<{[key: string]: AnimatedValue, ...}> {
222
231
  return [{translateX: this.x}, {translateY: this.y}];
223
232
  }
233
+
234
+ __attach(): void {
235
+ this.x.__addChild(this);
236
+ this.y.__addChild(this);
237
+ super.__attach();
238
+ }
239
+
240
+ __detach(): void {
241
+ this.x.__removeChild(this);
242
+ this.y.__removeChild(this);
243
+ super.__detach();
244
+ }
245
+
246
+ __makeNative(platformConfig: ?PlatformConfig) {
247
+ this.x.__makeNative(platformConfig);
248
+ this.y.__makeNative(platformConfig);
249
+ super.__makeNative(platformConfig);
250
+ }
224
251
  }
225
252
 
226
253
  module.exports = AnimatedValueXY;
@@ -82,6 +82,7 @@ export default function useAnimatedProps<TProps: {...}, TInstance>(
82
82
  scheduleUpdate();
83
83
  } else if (!node.__isNative) {
84
84
  // $FlowIgnore[not-a-function] - Assume it's still a function.
85
+ // $FlowFixMe[incompatible-use]
85
86
  instance.setNativeProps(node.__getAnimatedValue());
86
87
  } else {
87
88
  throw new Error(
@@ -404,15 +404,22 @@ class MessageQueue {
404
404
  this.__spy({type: TO_JS, module, method, args});
405
405
  }
406
406
  const moduleMethods = this.getCallableModule(module);
407
- invariant(
408
- !!moduleMethods,
409
- `Module ${module} is not a registered callable module (calling ${method}). A frequent cause of the error is that the application entry file path is incorrect.
410
- This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.`,
411
- );
412
- invariant(
413
- !!moduleMethods[method],
414
- `Method ${method} does not exist on module ${module}`,
415
- );
407
+ if (!moduleMethods) {
408
+ const callableModuleNames = Object.keys(this._lazyCallableModules);
409
+ const n = callableModuleNames.length;
410
+ const callableModuleNameList = callableModuleNames.join(', ');
411
+ invariant(
412
+ false,
413
+ `Failed to call into JavaScript module method ${module}.${method}(). Module has not been registered as callable. Registered callable JavaScript modules (n = ${n}): ${callableModuleNameList}.
414
+ A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.`,
415
+ );
416
+ }
417
+ if (!moduleMethods[method]) {
418
+ invariant(
419
+ false,
420
+ `Failed to call into JavaScript module method ${module}.${method}(). Module exists, but the method is undefined.`,
421
+ );
422
+ }
416
423
  moduleMethods[method].apply(moduleMethods, args);
417
424
  Systrace.endEvent();
418
425
  }
@@ -46,7 +46,6 @@ class FileReader extends (EventTarget(...READER_EVENTS): any) {
46
46
  _error: ?Error;
47
47
  _result: ?ReaderResult;
48
48
  _aborted: boolean = false;
49
- _subscriptions: Array<any> = [];
50
49
 
51
50
  constructor() {
52
51
  super();
@@ -59,11 +58,6 @@ class FileReader extends (EventTarget(...READER_EVENTS): any) {
59
58
  this._result = null;
60
59
  }
61
60
 
62
- _clearSubscriptions(): void {
63
- this._subscriptions.forEach(sub => sub.remove());
64
- this._subscriptions = [];
65
- }
66
-
67
61
  _setReadyState(newState: ReadyState) {
68
62
  this._readyState = newState;
69
63
  this.dispatchEvent({type: 'readystatechange'});
@@ -173,8 +173,8 @@ type IOSProps = $ReadOnly<{|
173
173
  */
174
174
  automaticallyAdjustContentInsets?: ?boolean,
175
175
  /**
176
- * Controls whether the ScrollView should automatically adjust it's contentInset
177
- * and scrollViewInsets when the Keyboard changes it's size. The default value is false.
176
+ * Controls whether the ScrollView should automatically adjust its `contentInset`
177
+ * and `scrollViewInsets` when the Keyboard changes its size. The default value is false.
178
178
  * @platform ios
179
179
  */
180
180
  automaticallyAdjustKeyboardInsets?: ?boolean,
@@ -1233,7 +1233,7 @@ function InternalTextInput(props: Props): React.Node {
1233
1233
 
1234
1234
  const style =
1235
1235
  props.multiline === true
1236
- ? [styles.multilineInput, props.style]
1236
+ ? StyleSheet.flatten([styles.multilineInput, props.style])
1237
1237
  : props.style;
1238
1238
 
1239
1239
  const useOnChangeSync =
@@ -1324,7 +1324,7 @@ function InternalTextInput(props: Props): React.Node {
1324
1324
 
1325
1325
  const style =
1326
1326
  props.multiline === true
1327
- ? [styles.multilineInput, props.style]
1327
+ ? StyleSheet.flatten([styles.multilineInput, props.style])
1328
1328
  : props.style;
1329
1329
 
1330
1330
  const useOnChangeSync =
@@ -13,5 +13,5 @@ exports.version = {
13
13
  major: 0,
14
14
  minor: 0,
15
15
  patch: 0,
16
- prerelease: '20220516-2016-4994b8b5d',
16
+ prerelease: '20220603-2051-11141b8b3',
17
17
  };
@@ -27,27 +27,36 @@ export function elementsThatOverlapOffsets(
27
27
  },
28
28
  zoomScale: number = 1,
29
29
  ): Array<number> {
30
- const out = [];
31
- let outLength = 0;
32
- for (let ii = 0; ii < itemCount; ii++) {
33
- const frame = getFrameMetrics(ii);
34
- const trailingOffset = (frame.offset + frame.length) * zoomScale;
35
- for (let kk = 0; kk < offsets.length; kk++) {
36
- if (out[kk] == null && trailingOffset >= offsets[kk]) {
37
- out[kk] = ii;
38
- outLength++;
39
- if (kk === offsets.length - 1) {
40
- invariant(
41
- outLength === offsets.length,
42
- 'bad offsets input, should be in increasing order: %s',
43
- JSON.stringify(offsets),
44
- );
45
- return out;
46
- }
30
+ const result = [];
31
+ for (let offsetIndex = 0; offsetIndex < offsets.length; offsetIndex++) {
32
+ const currentOffset = offsets[offsetIndex];
33
+ let left = 0;
34
+ let right = itemCount - 1;
35
+
36
+ while (left <= right) {
37
+ // eslint-disable-next-line no-bitwise
38
+ const mid = left + ((right - left) >>> 1);
39
+ const frame = getFrameMetrics(mid);
40
+ const scaledOffsetStart = frame.offset * zoomScale;
41
+ const scaledOffsetEnd = (frame.offset + frame.length) * zoomScale;
42
+
43
+ // We want the first frame that contains the offset, with inclusive bounds. Thus, for the
44
+ // first frame the scaledOffsetStart is inclusive, while for other frames it is exclusive.
45
+ if (
46
+ (mid === 0 && currentOffset < scaledOffsetStart) ||
47
+ (mid !== 0 && currentOffset <= scaledOffsetStart)
48
+ ) {
49
+ right = mid - 1;
50
+ } else if (currentOffset > scaledOffsetEnd) {
51
+ left = mid + 1;
52
+ } else {
53
+ result[offsetIndex] = mid;
54
+ break;
47
55
  }
48
56
  }
49
57
  }
50
- return out;
58
+
59
+ return result;
51
60
  }
52
61
 
53
62
  /**
@@ -1269,6 +1269,7 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1269
1269
  refreshControl={
1270
1270
  props.refreshControl == null ? (
1271
1271
  <RefreshControl
1272
+ // $FlowFixMe[incompatible-type]
1272
1273
  refreshing={props.refreshing}
1273
1274
  onRefresh={onRefresh}
1274
1275
  progressViewOffset={props.progressViewOffset}
@@ -1627,8 +1628,8 @@ class VirtualizedList extends React.PureComponent<Props, State> {
1627
1628
  this._hasWarned.perf = true;
1628
1629
  }
1629
1630
 
1630
- const zoomScale = e.nativeEvent.zoomScale;
1631
-
1631
+ // For invalid negative values (w/ RTL), set this to 1.
1632
+ const zoomScale = e.nativeEvent.zoomScale < 0 ? 1 : e.nativeEvent.zoomScale;
1632
1633
  this._scrollMetrics = {
1633
1634
  contentLength,
1634
1635
  dt,
@@ -65,8 +65,20 @@ describe('elementsThatOverlapOffsets', function () {
65
65
  elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1),
66
66
  ).toEqual([1, 1, 3]);
67
67
  });
68
+ it('handles frame boundaries', function () {
69
+ const offsets = [0, 100, 200, 300];
70
+ function getFrameMetrics(index: number) {
71
+ return {
72
+ length: 100,
73
+ offset: 100 * index,
74
+ };
75
+ }
76
+ expect(
77
+ elementsThatOverlapOffsets(offsets, 100, getFrameMetrics, 1),
78
+ ).toEqual([0, 0, 1, 2]);
79
+ });
68
80
  it('handles out of bounds', function () {
69
- const offsets = [150, 900];
81
+ const offsets = [-100, 150, 900];
70
82
  const frames = [
71
83
  {offset: 0, length: 50},
72
84
  {offset: 50, length: 150},
@@ -74,17 +86,6 @@ describe('elementsThatOverlapOffsets', function () {
74
86
  ];
75
87
  expect(
76
88
  elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1),
77
- ).toEqual([1]);
78
- });
79
- it('errors on non-increasing offsets', function () {
80
- const offsets = [150, 50];
81
- const frames = [
82
- {offset: 0, length: 50},
83
- {offset: 50, length: 150},
84
- {offset: 250, length: 100},
85
- ];
86
- expect(() => {
87
- elementsThatOverlapOffsets(offsets, frames.length, ii => frames[ii], 1);
88
- }).toThrowErrorMatchingSnapshot();
89
+ ).toEqual([undefined, 1]);
89
90
  });
90
91
  });
@@ -32,15 +32,18 @@ function LogBoxInspectorCodeFrame(props: Props): React.Node {
32
32
  }
33
33
 
34
34
  function getFileName() {
35
+ // $FlowFixMe[incompatible-use]
35
36
  const matches = /[^/]*$/.exec(codeFrame.fileName);
36
37
  if (matches && matches.length > 0) {
37
38
  return matches[0];
38
39
  }
39
40
 
41
+ // $FlowFixMe[incompatible-use]
40
42
  return codeFrame.fileName;
41
43
  }
42
44
 
43
45
  function getLocation() {
46
+ // $FlowFixMe[incompatible-use]
44
47
  const location = codeFrame.location;
45
48
  if (location != null) {
46
49
  return ` (${location.row}:${
@@ -61,6 +61,7 @@ class PureComponentDebug<
61
61
  }
62
62
  }
63
63
  for (const key in this.state) {
64
+ // $FlowFixMe[incompatible-use]
64
65
  if (this.state[key] !== (nextState || {})[key]) {
65
66
  ret = true;
66
67
  console.warn('PureComponentDebug: different state values', tag, key);
@@ -35,12 +35,16 @@ export type PermissionType =
35
35
  | 'android.permission.USE_SIP'
36
36
  | 'android.permission.PROCESS_OUTGOING_CALLS'
37
37
  | 'android.permission.BODY_SENSORS'
38
+ | 'android.permission.BODY_SENSORS_BACKGROUND'
38
39
  | 'android.permission.SEND_SMS'
39
40
  | 'android.permission.RECEIVE_SMS'
40
41
  | 'android.permission.READ_SMS'
41
42
  | 'android.permission.RECEIVE_WAP_PUSH'
42
43
  | 'android.permission.RECEIVE_MMS'
43
44
  | 'android.permission.READ_EXTERNAL_STORAGE'
45
+ | 'android.permission.READ_MEDIA_IMAGES',
46
+ | 'android.permission.READ_MEDIA_VIDEO',
47
+ | 'android.permission.READ_MEDIA_AUDIO',
44
48
  | 'android.permission.WRITE_EXTERNAL_STORAGE'
45
49
  | 'android.permission.BLUETOOTH_CONNECT'
46
50
  | 'android.permission.BLUETOOTH_SCAN'
@@ -50,7 +54,9 @@ export type PermissionType =
50
54
  | 'android.permission.ACTIVITY_RECOGNITION'
51
55
  | 'android.permission.ANSWER_PHONE_CALLS'
52
56
  | 'android.permission.READ_PHONE_NUMBERS'
53
- | 'android.permission.UWB_RANGING';
57
+ | 'android.permission.UWB_RANGING'
58
+ | 'android.permission.POST_NOTIFICATIONS'
59
+ | 'android.permission.NEARBY_WIFI_DEVICES';
54
60
  */
55
61
 
56
62
  export interface Spec extends TurboModule {
@@ -52,12 +52,16 @@ const PERMISSIONS = Object.freeze({
52
52
  USE_SIP: 'android.permission.USE_SIP',
53
53
  PROCESS_OUTGOING_CALLS: 'android.permission.PROCESS_OUTGOING_CALLS',
54
54
  BODY_SENSORS: 'android.permission.BODY_SENSORS',
55
+ BODY_SENSORS_BACKGROUND: 'android.permission.BODY_SENSORS_BACKGROUND',
55
56
  SEND_SMS: 'android.permission.SEND_SMS',
56
57
  RECEIVE_SMS: 'android.permission.RECEIVE_SMS',
57
58
  READ_SMS: 'android.permission.READ_SMS',
58
59
  RECEIVE_WAP_PUSH: 'android.permission.RECEIVE_WAP_PUSH',
59
60
  RECEIVE_MMS: 'android.permission.RECEIVE_MMS',
60
61
  READ_EXTERNAL_STORAGE: 'android.permission.READ_EXTERNAL_STORAGE',
62
+ READ_MEDIA_IMAGES: 'android.permission.READ_MEDIA_IMAGES',
63
+ READ_MEDIA_VIDEO: 'android.permission.READ_MEDIA_VIDEO',
64
+ READ_MEDIA_AUDIO: 'android.permission.READ_MEDIA_AUDIO',
61
65
  WRITE_EXTERNAL_STORAGE: 'android.permission.WRITE_EXTERNAL_STORAGE',
62
66
  BLUETOOTH_CONNECT: 'android.permission.BLUETOOTH_CONNECT',
63
67
  BLUETOOTH_SCAN: 'android.permission.BLUETOOTH_SCAN',
@@ -68,6 +72,8 @@ const PERMISSIONS = Object.freeze({
68
72
  ANSWER_PHONE_CALLS: 'android.permission.ANSWER_PHONE_CALLS',
69
73
  READ_PHONE_NUMBERS: 'android.permission.READ_PHONE_NUMBERS',
70
74
  UWB_RANGING: 'android.permission.UWB_RANGING',
75
+ POST_NOTIFICATION: 'android.permission.POST_NOTIFICATIONS',
76
+ NEARBY_WIFI_DEVICES: 'android.permission.NEARBY_WIFI_DEVICES',
71
77
  });
72
78
 
73
79
  /**
@@ -90,14 +96,20 @@ class PermissionsAndroid {
90
96
  BLUETOOTH_CONNECT: string,
91
97
  BLUETOOTH_SCAN: string,
92
98
  BODY_SENSORS: string,
99
+ BODY_SENSORS_BACKGROUND: string,
93
100
  CALL_PHONE: string,
94
101
  CAMERA: string,
95
102
  GET_ACCOUNTS: string,
103
+ NEARBY_WIFI_DEVICES: string,
104
+ POST_NOTIFICATION: string,
96
105
  PROCESS_OUTGOING_CALLS: string,
97
106
  READ_CALENDAR: string,
98
107
  READ_CALL_LOG: string,
99
108
  READ_CONTACTS: string,
100
109
  READ_EXTERNAL_STORAGE: string,
110
+ READ_MEDIA_IMAGES: string,
111
+ READ_MEDIA_VIDEO: string,
112
+ READ_MEDIA_AUDIO: string,
101
113
  READ_PHONE_NUMBERS: string,
102
114
  READ_PHONE_STATE: string,
103
115
  READ_SMS: string,
@@ -935,16 +935,15 @@ const getTouchFromPressEvent = (event: PressEvent) => {
935
935
  };
936
936
 
937
937
  function convertPointerEventToMouseEvent(input: PointerEvent): MouseEvent {
938
- const {touchHistory: _, ...synthEvent} = input;
939
- const {clientX, clientY, timestamp} = input.nativeEvent;
938
+ const {clientX, clientY} = input.nativeEvent;
940
939
  return {
941
- ...synthEvent,
940
+ ...input,
942
941
  nativeEvent: {
943
942
  clientX,
944
943
  clientY,
945
944
  pageX: clientX,
946
945
  pageY: clientY,
947
- timestamp,
946
+ timestamp: input.timeStamp,
948
947
  },
949
948
  };
950
949
  }
@@ -1029,8 +1029,7 @@ const getTouchFromPressEvent = (event: PressEvent) => {
1029
1029
  };
1030
1030
 
1031
1031
  function convertPointerEventToMouseEvent(input: PointerEvent): MouseEvent {
1032
- const {touchHistory: _, ...synthEvent} = input;
1033
- const {clientX, clientY, timestamp} = input.nativeEvent;
1032
+ const {clientX, clientY} = input.nativeEvent;
1034
1033
  // [Windows
1035
1034
  const {
1036
1035
  pointerType,
@@ -1047,13 +1046,13 @@ function convertPointerEventToMouseEvent(input: PointerEvent): MouseEvent {
1047
1046
  } = input.nativeEvent;
1048
1047
  // Windows]
1049
1048
  return {
1050
- ...synthEvent,
1049
+ ...input,
1051
1050
  nativeEvent: {
1052
1051
  clientX,
1053
1052
  clientY,
1054
1053
  pageX: clientX,
1055
1054
  pageY: clientY,
1056
- timestamp,
1055
+ timestamp: input.timeStamp,
1057
1056
  // [Windows
1058
1057
  target:
1059
1058
  input.nativeEvent.target ??
@@ -28,12 +28,24 @@ export type FeatureFlags = {|
28
28
  * for its hover callbacks
29
29
  */
30
30
  shouldPressibilityUseW3CPointerEventsForHover: () => boolean,
31
+ /**
32
+ * Enables an experimental flush-queue debouncing in Animated.js.
33
+ */
34
+ animatedShouldDebounceQueueFlush: () => boolean,
35
+ /**
36
+ * Enables an experimental mega-operation for Animated.js that replaces
37
+ * many calls to native with a single call into native, to reduce JSI/JNI
38
+ * traffic.
39
+ */
40
+ animatedShouldUseSingleOp: () => boolean,
31
41
  |};
32
42
 
33
43
  const ReactNativeFeatureFlags: FeatureFlags = {
34
44
  isLayoutAnimationEnabled: () => true,
35
45
  shouldEmitW3CPointerEvents: () => false,
36
46
  shouldPressibilityUseW3CPointerEventsForHover: () => false,
47
+ animatedShouldDebounceQueueFlush: () => false,
48
+ animatedShouldUseSingleOp: () => false,
37
49
  };
38
50
 
39
51
  module.exports = ReactNativeFeatureFlags;
@@ -50,10 +50,12 @@ export default function splitLayoutProps(props: ?____ViewStyle_Internal): {
50
50
  case 'top':
51
51
  case 'transform':
52
52
  // $FlowFixMe[cannot-write]
53
+ // $FlowFixMe[incompatible-use]
53
54
  outer[prop] = props[prop];
54
55
  break;
55
56
  default:
56
57
  // $FlowFixMe[cannot-write]
58
+ // $FlowFixMe[incompatible-use]
57
59
  inner[prop] = props[prop];
58
60
  break;
59
61
  }
@@ -83,17 +83,134 @@ export type TextLayoutEvent = SyntheticEvent<
83
83
  |}>,
84
84
  >;
85
85
 
86
- export type PointerEvent = ResponderSyntheticEvent<
87
- $ReadOnly<{|
88
- pointerId: number,
89
- pressure: number,
90
- pointerType: string,
91
- clientX: number,
92
- clientY: number,
93
- target: ?number,
94
- timestamp: number,
95
- |}>,
96
- >;
86
+ /**
87
+ * https://developer.mozilla.org/en-US/docs/Web/API/UIEvent
88
+ */
89
+ export interface NativeUIEvent {
90
+ /**
91
+ * Returns a long with details about the event, depending on the event type.
92
+ */
93
+ +detail: number;
94
+ }
95
+
96
+ /**
97
+ * https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
98
+ */
99
+ export interface NativeMouseEvent extends NativeUIEvent {
100
+ /**
101
+ * The X coordinate of the mouse pointer in global (screen) coordinates.
102
+ */
103
+ +screenX: number;
104
+ /**
105
+ * The Y coordinate of the mouse pointer in global (screen) coordinates.
106
+ */
107
+ +screenY: number;
108
+ /**
109
+ * The X coordinate of the mouse pointer relative to the whole document.
110
+ */
111
+ +pageX: number;
112
+ /**
113
+ * The Y coordinate of the mouse pointer relative to the whole document.
114
+ */
115
+ +pageY: number;
116
+ /**
117
+ * The X coordinate of the mouse pointer in local (DOM content) coordinates.
118
+ */
119
+ +clientX: number;
120
+ /**
121
+ * The Y coordinate of the mouse pointer in local (DOM content) coordinates.
122
+ */
123
+ +clientY: number;
124
+ /**
125
+ * Alias for NativeMouseEvent.clientX
126
+ */
127
+ +x: number;
128
+ /**
129
+ * Alias for NativeMouseEvent.clientY
130
+ */
131
+ +y: number;
132
+ /**
133
+ * Returns true if the control key was down when the mouse event was fired.
134
+ */
135
+ +ctrlKey: boolean;
136
+ /**
137
+ * Returns true if the shift key was down when the mouse event was fired.
138
+ */
139
+ +shiftKey: boolean;
140
+ /**
141
+ * Returns true if the alt key was down when the mouse event was fired.
142
+ */
143
+ +altKey: boolean;
144
+ /**
145
+ * Returns true if the meta key was down when the mouse event was fired.
146
+ */
147
+ +metaKey: boolean;
148
+ /**
149
+ * The button number that was pressed (if applicable) when the mouse event was fired.
150
+ */
151
+ +button: number;
152
+ /**
153
+ * The buttons being depressed (if any) when the mouse event was fired.
154
+ */
155
+ +buttons: number;
156
+ /**
157
+ * The secondary target for the event, if there is one.
158
+ */
159
+ +relatedTarget: null | number | React.ElementRef<HostComponent<mixed>>;
160
+ }
161
+
162
+ /**
163
+ * https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent
164
+ */
165
+ export interface NativePointerEvent extends NativeMouseEvent {
166
+ /**
167
+ * A unique identifier for the pointer causing the event.
168
+ */
169
+ +pointerId: number;
170
+ /**
171
+ * The width (magnitude on the X axis), in CSS pixels, of the contact geometry of the pointer
172
+ */
173
+ +width: number;
174
+ /**
175
+ * The height (magnitude on the Y axis), in CSS pixels, of the contact geometry of the pointer.
176
+ */
177
+ +height: number;
178
+ /**
179
+ * The normalized pressure of the pointer input in the range 0 to 1, where 0 and 1 represent
180
+ * the minimum and maximum pressure the hardware is capable of detecting, respectively.
181
+ */
182
+ +pressure: number;
183
+ /**
184
+ * The normalized tangential pressure of the pointer input (also known as barrel pressure or
185
+ * cylinder stress) in the range -1 to 1, where 0 is the neutral position of the control.
186
+ */
187
+ +tangentialPressure: number;
188
+ /**
189
+ * The plane angle (in degrees, in the range of -90 to 90) between the Y–Z plane and the plane
190
+ * containing both the pointer (e.g. pen stylus) axis and the Y axis.
191
+ */
192
+ +tiltX: number;
193
+ /**
194
+ * The plane angle (in degrees, in the range of -90 to 90) between the X–Z plane and the plane
195
+ * containing both the pointer (e.g. pen stylus) axis and the X axis.
196
+ */
197
+ +tiltY: number;
198
+ /**
199
+ * The clockwise rotation of the pointer (e.g. pen stylus) around its major axis in degrees,
200
+ * with a value in the range 0 to 359.
201
+ */
202
+ +twist: number;
203
+ /**
204
+ * Indicates the device type that caused the event (mouse, pen, touch, etc.)
205
+ */
206
+ +pointerType: string;
207
+ /**
208
+ * Indicates if the pointer represents the primary pointer of this pointer type.
209
+ */
210
+ +isPrimary: boolean;
211
+ }
212
+
213
+ export type PointerEvent = SyntheticEvent<NativePointerEvent>;
97
214
 
98
215
  export type PressEvent = ResponderSyntheticEvent<
99
216
  $ReadOnly<{|