Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/react-native/Libraries/Components/Keyboard/Keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import LayoutAnimation from '../../LayoutAnimation/LayoutAnimation';
import dismissKeyboard from '../../Utilities/dismissKeyboard';
import Platform from '../../Utilities/Platform';
import NativeKeyboardObserver from './NativeKeyboardObserver';
import warnOnce from '../../Utilities/warnOnce';

export type KeyboardEventName = $Keys<KeyboardEventDefinitions>;

Expand Down Expand Up @@ -114,6 +115,14 @@ class Keyboard {
);

constructor() {
if (Platform.isVisionOS) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not create Keyboard.visionOS.js and have it return a noop or throw upon require? It seems like these if should be pulled into the Tester app itself, which is what I could expect in end-user app logic as well. If a visionOS app requires this file, and tries to use any methods, the developer probably isn't understanding the platform correctly.

Copy link
Member

@okwasniewski okwasniewski Oct 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be a possible solution but I think it's a nice DX to have instructions that this module is not supported on this platform.

We can wait with merging of this PR till we will implement the Platform.OS (for visionOS) and make it a noop file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't the warning be annoying when writing cross platform apps?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, if we have the .visionOS platform file, would also vote for removing warnings

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also way to warnOnce as @satya164 said constant warning might be annoying. Looks like react-native-tvos is following this pattern:

image

warnOnce(
'Keyboard-unavailable',
'Keyboard is not available on visionOS platform. The system displays the keyboard in a separate window, leaving the app’s window unaffected by the keyboard’s appearance and disappearance',
);
return;
}

this.addListener('keyboardDidShow', ev => {
this._currentlyShowing = ev;
});
Expand Down Expand Up @@ -151,6 +160,10 @@ class Keyboard {
listener: (...$ElementType<KeyboardEventDefinitions, K>) => mixed,
context?: mixed,
): EventSubscription {
if (Platform.isVisionOS) {
return;
}

return this._emitter.addListener(eventType, listener);
}

Expand All @@ -160,6 +173,10 @@ class Keyboard {
* @param {string} eventType The native event string listeners are watching which will be removed.
*/
removeAllListeners<K: $Keys<KeyboardEventDefinitions>>(eventType: ?K): void {
if (Platform.isVisionOS) {
return;
}

this._emitter.removeAllListeners(eventType);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
import View from '../View/View';
import Keyboard from './Keyboard';
import * as React from 'react';
import warnOnce from '../../Utilities/warnOnce';

type Props = $ReadOnly<{|
...ViewProps,
Expand Down Expand Up @@ -176,6 +177,13 @@ class KeyboardAvoidingView extends React.Component<Props, State> {

componentDidMount(): void {
if (Platform.OS === 'ios') {
if (Platform.isVisionOS) {
warnOnce(
'KeyboardAvoidingView-unavailable',
'KeyboardAvoidingView is not available on visionOS platform. The system displays the keyboard in a separate window, leaving the app’s window unaffected by the keyboard’s appearance and disappearance',
);
return;
}
this._subscriptions = [
Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
];
Expand Down Expand Up @@ -205,6 +213,16 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
onLayout,
...props
} = this.props;

if (Platform.isVisionOS) {
// KeyboardAvoidingView is not supported on VisionOS, so we return a simple View without the onLayout handler
return (
<View ref={this.viewRef} style={style} {...props}>
{children}
</View>
);
}

const bottomHeight = enabled === true ? this.state.bottom : 0;
switch (behavior) {
case 'height':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ @implementation RCTKeyboardObserver

- (void)startObserving
{
#if !TARGET_OS_VISION
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define ADD_KEYBOARD_HANDLER(NAME, SELECTOR) [nc addObserver:self selector:@selector(SELECTOR:) name:NAME object:nil]
Expand All @@ -35,6 +36,7 @@ - (void)startObserving
ADD_KEYBOARD_HANDLER(UIKeyboardDidChangeFrameNotification, keyboardDidChangeFrame);

#undef ADD_KEYBOARD_HANDLER
#endif
}

- (NSArray<NSString *> *)supportedEvents
Expand All @@ -51,9 +53,12 @@ - (void)startObserving

- (void)stopObserving
{
#if !TARGET_OS_VISION
[[NSNotificationCenter defaultCenter] removeObserver:self];
#endif
}

#if !TARGET_OS_VISION
// Bridge might be already invalidated by the time the keyboard is about to be dismissed.
// This might happen, for example, when reload from the packager is performed.
// Thus we need to check against nil here.
Expand All @@ -72,6 +77,7 @@ -(void)EVENT : (NSNotification *)notification
IMPLEMENT_KEYBOARD_HANDLER(keyboardDidHide)
IMPLEMENT_KEYBOARD_HANDLER(keyboardWillChangeFrame)
IMPLEMENT_KEYBOARD_HANDLER(keyboardDidChangeFrame)
#endif

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
Expand Down