Skip to content

Commit 3847ac6

Browse files
committed
feat: add visionos support
fix: address issues with scale, ScrollView prop feat: move min_visionos_version_supported to Helpers feat: implement `visionos_hoverStyle` prop chore: update README.MD fix: refactor visionos_hoverStyle to take a string and new arch support docs: add link to rn-tester's README.md (#5) chore: change VisionOS to visionOS (#13) chore: use `min_supported_versions` for third-party-podspecs (#18) chore: remove not necessary ifs TARGET_OS_VISION, minimise code diff (#22) feat: add visionos support add warning when using InputAccessoryView update platform naming fix: remove keyboard listerners and mark as unsupported (#25) * fix: remove keyboard listerners and mark as unsupported * chore: replace warn with warnOnce feat: support building visionOS with dynamic frameworks enabled (#28) chore: sync Podfile.lock with upstream, remove unnecessary #endif feat: add visionOS as separate target to fix iOS tests (#31) * feat: add visionOS as separate target to fix iOS tests * fix: disable multiple windows support * feat: add visionOS App Icon * fix: creating Release build Update README.md (#36) * Update README.md * fix: update README link * feat: add caution section * fix: bring back info about Hermes Add platform guidelines to README (#37) * Add platform guidelines to README * fix: link to docs Rename react-native package to @callstack/react-native-visionos (#35) * rename react-native package to @callstack/react-native-visionos * fix typo * Make JS and TS tests independent of react-native package name * change name in template * replace more refs in e2e tests * revert tests changes * disable js e2e tests for visionos * bring back react-native for other platforms compat * ci: run js, no e2e js Fix codegen issues for RNTester after renaming package (#40) feat: make hermes build for visionOS (#26) * [WIP] feat: make hermes build for visionOS * feat: point to callstack/hermes-visionos fork, update README * fix: remove USE_HERMES from project.pbxproj feat: align unnecessary compiler conditionals (#51) chore: sync Podfile.lock feat: implement OOT release script (#43) * feat: implement OOT release script * docs: add readme on Release process * fix: remove header file Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * add reference --------- Co-authored-by: Michał Pierzchała <thymikee@gmail.com> feat: add visionOS template (#34) * Update CLI to v12.1.1 * feat: implement visionos react-native template * feat: modify template look * feat: add `@callstack/out-of-tree-platforms` to metro config * fix: metro config * feat: update supported platforms --------- Co-authored-by: szymonrybczak <szymon.rybczak@gmail.com> task(StatusBar component): show warn when using StatusBar (#49) * task(StatusBar component): show warn when using StatusBar * pr suggestions docs: update CMake instructions (#55) Fix iOS native tests (#58) * fix: remove unnecessary libevent.podspec * fix: make OCMock build for visionOS fix: remove unnecessary YogaKit pod (#61) feat: add warning while building Hermes that at least CMake 3.28.0 is required (#63) fix: RCTAlertController transparent background override added cornerRadius for hover style (#66) * added corner radius for hover style * fix: implement proper handling for old arch, reformat code --------- Co-authored-by: Oskar Kwaśniewski <oskarkwasniewski@icloud.com> chore: sync Podfile.lock fix: don't warn users about the Keyboard API (#71) feat: implement visionos cli commands (#64) fix: use isVision instead of isVisionOS (#76) fix: release build bundle (#74) fix: remove duplicated isVision key (#78) fix: change resolver option name (#79) fix: RCTDeviceInfo UIApplicationDidChangeStatusBarOrientationNotification method fix: update README.md with corrected capitalization (#84) fix: upstream sync ifdefs fix: providing unsupported value to hoverStyle crashed the app (#88) fix: pointer events (#114) fix: hoverEffect for bridgeless mode (#92) refactor: remove unused RCTForegroundWindow (#94) fix: properly retrieve window when clicking DevMenu action (#95) sync with upstream chore: sync Podfile.lock docs: add how is it different from iOS version section (#91) docs: move to documentation website (#119) Update README.md (#121) * Update README.md * Update README.md Co-authored-by: Kacper Rożniata <56474758+krozniata@users.noreply.github.com> --------- Co-authored-by: Kacper Rożniata <56474758+krozniata@users.noreply.github.com> Update getting started link in Readme. (#123) Co-authored-by: christinamartinez <christina.martinez@faithlife.com> chore: remove hover effect & add cursor: pointer (#122) * chore: remove hover effect * fix: set cursor pointer by default, update tests * feat(iOS): Implement cursor style prop --------- Co-authored-by: Saad Najmi <sanajmi@microsoft.com> chore: resync with upstream fix: change versio of @callstack/out-of-tree-platforms feat: make SwiftUI React Native entry point (#68) * feat: add Swift entrypoint [wip] add module maps to some RN modules to allow for swift c++ imports feat: implement RCTReactController and RCTSwiftUIAppDelegate feat: introduce new method to RCTAppDelegate * feat: modify template to use SwiftUI * fix: dimensions, use RCTMainWindow() * fix: fallback to DarkMode on visionOS * fix: use KeyWindow() in RCTPerfMonitor feat: update docs (#80) * feat: update docs * Update README.md Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update README.md Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update README.md Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update README.md Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update README.md Co-authored-by: Michał Pierzchała <thymikee@gmail.com> --------- Co-authored-by: Michał Pierzchała <thymikee@gmail.com> feat: add UIApplicationSceneManifest to template Create custom resolver and utils package for out-of-tree platforms (#32) * rename react-native package to @callstack/react-native-visionos * wip: metro setup for other platform * fix(flow): add .ios.visionos as support platform * fix some flow errors * fix flow * revert Platform.select change * revert KeyboardAvoidingView change * fix type * change kBundlePath to ios.visionos * fix: remove redundant isVisionOS * use custom resolver options to read platform for OOT * fix types * remove formatting * add/remove platform checks * document variant behavior * use visionOS Keyboard mock * use visionOS KeyboardAvoidingView mock * use visionOS InputAccessoryView mock * test: add test for metroPlatformResolver * move implementation to user space * create out-of-tree-platforms package and bring back resolver options * revert flow changes * revert sourceExts changes * update links * add comments * fix visionos typo * adjust lockfile * revert loadMetroConfig change * remove podfile lock * revert scripts changes Fix build step for `@callstack/out-of-tree-platforms` (#46) * feat: setup @callstack/out-of-tree-platforms to build properly * feat: add build packages step to `oot-release.js` script * chore: format package.json fix(#48) local build of @callstack/out-of-tree-platforms (#50)
1 parent fc8a7b9 commit 3847ac6

File tree

117 files changed

+3049
-258
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

117 files changed

+3049
-258
lines changed

README.md

Lines changed: 26 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,147 +1,52 @@
11
<h1 align="center">
2-
<a href="https://reactnative.dev/">
3-
React Native
2+
<a href="https://callstack.github.io/react-native-visionos-docs">
3+
React Native visionOS
44
</a>
55
</h1>
66

77
<p align="center">
88
<strong>Learn once, write anywhere:</strong><br>
9-
Build mobile apps with React.
9+
Build spatial apps with React.
1010
</p>
1111

12-
<p align="center">
13-
<a href="https://github.com/facebook/react-native/blob/HEAD/LICENSE">
14-
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="React Native is released under the MIT license." />
15-
</a>
16-
<a href="https://circleci.com/gh/facebook/react-native">
17-
<img src="https://circleci.com/gh/facebook/react-native.svg?style=shield" alt="Current CircleCI build status." />
18-
</a>
19-
<a href="https://www.npmjs.org/package/react-native">
20-
<img src="https://img.shields.io/npm/v/react-native?color=brightgreen&label=npm%20package" alt="Current npm package version." />
21-
</a>
22-
<a href="https://reactnative.dev/docs/contributing">
23-
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
24-
</a>
25-
<a href="https://twitter.com/intent/follow?screen_name=reactnative">
26-
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative" />
27-
</a>
28-
</p>
29-
30-
<h3 align="center">
31-
<a href="https://reactnative.dev/docs/getting-started">Getting Started</a>
32-
<span> · </span>
33-
<a href="https://reactnative.dev/docs/tutorial">Learn the Basics</a>
34-
<span> · </span>
35-
<a href="https://reactnative.dev/showcase">Showcase</a>
36-
<span> · </span>
37-
<a href="https://reactnative.dev/docs/contributing">Contribute</a>
38-
<span> · </span>
39-
<a href="https://reactnative.dev/help">Community</a>
40-
<span> · </span>
41-
<a href="https://github.com/facebook/react-native/blob/HEAD/.github/SUPPORT.md">Support</a>
42-
</h3>
43-
44-
React Native brings [**React**'s][r] declarative UI framework to iOS and Android. With React Native, you use native UI controls and have full access to the native platform.
45-
46-
- **Declarative.** React makes it painless to create interactive UIs. Declarative views make your code more predictable and easier to debug.
47-
- **Component-Based.** Build encapsulated components that manage their state, then compose them to make complex UIs.
48-
- **Developer Velocity.** See local changes in seconds. Changes to JavaScript code can be live reloaded without rebuilding the native app.
49-
- **Portability.** Reuse code across iOS, Android, and [other platforms][p].
50-
51-
React Native is developed and supported by many companies and individual core contributors. Find out more in our [ecosystem overview][e].
52-
53-
[r]: https://react.dev/
54-
[p]: https://reactnative.dev/docs/out-of-tree-platforms
55-
[e]: https://github.com/facebook/react-native/blob/HEAD/ECOSYSTEM.md
56-
57-
## Contents
58-
59-
- [Requirements](#-requirements)
60-
- [Building your first React Native app](#-building-your-first-react-native-app)
61-
- [Documentation](#-documentation)
62-
- [Upgrading](#-upgrading)
63-
- [How to Contribute](#-how-to-contribute)
64-
- [Code of Conduct](#code-of-conduct)
65-
- [License](#-license)
66-
67-
68-
## 📋 Requirements
69-
70-
React Native apps may target iOS 13.4 and Android 6.0 (API 23) or newer. You may use Windows, macOS, or Linux as your development operating system, though building and running iOS apps is limited to macOS. Tools like [Expo](https://expo.dev) can be used to work around this.
12+
React Native visionOS allows you to write visionOS with full support for platform SDK. This is a full fork of the main repository with changes needed to support visionOS.
7113

72-
## 🎉 Building your first React Native app
14+
![Screenshot](https://github.com/callstack/react-native-visionos/assets/52801365/0fcd5e5f-628c-49ef-84ab-d1d4675a011a)
7315

74-
Follow the [Getting Started guide](https://reactnative.dev/docs/getting-started). The recommended way to install React Native depends on your project. Here you can find short guides for the most common scenarios:
16+
## 🎉 Building your first spatial React Native app
17+
Follow the [Getting Started](https://callstack.github.io/react-native-visionos-docs/category/getting-started) guide. If you wish to get started quickly, you can utilize this command:
7518

76-
- [Trying out React Native][hello-world]
77-
- [Creating a New Application][new-app]
78-
- [Adding React Native to an Existing Application][existing]
19+
```sh
20+
npx @callstack/react-native-visionos@latest init YourApp
21+
```
7922

80-
[hello-world]: https://snack.expo.dev/@samples/hello-world
81-
[new-app]: https://reactnative.dev/docs/getting-started
82-
[existing]: https://reactnative.dev/docs/integration-with-existing-apps
8323

8424
## 📖 Documentation
8525

86-
The full documentation for React Native can be found on our [website][docs].
87-
88-
The React Native documentation discusses components, APIs, and topics that are specific to React Native. For further documentation on the React API that is shared between React Native and React DOM, refer to the [React documentation][r-docs].
89-
90-
The source for the React Native documentation and website is hosted on a separate repo, [**@facebook/react-native-website**][repo-website].
91-
92-
[docs]: https://reactnative.dev/docs/getting-started
93-
[r-docs]: https://react.dev/learn
94-
[repo-website]: https://github.com/facebook/react-native-website
95-
96-
## 🚀 Upgrading
97-
98-
Upgrading to new versions of React Native may give you access to more APIs, views, developer tools, and other goodies. See the [Upgrading Guide][u] for instructions.
99-
100-
React Native releases are discussed [in this discussion repo](https://github.com/reactwg/react-native-releases/discussions).
101-
102-
[u]: https://reactnative.dev/docs/upgrading
103-
[repo-releases]: https://github.com/react-native-community/react-native-releases
104-
105-
## 👏 How to Contribute
106-
107-
The main purpose of this repository is to continue evolving React Native core. We want to make contributing to this project as easy and transparent as possible, and we are grateful to the community for contributing bug fixes and improvements. Read below to learn how you can take part in improving React Native.
108-
109-
### [Code of Conduct][code]
110-
111-
Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
112-
Please read the [full text][code] so that you can understand what actions will and will not be tolerated.
113-
114-
[code]: https://code.fb.com/codeofconduct/
115-
116-
### [Contributing Guide][contribute]
117-
118-
Read our [**Contributing Guide**][contribute] to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to React Native.
119-
120-
[contribute]: https://reactnative.dev/docs/contributing
121-
122-
### [Open Source Roadmap][roadmap]
123-
124-
You can learn more about our vision for React Native in the [**Roadmap**][roadmap].
26+
The full documentation for React Native visionOS can be found on our [website](https://callstack.github.io/react-native-visionos-docs).
12527

126-
[roadmap]: https://github.com/facebook/react-native/wiki/Roadmap
28+
The source for the React Native visionOS documentation and website is hosted on a separate repo, @callstack/react-native-visionos-docs.
12729

128-
### Good First Issues
30+
## Contributing
12931

130-
We have a list of [good first issues][gfi] that contain bugs which have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process.
32+
Prerequisites:
33+
- Download the latest Xcode (at least 15.2)
34+
- Install the latest version of CMake (at least v3.28.0)
13135

132-
[gfi]: https://github.com/facebook/react-native/labels/good%20first%20issue
36+
Check out `rn-tester` [README.md](./packages/rn-tester/README.md) to build React Native from the source.
13337

134-
### Discussions
38+
Remember to use `RNTester-visionOS` target
13539

136-
Larger discussions and proposals are discussed in [**@react-native-community/discussions-and-proposals**][repo-meta].
40+
If `RNTester-visionOS` scheme is not showing up, click "New Scheme", which should be pre-populated with `RNTester-visionOS`. Build the app using Xcode.
13741

138-
[repo-meta]: https://github.com/react-native-community/discussions-and-proposals
42+
## Release process
13943

140-
## 📄 License
44+
We use a script called `oot-release.js` which automatically releases `visionos` packages and aligns versions of dependencies with React Native core.
14145

142-
React Native is MIT licensed, as found in the [LICENSE][l] file.
46+
Usage:
14347

144-
React Native documentation is Creative Commons licensed, as found in the [LICENSE-docs][ld] file.
48+
```sh
49+
node ./scripts/oot-release.js --new-version "<visionos-version>" --react-native-version "<react-native-version>" --one-time-password "<otp>"
50+
```
14551

146-
[l]: https://github.com/facebook/react-native/blob/main/LICENSE
147-
[ld]: https://github.com/facebook/react-native/blob/main/LICENSE-docs
52+
To test releases and template we use [Verdaccio](https://verdaccio.org/).

jest.config.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ module.exports = {
4040
defaultPlatform: 'ios',
4141
platforms: ['ios', 'android'],
4242
},
43+
moduleNameMapper: {
44+
// These mappers allow out-of-tree platforms tests to seamlessly resolve RN imports
45+
'^react-native/(.*)': '<rootDir>/packages/react-native/$1',
46+
'^react-native$': '<rootDir>/packages/react-native/index.js',
47+
// This module is internal to Meta and used by their custom React renderer.
48+
// In tests, we can just use a mock.
49+
'^ReactNativeInternalFeatureFlags$':
50+
'<rootDir>/packages/react-native/jest/ReactNativeInternalFeatureFlagsMock.js',
51+
},
4352
moduleFileExtensions: ['fb.js'].concat(defaults.moduleFileExtensions),
4453
modulePathIgnorePatterns: ['scripts/.*/__fixtures__/'],
4554
unmockedModulePathPatterns: [
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Build output
2+
/dist
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# @callstack/out-of-tree-platforms
2+
3+
[![Version][version-badge]][package]
4+
5+
Utilities for Out of Tree (OOT) platforms.
6+
7+
## `getPlatformResolver`
8+
9+
```js
10+
getPlatformResolver(options: ResolverConfig): CustomResolver
11+
```
12+
13+
### options
14+
15+
```js
16+
type ResolverConfig = {
17+
platformImplementations: {[platform: string]: string},
18+
};
19+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './src';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@callstack/out-of-tree-platforms",
3+
"version": "0.75.0-main",
4+
"description": "Utils for React Native out of tree platforms.",
5+
"keywords": ["out-of-tree", "react-native"],
6+
"homepage": "https://github.com/callstack/react-native-visionos/tree/HEAD/packages/out-of-tree-platforms#readme",
7+
"bugs": "https://github.com/callstack/react-native-visionos/issues",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/callstack/react-native-visionos.git",
11+
"directory": "packages/out-of-tree-platforms"
12+
},
13+
"license": "MIT",
14+
"exports": {
15+
".": "./src/index.js",
16+
"./package.json": "./package.json"
17+
},
18+
"files": [
19+
"dist"
20+
],
21+
"devDependencies": {
22+
"metro-resolver": "^0.80.0"
23+
},
24+
"engines": {
25+
"node": ">=18"
26+
}
27+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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
8+
* @format
9+
*/
10+
11+
import type {CustomResolver} from 'metro-resolver';
12+
13+
type ResolverConfig = {
14+
platformNameMap: {[platform: string]: string},
15+
};
16+
17+
/**
18+
* Creates a custom Metro resolver that maps platform extensions to package names.
19+
* To be used in app's `metro.config.js` as `resolver.resolveRequest`.
20+
*/
21+
export const getPlatformResolver = (config: ResolverConfig): CustomResolver => {
22+
return (context, moduleName, platform) => {
23+
// `customResolverOptions` is populated through `?resolver.platformExtension` query params
24+
// in the jsBundleURLForBundleRoot method of the react-native/React/Base/RCTBundleURLProvider.mm
25+
const platformExtension = context.customResolverOptions?.platformExtension;
26+
let modifiedModuleName = moduleName;
27+
if (
28+
typeof platformExtension === 'string' &&
29+
config.platformNameMap?.[platformExtension]
30+
) {
31+
const packageName = config.platformNameMap[platformExtension];
32+
if (moduleName === 'react-native') {
33+
modifiedModuleName = packageName;
34+
} else if (moduleName.startsWith('react-native/')) {
35+
modifiedModuleName = `${packageName}/${modifiedModuleName.slice(
36+
'react-native/'.length,
37+
)}`;
38+
}
39+
}
40+
41+
return context.resolveRequest(context, modifiedModuleName, platform);
42+
};
43+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
if (!process.env.BUILD_EXCLUDE_BABEL_REGISTER) {
2+
require('../../../scripts/build/babel-register').registerForMonorepo();
3+
}
4+
5+
export * from './getPlatformResolver';

packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#import <react/renderer/graphics/ColorComponents.h>
1919
#import "RCTAppDelegate+Protected.h"
2020
#import "RCTAppSetupUtils.h"
21+
#import <objc/runtime.h>
2122

2223
#if RN_DISABLE_OSS_PLUGIN_HEADER
2324
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
@@ -48,10 +49,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
4849

4950
self.rootViewFactory = [self createRCTRootViewFactory];
5051

51-
UIView *rootView = [self.rootViewFactory viewWithModuleName:self.moduleName
52-
initialProperties:self.initialProps
53-
launchOptions:launchOptions];
54-
5552
if (self.newArchEnabled || self.fabricEnabled) {
5653
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
5754
}

packages/react-native/Libraries/Components/Keyboard/Keyboard.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import LayoutAnimation from '../../LayoutAnimation/LayoutAnimation';
1515
import dismissKeyboard from '../../Utilities/dismissKeyboard';
1616
import Platform from '../../Utilities/Platform';
1717
import NativeKeyboardObserver from './NativeKeyboardObserver';
18+
import warnOnce from '../../Utilities/warnOnce';
1819

1920
export type KeyboardEventName = $Keys<KeyboardEventDefinitions>;
2021

@@ -114,6 +115,10 @@ class Keyboard {
114115
);
115116

116117
constructor() {
118+
if (Platform.isVision) {
119+
return;
120+
}
121+
117122
this.addListener('keyboardDidShow', ev => {
118123
this._currentlyShowing = ev;
119124
});
@@ -151,6 +156,14 @@ class Keyboard {
151156
listener: (...$ElementType<KeyboardEventDefinitions, K>) => mixed,
152157
context?: mixed,
153158
): EventSubscription {
159+
if (Platform.isVision) {
160+
warnOnce(
161+
'Keyboard-unavailable',
162+
'Keyboard API 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',
163+
);
164+
return {remove() {}};
165+
}
166+
154167
return this._emitter.addListener(eventType, listener);
155168
}
156169

@@ -160,6 +173,10 @@ class Keyboard {
160173
* @param {string} eventType The native event string listeners are watching which will be removed.
161174
*/
162175
removeAllListeners<K: $Keys<KeyboardEventDefinitions>>(eventType: ?K): void {
176+
if (Platform.isVision) {
177+
return;
178+
}
179+
163180
this._emitter.removeAllListeners(eventType);
164181
}
165182

packages/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
2424
import View from '../View/View';
2525
import Keyboard from './Keyboard';
2626
import * as React from 'react';
27+
import warnOnce from '../../Utilities/warnOnce';
2728

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

177178
componentDidMount(): void {
178179
if (Platform.OS === 'ios') {
180+
if (Platform.isVision) {
181+
warnOnce(
182+
'KeyboardAvoidingView-unavailable',
183+
'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',
184+
);
185+
return;
186+
}
179187
this._subscriptions = [
180188
Keyboard.addListener('keyboardWillChangeFrame', this._onKeyboardChange),
181189
];
@@ -205,6 +213,16 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
205213
onLayout,
206214
...props
207215
} = this.props;
216+
217+
if (Platform.isVision) {
218+
// KeyboardAvoidingView is not supported on VisionOS, so we return a simple View without the onLayout handler
219+
return (
220+
<View ref={this.viewRef} style={style} {...props}>
221+
{children}
222+
</View>
223+
);
224+
}
225+
208226
const bottomHeight = enabled === true ? this.state.bottom : 0;
209227
switch (behavior) {
210228
case 'height':

0 commit comments

Comments
 (0)