0
# Event Handling System
1
2
Comprehensive event handling system with Windows-specific enhancements including keyboard navigation, mouse interactions, focus management, and native event integration.
3
4
## Capabilities
5
6
### Keyboard Events
7
8
#### Enhanced Keyboard Support
9
10
Windows-specific keyboard event handling with support for modifier keys, key combinations, and navigation patterns.
11
12
```typescript { .api }
13
/**
14
* Event phase enumeration for keyboard and mouse events
15
*/
16
namespace EventPhase {
17
export const None = 0;
18
export const Capturing = 1;
19
export const AtTarget = 2;
20
export const Bubbling = 3;
21
}
22
23
/**
24
* React Native synthetic event wrapper
25
*/
26
interface NativeSyntheticEvent<T> {
27
nativeEvent: T;
28
currentTarget: EventTarget;
29
target: EventTarget;
30
bubbles: boolean;
31
cancelable: boolean;
32
defaultPrevented: boolean;
33
eventPhase: number;
34
isTrusted: boolean;
35
preventDefault(): void;
36
stopPropagation(): void;
37
timeStamp: number;
38
type: string;
39
}
40
41
/**
42
* Windows keyboard event interface with comprehensive key information
43
* Supports modifier keys, key codes, and event phases
44
*/
45
interface INativeKeyboardEvent {
46
/** Alt key pressed state */
47
altKey: boolean;
48
/** Ctrl key pressed state */
49
ctrlKey: boolean;
50
/** Meta key (Windows key) pressed state */
51
metaKey: boolean;
52
/** Shift key pressed state */
53
shiftKey: boolean;
54
/** Key identifier string */
55
key: string;
56
/** Physical key code */
57
code: string;
58
/** Event phase (capturing, at target, bubbling) */
59
eventPhase: EventPhase.None | EventPhase.Capturing | EventPhase.AtTarget | EventPhase.Bubbling;
60
}
61
62
type IKeyboardEvent = NativeSyntheticEvent<INativeKeyboardEvent>;
63
64
/**
65
* Handled keyboard event configuration interface
66
*/
67
interface IHandledKeyboardEvent {
68
/** Alt key requirement */
69
altKey?: boolean;
70
/** Ctrl key requirement */
71
ctrlKey?: boolean;
72
/** Meta key requirement */
73
metaKey?: boolean;
74
/** Shift key requirement */
75
shiftKey?: boolean;
76
/** Physical key code to handle */
77
code: string;
78
/** Event phase to handle */
79
handledEventPhase?: EventPhase.Capturing | EventPhase.Bubbling;
80
}
81
82
/**
83
* Keyboard event handlers for Windows components
84
*/
85
interface KeyboardEventHandlers {
86
/** Key down event handler */
87
onKeyDown?: (args: IKeyboardEvent) => void;
88
/** Key up event handler */
89
onKeyUp?: (args: IKeyboardEvent) => void;
90
/** Capture phase key down handler */
91
onKeyDownCapture?: (args: IKeyboardEvent) => void;
92
/** Capture phase key up handler */
93
onKeyUpCapture?: (args: IKeyboardEvent) => void;
94
/** Array of handled keyboard events for onKeyDown */
95
keyDownEvents?: IHandledKeyboardEvent[];
96
/** Array of handled keyboard events for onKeyUp */
97
keyUpEvents?: IHandledKeyboardEvent[];
98
}
99
```
100
101
**Usage Examples:**
102
103
```typescript
104
import React from 'react';
105
import { View, Text } from 'react-native-windows';
106
107
const KeyboardExample: React.FC = () => {
108
const handleKeyDown = (event: IKeyboardEvent) => {
109
const { key, ctrlKey, shiftKey, altKey } = event.nativeEvent;
110
111
// Handle specific key combinations
112
if (ctrlKey && key === 's') {
113
console.log('Save shortcut pressed');
114
event.preventDefault();
115
} else if (key === 'Enter') {
116
console.log('Enter key pressed');
117
} else if (key === 'Escape') {
118
console.log('Escape key pressed');
119
}
120
121
// Handle modifier combinations
122
if (ctrlKey && shiftKey && key === 'p') {
123
console.log('Command palette shortcut');
124
}
125
};
126
127
return (
128
<View
129
tabIndex={0}
130
onKeyDown={handleKeyDown}
131
keyDownEvents={[
132
{ code: 'Enter' },
133
{ code: 'Escape' },
134
{ code: 'Space' },
135
{ code: 'ArrowUp' },
136
{ code: 'ArrowDown' }
137
]}
138
style={{ padding: 16, backgroundColor: '#f0f0f0' }}
139
>
140
<Text>Press keys to interact</Text>
141
</View>
142
);
143
};
144
```
145
146
### Mouse Events
147
148
#### Mouse Interaction Support
149
150
Comprehensive mouse event handling with button states, coordinates, and modifier key support.
151
152
```typescript { .api }
153
/**
154
* Windows mouse event interface with detailed interaction information
155
* Provides button states, coordinates, and modifier keys
156
*/
157
type INativeMouseEvent = {
158
/** Target element reference */
159
target: number;
160
/** Mouse event identifier */
161
identifier: number;
162
/** X coordinate relative to page */
163
pageX: number;
164
/** Y coordinate relative to page */
165
pageY: number;
166
/** X coordinate relative to the element */
167
locationX: number;
168
/** Y coordinate relative to the element */
169
locationY: number;
170
/** Event timestamp */
171
timestamp: number;
172
/** Pointer type (mouse, pen, touch) */
173
pointerType: string;
174
/** Pressure force applied */
175
force: number;
176
/** Left mouse button pressed state */
177
isLeftButton: boolean;
178
/** Right mouse button pressed state */
179
isRightButton: boolean;
180
/** Middle mouse button pressed state */
181
isMiddleButton: boolean;
182
/** Barrel button pressed state (pen) */
183
isBarrelButtonPressed: boolean;
184
/** Horizontal scroll wheel active */
185
isHorizontalScrollWheel: boolean;
186
/** Eraser mode active (pen) */
187
isEraser: boolean;
188
/** Shift key pressed state */
189
shiftKey: boolean;
190
/** Ctrl key pressed state */
191
ctrlKey: boolean;
192
/** Alt key pressed state */
193
altKey: boolean;
194
};
195
196
type IMouseEvent = NativeSyntheticEvent<INativeMouseEvent>;
197
198
/**
199
* Mouse event handlers for Windows components
200
*/
201
interface MouseEventHandlers {
202
/** Mouse enter event handler */
203
onMouseEnter?: (args: IMouseEvent) => void;
204
/** Mouse leave event handler */
205
onMouseLeave?: (args: IMouseEvent) => void;
206
}
207
```
208
209
**Usage Examples:**
210
211
```typescript
212
import React, { useState } from 'react';
213
import { View, Text } from 'react-native-windows';
214
215
const MouseExample: React.FC = () => {
216
const [mouseInfo, setMouseInfo] = useState('');
217
const [isHovered, setIsHovered] = useState(false);
218
219
const handleMouseEnter = (event: IMouseEvent) => {
220
setIsHovered(true);
221
setMouseInfo(`Mouse entered at (${event.nativeEvent.pageX}, ${event.nativeEvent.pageY})`);
222
};
223
224
const handleMouseLeave = () => {
225
setIsHovered(false);
226
setMouseInfo('Mouse left');
227
};
228
229
230
return (
231
<View
232
onMouseEnter={handleMouseEnter}
233
onMouseLeave={handleMouseLeave}
234
style={{
235
padding: 20,
236
backgroundColor: isHovered ? '#e3f2fd' : '#f5f5f5',
237
borderRadius: 8,
238
margin: 16,
239
}}
240
>
241
<Text>Mouse interaction area</Text>
242
<Text style={{ fontSize: 12, color: '#666', marginTop: 8 }}>
243
{mouseInfo || 'Move mouse over this area'}
244
</Text>
245
</View>
246
);
247
};
248
```
249
250
### Focus Events
251
252
#### Focus Management System
253
254
Windows focus management with accessibility support and keyboard navigation.
255
256
```typescript { .api }
257
/**
258
* Focus event interface for accessibility and navigation
259
*/
260
interface IFocusEvent {
261
/** Target element that received/lost focus */
262
target: any;
263
/** Related target (element losing/gaining focus) */
264
relatedTarget?: any;
265
/** Event timestamp */
266
timeStamp: number;
267
}
268
269
/**
270
* Focus event handlers
271
*/
272
interface FocusEventHandlers {
273
/** Focus gained handler */
274
onFocus?: (event: { nativeEvent: IFocusEvent }) => void;
275
/** Focus lost handler */
276
onBlur?: (event: { nativeEvent: IFocusEvent }) => void;
277
/** Focus gained (capture phase) */
278
onFocusCapture?: (event: { nativeEvent: IFocusEvent }) => void;
279
/** Focus lost (capture phase) */
280
onBlurCapture?: (event: { nativeEvent: IFocusEvent }) => void;
281
}
282
283
/**
284
* Focus management properties
285
*/
286
interface FocusProps {
287
/** Tab navigation index */
288
tabIndex?: number;
289
/** Enable focus ring visibility */
290
enableFocusRing?: boolean;
291
/** Auto focus on mount */
292
autoFocus?: boolean;
293
/** Focus on click/press */
294
focusable?: boolean;
295
}
296
```
297
298
**Usage Examples:**
299
300
```typescript
301
import React, { useState, useRef } from 'react';
302
import { View, Text, Pressable } from 'react-native-windows';
303
304
const FocusExample: React.FC = () => {
305
const [focusedElement, setFocusedElement] = useState<string>('');
306
const buttonRefs = useRef<Array<React.RefObject<any>>>([]);
307
308
const handleFocus = (elementName: string) => (event: { nativeEvent: IFocusEvent }) => {
309
setFocusedElement(elementName);
310
console.log(`${elementName} gained focus`);
311
};
312
313
const handleBlur = (elementName: string) => () => {
314
console.log(`${elementName} lost focus`);
315
};
316
317
const handleKeyDown = (event: { nativeEvent: IKeyboardEvent }) => {
318
const { key } = event.nativeEvent;
319
320
// Arrow key navigation
321
if (key === 'ArrowDown' || key === 'ArrowRight') {
322
// Move to next focusable element
323
const currentIndex = focusedElement ? parseInt(focusedElement.split(' ')[1]) - 1 : -1;
324
const nextIndex = Math.min(currentIndex + 1, buttonRefs.current.length - 1);
325
buttonRefs.current[nextIndex]?.current?.focus();
326
} else if (key === 'ArrowUp' || key === 'ArrowLeft') {
327
// Move to previous focusable element
328
const currentIndex = focusedElement ? parseInt(focusedElement.split(' ')[1]) - 1 : buttonRefs.current.length;
329
const prevIndex = Math.max(currentIndex - 1, 0);
330
buttonRefs.current[prevIndex]?.current?.focus();
331
}
332
};
333
334
return (
335
<View onKeyDown={handleKeyDown} style={{ padding: 16 }}>
336
<Text style={{ marginBottom: 16 }}>
337
Currently focused: {focusedElement || 'None'}
338
</Text>
339
340
{[1, 2, 3].map((num) => {
341
const ref = React.createRef();
342
buttonRefs.current[num - 1] = ref;
343
344
return (
345
<Pressable
346
key={num}
347
ref={ref}
348
tabIndex={num}
349
enableFocusRing={true}
350
onFocus={handleFocus(`Button ${num}`)}
351
onBlur={handleBlur(`Button ${num}`)}
352
style={{
353
padding: 12,
354
backgroundColor: focusedElement === `Button ${num}` ? '#0078d4' : '#f0f0f0',
355
marginBottom: 8,
356
borderRadius: 4,
357
}}
358
>
359
<Text style={{
360
color: focusedElement === `Button ${num}` ? 'white' : 'black'
361
}}>
362
Button {num} (Tab Index: {num})
363
</Text>
364
</Pressable>
365
);
366
})}
367
</View>
368
);
369
};
370
```
371
372
### Touch and Gesture Events
373
374
#### Touch Event System
375
376
Enhanced touch event handling with Windows-specific touch and pen support.
377
378
```typescript { .api }
379
/**
380
* Touch event interface with multi-touch support
381
*/
382
interface ITouchEvent {
383
/** Array of changed touch points */
384
changedTouches: Touch[];
385
/** Touch identifier */
386
identifier: number;
387
/** X coordinate relative to component */
388
locationX: number;
389
/** Y coordinate relative to component */
390
locationY: number;
391
/** X coordinate relative to page */
392
pageX: number;
393
/** Y coordinate relative to page */
394
pageY: number;
395
/** Target element */
396
target: number;
397
/** Event timestamp */
398
timestamp: number;
399
/** All active touch points */
400
touches: Touch[];
401
}
402
403
interface Touch {
404
/** Unique touch identifier */
405
identifier: number;
406
/** X coordinate relative to component */
407
locationX: number;
408
/** Y coordinate relative to component */
409
locationY: number;
410
/** X coordinate relative to page */
411
pageX: number;
412
/** Y coordinate relative to page */
413
pageY: number;
414
/** Target element */
415
target: number;
416
/** Touch timestamp */
417
timestamp: number;
418
/** Touch force (pressure) */
419
force?: number;
420
/** Touch radius */
421
majorRadius?: number;
422
/** Touch radius */
423
minorRadius?: number;
424
}
425
426
/**
427
* Touch event handlers
428
*/
429
interface TouchEventHandlers {
430
/** Touch start handler */
431
onTouchStart?: (event: { nativeEvent: ITouchEvent }) => void;
432
/** Touch move handler */
433
onTouchMove?: (event: { nativeEvent: ITouchEvent }) => void;
434
/** Touch end handler */
435
onTouchEnd?: (event: { nativeEvent: ITouchEvent }) => void;
436
/** Touch cancel handler */
437
onTouchCancel?: (event: { nativeEvent: ITouchEvent }) => void;
438
}
439
```
440
441
### Event Phase Management
442
443
#### Event Phase Control
444
445
Windows-specific event phase management for capture and bubble phases.
446
447
```typescript { .api }
448
/**
449
* Event phase enumeration for Windows event handling
450
*/
451
enum EventPhase {
452
/** No event phase */
453
None = 0,
454
/** Capture phase (top-down) */
455
Capturing = 1,
456
/** At target element */
457
AtTarget = 2,
458
/** Bubble phase (bottom-up) */
459
Bubbling = 3,
460
}
461
462
/**
463
* Handled event phase enumeration
464
*/
465
enum HandledEventPhase {
466
/** No handling */
467
None = 0,
468
/** Handle in capture phase */
469
Capturing = 1,
470
/** Handle at target */
471
AtTarget = 2,
472
/** Handle in bubble phase */
473
Bubbling = 3,
474
}
475
476
/**
477
* Event handler configuration with phase control
478
*/
479
interface EventHandlerConfig {
480
/** Event phase to handle */
481
handledEventPhase?: HandledEventPhase;
482
/** Stop event propagation */
483
stopPropagation?: boolean;
484
/** Prevent default behavior */
485
preventDefault?: boolean;
486
}
487
```
488
489
**Usage Examples:**
490
491
```typescript
492
import React from 'react';
493
import { View, Text } from 'react-native-windows';
494
495
const EventPhaseExample: React.FC = () => {
496
const handleParentKeyDown = (event: { nativeEvent: IKeyboardEvent }) => {
497
console.log('Parent received key event in:',
498
event.nativeEvent.eventPhase === EventPhase.Capturing ? 'Capture' : 'Bubble');
499
};
500
501
const handleChildKeyDown = (event: { nativeEvent: IKeyboardEvent }) => {
502
console.log('Child handling key event:', event.nativeEvent.key);
503
504
// Stop propagation to parent
505
if (event.nativeEvent.key === 'Escape') {
506
event.stopPropagation();
507
}
508
};
509
510
return (
511
<View
512
tabIndex={0}
513
onKeyDown={handleParentKeyDown}
514
onKeyDownCapture={handleParentKeyDown} // Capture phase
515
style={{ padding: 20, backgroundColor: '#f0f0f0' }}
516
>
517
<Text>Parent Container (receives events in capture and bubble)</Text>
518
519
<View
520
tabIndex={0}
521
onKeyDown={handleChildKeyDown}
522
style={{
523
padding: 16,
524
marginTop: 16,
525
backgroundColor: '#e3f2fd',
526
borderRadius: 4
527
}}
528
>
529
<Text>Child Element (press Escape to stop propagation)</Text>
530
</View>
531
</View>
532
);
533
};
534
```
535
536
### Custom Event Handling
537
538
#### Advanced Event Patterns
539
540
Complex event handling patterns for Windows applications.
541
542
```typescript { .api }
543
/**
544
* Custom event handler utilities
545
*/
546
interface EventUtils {
547
/** Throttle event handler */
548
throttle<T extends (...args: any[]) => any>(
549
func: T,
550
delay: number
551
): T;
552
553
/** Debounce event handler */
554
debounce<T extends (...args: any[]) => any>(
555
func: T,
556
delay: number
557
): T;
558
559
/** Combine multiple event handlers */
560
combine<T>(...handlers: Array<(event: T) => void>): (event: T) => void;
561
}
562
```
563
564
**Usage Examples:**
565
566
```typescript
567
import React, { useCallback, useMemo } from 'react';
568
import { View, Text } from 'react-native-windows';
569
570
const CustomEventExample: React.FC = () => {
571
// Debounced search handler
572
const debouncedSearch = useCallback(
573
debounce((query: string) => {
574
console.log('Searching for:', query);
575
}, 300),
576
[]
577
);
578
579
// Throttled scroll handler
580
const throttledScroll = useCallback(
581
throttle((event: any) => {
582
console.log('Scroll position:', event.nativeEvent.contentOffset);
583
}, 100),
584
[]
585
);
586
587
// Combined key handler
588
const combinedKeyHandler = useMemo(
589
() => combine(
590
(event: { nativeEvent: IKeyboardEvent }) => {
591
// Log all keys
592
console.log('Key pressed:', event.nativeEvent.key);
593
},
594
(event: { nativeEvent: IKeyboardEvent }) => {
595
// Handle shortcuts
596
if (event.nativeEvent.ctrlKey && event.nativeEvent.key === 'f') {
597
console.log('Find shortcut');
598
}
599
}
600
),
601
[]
602
);
603
604
return (
605
<View
606
tabIndex={0}
607
onKeyDown={combinedKeyHandler}
608
style={{ padding: 16 }}
609
>
610
<Text>Advanced event handling example</Text>
611
</View>
612
);
613
};
614
615
// Utility implementations
616
function debounce<T extends (...args: any[]) => any>(func: T, delay: number): T {
617
let timeoutId: NodeJS.Timeout;
618
return ((...args: any[]) => {
619
clearTimeout(timeoutId);
620
timeoutId = setTimeout(() => func.apply(this, args), delay);
621
}) as T;
622
}
623
624
function throttle<T extends (...args: any[]) => any>(func: T, delay: number): T {
625
let inThrottle: boolean;
626
return ((...args: any[]) => {
627
if (!inThrottle) {
628
func.apply(this, args);
629
inThrottle = true;
630
setTimeout(() => inThrottle = false, delay);
631
}
632
}) as T;
633
}
634
635
function combine<T>(...handlers: Array<(event: T) => void>): (event: T) => void {
636
return (event: T) => {
637
handlers.forEach(handler => handler(event));
638
};
639
}
640
```
641
642
## Windows Event Patterns
643
644
### Keyboard Navigation
645
646
```typescript
647
// Standard Windows keyboard navigation
648
const keyboardNavigation = {
649
// Tab navigation
650
'Tab': () => focusNext(),
651
'Shift+Tab': () => focusPrevious(),
652
653
// Arrow navigation
654
'ArrowDown': () => moveDown(),
655
'ArrowUp': () => moveUp(),
656
'ArrowLeft': () => moveLeft(),
657
'ArrowRight': () => moveRight(),
658
659
// Action keys
660
'Enter': () => activate(),
661
'Space': () => activate(),
662
'Escape': () => cancel(),
663
664
// Windows shortcuts
665
'Ctrl+a': () => selectAll(),
666
'Ctrl+c': () => copy(),
667
'Ctrl+v': () => paste(),
668
'Ctrl+z': () => undo(),
669
'F1': () => showHelp(),
670
'Alt+F4': () => closeWindow(),
671
};
672
```
673
674
### Accessibility Events
675
676
```typescript
677
// Accessibility-focused event handling
678
const accessibilityEvents = {
679
onFocus: (event) => {
680
// Announce focus change to screen readers
681
announceForAccessibility(`Focused on ${getAccessibilityLabel(event.target)}`);
682
},
683
684
onKeyDown: (event) => {
685
// Handle accessibility shortcuts
686
if (event.nativeEvent.key === 'F6') {
687
// Move between major UI sections
688
moveToNextSection();
689
}
690
},
691
692
onMouseEnter: (event) => {
693
// Provide hover feedback for screen readers
694
if (isScreenReaderActive()) {
695
announceHoverContent(event.target);
696
}
697
},
698
};
699
```
700
701
### High Performance Events
702
703
```typescript
704
// Optimized event handling for performance
705
const highPerformanceEvents = {
706
// Use native driver for animations
707
onScroll: Animated.event(
708
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
709
{ useNativeDriver: true }
710
),
711
712
// Minimize re-renders with useCallback
713
onPress: useCallback((event) => {
714
handlePress(event);
715
}, [dependencies]),
716
717
// Batch state updates
718
onMultipleEvents: (events) => {
719
unstable_batchedUpdates(() => {
720
events.forEach(handleEvent);
721
});
722
},
723
};
724
```