Skip to content

Commit dbc9942

Browse files
committed
docs: document, cursor: pointer, windowmanager, XR
1 parent c1fb4b3 commit dbc9942

File tree

8 files changed

+195
-48
lines changed

8 files changed

+195
-48
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
npm-debug.log*
1919
yarn-debug.log*
2020
yarn-error.log*
21+
.yarn

Diff for: docs/api/XR.md

+4-35
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ Manage Immersive Experiences.
55
#### **`requestSession`**
66

77
```js
8-
requestSession: (sessionId?: string) => Promise<void>
8+
requestSession: (sessionId: string, userInfo?: Object) => Promise<void>
99
```
1010

11-
Opens a new [`ImmersiveSpace`](https://developer.apple.com/documentation/swiftui/immersive-spaces) given it's unique `Id`.
11+
Opens a new [`ImmersiveSpace`](https://developer.apple.com/documentation/swiftui/immersive-spaces) given it's unique `Id`. Can also accept `userInfo` object that get's passed to the SwiftUI view.
1212

1313
:::warning
1414

@@ -28,37 +28,6 @@ endSession: () => Promise<void>
2828

2929
Closes currently open `ImmersiveSpace`.
3030

31-
## Constants
32-
33-
#### **`supportsMultipleScenes`**
34-
35-
```js
36-
supportsMultipleScenes: boolean;
37-
```
38-
39-
A Boolean value that indicates whether the app may display multiple scenes simultaneously. Returns the value of `UIApplicationSupportsMultipleScenes` key from `Info.plist`.
40-
41-
:::info
42-
43-
## UIApplicationSupportsMultipleScenes
44-
45-
In order to use this API, make sure your app supports multiple scenes. Set `UIApplicationSupportsMultipleScenes` to `true` in `Info.plist`:
46-
47-
```json
48-
<dict>
49-
<key>UIApplicationSceneManifest</key>
50-
<dict>
51-
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
52-
<string>UIWindowSceneSessionRoleApplication</string>
53-
<key>UIApplicationSupportsMultipleScenes</key>
54-
// highlight-next-line
55-
<true/>
56-
<key>UISceneConfigurations</key>
57-
<dict/>
58-
</dict>
59-
</dict>
60-
</plist>
61-
62-
```
63-
31+
:::warning
32+
Make sure to set `UIApplicationSupportsMultipleScenes` to `true` in `Info.plist` as described [here](/api/window-manager#uiapplicationsupportsmultiplescenes).
6433
:::

Diff for: docs/api/hoverEffect.md

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
# Hover Effects
22

3-
:::warning
4-
5-
This prop is soon to be removed in favour of applying this effect using `cursor: pointer` style.
6-
7-
:::
8-
9-
This is a prop on `<View />` component allowing to add hover effect. It's applied to all Touchable and Pressable components by default.
10-
11-
If you want to customize it you can use the `visionos_hoverEffect` prop, like so:
3+
This is an additional style option allowing to add hover effect when **user looks at an element**. It's applied to all Touchable and Pressable components by default.
124

135
```tsx
14-
<TouchableOpacity visionos_hoverEffect="lift">
6+
<TouchableOpacity style={{ cursor: "pointer" }}>
157
<Text>Click me</Text>
168
</TouchableOpacity>
179
```
1810

19-
The available options are: `lift` or `highlight`.
11+
## Example
12+
13+
![Hover effect](../../static/img/visionos-hover.gif)

Diff for: docs/api/intro.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ React Native visionOS builds upon APIs provided by [React Native Core](https://r
99
### List of APIs provided by React Native visionOS
1010

1111
- `XR` - API to manage Immersive Experiences
12-
- `visionos_hoverEffect` - Hover effects (soon to be removed in favour of `cursor: 'pointer'`).
12+
- `cursor: pointer` - Style used to manage hover effects.

Diff for: docs/api/window-manager.md

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Window Manager
2+
3+
This API allows you to create multi-window experiences on visionOS.
4+
5+
![Multi Window](../../static/img/multi-window.jpeg)
6+
7+
## Methods
8+
9+
#### **`getWindow`**
10+
11+
```js
12+
getWindow(id: String): Window;
13+
```
14+
15+
The `getWindow` method returns a `Window` object, which contains following properties:
16+
17+
```ts
18+
interface Window {
19+
id: String;
20+
open(props?: Object): Promise<void>;
21+
update(props: Object): Promise<void>;
22+
close(): Promise<void>;
23+
}
24+
```
25+
26+
## Constants
27+
28+
#### **`supportsMultipleScenes`**
29+
30+
```js
31+
supportsMultipleScenes: boolean;
32+
```
33+
34+
A Boolean value that indicates whether the app may display multiple scenes simultaneously. Returns the value of `UIApplicationSupportsMultipleScenes` key from `Info.plist`.
35+
36+
:::info
37+
38+
## UIApplicationSupportsMultipleScenes
39+
40+
In order to use this API, make sure your app supports multiple scenes. Set `UIApplicationSupportsMultipleScenes` to `true` in `Info.plist`:
41+
42+
```json
43+
<dict>
44+
<key>UIApplicationSceneManifest</key>
45+
<dict>
46+
<key>UIApplicationPreferredDefaultSceneSessionRole</key>
47+
<string>UIWindowSceneSessionRoleApplication</string>
48+
<key>UIApplicationSupportsMultipleScenes</key>
49+
// highlight-next-line
50+
<true/>
51+
<key>UISceneConfigurations</key>
52+
<dict/>
53+
</dict>
54+
</dict>
55+
</plist>
56+
57+
```
58+
59+
:::
60+
61+
## Example usage
62+
63+
1. Create a new component that will be used as an entry point for the second window:
64+
65+
```tsx title="SecondWindow.tsx"
66+
import { Text, View } from "react-native";
67+
import React from "react";
68+
69+
const SecondWindow = () => {
70+
return (
71+
<View>
72+
<Text>SecondWindow</Text>
73+
</View>
74+
);
75+
};
76+
77+
export default SecondWindow;
78+
```
79+
80+
2. In `index.js` use `AppRegistry.registerComponent` to register additional component:
81+
82+
```js title="index.js"
83+
AppRegistry.registerComponent("SecondWindow", () => SecondWindow);
84+
```
85+
86+
### Add native entry point
87+
88+
In `App.swift` add a second window and pass it `sceneData` object.
89+
90+
We need to retrieve `reactContext` from the environment, it contains data passed to windows from JS side.
91+
92+
Object returned from the `getSceneData` method is _reactive_ (uses Swift Observation Framework) which means that it will cause views to re-render when updated from JS side.
93+
94+
```swift
95+
@main
96+
struct HelloWorldApp: App {
97+
@UIApplicationDelegateAdaptor var delegate: AppDelegate
98+
99+
// highlight-next-line
100+
@Environment(\.reactContext) private var reactContext
101+
102+
var body: some Scene {
103+
RCTMainWindow(moduleName: "HelloWorld")
104+
// highlight-next-line
105+
RCTWindow(id: "SecondWindow", sceneData: reactContext.getSceneData(id: "SecondWindow"))
106+
}
107+
}
108+
```
109+
110+
### 4. Open Windows from JS
111+
112+
```jsx
113+
const secondWindow = WindowManager.getWindow("SecondWindow");
114+
115+
const Example = () => {
116+
return (
117+
<View style={styles.container}>
118+
<Button
119+
title="Open Second Window"
120+
onPress={() => {
121+
secondWindow.open({ title: "React Native Window" });
122+
}}
123+
/>
124+
<Button
125+
title="Update Second Window"
126+
onPress={() => {
127+
secondWindow.update({ title: "Updated Window" });
128+
}}
129+
/>
130+
<Button
131+
title="Close Second Window"
132+
onPress={() => {
133+
secondWindow.close();
134+
}}
135+
/>
136+
</View>
137+
);
138+
};
139+
```
140+
141+
### (Optional) 5. Use SwiftUI to render windows
142+
143+
Sometimes you might need to use SwiftUI for particular window and thanks to Swift Observation, SwiftUI views will be properly re-rendered when user calls `window.update({props})`.
144+
145+
In order to use SwiftUI as a view instead of `RCTWindow` create a new SwiftUI view and accept `sceneData` as parameter. This allows us to reach to the `sceneData.props` dictionary and retrieve props passed from the JS side.
146+
147+
```swift title="SecondWindow.swift"
148+
import SwiftUI
149+
// highlight-next-line
150+
import React_RCTSwiftExtensions
151+
152+
struct SecondWindow: View {
153+
// highlight-next-line
154+
let sceneData: RCTSceneData?
155+
156+
var body: some View {
157+
if let sceneData {
158+
Text(sceneData.props?["title"] as? String ?? "Title wasn't passed")
159+
}
160+
}
161+
}
162+
```
163+
164+
Next, in `App.swift`, add new WindowGroup:
165+
166+
```swift
167+
@main
168+
struct HelloWorldApp: App {
169+
@UIApplicationDelegateAdaptor var delegate: AppDelegate
170+
171+
// highlight-next-line
172+
@Environment(\.reactContext) private var reactContext
173+
174+
var body: some Scene {
175+
RCTMainWindow(moduleName: "HelloWorld")
176+
// highlight-start
177+
WindowGroup(id: "SecondWindow") {
178+
SecondWindow(sceneData: reactContext.getSceneData(id: "SecondWindow"))
179+
}
180+
// highlight-end
181+
}
182+
}
183+
```

Diff for: docs/docs/guides/immersive-spaces.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
One of the key features of visionOS are [`ImmersiveSpaces`](https://developer.apple.com/documentation/swiftui/immersive-spaces), which allow to display unbounded content in a person’s surroundings.
44

55
:::warning
6-
Make sure to set `UIApplicationSupportsMultipleScenes` to `true` in `Info.plist` as described [here](/api/XR#uiapplicationsupportsmultiplescenes).
6+
Make sure to set `UIApplicationSupportsMultipleScenes` to `true` in `Info.plist` as described [here](/api/window-manager#uiapplicationsupportsmultiplescenes).
77
:::
88

99
### Declare ImmersiveSpace in `App.swift`

Diff for: static/img/multi-window.jpeg

576 KB
Loading

Diff for: static/img/visionos-hover.gif

8.64 MB
Loading

0 commit comments

Comments
 (0)