react-native-windows 0.76.7 → 0.76.9

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 (136) hide show
  1. package/Libraries/Components/Button.windows.js +9 -0
  2. package/Libraries/Components/Pressable/Pressable.windows.js +9 -0
  3. package/Libraries/Components/TextInput/TextInput.windows.js +11 -1
  4. package/Libraries/Components/Touchable/TouchableBounce.windows.js +229 -0
  5. package/Libraries/Components/Touchable/TouchableNativeFeedback.windows.js +373 -0
  6. package/Libraries/Components/Touchable/TouchableOpacity.windows.js +7 -0
  7. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +8 -0
  8. package/Libraries/Components/View/View.windows.js +11 -1
  9. package/Libraries/Components/View/ViewAccessibility.d.ts +15 -0
  10. package/Libraries/Components/View/ViewAccessibility.windows.js +3 -0
  11. package/Libraries/Components/View/ViewPropTypes.windows.js +3 -0
  12. package/Libraries/Core/ReactNativeVersion.js +1 -1
  13. package/Libraries/Image/Image.windows.js +7 -0
  14. package/Libraries/Modal/Modal.windows.js +4 -1
  15. package/Libraries/Text/Text.windows.js +14 -1
  16. package/Libraries/Text/TextProps.windows.js +3 -0
  17. package/Microsoft.ReactNative/CompositionComponentView.idl +13 -1
  18. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
  19. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
  20. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
  21. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +8 -10
  22. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +4 -2
  23. package/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +0 -5
  24. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +428 -39
  25. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +39 -1
  26. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +55 -33
  27. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +5 -3
  28. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +43 -5
  29. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.h +2 -1
  30. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.cpp +115 -0
  31. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextProvider.h +41 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.cpp +298 -0
  33. package/Microsoft.ReactNative/Fabric/Composition/CompositionTextRangeProvider.h +59 -0
  34. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +106 -56
  35. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  36. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +163 -10
  37. package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +17 -1
  38. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +4 -2
  39. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +9 -1
  40. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +348 -316
  41. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +3 -61
  42. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +78 -0
  43. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.h +52 -0
  44. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +22 -0
  45. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +7 -5
  46. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +99 -37
  47. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -6
  48. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +81 -22
  49. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +21 -2
  50. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +6 -1
  51. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +41 -37
  52. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +76 -33
  53. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +8 -2
  54. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +1 -6
  55. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.h +0 -3
  56. package/Microsoft.ReactNative/Fabric/WindowsComponentDescriptorRegistry.cpp +0 -2
  57. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/HostPlatformColor.h +5 -8
  58. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorParser.h +1 -2
  59. package/Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/PlatformColorUtils.cpp +1 -1
  60. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +15 -1
  61. package/Microsoft.ReactNative/IReactContext.cpp +2 -2
  62. package/Microsoft.ReactNative/IReactContext.h +1 -1
  63. package/Microsoft.ReactNative/IReactContext.idl +2 -2
  64. package/Microsoft.ReactNative/IReactPackageBuilder.idl +3 -3
  65. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +97 -87
  66. package/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +4 -0
  67. package/Microsoft.ReactNative/Modules/AlertModule.cpp +9 -4
  68. package/Microsoft.ReactNative/Modules/Animated/NativeAnimatedNodeManager.cpp +1 -1
  69. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.cpp +32 -35
  70. package/Microsoft.ReactNative/Modules/Animated/PropsAnimatedNode.h +7 -4
  71. package/Microsoft.ReactNative/Modules/AppStateModule.cpp +1 -1
  72. package/Microsoft.ReactNative/Modules/AppThemeModuleUwp.cpp +2 -2
  73. package/Microsoft.ReactNative/Modules/AppearanceModule.cpp +2 -2
  74. package/Microsoft.ReactNative/Modules/ClipboardModule.cpp +1 -1
  75. package/Microsoft.ReactNative/Modules/ClipboardModule.h +1 -1
  76. package/Microsoft.ReactNative/Modules/DeviceInfoModule.cpp +3 -3
  77. package/Microsoft.ReactNative/Modules/I18nManagerModule.cpp +1 -1
  78. package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +7 -5
  79. package/Microsoft.ReactNative/Modules/LogBoxModule.h +2 -1
  80. package/Microsoft.ReactNative/Modules/Timing.cpp +2 -2
  81. package/Microsoft.ReactNative/ReactHost/IReactInstance.h +5 -0
  82. package/Microsoft.ReactNative/ReactHost/React.h +0 -3
  83. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +36 -12
  84. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.h +1 -1
  85. package/Microsoft.ReactNative/ReactNativeHost.cpp +9 -4
  86. package/Microsoft.ReactNative/ReactNativeIsland.idl +5 -1
  87. package/Microsoft.ReactNative/ReactPackageBuilder.cpp +3 -3
  88. package/Microsoft.ReactNative/ReactPackageBuilder.h +4 -4
  89. package/Microsoft.ReactNative/Utils/Helpers.cpp +0 -2
  90. package/Microsoft.ReactNative/Views/DevMenu.cpp +6 -6
  91. package/Microsoft.ReactNative/Views/DevMenu.h +1 -1
  92. package/Microsoft.ReactNative/XamlUIService.cpp +13 -7
  93. package/Microsoft.ReactNative/XamlUIService.h +4 -1
  94. package/Microsoft.ReactNative/XamlUIService.idl +2 -0
  95. package/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +6 -2
  96. package/Microsoft.ReactNative.Cxx/NativeModules.h +29 -0
  97. package/Microsoft.ReactNative.Cxx/ReactContext.h +1 -1
  98. package/Microsoft.ReactNative.Cxx/XamlUtils.h +12 -0
  99. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  100. package/PropertySheets/React.Cpp.props +3 -0
  101. package/PropertySheets/WebView2.props +1 -1
  102. package/PropertySheets/WinUI.props +5 -4
  103. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/AccessibilityPrimitives.h +253 -0
  104. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/accessibilityPropsConversions.h +799 -0
  105. package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +39 -35
  106. package/Shared/InspectorPackagerConnection.cpp +2 -5
  107. package/Shared/InspectorPackagerConnection.h +2 -2
  108. package/Shared/Networking/WinRTWebSocketResource.cpp +369 -7
  109. package/Shared/Networking/WinRTWebSocketResource.h +118 -0
  110. package/Shared/Shared.vcxitems +12 -5
  111. package/Shared/Shared.vcxitems.filters +11 -4
  112. package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +91 -97
  113. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +212 -0
  114. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +295 -0
  115. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +200 -0
  116. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +224 -0
  117. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +250 -0
  118. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +267 -0
  119. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +234 -0
  120. package/codegen/react/components/rnwcore/InputAccessory.g.h +200 -0
  121. package/codegen/react/components/rnwcore/ModalHostView.g.h +279 -0
  122. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +246 -0
  123. package/codegen/react/components/rnwcore/SafeAreaView.g.h +197 -0
  124. package/codegen/react/components/rnwcore/Switch.g.h +263 -0
  125. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +200 -0
  126. package/codegen/rnwcoreJSI-generated.cpp +0 -6
  127. package/codegen/rnwcoreJSI.h +0 -9
  128. package/jest/setup.js +5 -1
  129. package/just-task.js +1 -1
  130. package/package.json +11 -11
  131. package/src/private/featureflags/ReactNativeFeatureFlags.js +1 -6
  132. package/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +1 -2
  133. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +0 -191
  134. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentDescriptor.h +0 -39
  135. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.cpp +0 -18
  136. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewShadowNode.h +0 -39
@@ -164,6 +164,9 @@ type ButtonProps = $ReadOnly<{|
164
164
  'aria-disabled'?: ?boolean,
165
165
  'aria-expanded'?: ?boolean,
166
166
  'aria-selected'?: ?boolean,
167
+ 'aria-readonly'?: ?boolean, // Windows
168
+ 'aria-multiselectable'?: ?boolean, // Windows
169
+ 'aria-required'?: ?boolean, // Windows
167
170
 
168
171
  /**
169
172
  * [Android] Controlling if a view fires accessibility events and if it is reported to accessibility services.
@@ -308,6 +311,9 @@ const Button: React.AbstractComponent<
308
311
  'aria-expanded': ariaExpanded,
309
312
  'aria-label': ariaLabel,
310
313
  'aria-selected': ariaSelected,
314
+ 'aria-readonly': ariaReadOnly, // Windows
315
+ 'aria-multiselectable': ariaMultiselectable, // Windows
316
+ 'aria-required': ariaRequired, // Windows
311
317
  importantForAccessibility,
312
318
  color,
313
319
  onPress,
@@ -343,6 +349,9 @@ const Button: React.AbstractComponent<
343
349
  disabled: ariaDisabled ?? accessibilityState?.disabled,
344
350
  expanded: ariaExpanded ?? accessibilityState?.expanded,
345
351
  selected: ariaSelected ?? accessibilityState?.selected,
352
+ readOnly: ariaReadOnly ?? accessibilityState?.readOnly, // Windows
353
+ multiselectable: ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
354
+ required: ariaRequired ?? accessibilityState?.required, // Windows
346
355
  };
347
356
 
348
357
  const disabled =
@@ -75,6 +75,9 @@ type Props = $ReadOnly<{|
75
75
  'aria-disabled'?: ?boolean,
76
76
  'aria-expanded'?: ?boolean,
77
77
  'aria-selected'?: ?boolean,
78
+ 'aria-readonly'?: ?boolean, // Windows
79
+ 'aria-multiselectable'?: ?boolean, // Windows
80
+ 'aria-required'?: ?boolean, // Windows
78
81
  /**
79
82
  * A value indicating whether the accessibility elements contained within
80
83
  * this accessibility element are hidden.
@@ -262,6 +265,9 @@ function Pressable(
262
265
  'aria-expanded': ariaExpanded,
263
266
  'aria-label': ariaLabel,
264
267
  'aria-selected': ariaSelected,
268
+ 'aria-readonly': ariaReadOnly,
269
+ 'aria-multiselectable': ariaMultiselectable, // Windows
270
+ 'aria-required': ariaRequired, // Windows
265
271
  cancelable,
266
272
  children,
267
273
  delayHoverIn,
@@ -305,6 +311,9 @@ function Pressable(
305
311
  disabled: ariaDisabled ?? accessibilityState?.disabled,
306
312
  expanded: ariaExpanded ?? accessibilityState?.expanded,
307
313
  selected: ariaSelected ?? accessibilityState?.selected,
314
+ readOnly: ariaReadOnly ?? accessibilityState?.readOnly,
315
+ multiselectable: ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
316
+ required: ariaRequired ?? accessibilityState?.required, // Windows
308
317
  };
309
318
 
310
319
  _accessibilityState =
@@ -1336,6 +1336,9 @@ function InternalTextInput(props: Props): React.Node {
1336
1336
  'aria-disabled': ariaDisabled,
1337
1337
  'aria-expanded': ariaExpanded,
1338
1338
  'aria-selected': ariaSelected,
1339
+ 'aria-readonly': ariaReadOnly, // Windows
1340
+ 'aria-multiselectable': ariaMultiselectable, // Windows
1341
+ 'aria-required': ariaRequired, // Windows
1339
1342
  accessibilityState,
1340
1343
  id,
1341
1344
  tabIndex,
@@ -1664,7 +1667,10 @@ function InternalTextInput(props: Props): React.Node {
1664
1667
  ariaChecked != null ||
1665
1668
  ariaDisabled != null ||
1666
1669
  ariaExpanded != null ||
1667
- ariaSelected != null
1670
+ ariaSelected != null ||
1671
+ ariaReadOnly != null || // Windows
1672
+ ariaMultiselectable != null || // Windows
1673
+ ariaRequired != null // Windows
1668
1674
  ) {
1669
1675
  _accessibilityState = {
1670
1676
  busy: ariaBusy ?? accessibilityState?.busy,
@@ -1672,6 +1678,10 @@ function InternalTextInput(props: Props): React.Node {
1672
1678
  disabled: ariaDisabled ?? accessibilityState?.disabled,
1673
1679
  expanded: ariaExpanded ?? accessibilityState?.expanded,
1674
1680
  selected: ariaSelected ?? accessibilityState?.selected,
1681
+ readOnly: ariaReadOnly ?? accessibilityState?.readOnly, // Windows
1682
+ multiselectable:
1683
+ ariaMultiselectable ?? accessibilityState?.multiselectable, // Windows
1684
+ required: ariaRequired ?? accessibilityState?.required, // Windows
1675
1685
  };
1676
1686
  }
1677
1687
 
@@ -0,0 +1,229 @@
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-local
8
+ * @format
9
+ */
10
+
11
+ import type {ViewStyleProp} from '../../StyleSheet/StyleSheet';
12
+ import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback';
13
+
14
+ import Animated from '../../Animated/Animated';
15
+ import Pressability, {
16
+ type PressabilityConfig,
17
+ } from '../../Pressability/Pressability';
18
+ import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
19
+ import Platform from '../../Utilities/Platform';
20
+ import * as React from 'react';
21
+
22
+ type Props = $ReadOnly<{|
23
+ ...React.ElementConfig<TouchableWithoutFeedback>,
24
+
25
+ onPressAnimationComplete?: ?() => void,
26
+ onPressWithCompletion?: ?(callback: () => void) => void,
27
+ releaseBounciness?: ?number,
28
+ releaseVelocity?: ?number,
29
+ style?: ?ViewStyleProp,
30
+
31
+ hostRef: React.RefSetter<React.ElementRef<typeof Animated.View>>,
32
+ |}>;
33
+
34
+ type State = $ReadOnly<{|
35
+ pressability: Pressability,
36
+ scale: Animated.Value,
37
+ |}>;
38
+
39
+ class TouchableBounce extends React.Component<Props, State> {
40
+ state: State = {
41
+ pressability: new Pressability(this._createPressabilityConfig()),
42
+ scale: new Animated.Value(1),
43
+ };
44
+
45
+ _createPressabilityConfig(): PressabilityConfig {
46
+ return {
47
+ cancelable: !this.props.rejectResponderTermination,
48
+ disabled: this.props.disabled,
49
+ hitSlop: this.props.hitSlop,
50
+ delayLongPress: this.props.delayLongPress,
51
+ delayPressIn: this.props.delayPressIn,
52
+ delayPressOut: this.props.delayPressOut,
53
+ minPressDuration: 0,
54
+ pressRectOffset: this.props.pressRetentionOffset,
55
+ android_disableSound: this.props.touchSoundDisabled,
56
+ onBlur: event => {
57
+ if (Platform.isTV) {
58
+ this._bounceTo(1, 0.4, 0);
59
+ }
60
+ if (this.props.onBlur != null) {
61
+ this.props.onBlur(event);
62
+ }
63
+ },
64
+ onFocus: event => {
65
+ if (Platform.isTV) {
66
+ this._bounceTo(0.93, 0.1, 0);
67
+ }
68
+ if (this.props.onFocus != null) {
69
+ this.props.onFocus(event);
70
+ }
71
+ },
72
+ onLongPress: this.props.onLongPress,
73
+ onPress: event => {
74
+ const {onPressAnimationComplete, onPressWithCompletion} = this.props;
75
+ const releaseBounciness = this.props.releaseBounciness ?? 10;
76
+ const releaseVelocity = this.props.releaseVelocity ?? 10;
77
+
78
+ if (onPressWithCompletion != null) {
79
+ onPressWithCompletion(() => {
80
+ this.state.scale.setValue(0.93);
81
+ this._bounceTo(
82
+ 1,
83
+ releaseVelocity,
84
+ releaseBounciness,
85
+ onPressAnimationComplete,
86
+ );
87
+ });
88
+ return;
89
+ }
90
+
91
+ this._bounceTo(
92
+ 1,
93
+ releaseVelocity,
94
+ releaseBounciness,
95
+ onPressAnimationComplete,
96
+ );
97
+ if (this.props.onPress != null) {
98
+ this.props.onPress(event);
99
+ }
100
+ },
101
+ onPressIn: event => {
102
+ this._bounceTo(0.93, 0.1, 0);
103
+ if (this.props.onPressIn != null) {
104
+ this.props.onPressIn(event);
105
+ }
106
+ },
107
+ onPressOut: event => {
108
+ this._bounceTo(1, 0.4, 0);
109
+ if (this.props.onPressOut != null) {
110
+ this.props.onPressOut(event);
111
+ }
112
+ },
113
+ };
114
+ }
115
+
116
+ _bounceTo(
117
+ toValue: number,
118
+ velocity: number,
119
+ bounciness: number,
120
+ callback?: ?() => void,
121
+ ) {
122
+ Animated.spring(this.state.scale, {
123
+ toValue,
124
+ velocity,
125
+ bounciness,
126
+ useNativeDriver: true,
127
+ }).start(callback);
128
+ }
129
+
130
+ render(): React.Node {
131
+ // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
132
+ // adopting `Pressability`, so preserve that behavior.
133
+ const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
134
+ this.state.pressability.getEventHandlers();
135
+ const accessibilityLiveRegion =
136
+ this.props['aria-live'] === 'off'
137
+ ? 'none'
138
+ : this.props['aria-live'] ?? this.props.accessibilityLiveRegion;
139
+ const _accessibilityState = {
140
+ busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy,
141
+ checked:
142
+ this.props['aria-checked'] ?? this.props.accessibilityState?.checked,
143
+ disabled:
144
+ this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled,
145
+ expanded:
146
+ this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded,
147
+ selected:
148
+ this.props['aria-selected'] ?? this.props.accessibilityState?.selected,
149
+ readOnly:
150
+ this.props['aria-readonly'] ?? this.props.accessibilityState?.readOnly, // Windows
151
+ multiselectable:
152
+ this.props['aria-multiselectable'] ??
153
+ this.props.accessibilityState?.multiselectable, // Windows
154
+ required:
155
+ this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows
156
+ };
157
+
158
+ const accessibilityValue = {
159
+ max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max,
160
+ min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min,
161
+ now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now,
162
+ text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text,
163
+ };
164
+
165
+ const accessibilityLabel =
166
+ this.props['aria-label'] ?? this.props.accessibilityLabel;
167
+ return (
168
+ <Animated.View
169
+ style={[{transform: [{scale: this.state.scale}]}, this.props.style]}
170
+ accessible={this.props.accessible !== false}
171
+ accessibilityLabel={accessibilityLabel}
172
+ accessibilityHint={this.props.accessibilityHint}
173
+ accessibilityLanguage={this.props.accessibilityLanguage}
174
+ accessibilityRole={this.props.accessibilityRole}
175
+ accessibilityState={_accessibilityState}
176
+ accessibilityActions={this.props.accessibilityActions}
177
+ onAccessibilityAction={this.props.onAccessibilityAction}
178
+ accessibilityValue={accessibilityValue}
179
+ accessibilityLiveRegion={accessibilityLiveRegion}
180
+ importantForAccessibility={
181
+ this.props['aria-hidden'] === true
182
+ ? 'no-hide-descendants'
183
+ : this.props.importantForAccessibility
184
+ }
185
+ accessibilityViewIsModal={
186
+ this.props['aria-modal'] ?? this.props.accessibilityViewIsModal
187
+ }
188
+ accessibilityElementsHidden={
189
+ this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden
190
+ }
191
+ nativeID={this.props.id ?? this.props.nativeID}
192
+ testID={this.props.testID}
193
+ hitSlop={this.props.hitSlop}
194
+ focusable={
195
+ this.props.focusable !== false &&
196
+ this.props.onPress !== undefined &&
197
+ !this.props.disabled
198
+ }
199
+ // $FlowFixMe[prop-missing]
200
+ ref={this.props.hostRef}
201
+ {...eventHandlersWithoutBlurAndFocus}>
202
+ {this.props.children}
203
+ {__DEV__ ? (
204
+ <PressabilityDebugView color="orange" hitSlop={this.props.hitSlop} />
205
+ ) : null}
206
+ </Animated.View>
207
+ );
208
+ }
209
+
210
+ componentDidUpdate(prevProps: Props, prevState: State) {
211
+ this.state.pressability.configure(this._createPressabilityConfig());
212
+ }
213
+
214
+ componentDidMount(): mixed {
215
+ this.state.pressability.configure(this._createPressabilityConfig());
216
+ }
217
+
218
+ componentWillUnmount(): void {
219
+ this.state.pressability.reset();
220
+ this.state.scale.resetAnimation();
221
+ }
222
+ }
223
+
224
+ module.exports = (React.forwardRef((props, hostRef) => (
225
+ <TouchableBounce {...props} hostRef={hostRef} />
226
+ )): component(
227
+ ref: React.RefSetter<mixed>,
228
+ ...props: $ReadOnly<$Diff<Props, {|hostRef: mixed|}>>
229
+ ));
@@ -0,0 +1,373 @@
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-local
8
+ * @format
9
+ */
10
+
11
+ import type {PressEvent} from '../../Types/CoreEventTypes';
12
+ import typeof TouchableWithoutFeedback from './TouchableWithoutFeedback';
13
+
14
+ import View from '../../Components/View/View';
15
+ import Pressability, {
16
+ type PressabilityConfig,
17
+ } from '../../Pressability/Pressability';
18
+ import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
19
+ import {findHostInstance_DEPRECATED} from '../../ReactNative/RendererProxy';
20
+ import processColor from '../../StyleSheet/processColor';
21
+ import Platform from '../../Utilities/Platform';
22
+ import {Commands} from '../View/ViewNativeComponent';
23
+ import invariant from 'invariant';
24
+ import * as React from 'react';
25
+
26
+ type Props = $ReadOnly<{|
27
+ ...React.ElementConfig<TouchableWithoutFeedback>,
28
+
29
+ /**
30
+ * Determines the type of background drawable that's going to be used to
31
+ * display feedback. It takes an object with `type` property and extra data
32
+ * depending on the `type`. It's recommended to use one of the static
33
+ * methods to generate that dictionary.
34
+ */
35
+ background?: ?(
36
+ | $ReadOnly<{|
37
+ type: 'ThemeAttrAndroid',
38
+ attribute:
39
+ | 'selectableItemBackground'
40
+ | 'selectableItemBackgroundBorderless',
41
+ rippleRadius: ?number,
42
+ |}>
43
+ | $ReadOnly<{|
44
+ type: 'RippleAndroid',
45
+ color: ?number,
46
+ borderless: boolean,
47
+ rippleRadius: ?number,
48
+ |}>
49
+ ),
50
+
51
+ /**
52
+ * TV preferred focus (see documentation for the View component).
53
+ */
54
+ hasTVPreferredFocus?: ?boolean,
55
+
56
+ /**
57
+ * TV next focus down (see documentation for the View component).
58
+ */
59
+ nextFocusDown?: ?number,
60
+
61
+ /**
62
+ * TV next focus forward (see documentation for the View component).
63
+ */
64
+ nextFocusForward?: ?number,
65
+
66
+ /**
67
+ * TV next focus left (see documentation for the View component).
68
+ */
69
+ nextFocusLeft?: ?number,
70
+
71
+ /**
72
+ * TV next focus right (see documentation for the View component).
73
+ */
74
+ nextFocusRight?: ?number,
75
+
76
+ /**
77
+ * TV next focus up (see documentation for the View component).
78
+ */
79
+ nextFocusUp?: ?number,
80
+
81
+ /**
82
+ * Set to true to add the ripple effect to the foreground of the view, instead
83
+ * of the background. This is useful if one of your child views has a
84
+ * background of its own, or you're e.g. displaying images, and you don't want
85
+ * the ripple to be covered by them.
86
+ *
87
+ * Check TouchableNativeFeedback.canUseNativeForeground() first, as this is
88
+ * only available on Android 6.0 and above. If you try to use this on older
89
+ * versions, this will fallback to background.
90
+ */
91
+ useForeground?: ?boolean,
92
+ |}>;
93
+
94
+ type State = $ReadOnly<{|
95
+ pressability: Pressability,
96
+ |}>;
97
+
98
+ class TouchableNativeFeedback extends React.Component<Props, State> {
99
+ /**
100
+ * Creates a value for the `background` prop that uses the Android theme's
101
+ * default background for selectable elements.
102
+ */
103
+ static SelectableBackground: (rippleRadius: ?number) => $ReadOnly<{|
104
+ attribute: 'selectableItemBackground',
105
+ type: 'ThemeAttrAndroid',
106
+ rippleRadius: ?number,
107
+ |}> = (rippleRadius: ?number) => ({
108
+ type: 'ThemeAttrAndroid',
109
+ attribute: 'selectableItemBackground',
110
+ rippleRadius,
111
+ });
112
+
113
+ /**
114
+ * Creates a value for the `background` prop that uses the Android theme's
115
+ * default background for borderless selectable elements. Requires API 21+.
116
+ */
117
+ static SelectableBackgroundBorderless: (rippleRadius: ?number) => $ReadOnly<{|
118
+ attribute: 'selectableItemBackgroundBorderless',
119
+ type: 'ThemeAttrAndroid',
120
+ rippleRadius: ?number,
121
+ |}> = (rippleRadius: ?number) => ({
122
+ type: 'ThemeAttrAndroid',
123
+ attribute: 'selectableItemBackgroundBorderless',
124
+ rippleRadius,
125
+ });
126
+
127
+ /**
128
+ * Creates a value for the `background` prop that uses the Android ripple with
129
+ * the supplied color. If `borderless` is true, the ripple will render outside
130
+ * of the view bounds. Requires API 21+.
131
+ */
132
+ static Ripple: (
133
+ color: string,
134
+ borderless: boolean,
135
+ rippleRadius: ?number,
136
+ ) => $ReadOnly<{|
137
+ borderless: boolean,
138
+ color: ?number,
139
+ rippleRadius: ?number,
140
+ type: 'RippleAndroid',
141
+ |}> = (color: string, borderless: boolean, rippleRadius: ?number) => {
142
+ const processedColor = processColor(color);
143
+ invariant(
144
+ processedColor == null || typeof processedColor === 'number',
145
+ 'Unexpected color given for Ripple color',
146
+ );
147
+ return {
148
+ type: 'RippleAndroid',
149
+ // $FlowFixMe[incompatible-type]
150
+ color: processedColor,
151
+ borderless,
152
+ rippleRadius,
153
+ };
154
+ };
155
+
156
+ /**
157
+ * Whether `useForeground` is supported.
158
+ */
159
+ static canUseNativeForeground: () => boolean = () =>
160
+ Platform.OS === 'android';
161
+
162
+ state: State = {
163
+ pressability: new Pressability(this._createPressabilityConfig()),
164
+ };
165
+
166
+ _createPressabilityConfig(): PressabilityConfig {
167
+ const accessibilityStateDisabled =
168
+ this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled;
169
+ return {
170
+ cancelable: !this.props.rejectResponderTermination,
171
+ disabled:
172
+ this.props.disabled != null
173
+ ? this.props.disabled
174
+ : accessibilityStateDisabled,
175
+ hitSlop: this.props.hitSlop,
176
+ delayLongPress: this.props.delayLongPress,
177
+ delayPressIn: this.props.delayPressIn,
178
+ delayPressOut: this.props.delayPressOut,
179
+ minPressDuration: 0,
180
+ pressRectOffset: this.props.pressRetentionOffset,
181
+ android_disableSound: this.props.touchSoundDisabled,
182
+ onLongPress: this.props.onLongPress,
183
+ onPress: this.props.onPress,
184
+ onPressIn: event => {
185
+ if (Platform.OS === 'android') {
186
+ this._dispatchHotspotUpdate(event);
187
+ this._dispatchPressedStateChange(true);
188
+ }
189
+ if (this.props.onPressIn != null) {
190
+ this.props.onPressIn(event);
191
+ }
192
+ },
193
+ onPressMove: event => {
194
+ if (Platform.OS === 'android') {
195
+ this._dispatchHotspotUpdate(event);
196
+ }
197
+ },
198
+ onPressOut: event => {
199
+ if (Platform.OS === 'android') {
200
+ this._dispatchPressedStateChange(false);
201
+ }
202
+ if (this.props.onPressOut != null) {
203
+ this.props.onPressOut(event);
204
+ }
205
+ },
206
+ };
207
+ }
208
+
209
+ _dispatchPressedStateChange(pressed: boolean): void {
210
+ if (Platform.OS === 'android') {
211
+ const hostComponentRef = findHostInstance_DEPRECATED(this);
212
+ if (hostComponentRef == null) {
213
+ console.warn(
214
+ 'Touchable: Unable to find HostComponent instance. ' +
215
+ 'Has your Touchable component been unmounted?',
216
+ );
217
+ } else {
218
+ Commands.setPressed(hostComponentRef, pressed);
219
+ }
220
+ }
221
+ }
222
+
223
+ _dispatchHotspotUpdate(event: PressEvent): void {
224
+ if (Platform.OS === 'android') {
225
+ const {locationX, locationY} = event.nativeEvent;
226
+ const hostComponentRef = findHostInstance_DEPRECATED(this);
227
+ if (hostComponentRef == null) {
228
+ console.warn(
229
+ 'Touchable: Unable to find HostComponent instance. ' +
230
+ 'Has your Touchable component been unmounted?',
231
+ );
232
+ } else {
233
+ Commands.hotspotUpdate(
234
+ hostComponentRef,
235
+ locationX ?? 0,
236
+ locationY ?? 0,
237
+ );
238
+ }
239
+ }
240
+ }
241
+
242
+ render(): React.Node {
243
+ const element = React.Children.only<$FlowFixMe>(this.props.children);
244
+ const children: Array<React.Node> = [element.props.children];
245
+ if (__DEV__) {
246
+ if (element.type === View) {
247
+ children.push(
248
+ <PressabilityDebugView color="brown" hitSlop={this.props.hitSlop} />,
249
+ );
250
+ }
251
+ }
252
+
253
+ // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
254
+ // adopting `Pressability`, so preserve that behavior.
255
+ const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
256
+ this.state.pressability.getEventHandlers();
257
+
258
+ let _accessibilityState = {
259
+ busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy,
260
+ checked:
261
+ this.props['aria-checked'] ?? this.props.accessibilityState?.checked,
262
+ disabled:
263
+ this.props['aria-disabled'] ?? this.props.accessibilityState?.disabled,
264
+ expanded:
265
+ this.props['aria-expanded'] ?? this.props.accessibilityState?.expanded,
266
+ selected:
267
+ this.props['aria-selected'] ?? this.props.accessibilityState?.selected,
268
+ readOnly:
269
+ this.props['aria-readonly'] ?? this.props.accessibilityState?.readOnly,
270
+ multiselectable:
271
+ this.props['aria-multiselectable'] ??
272
+ this.props.accessibilityState?.multiselectable, // Windows
273
+ required:
274
+ this.props['aria-required'] ?? this.props.accessibilityState?.required, // Windows
275
+ };
276
+
277
+ _accessibilityState =
278
+ this.props.disabled != null
279
+ ? {
280
+ ..._accessibilityState,
281
+ disabled: this.props.disabled,
282
+ }
283
+ : _accessibilityState;
284
+
285
+ const accessibilityValue = {
286
+ max: this.props['aria-valuemax'] ?? this.props.accessibilityValue?.max,
287
+ min: this.props['aria-valuemin'] ?? this.props.accessibilityValue?.min,
288
+ now: this.props['aria-valuenow'] ?? this.props.accessibilityValue?.now,
289
+ text: this.props['aria-valuetext'] ?? this.props.accessibilityValue?.text,
290
+ };
291
+
292
+ const accessibilityLiveRegion =
293
+ this.props['aria-live'] === 'off'
294
+ ? 'none'
295
+ : this.props['aria-live'] ?? this.props.accessibilityLiveRegion;
296
+
297
+ const accessibilityLabel =
298
+ this.props['aria-label'] ?? this.props.accessibilityLabel;
299
+ return React.cloneElement(
300
+ element,
301
+ {
302
+ ...eventHandlersWithoutBlurAndFocus,
303
+ ...getBackgroundProp(
304
+ this.props.background === undefined
305
+ ? TouchableNativeFeedback.SelectableBackground()
306
+ : this.props.background,
307
+ this.props.useForeground === true,
308
+ ),
309
+ accessible: this.props.accessible !== false,
310
+ accessibilityHint: this.props.accessibilityHint,
311
+ accessibilityLanguage: this.props.accessibilityLanguage,
312
+ accessibilityLabel: accessibilityLabel,
313
+ accessibilityRole: this.props.accessibilityRole,
314
+ accessibilityState: _accessibilityState,
315
+ accessibilityActions: this.props.accessibilityActions,
316
+ onAccessibilityAction: this.props.onAccessibilityAction,
317
+ accessibilityValue: accessibilityValue,
318
+ importantForAccessibility:
319
+ this.props['aria-hidden'] === true
320
+ ? 'no-hide-descendants'
321
+ : this.props.importantForAccessibility,
322
+ accessibilityViewIsModal:
323
+ this.props['aria-modal'] ?? this.props.accessibilityViewIsModal,
324
+ accessibilityLiveRegion: accessibilityLiveRegion,
325
+ accessibilityElementsHidden:
326
+ this.props['aria-hidden'] ?? this.props.accessibilityElementsHidden,
327
+ hasTVPreferredFocus: this.props.hasTVPreferredFocus,
328
+ hitSlop: this.props.hitSlop,
329
+ focusable:
330
+ this.props.focusable !== false &&
331
+ this.props.onPress !== undefined &&
332
+ !this.props.disabled,
333
+ nativeID: this.props.id ?? this.props.nativeID,
334
+ nextFocusDown: this.props.nextFocusDown,
335
+ nextFocusForward: this.props.nextFocusForward,
336
+ nextFocusLeft: this.props.nextFocusLeft,
337
+ nextFocusRight: this.props.nextFocusRight,
338
+ nextFocusUp: this.props.nextFocusUp,
339
+ onLayout: this.props.onLayout,
340
+ testID: this.props.testID,
341
+ },
342
+ ...children,
343
+ );
344
+ }
345
+
346
+ componentDidUpdate(prevProps: Props, prevState: State) {
347
+ this.state.pressability.configure(this._createPressabilityConfig());
348
+ }
349
+
350
+ componentDidMount(): mixed {
351
+ this.state.pressability.configure(this._createPressabilityConfig());
352
+ }
353
+
354
+ componentWillUnmount(): void {
355
+ this.state.pressability.reset();
356
+ }
357
+ }
358
+
359
+ const getBackgroundProp =
360
+ Platform.OS === 'android'
361
+ ? /* $FlowFixMe[missing-local-annot] The type annotation(s) required by
362
+ * Flow's LTI update could not be added via codemod */
363
+ (background, useForeground: boolean) =>
364
+ useForeground && TouchableNativeFeedback.canUseNativeForeground()
365
+ ? {nativeForegroundAndroid: background}
366
+ : {nativeBackgroundAndroid: background}
367
+ : /* $FlowFixMe[missing-local-annot] The type annotation(s) required by
368
+ * Flow's LTI update could not be added via codemod */
369
+ (background, useForeground: boolean) => null;
370
+
371
+ TouchableNativeFeedback.displayName = 'TouchableNativeFeedback';
372
+
373
+ module.exports = TouchableNativeFeedback;