react-native-tvos 0.76.0-0rc6 → 0.76.1-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 (52) hide show
  1. package/Libraries/AppDelegate/RCTAppDelegate.mm +3 -2
  2. package/Libraries/Components/Pressable/Pressable.d.ts +1 -1
  3. package/Libraries/Components/Pressable/Pressable.js +0 -48
  4. package/Libraries/Components/Pressable/useAndroidRippleForView.js +4 -4
  5. package/Libraries/Components/TV/TVViewPropTypes.js +2 -0
  6. package/Libraries/Components/TextInput/TextInput.d.ts +1 -1
  7. package/Libraries/Components/Touchable/Touchable.js +0 -43
  8. package/Libraries/Components/Touchable/TouchableBounce.js +0 -33
  9. package/Libraries/Components/Touchable/TouchableHighlight.js +12 -47
  10. package/Libraries/Components/Touchable/TouchableNativeFeedback.js +0 -33
  11. package/Libraries/Components/Touchable/TouchableOpacity.js +12 -44
  12. package/Libraries/Components/Touchable/TouchableWithoutFeedback.js +0 -19
  13. package/Libraries/Components/View/ViewNativeComponent.js +6 -0
  14. package/Libraries/Components/View/ViewPropTypes.d.ts +12 -1
  15. package/Libraries/Components/View/ViewPropTypes.js +7 -0
  16. package/Libraries/Core/ReactNativeVersion.js +2 -2
  17. package/Libraries/NativeComponent/BaseViewConfig.android.js +19 -0
  18. package/Libraries/NativeComponent/BaseViewConfig.ios.js +6 -0
  19. package/Libraries/NativeComponent/TVViewConfig.js +4 -0
  20. package/Libraries/Pressability/Pressability.js +54 -0
  21. package/Libraries/ReactNative/AppRegistry.js +3 -3
  22. package/Libraries/Types/CoreEventTypes.d.ts +21 -0
  23. package/Libraries/Types/CoreEventTypes.js +6 -0
  24. package/README.md +38 -26
  25. package/React/Base/RCTVersion.m +2 -2
  26. package/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +41 -25
  27. package/React/Views/RCTTVView.h +13 -0
  28. package/React/Views/RCTTVView.m +54 -34
  29. package/React/Views/RCTViewManager.m +4 -0
  30. package/ReactAndroid/gradle.properties +1 -1
  31. package/ReactAndroid/src/main/java/com/facebook/react/HeadlessJsTaskService.java +4 -8
  32. package/ReactAndroid/src/main/java/com/facebook/react/defaults/DefaultReactNativeHost.kt +1 -1
  33. package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.java +2 -2
  34. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +16 -0
  35. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java +20 -0
  36. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/BlurEvent.kt +16 -0
  37. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/FocusEvent.kt +16 -0
  38. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PressInEvent.kt +16 -0
  39. package/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/PressOutEvent.kt +16 -0
  40. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +212 -4
  41. package/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +47 -4
  42. package/ReactCommon/cxxreact/ReactNativeVersion.h +2 -2
  43. package/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.cpp +18 -0
  44. package/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h +8 -0
  45. package/package.json +8 -8
  46. package/scripts/cocoapods/utils.rb +4 -2
  47. package/scripts/codegen/generate-artifacts-executor.js +19 -4
  48. package/sdks/hermesc/osx-bin/hermes +0 -0
  49. package/sdks/hermesc/osx-bin/hermesc +0 -0
  50. package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
  51. package/types/public/ReactNativeTVTypes.d.ts +1 -1
  52. package/Libraries/Components/Touchable/TVTouchable.js +0 -71
@@ -76,7 +76,8 @@
76
76
  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
77
77
  UIViewController *rootViewController = [self createRootViewController];
78
78
  [self setRootView:rootView toRootViewController:rootViewController];
79
- self.window.rootViewController = rootViewController;
79
+ _window.windowScene.delegate = self;
80
+ _window.rootViewController = rootViewController;
80
81
  #if TARGET_OS_TV
81
82
  UIUserInterfaceStyle style = rootViewController.traitCollection.userInterfaceStyle;
82
83
  if (style == UIUserInterfaceStyleDark) {
@@ -85,7 +86,7 @@
85
86
  rootView.backgroundColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
86
87
  }
87
88
  #endif
88
- [self.window makeKeyAndVisible];
89
+ [_window makeKeyAndVisible];
89
90
  }
90
91
 
91
92
  - (void)applicationDidEnterBackground:(UIApplication *)application
@@ -34,7 +34,7 @@ export interface PressableAndroidRippleConfig {
34
34
 
35
35
  export interface PressableProps
36
36
  extends AccessibilityProps,
37
- Omit<ViewProps, 'children' | 'style' | 'hitSlop'> {
37
+ Omit<ViewProps, 'children' | 'style' | 'hitSlop' | 'onFocus' | 'onBlur' | 'onPressIn' | 'onPressOut'> {
38
38
  /**
39
39
  * Called when the hover is activated to provide visual feedback.
40
40
  */
@@ -28,7 +28,6 @@ import {type RectOrSize} from '../../StyleSheet/Rect';
28
28
  import useMergeRefs from '../../Utilities/useMergeRefs';
29
29
  import View from '../View/View';
30
30
  import type {TVParallaxPropertiesType} from '../TV/TVViewPropTypes';
31
- import {tvFocusEventHandler} from '../TV/TVFocusEventHandler';
32
31
  import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
33
32
  import useAndroidRippleForView, {
34
33
  type RippleConfig,
@@ -392,53 +391,6 @@ function Pressable(
392
391
  // $FlowFixMe[incompatible-call]
393
392
  const eventHandlers = usePressability(config);
394
393
 
395
- const pressableTVFocusEventHandler = React.useCallback(
396
- (evt: any) => {
397
- if (isTVSelectable !== false || focusable !== false) {
398
- // $FlowFixMe[prop-missing]
399
- if (evt?.eventType === 'focus') {
400
- shouldUpdatePressed && setFocused(true);
401
- onFocus && onFocus(evt);
402
- // $FlowFixMe[prop-missing]
403
- } else if (evt.eventType === 'blur') {
404
- onBlur && onBlur(evt);
405
- shouldUpdatePressed && setFocused(false);
406
- }
407
- }
408
- // $FlowFixMe[prop-missing]
409
- if (evt.eventType === 'select') {
410
- // $FlowFixMe[incompatible-exact]
411
- onPress && onPress(evt);
412
- }
413
- // $FlowFixMe[prop-missing]
414
- if (evt.eventType === 'longSelect') {
415
- // $FlowFixMe[incompatible-exact]
416
- onLongPress && onLongPress(evt);
417
- }
418
- },
419
- [
420
- onBlur,
421
- onFocus,
422
- onLongPress,
423
- onPress,
424
- focusable,
425
- isTVSelectable,
426
- shouldUpdatePressed,
427
- ],
428
- );
429
-
430
- React.useEffect(() => {
431
- if (!tvFocusEventHandler) {
432
- return;
433
- }
434
- // $FlowFixMe[prop-missing]
435
- const viewTag = tagForComponentOrHandle(viewRef?.current);
436
- tvFocusEventHandler.register(viewTag, pressableTVFocusEventHandler);
437
- return () => {
438
- tvFocusEventHandler.unregister(viewTag);
439
- };
440
- }, [pressableTVFocusEventHandler, viewRef]);
441
-
442
394
  return (
443
395
  <View
444
396
  {...restPropsWithDefaults}
@@ -80,8 +80,8 @@ export default function useAndroidRippleForView(
80
80
  if (view != null) {
81
81
  Commands.hotspotUpdate(
82
82
  view,
83
- event.nativeEvent.locationX ?? 0,
84
- event.nativeEvent.locationY ?? 0,
83
+ event.nativeEvent?.locationX ?? 0,
84
+ event.nativeEvent?.locationY ?? 0,
85
85
  );
86
86
  Commands.setPressed(view, true);
87
87
  }
@@ -91,8 +91,8 @@ export default function useAndroidRippleForView(
91
91
  if (view != null) {
92
92
  Commands.hotspotUpdate(
93
93
  view,
94
- event.nativeEvent.locationX ?? 0,
95
- event.nativeEvent.locationY ?? 0,
94
+ event.nativeEvent?.locationX ?? 0,
95
+ event.nativeEvent?.locationY ?? 0,
96
96
  );
97
97
  }
98
98
  },
@@ -85,4 +85,6 @@ export type TVViewProps = $ReadOnly<{|
85
85
  enabled?: boolean,
86
86
  autoFocus?: boolean,
87
87
  safePadding?: string | null,
88
+ onPressIn?: (event: any) => void,
89
+ onPressOut?: (event: any) => void,
88
90
  |}>;
@@ -491,7 +491,7 @@ export interface TextInputSubmitEditingEventData {
491
491
  * @see https://reactnative.dev/docs/textinput#props
492
492
  */
493
493
  export interface TextInputProps
494
- extends ViewProps,
494
+ extends Omit<ViewProps, 'onFocus' | 'onBlur' | 'onPressIn' | 'onPressOut'>,
495
495
  TextInputIOSProps,
496
496
  TextInputAndroidProps,
497
497
  AccessibilityProps {
@@ -16,8 +16,6 @@ import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
16
16
  import UIManager from '../../ReactNative/UIManager';
17
17
  import Platform from '../../Utilities/Platform';
18
18
  import SoundManager from '../Sound/SoundManager';
19
- import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
20
- import {tvFocusEventHandler} from '../TV/TVFocusEventHandler';
21
19
  import BoundingDimensions from './BoundingDimensions';
22
20
  import Position from './Position';
23
21
  import * as React from 'react';
@@ -373,47 +371,6 @@ const LONG_PRESS_ALLOWED_MOVEMENT = 10;
373
371
  * @lends Touchable.prototype
374
372
  */
375
373
  const TouchableMixin = {
376
- componentDidMount: function (this: any) {
377
- if (!Platform.isTV) {
378
- return;
379
- }
380
- if (!tvFocusEventHandler) {
381
- return;
382
- }
383
-
384
- this._componentTag = tagForComponentOrHandle(this);
385
- tvFocusEventHandler.register(this._componentTag, evt => {
386
- evt.dispatchConfig = {};
387
- if (evt.eventType === 'focus') {
388
- this.touchableHandleFocus(evt);
389
- } else if (evt.eventType === 'blur') {
390
- this.touchableHandleBlur(evt);
391
- } else if (evt.eventType === 'select' && Platform.OS !== 'android') {
392
- this.touchableHandlePress &&
393
- !this.props.disabled &&
394
- this.touchableHandlePress(evt);
395
- } else if (evt.eventType === 'longSelect') {
396
- this.touchableHandleLongPress &&
397
- !this.props.disabled &&
398
- this.touchableHandleLongPress();
399
- }
400
- });
401
- },
402
-
403
- /**
404
- * Clear all timeouts on unmount
405
- */
406
- /* $FlowFixMe[missing-this-annot] The 'this' type annotation(s) required by
407
- * Flow's LTI update could not be added via codemod */
408
- componentWillUnmount: function () {
409
- if (tvFocusEventHandler) {
410
- tvFocusEventHandler.unregister(this._componentTag);
411
- }
412
- this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout);
413
- this.longPressDelayTimeout && clearTimeout(this.longPressDelayTimeout);
414
- this.pressOutDelayTimeout && clearTimeout(this.pressOutDelayTimeout);
415
- },
416
-
417
374
  /**
418
375
  * It's prefer that mixins determine state in this way, having the class
419
376
  * explicitly mix the state in the one and only `getInitialState` method.
@@ -17,7 +17,6 @@ import Pressability, {
17
17
  } from '../../Pressability/Pressability';
18
18
  import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
19
19
  import Platform from '../../Utilities/Platform';
20
- import TVTouchable from './TVTouchable';
21
20
  import * as React from 'react';
22
21
 
23
22
  type Props = $ReadOnly<{|
@@ -38,8 +37,6 @@ type State = $ReadOnly<{|
38
37
  |}>;
39
38
 
40
39
  class TouchableBounce extends React.Component<Props, State> {
41
- _tvTouchable: ?TVTouchable;
42
-
43
40
  state: State = {
44
41
  pressability: new Pressability(this._createPressabilityConfig()),
45
42
  scale: new Animated.Value(1),
@@ -203,31 +200,6 @@ class TouchableBounce extends React.Component<Props, State> {
203
200
  }
204
201
 
205
202
  componentDidMount(): void {
206
- if (Platform.isTV) {
207
- this._tvTouchable = new TVTouchable(this, {
208
- getDisabled: () => this.props.disabled === true,
209
- onBlur: event => {
210
- if (this.props.onBlur != null) {
211
- this.props.onBlur(event);
212
- }
213
- },
214
- onFocus: event => {
215
- if (this.props.onFocus != null) {
216
- this.props.onFocus(event);
217
- }
218
- },
219
- onPress: event => {
220
- if (this.props.onPress != null) {
221
- this.props.onPress(event);
222
- }
223
- },
224
- onLongPress: event => {
225
- if (this.props.onLongPress != null) {
226
- this.props.onLongPress(event);
227
- }
228
- },
229
- });
230
- }
231
203
  this.state.pressability.configure(this._createPressabilityConfig());
232
204
  }
233
205
 
@@ -236,11 +208,6 @@ class TouchableBounce extends React.Component<Props, State> {
236
208
  }
237
209
 
238
210
  componentWillUnmount(): void {
239
- if (Platform.isTV) {
240
- if (this._tvTouchable != null) {
241
- this._tvTouchable.destroy();
242
- }
243
- }
244
211
  this.state.pressability.reset();
245
212
  this.state.scale.resetAnimation();
246
213
  }
@@ -20,7 +20,6 @@ import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
20
20
  import StyleSheet, {type ViewStyleProp} from '../../StyleSheet/StyleSheet';
21
21
  import Platform from '../../Utilities/Platform';
22
22
  import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
23
- import TVTouchable from './TVTouchable';
24
23
  import * as React from 'react';
25
24
 
26
25
  type AndroidProps = $ReadOnly<{|
@@ -166,7 +165,6 @@ type State = $ReadOnly<{|
166
165
  class TouchableHighlight extends React.Component<Props, State> {
167
166
  _hideTimeout: ?TimeoutID;
168
167
  _isMounted: boolean = false;
169
- _tvTouchable: ?TVTouchable;
170
168
 
171
169
  state: State = {
172
170
  pressability: new Pressability(this._createPressabilityConfig()),
@@ -220,18 +218,22 @@ class TouchableHighlight extends React.Component<Props, State> {
220
218
  }
221
219
  },
222
220
  onPressIn: event => {
223
- if (this._hideTimeout != null) {
224
- clearTimeout(this._hideTimeout);
225
- this._hideTimeout = null;
221
+ if (!Platform.isTV) {
222
+ if (this._hideTimeout != null) {
223
+ clearTimeout(this._hideTimeout);
224
+ this._hideTimeout = null;
225
+ }
226
+ this._showUnderlay();
226
227
  }
227
- this._showUnderlay();
228
228
  if (this.props.onPressIn != null) {
229
229
  this.props.onPressIn(event);
230
230
  }
231
231
  },
232
232
  onPressOut: event => {
233
- if (this._hideTimeout == null) {
234
- this._hideUnderlay();
233
+ if (!Platform.isTV) {
234
+ if (this._hideTimeout == null) {
235
+ this._hideUnderlay();
236
+ }
235
237
  }
236
238
  if (this.props.onPressOut != null) {
237
239
  this.props.onPressOut(event);
@@ -292,8 +294,7 @@ class TouchableHighlight extends React.Component<Props, State> {
292
294
 
293
295
  // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
294
296
  // adopting `Pressability`, so preserve that behavior.
295
- const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
296
- this.state.pressability.getEventHandlers();
297
+ const eventHandlers = this.state.pressability.getEventHandlers();
297
298
 
298
299
  const accessibilityState =
299
300
  this.props.disabled != null
@@ -364,7 +365,7 @@ class TouchableHighlight extends React.Component<Props, State> {
364
365
  nativeID={this.props.id ?? this.props.nativeID}
365
366
  testID={this.props.testID}
366
367
  ref={this.props.hostRef}
367
- {...eventHandlersWithoutBlurAndFocus}>
368
+ {...eventHandlers}>
368
369
  {React.cloneElement(child, {
369
370
  style: StyleSheet.compose(
370
371
  child.props.style,
@@ -380,37 +381,6 @@ class TouchableHighlight extends React.Component<Props, State> {
380
381
 
381
382
  componentDidMount(): void {
382
383
  this._isMounted = true;
383
- if (Platform.isTV) {
384
- this._tvTouchable = new TVTouchable(this, {
385
- getDisabled: () => this.props.disabled === true,
386
- onBlur: event => {
387
- if (Platform.isTV) {
388
- this._hideUnderlay();
389
- }
390
- if (this.props.onBlur != null) {
391
- this.props.onBlur(event);
392
- }
393
- },
394
- onFocus: event => {
395
- if (Platform.isTV) {
396
- this._showUnderlay();
397
- }
398
- if (this.props.onFocus != null) {
399
- this.props.onFocus(event);
400
- }
401
- },
402
- onPress: event => {
403
- if (this.props.onPress != null) {
404
- this.props.onPress(event);
405
- }
406
- },
407
- onLongPress: event => {
408
- if (this.props.onLongPress != null) {
409
- this.props.onLongPress(event);
410
- }
411
- },
412
- });
413
- }
414
384
  this.state.pressability.configure(this._createPressabilityConfig());
415
385
  }
416
386
 
@@ -423,11 +393,6 @@ class TouchableHighlight extends React.Component<Props, State> {
423
393
  if (this._hideTimeout != null) {
424
394
  clearTimeout(this._hideTimeout);
425
395
  }
426
- if (Platform.isTV) {
427
- if (this._tvTouchable != null) {
428
- this._tvTouchable.destroy();
429
- }
430
- }
431
396
  this.state.pressability.reset();
432
397
  }
433
398
  }
@@ -16,7 +16,6 @@ import Pressability, {
16
16
  type PressabilityConfig,
17
17
  } from '../../Pressability/Pressability';
18
18
  import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
19
- import TVTouchable from './TVTouchable';
20
19
  import {findHostInstance_DEPRECATED} from '../../ReactNative/RendererProxy';
21
20
  import processColor from '../../StyleSheet/processColor';
22
21
  import tagForComponentOrHandle from '../TV/tagForComponentOrHandle';
@@ -161,8 +160,6 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
161
160
  static canUseNativeForeground: () => boolean = () =>
162
161
  Platform.OS === 'android';
163
162
 
164
- _tvTouchable: ?TVTouchable;
165
-
166
163
  state: State = {
167
164
  pressability: new Pressability(this._createPressabilityConfig()),
168
165
  };
@@ -342,31 +339,6 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
342
339
 
343
340
  componentDidMount(): void {
344
341
  this.state.pressability.configure(this._createPressabilityConfig());
345
- if (Platform.isTV) {
346
- this._tvTouchable = new TVTouchable(this, {
347
- getDisabled: () => this.props.disabled === true,
348
- onBlur: event => {
349
- if (this.props.onBlur != null) {
350
- this.props.onBlur(event);
351
- }
352
- },
353
- onFocus: event => {
354
- if (this.props.onFocus != null) {
355
- this.props.onFocus(event);
356
- }
357
- },
358
- onPress: event => {
359
- if (this.props.onPress != null) {
360
- this.props.onPress(event);
361
- }
362
- },
363
- onLongPress: event => {
364
- if (this.props.onLongPress != null) {
365
- this.props.onLongPress(event);
366
- }
367
- },
368
- });
369
- }
370
342
  }
371
343
 
372
344
  componentDidUpdate(prevProps: Props, prevState: State) {
@@ -374,11 +346,6 @@ class TouchableNativeFeedback extends React.Component<Props, State> {
374
346
  }
375
347
 
376
348
  componentWillUnmount(): void {
377
- if (Platform.isTV) {
378
- if (this._tvTouchable != null) {
379
- this._tvTouchable.destroy();
380
- }
381
- }
382
349
  this.state.pressability.reset();
383
350
  }
384
351
  }
@@ -17,7 +17,6 @@ import Pressability, {
17
17
  type PressabilityConfig,
18
18
  } from '../../Pressability/Pressability';
19
19
  import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
20
- import TVTouchable from './TVTouchable';
21
20
  import flattenStyle from '../../StyleSheet/flattenStyle';
22
21
  import Platform from '../../Utilities/Platform';
23
22
  import type {TVParallaxPropertiesType} from '../TV/TVViewPropTypes';
@@ -136,8 +135,6 @@ type State = $ReadOnly<{|
136
135
  *
137
136
  */
138
137
  class TouchableOpacity extends React.Component<Props, State> {
139
- _tvTouchable: ?TVTouchable;
140
-
141
138
  state: State = {
142
139
  anim: new Animated.Value(this._getChildStyleOpacityWithDefault()),
143
140
  pressability: new Pressability(this._createPressabilityConfig()),
@@ -175,17 +172,21 @@ class TouchableOpacity extends React.Component<Props, State> {
175
172
  onLongPress: this.props.onLongPress,
176
173
  onPress: this.props.onPress,
177
174
  onPressIn: event => {
178
- this._opacityActive(
179
- event.dispatchConfig.registrationName === 'onResponderGrant'
180
- ? 0
181
- : 150,
182
- );
175
+ if (!Platform.isTV) {
176
+ this._opacityActive(
177
+ event.dispatchConfig?.registrationName === 'onResponderGrant'
178
+ ? 0
179
+ : 150,
180
+ );
181
+ }
183
182
  if (this.props.onPressIn != null) {
184
183
  this.props.onPressIn(event);
185
184
  }
186
185
  },
187
186
  onPressOut: event => {
188
- this._opacityInactive(250);
187
+ if (!Platform.isTV) {
188
+ this._opacityInactive(250);
189
+ }
189
190
  if (this.props.onPressOut != null) {
190
191
  this.props.onPressOut(event);
191
192
  }
@@ -223,8 +224,7 @@ class TouchableOpacity extends React.Component<Props, State> {
223
224
  render(): React.Node {
224
225
  // BACKWARD-COMPATIBILITY: Focus and blur events were never supported before
225
226
  // adopting `Pressability`, so preserve that behavior.
226
- const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
227
- this.state.pressability.getEventHandlers();
227
+ const eventHandlers = this.state.pressability.getEventHandlers();
228
228
 
229
229
  let _accessibilityState = {
230
230
  busy: this.props['aria-busy'] ?? this.props.accessibilityState?.busy,
@@ -304,7 +304,7 @@ class TouchableOpacity extends React.Component<Props, State> {
304
304
  !this.props.disabled
305
305
  }
306
306
  ref={this.props.hostRef}
307
- {...eventHandlersWithoutBlurAndFocus}>
307
+ {...eventHandlers}>
308
308
  {this.props.children}
309
309
  {__DEV__ ? (
310
310
  <PressabilityDebugView color="cyan" hitSlop={this.props.hitSlop} />
@@ -314,33 +314,6 @@ class TouchableOpacity extends React.Component<Props, State> {
314
314
  }
315
315
 
316
316
  componentDidMount(): void {
317
- if (Platform.isTV) {
318
- this._tvTouchable = new TVTouchable(this, {
319
- getDisabled: () => this.props.disabled === true,
320
- onBlur: event => {
321
- this._opacityInactive(250);
322
- if (this.props.onBlur != null) {
323
- this.props.onBlur(event);
324
- }
325
- },
326
- onFocus: event => {
327
- this._opacityActive(150);
328
- if (this.props.onFocus != null) {
329
- this.props.onFocus(event);
330
- }
331
- },
332
- onPress: event => {
333
- if (this.props.onPress != null) {
334
- this.props.onPress(event);
335
- }
336
- },
337
- onLongPress: event => {
338
- if (this.props.onLongPress != null) {
339
- this.props.onLongPress(event);
340
- }
341
- },
342
- });
343
- }
344
317
  this.state.pressability.configure(this._createPressabilityConfig());
345
318
  }
346
319
 
@@ -360,11 +333,6 @@ class TouchableOpacity extends React.Component<Props, State> {
360
333
  }
361
334
 
362
335
  componentWillUnmount(): void {
363
- if (Platform.isTV) {
364
- if (this._tvTouchable != null) {
365
- this._tvTouchable.destroy();
366
- }
367
- }
368
336
  this.state.pressability.reset();
369
337
  this.state.anim.resetAnimation();
370
338
  }
@@ -27,7 +27,6 @@ import type {TVParallaxPropertiesType} from '../TV/TVViewPropTypes';
27
27
  import View from '../../Components/View/View';
28
28
  import {PressabilityDebugView} from '../../Pressability/PressabilityDebug';
29
29
  import usePressability from '../../Pressability/usePressability';
30
- import useTVEventHandler from '../TV/useTVEventHandler';
31
30
  import * as React from 'react';
32
31
  import {useMemo} from 'react';
33
32
 
@@ -202,24 +201,6 @@ module.exports = function TouchableWithoutFeedback(props: Props): React.Node {
202
201
  const {onBlur, onFocus, ...eventHandlersWithoutBlurAndFocus} =
203
202
  eventHandlers || {};
204
203
 
205
- useTVEventHandler(evt => {
206
- if (props.disabled === true || props['aria-disabled'] === true) {
207
- return;
208
- }
209
- if (evt.eventType === 'focus') {
210
- props.onFocus && props.onFocus(evt);
211
- }
212
- if (evt.eventType === 'blur') {
213
- props.onBlur && props.onBlur(evt);
214
- }
215
- if (evt.eventType === 'select') {
216
- props.onPress && props.onPress(evt);
217
- }
218
- if (evt.eventType === 'longSelect') {
219
- props.onLongPress && props.onLongPress(evt);
220
- }
221
- });
222
-
223
204
  const elementProps: {[string]: mixed, ...} = {
224
205
  ...eventHandlersWithoutBlurAndFocus,
225
206
  accessible: props.accessible !== false,
@@ -29,6 +29,8 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
29
29
 
30
30
  // ReactViewManager @ReactProps
31
31
  accessible: true,
32
+
33
+ // TV props
32
34
  hasTVPreferredFocus: true,
33
35
  nextFocusDown: true,
34
36
  nextFocusForward: true,
@@ -40,6 +42,10 @@ export const __INTERNAL_VIEW_CONFIG: PartialViewConfig =
40
42
  trapFocusDown: true,
41
43
  trapFocusLeft: true,
42
44
  trapFocusRight: true,
45
+ onFocus: true,
46
+ onBlur: true,
47
+ onPressIn: true,
48
+ onPressOut: true,
43
49
 
44
50
  borderRadius: true,
45
51
  borderTopLeftRadius: true,
@@ -12,9 +12,15 @@ import {Insets} from '../../../types/public/Insets';
12
12
  import {GestureResponderHandlers} from '../../../types/public/ReactNativeRenderer';
13
13
  import {StyleProp} from '../../StyleSheet/StyleSheet';
14
14
  import {ViewStyle} from '../../StyleSheet/StyleSheetTypes';
15
- import {LayoutChangeEvent, PointerEvents} from '../../Types/CoreEventTypes';
15
+ import {
16
+ LayoutChangeEvent,
17
+ PointerEvents,
18
+ FocusEvents,
19
+ PressEvents,
20
+ } from '../../Types/CoreEventTypes';
16
21
  import {Touchable} from '../Touchable/Touchable';
17
22
  import {AccessibilityProps} from './ViewAccessibility';
23
+ import type {BubblingEventHandler} from 'react-native/Libraries/Types/CodegenTypes';
18
24
 
19
25
  export interface TVViewPropsIOS {
20
26
  /**
@@ -125,6 +131,8 @@ export interface ViewProps
125
131
  GestureResponderHandlers,
126
132
  Touchable,
127
133
  PointerEvents,
134
+ FocusEvents,
135
+ PressEvents,
128
136
  AccessibilityProps {
129
137
  children?: React.ReactNode | undefined;
130
138
  /**
@@ -211,4 +219,7 @@ export interface ViewProps
211
219
  * Used to reference react managed views from native code.
212
220
  */
213
221
  nativeID?: string | undefined;
222
+
223
+ readonly onFocus?: BubblingEventHandler<Event> | undefined;
224
+ readonly onBlur?: BubblingEventHandler<Event> | undefined;
214
225
  }
@@ -20,6 +20,7 @@ import type {
20
20
  MouseEvent,
21
21
  PointerEvent,
22
22
  PressEvent,
23
+ RemotePressEvent,
23
24
  } from '../../Types/CoreEventTypes';
24
25
  import type {TVViewProps} from '../TV/TVViewPropTypes';
25
26
  import type {
@@ -130,6 +131,11 @@ type TouchEventProps = $ReadOnly<{|
130
131
  onTouchStartCapture?: ?(e: PressEvent) => void,
131
132
  |}>;
132
133
 
134
+ type PressEventProps = $ReadOnly<{|
135
+ onPressIn?: ?(e: RemotePressEvent) => void,
136
+ onPressOut?: ?(e: RemotePressEvent) => void,
137
+ |}>;
138
+
133
139
  /**
134
140
  * For most touch interactions, you'll simply want to wrap your component in
135
141
  * `TouchableHighlight` or `TouchableOpacity`. Check out `Touchable.js`,
@@ -470,6 +476,7 @@ export type ViewProps = $ReadOnly<{|
470
476
  ...IOSViewProps,
471
477
  ...TVViewProps,
472
478
  ...NextFocusProps,
479
+ ...PressEventProps,
473
480
 
474
481
  children?: Node,
475
482
  style?: ?ViewStyleProp,
@@ -16,8 +16,8 @@ const version: $ReadOnly<{
16
16
  }> = {
17
17
  major: 0,
18
18
  minor: 76,
19
- patch: 0,
20
- prerelease: '0rc6',
19
+ patch: 1,
20
+ prerelease: '1',
21
21
  };
22
22
 
23
23
  module.exports = {version};