Skip to content

Commit 9ed2ea2

Browse files
CopilotSaadnajmi
andauthored
docs: Add documentation pages for macOS only props and events (#2741)
## Summary Originally made with @Copilot . Added a new navbar "API" tab to the docsite that shows off the macOS specific props and APIs we have. ## Test Plan <img width="1232" height="1414" alt="image" src="https://github.com/user-attachments/assets/0037e592-2b33-4844-b77a-89f2d6ffe1b8" /> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Saadnajmi <6722175+Saadnajmi@users.noreply.github.com> Co-authored-by: Saad Najmi <sanajmi@microsoft.com>
1 parent e57e55c commit 9ed2ea2

File tree

5 files changed

+499
-0
lines changed

5 files changed

+499
-0
lines changed

docsite/api/intro.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
sidebar_position: 1
3+
slug: /
4+
---
5+
6+
# macOS API Reference
7+
8+
Welcome to the React Native macOS API reference documentation. This section covers macOS-specific props and events that extend the standard React Native components.
9+
10+
Most of the additional functionality out of React Native macOS directly is in the form of additional props and callback events implemented on `<View>`, to provide macOS and desktop specific behavior

docsite/api/view-events.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
sidebar_label: 'Events'
3+
sidebar_position: 2
4+
---
5+
6+
# Events
7+
8+
React Native macOS extends the standard React Native View component with additional events that are specific to macOS. These events allow you to respond to macOS-specific user interactions such as keyboard input, mouse movements, drag and drop operations, and more.
9+
10+
## Focus
11+
12+
This event is useful for implementing custom focus management and showing focus-specific UI elements. For these to fire, the prop [focusable](view-props#focusable) must be set.
13+
14+
### `onFocus`
15+
16+
Fired when the view receives focus.
17+
18+
---
19+
20+
### `onBlur`
21+
22+
Fired when the view loses focus. This is supported for all Views
23+
24+
---
25+
26+
27+
## Keyboard
28+
29+
### `onKeyDown`
30+
31+
Fired when a key is pressed while the view has focus.
32+
33+
**Event Data:** Key event with the following properties:
34+
- `key`: The key value (aligned with [W3C UI Events](https://www.w3.org/TR/uievents-key/))
35+
- `altKey`: Whether Alt/Option key is pressed
36+
- `ctrlKey`: Whether Control key is pressed
37+
- `shiftKey`: Whether Shift key is pressed
38+
- `metaKey`: Whether Command key is pressed
39+
- `capsLockKey`: Whether Caps Lock is active
40+
- `numericPadKey`: Whether the key is on the numeric keypad
41+
- `helpKey`: Whether Help key is pressed
42+
- `functionKey`: Whether a function key is pressed
43+
44+
:::note
45+
To receive key events, the view must have `focusable={true}` set, and you should specify which keys to handle using the `keyDownEvents` prop.
46+
:::
47+
48+
Example:
49+
```javascript
50+
<View
51+
focusable={true}
52+
keyDownEvents=[
53+
{ key: 'Enter' },
54+
{ key: 's', metaKey: true }
55+
]
56+
onKeyDown={(event) => {
57+
const { key, metaKey } = event.nativeEvent;
58+
if (key === 'Enter') {
59+
console.log('Enter pressed');
60+
} else if (key === 's' && metaKey) {
61+
console.log('Command+S pressed');
62+
}
63+
}}
64+
>
65+
<Text>Press Enter or Cmd+S</Text>
66+
</View>
67+
```
68+
69+
---
70+
71+
### `onKeyUp`
72+
73+
Fired when a key is released while the view has focus.
74+
75+
**Event Data:** Key event (same format as `onKeyDown`)
76+
77+
:::note
78+
To receive key events, the view must have `focusable={true}` set, and you should specify which keys to handle using the `keyUpEvents` prop.
79+
:::
80+
81+
---
82+
83+
## Mouse
84+
85+
### `onMouseEnter`
86+
87+
Fired when the mouse cursor enters the view's bounds.
88+
89+
**Event Data:** Mouse event with the following properties:
90+
- `clientX`: Horizontal position in the target view
91+
- `clientY`: Vertical position in the target view
92+
- `screenX`: Horizontal position in the window
93+
- `screenY`: Vertical position in the window
94+
- `altKey`: Whether Alt/Option key is pressed
95+
- `ctrlKey`: Whether Control key is pressed
96+
- `shiftKey`: Whether Shift key is pressed
97+
- `metaKey`: Whether Command key is pressed
98+
99+
Example:
100+
```javascript
101+
<View onMouseEnter={(event) => {
102+
console.log('Mouse entered at', event.nativeEvent.clientX, event.nativeEvent.clientY);
103+
}}>
104+
<Text>Hover over me</Text>
105+
</View>
106+
```
107+
108+
---
109+
110+
### `onMouseLeave`
111+
112+
Fired when the mouse cursor leaves the view's bounds.
113+
114+
**Event Data:** Mouse event (same format as `onMouseEnter`)
115+
116+
Example:
117+
```javascript
118+
<View
119+
onMouseEnter={() => setIsHovered(true)}
120+
onMouseLeave={() => setIsHovered(false)}
121+
style={{ backgroundColor: isHovered ? 'lightblue' : 'white' }}
122+
>
123+
<Text>Hover state example</Text>
124+
</View>
125+
```
126+
127+
---
128+
129+
### `onDoubleClick`
130+
131+
Fired when the user double-clicks on the view.
132+
133+
**Event Data:** Mouse event with the following properties:
134+
- `clientX`: Horizontal position in the target view
135+
- `clientY`: Vertical position in the target view
136+
- `screenX`: Horizontal position in the window
137+
- `screenY`: Vertical position in the window
138+
- `altKey`: Whether Alt/Option key is pressed
139+
- `ctrlKey`: Whether Control key is pressed
140+
- `shiftKey`: Whether Shift key is pressed
141+
- `metaKey`: Whether Command key is pressed
142+
143+
Example:
144+
```javascript
145+
<View onDoubleClick={(event) => {
146+
console.log('Double clicked at', event.nativeEvent.clientX, event.nativeEvent.clientY);
147+
}}>
148+
<Text>Double click me</Text>
149+
</View>
150+
```
151+
152+
---
153+
154+
### `onDragEnter`
155+
156+
Fired when a drag operation enters the view's bounds.
157+
158+
**Event Data:** Drag event with mouse position and data transfer information
159+
160+
This event is fired when the user drags content over the view. Use this to provide visual feedback that the view can accept the dragged content.
161+
162+
---
163+
164+
### `onDragLeave`
165+
166+
Fired when a drag operation leaves the view's bounds.
167+
168+
**Event Data:** Drag event with mouse position and data transfer information
169+
170+
This event is fired when the user drags content away from the view. Use this to remove any visual feedback shown during drag enter.
171+
172+
---
173+
174+
### `onDrop`
175+
176+
Fired when the user drops content onto the view.
177+
178+
**Event Data:** Drag event with the following properties:
179+
- Mouse position (`clientX`, `clientY`, `screenX`, `screenY`)
180+
- Modifier keys (`altKey`, `ctrlKey`, `shiftKey`, `metaKey`)
181+
- `dataTransfer`: Object containing:
182+
- `files`: Array of dropped files, each with:
183+
- `name`: File name
184+
- `type`: MIME type
185+
- `uri`: File URI
186+
- `size`: File size (optional)
187+
- `width`: Image width (optional, for images)
188+
- `height`: Image height (optional, for images)
189+
- `items`: Array of data transfer items, each with:
190+
- `kind`: Item kind (e.g., 'file', 'string')
191+
- `type`: MIME type
192+
- `types`: Array of available data types
193+
194+
Example:
195+
```javascript
196+
<View
197+
draggedTypes={['public.file-url']}
198+
onDrop={(event) => {
199+
const files = event.nativeEvent.dataTransfer.files;
200+
files.forEach(file => {
201+
console.log('Dropped file:', file.name, file.uri);
202+
});
203+
}}
204+
>
205+
<Text>Drop files here</Text>
206+
</View>
207+
```
208+
209+
---
210+
211+
## Complete Example
212+
213+
Here's a comprehensive example showing multiple macOS-specific events:
214+
215+
```javascript
216+
import React, { useState } from 'react';
217+
import { View, Text, StyleSheet } from 'react-native';
218+
219+
function MacOSEventsExample() {
220+
const [status, setStatus] = useState('Ready');
221+
const [isHovered, setIsHovered] = useState(false);
222+
223+
return (
224+
<View style={styles.container}>
225+
<View
226+
style={[
227+
styles.interactiveView,
228+
isHovered && styles.hoveredView
229+
]}
230+
focusable={true}
231+
enableFocusRing={true}
232+
draggedTypes={['public.file-url', 'public.text']}
233+
keyDownEvents={[
234+
{ key: 'Enter' },
235+
{ key: 'Escape' }
236+
]}
237+
onFocus={() => setStatus('Focused')}
238+
onBlur={() => setStatus('Blurred')}
239+
onKeyDown={(e) => setStatus(`Key down: ${e.nativeEvent.key}`)}
240+
onKeyUp={(e) => setStatus(`Key up: ${e.nativeEvent.key}`)}
241+
onMouseEnter={(e) => {
242+
setIsHovered(true);
243+
setStatus(`Mouse entered at (${e.nativeEvent.clientX}, ${e.nativeEvent.clientY})`);
244+
}}
245+
onMouseLeave={() => {
246+
setIsHovered(false);
247+
setStatus('Mouse left');
248+
}}
249+
onDoubleClick={() => setStatus('Double clicked!')}
250+
onDragEnter={() => setStatus('Drag entered')}
251+
onDragLeave={() => setStatus('Drag left')}
252+
onDrop={(e) => {
253+
const files = e.nativeEvent.dataTransfer.files;
254+
setStatus(`Dropped ${files.length} file(s)`);
255+
}}
256+
>
257+
<Text>Interactive macOS View</Text>
258+
<Text style={styles.statusText}>{status}</Text>
259+
</View>
260+
</View>
261+
);
262+
}
263+
264+
265+
height: 200,
266+
backgroundColor: 'white',
267+
borderWidth: 2,
268+
borderColor: 'gray',
269+
padding: 20,
270+
},
271+
hoveredView: {
272+
backgroundColor: 'lightblue',
273+
},
274+
statusText: {
275+
marginTop: 10,
276+
fontStyle: 'italic',
277+
},
278+
});
279+
280+
export default MacOSEventsExample;
281+
```

0 commit comments

Comments
 (0)