@@ -15,7 +15,6 @@ import type {KeyEvent} from 'react-native/Libraries/Types/CoreEventTypes';
1515import * as React from 'react' ;
1616
1717import {
18- Button ,
1918 Pressable ,
2019 StyleSheet ,
2120 Switch ,
@@ -128,132 +127,149 @@ function BubblingExample(): React.Node {
128127}
129128
130129function KeyboardEventExample ( ) : React . Node {
131- const viewRef = React . useRef < React . ElementRef < typeof View > | null > ( null ) ;
132- const [ log , setLog ] = React . useState < Array < string >> ( [ ] ) ;
130+ const pressableRef = React . useRef < React . ElementRef < typeof Pressable > | null > ( null ) ;
131+ const [ eventLog , setEventLog ] = React . useState < Array < string >> ( [ ] ) ;
133132
134- const clearLog = React . useCallback ( ( ) => {
135- setLog ( [ ] ) ;
136- } , [ setLog ] ) ;
133+ function appendEvent ( eventName : string , source ?: string ) {
134+ const limit = 12 ;
135+ setEventLog ( ( current : Array < string > ) => {
136+ const prefix = source != null ? `${ source } : ` : '' ;
137+ return [ `${ prefix } ${ eventName } ` ] . concat ( current . slice ( 0 , limit - 1 ) ) ;
138+ } ) ;
139+ }
137140
138- const appendLog = React . useCallback (
139- ( line : string ) => {
140- const limit = 12 ;
141- const newLog = log . slice ( 0 , limit - 1 ) ;
142- newLog . unshift ( line ) ;
143- setLog ( newLog ) ;
141+ const handleSingleLineKeyDown = React . useCallback (
142+ ( e : KeyEvent ) => {
143+ appendEvent ( `keyDown: ${ e . nativeEvent . key } ` , 'Single-line TextInput' ) ;
144144 } ,
145- [ log , setLog ] ,
145+ [ ] ,
146146 ) ;
147147
148- const handleKeyDown = React . useCallback (
148+ const handleSingleLineKeyUp = React . useCallback (
149149 ( e : KeyEvent ) => {
150- appendLog ( 'Key Down:' + e . nativeEvent . key ) ;
150+ appendEvent ( `keyUp: ${ e . nativeEvent . key } ` , 'Single-line TextInput' ) ;
151151 } ,
152- [ appendLog ] ,
152+ [ ] ,
153153 ) ;
154154
155- const handleKeyUp = React . useCallback (
155+ const handleMultiLineKeyDown = React . useCallback (
156156 ( e : KeyEvent ) => {
157- appendLog ( 'Key Up:' + e . nativeEvent . key ) ;
157+ appendEvent ( `keyDown: ${ e . nativeEvent . key } ` , 'Multi-line TextInput' ) ;
158158 } ,
159- [ appendLog ] ,
159+ [ ] ,
160160 ) ;
161161
162- const viewText =
163- "keyDownEvents: [{key: 'g'}, {key: 'Escape'}, {key: 'Enter'}, {key: 'ArrowLeft'}] \nkeyUpEvents: [{key: 'c'}, {key: 'd'}]" ;
164- const viewKeyboardProps = {
165- onKeyDown : handleKeyDown ,
166- keyDownEvents : [
167- { key : 'g' } ,
168- { key : 'Escape' } ,
169- { key : 'Enter' } ,
170- { key : 'ArrowLeft' } ,
171- ] ,
172- onKeyUp : handleKeyUp ,
173- keyUpEvents : [ { key : 'c' } , { key : 'd' } ] ,
174- } ;
175-
176- const textInputText =
177- "keyDownEvents: [{key: 'ArrowRight'}, {key: 'ArrowDown'}, {key: 'Enter', ctrlKey: true}, \nkeyUpEvents: [{key: 'Escape'}, {key: 'Enter'}]" ;
178- const textInputKeyboardProps = {
179- onKeyDown : handleKeyDown ,
180- keyDownEvents : [
181- { key : 'ArrowRight' } ,
182- { key : 'ArrowDown' } ,
183- { key : 'Enter' , ctrlKey : true } ,
184- ] ,
185- onKeyUp : handleKeyUp ,
186- keyUpEvents : [ { key : 'Escape' } , { key : 'Enter' } ] ,
187- } ;
162+ const handleMultiLineKeyUp = React . useCallback (
163+ ( e : KeyEvent ) => {
164+ appendEvent ( `keyUp: ${ e . nativeEvent . key } ` , 'Multi-line TextInput' ) ;
165+ } ,
166+ [ ] ,
167+ ) ;
188168
189- const textInputUnhandledText =
190- "keyDownEvents: [{key: 'ArrowRight'}, {key: 'ArrowDown'}, {key: 'Enter', ctrlKey: true}, \nkeyUpEvents: [{key: 'Escape'}, {key: 'Enter'}]" ;
191- const textInputunHandledKeyboardProps = {
192- onKeyDown : handleKeyDown ,
193- onKeyUp : handleKeyUp ,
194- } ;
169+ const handlePressableKeyDown = React . useCallback (
170+ ( e : KeyEvent ) => {
171+ appendEvent ( `keyDown: ${ e . nativeEvent . key } ` , 'Focusable Pressable' ) ;
172+ } ,
173+ [ ] ,
174+ ) ;
195175
196- React . useEffect ( ( ) => {
197- // Focus the first view on mount
198- viewRef . current ?. focus ( ) ;
199- } , [ ] ) ;
176+ const handlePressableKeyUp = React . useCallback (
177+ ( e : KeyEvent ) => {
178+ appendEvent ( `keyUp: ${ e . nativeEvent . key } ` , 'Focusable Pressable' ) ;
179+ } ,
180+ [ ] ,
181+ ) ;
200182
201183 return (
202- < View
203- style = { {
204- padding : 10 ,
205- } } >
206- < Text >
207- Key events are called when a component detects a key press.To tab
208- between views on macOS: Enable System Preferences / Keyboard / Shortcuts{ ' ' }
209- { '>' } Use keyboard navigation to move focus between controls.
184+ < View style = { { marginTop : 10 } } >
185+ < Text style = { styles . description } >
186+ Examples of keyboard event handling with keyDownEvents and keyUpEvents arrays.
210187 </ Text >
211- < View >
212- < Text style = { styles . text } > { viewText } </ Text >
213- < View
214- ref = { viewRef }
215- focusable = { true }
216- style = { styles . input }
217- { ...viewKeyboardProps }
218- />
219- < Text style = { styles . text } > { textInputText } </ Text >
188+
189+ < View style = { styles . inputContainer } >
190+ < Text style = { styles . inputLabel } >
191+ Single-line TextInput (keyDownEvents: g, Escape, Enter, ArrowLeft)
192+ </ Text >
220193 < TextInput
221- blurOnSubmit = { false }
222- placeholder = { 'Singleline textInput' }
223- multiline = { false }
224- focusable = { true }
225- style = { styles . input }
226- { ...textInputKeyboardProps }
194+ style = { styles . styledTextInput }
195+ placeholder = "Type here and press g, Escape, Enter, or ArrowLeft"
196+ placeholderTextColor = "#999"
197+ onKeyDown = { handleSingleLineKeyDown }
198+ onKeyUp = { handleSingleLineKeyUp }
199+ keyDownEvents = { [
200+ { key : 'g' } ,
201+ { key : 'Escape' } ,
202+ { key : 'Enter' } ,
203+ { key : 'ArrowLeft' } ,
204+ ] }
205+ keyUpEvents = { [ { key : 'c' } , { key : 'd' } ] }
227206 />
207+ </ View >
208+
209+ < View style = { styles . inputContainer } >
210+ < Text style = { styles . inputLabel } >
211+ Multi-line TextInput (keyDownEvents: ArrowRight, ArrowDown, Cmd+Enter)
212+ </ Text >
228213 < TextInput
229- placeholder = { 'Multiline textInput' }
214+ style = { [ styles . styledTextInput , styles . multilineInput ] }
215+ placeholder = "Multi-line input - try arrow keys and Cmd+Enter"
216+ placeholderTextColor = "#999"
230217 multiline = { true }
231- focusable = { true }
232- style = { styles . input }
233- { ...textInputKeyboardProps }
218+ onKeyDown = { handleMultiLineKeyDown }
219+ onKeyUp = { handleMultiLineKeyUp }
220+ keyDownEvents = { [
221+ { key : 'ArrowRight' } ,
222+ { key : 'ArrowDown' } ,
223+ { key : 'Enter' , metaKey : true } ,
224+ ] }
225+ keyUpEvents = { [ { key : 'Escape' } , { key : 'Enter' } ] }
234226 />
235- < Text style = { styles . text } > { textInputUnhandledText } </ Text >
236- < TextInput
237- blurOnSubmit = { false }
238- placeholder = { 'Singleline textInput' }
239- multiline = { false }
240- focusable = { true }
241- style = { styles . input }
242- { ... textInputunHandledKeyboardProps }
243- />
244- < TextInput
245- placeholder = { 'Multiline textInput' }
246- multiline = { true }
227+ </ View >
228+
229+ < View style = { styles . inputContainer } >
230+ < Text style = { styles . inputLabel } >
231+ Focusable Pressable (keyDownEvents: Space, Enter, Tab, Backspace)
232+ </ Text >
233+ < Pressable
234+ ref = { pressableRef }
235+ style = { ( { pressed } ) => [
236+ styles . focusablePressable ,
237+ pressed && styles . focusablePressablePressed ,
238+ ] }
247239 focusable = { true }
248- style = { styles . input }
249- { ...textInputunHandledKeyboardProps }
250- />
251- < Button
252- testID = "event_clear_button"
253- onPress = { clearLog }
254- title = "Clear event log"
255- />
256- < Text > { 'Events:\n' + log . join ( '\n' ) } </ Text >
240+ onKeyDown = { handlePressableKeyDown }
241+ onKeyUp = { handlePressableKeyUp }
242+ keyDownEvents = { [
243+ { key : 'Space' } ,
244+ { key : 'Enter' } ,
245+ { key : 'Tab' } ,
246+ { key : 'Backspace' } ,
247+ ] }
248+ onPress = { ( ) => {
249+ pressableRef . current ?. focus ( ) ;
250+ } }
251+ >
252+ < Text style = { styles . pressableText } > Click to focus, then press Space, Enter, Tab, or Backspace</ Text >
253+ </ Pressable >
254+ </ View >
255+
256+ < View testID = "keyboard_events_example_console" style = { styles . eventLogBox } >
257+ < View style = { styles . logHeaderRow } >
258+ < Text style = { styles . logHeader } > Event Log</ Text >
259+ < Pressable
260+ style = { ( { pressed} ) => [
261+ styles . clearButton ,
262+ pressed && styles . clearButtonPressed ,
263+ ] }
264+ onPress = { ( ) => setEventLog ( [ ] ) } >
265+ < Text style = { styles . clearButtonText } > Clear</ Text >
266+ </ Pressable >
267+ </ View >
268+ { eventLog . map ( ( e , ii ) => (
269+ < Text key = { ii } style = { styles . logEntry } >
270+ { e }
271+ </ Text >
272+ ) ) }
257273 </ View >
258274 </ View >
259275 ) ;
@@ -266,6 +282,7 @@ const styles = StyleSheet.create({
266282 height : 300 ,
267283 borderWidth : StyleSheet . hairlineWidth ,
268284 borderColor : '#f0f0f0' ,
285+ borderCurve : 'continuous' ,
269286 backgroundColor : '#f9f9f9' ,
270287 } ,
271288 logHeaderRow : {
@@ -361,6 +378,54 @@ const styles = StyleSheet.create({
361378 fontSize : 12 ,
362379 paddingBottom : 4 ,
363380 } ,
381+ description : {
382+ fontSize : 14 ,
383+ color : '#666' ,
384+ marginBottom : 16 ,
385+ } ,
386+ inputContainer : {
387+ marginBottom : 16 ,
388+ } ,
389+ inputLabel : {
390+ fontSize : 13 ,
391+ fontWeight : '500' ,
392+ color : '#333' ,
393+ marginBottom : 6 ,
394+ } ,
395+ styledTextInput : {
396+ borderWidth : 1 ,
397+ borderColor : '#ddd' ,
398+ borderRadius : 6 ,
399+ paddingHorizontal : 12 ,
400+ paddingVertical : 8 ,
401+ fontSize : 14 ,
402+ backgroundColor : '#fff' ,
403+ minHeight : 36 ,
404+ } ,
405+ multilineInput : {
406+ minHeight : 72 ,
407+ textAlignVertical : 'top' ,
408+ } ,
409+ focusablePressable : {
410+ borderWidth : 1 ,
411+ borderColor : '#ddd' ,
412+ borderRadius : 6 ,
413+ paddingHorizontal : 12 ,
414+ paddingVertical : 16 ,
415+ backgroundColor : '#f8f9fa' ,
416+ minHeight : 50 ,
417+ justifyContent : 'center' ,
418+ alignItems : 'center' ,
419+ } ,
420+ focusablePressablePressed : {
421+ backgroundColor : '#e9ecef' ,
422+ borderColor : '#007AFF' ,
423+ } ,
424+ pressableText : {
425+ fontSize : 14 ,
426+ color : '#666' ,
427+ textAlign : 'center' ,
428+ } ,
364429} ) ;
365430
366431exports . title = 'Keyboard Events' ;
0 commit comments