From 5c62903698487a6110d3aa6da25cede7ed451006 Mon Sep 17 00:00:00 2001 From: Igor Klemenski Date: Tue, 20 Apr 2021 16:03:53 -0700 Subject: [PATCH 1/5] Match native View.keyDownEvents behavior in JS. --- .../Pressable/PressableExample.windows.js | 84 ++++++++----------- .../TextInput/TextInputSharedExamples.js | 1 + .../Components/Pressable/Pressable.windows.js | 21 +++++ .../Libraries/Components/View/View.windows.js | 55 +++++++++++- .../Components/View/ViewPropTypes.windows.js | 2 + 5 files changed, 113 insertions(+), 50 deletions(-) diff --git a/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js index 5a5420dda86..fe6b6b1b133 100644 --- a/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js @@ -350,61 +350,47 @@ function PressWithOnKeyDown() { function PressWithKeyCapture() { const [eventLog, setEventLog] = useState([]); - const [shouldStopPropagation, setShouldStopPropagation] = useState(false); - const toggleSwitch2 = () => - setShouldStopPropagation(shouldStopPropagation => !shouldStopPropagation); + const [timesPressed, setTimesPressed] = useState(0); - function appendEvent(eventName) { + function logEvent(eventName) { const limit = 6; setEventLog(current => { return [eventName].concat(current.slice(0, limit - 1)); }); - } - - function myKeyDown(event) { - appendEvent('keyDown ' + event.nativeEvent.code); - - if (shouldStopPropagation) { - event.stopPropagation(); - } - } - - function myKeyUp(event) { - appendEvent('keyUp ' + event.nativeEvent.code); - - if (shouldStopPropagation) { - event.stopPropagation(); - } - } - - function myKeyDownCapture(event) { - appendEvent('keyDownCapture ' + event.nativeEvent.code); - - if (shouldStopPropagation) { - event.stopPropagation(); - } + console.log(eventName); } return ( <> - - myKeyDownCapture(event)}> - myKeyDown(event)} - onKeyUp={event => myKeyUp(event)} - onPress={() => appendEvent('press')}> - Press Me - - - - {eventLog.map((e, ii) => ( - {e} - ))} - - + logEvent('outer keyDown ' + event.nativeEvent.code)} + onKeyDownCapture={event => + logEvent('outer keyDownCapture ' + event.nativeEvent.code) + }> + logEvent('keyDown ' + event.nativeEvent.code)} + onKeyDownCapture={event => + logEvent('keyDownCapture ' + event.nativeEvent.code) + } + onPress={() => { + setTimesPressed(current => current + 1); + logEvent('pressed ' + timesPressed); + }}> + {({pressed}) => ( + {pressed ? 'Pressed!' : 'Press Me'} + )} + + + + + {eventLog.map((e, ii) => ( + {e} + ))} ); @@ -658,9 +644,9 @@ exports.examples = [ { title: 'OnKeyDownCapture on Pressable (View)', description: ('You can intercept routed KeyDown/KeyUp events by specifying the onKeyDownCapture/onKeyUpCapture callbacks.' + - " In the example below, set focus to the 'Press me' element (by tabbing into it), and start pressing letters (or any other keys) on the keyboard to observe the event log below." + - " Additionally, it's possible to control whether the intercepted event will continue down the route to its originating element, by toggling the switch below." + - " This specifies that the stopPropagation() method will be called on the event. When the switch is on, you'll see the KeyDown event doesn't show up after the KeyDownCapture for a given key.": string), + " In the example below, a is wrapper in a , and each specifies onKeyDown and onKeyDownCapture callbacks. Set focus to the 'Press me' element by tabbing into it, and start pressing letters on the keyboard to observe the event log below." + + " Additionally, because the keyDownEvents prop is specified - keyDownEvents={[{code: 'KeyW', handledEventPhase: 3}, {code: 'KeyE', handledEventPhase: 1}]} - " + + 'for these keys the event routing will be interrupted at the phase specified (3 - bubbling, 1 - capturing) to match processing on the native side.': string), render: function(): React.Node { return ; }, diff --git a/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js index edb7c141f7f..cd63ad0e379 100644 --- a/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js @@ -470,6 +470,7 @@ module.exports = ([ ); diff --git a/vnext/src/Libraries/Components/Pressable/Pressable.windows.js b/vnext/src/Libraries/Components/Pressable/Pressable.windows.js index baa0355db78..f21414ef245 100644 --- a/vnext/src/Libraries/Components/Pressable/Pressable.windows.js +++ b/vnext/src/Libraries/Components/Pressable/Pressable.windows.js @@ -31,6 +31,7 @@ import type { FocusEvent, KeyEvent, // Windows] } from '../../Types/CoreEventTypes'; +import type {HandledKeyboardEvent} from '../../Components/View/ViewPropTypes'; import View from '../View/View'; import TextInputState from '../TextInput/TextInputState'; @@ -137,6 +138,26 @@ type Props = $ReadOnly<{| */ onKeyUp?: ?(event: KeyEvent) => mixed, + /* + * List of keys handled only by JS. + */ + keyDownEvents?: ?$ReadOnlyArray, + + /* + * List of keys to be handled only by JS. + */ + keyUpEvents?: ?$ReadOnlyArray, + + /* + * Called in the tunneling phase after a key up event is detected. + */ + onKeyDownCapture?: ?(event: KeyEvent) => void, + + /* + * Called in the tunneling phase after a key up event is detected. + */ + onKeyUpCapture?: ?(event: KeyEvent) => void, + /** * Either view styles or a function that receives a boolean reflecting whether * the component is currently pressed and returns view styles. diff --git a/vnext/src/Libraries/Components/View/View.windows.js b/vnext/src/Libraries/Components/View/View.windows.js index 0c2e89fe0b9..964f04f2aa1 100644 --- a/vnext/src/Libraries/Components/View/View.windows.js +++ b/vnext/src/Libraries/Components/View/View.windows.js @@ -28,6 +28,50 @@ const View: React.AbstractComponent< ViewProps, React.ElementRef, > = React.forwardRef((props: ViewProps, forwardedRef) => { + const _keyDown = (event: KeyEvent) => { + if (props.keyDownEvents && !event.isPropagationStopped()) { + for (const el of props.keyDownEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { + event.stopPropagation(); + } + } + } + props.onKeyDown && props.onKeyDown(event); + }; + + const _keyUp = (event: KeyEvent) => { + if (props.keyUpEvents && !event.isPropagationStopped()) { + for (const el of props.keyUpEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { + event.stopPropagation(); + } + } + } + props.onKeyUp && props.onKeyUp(event); + }; + + const _keyDownCapture = (event: KeyEvent) => { + if (props.keyDownEvents && !event.isPropagationStopped()) { + for (const el of props.keyDownEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { + event.stopPropagation(); + } + } + } + props.onKeyDownCapture && props.onKeyDownCapture(event); + }; + + const _keyUpCapture = (event: KeyEvent) => { + if (props.keyUpEvents) { + for (const el of props.keyUpEvents && !event.isPropagationStopped()) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { + event.stopPropagation(); + } + } + } + props.onKeyUpCapture && props.onKeyUpCapture(event); + }; + return ( // [Windows // In core this is a TextAncestor.Provider value={false} See @@ -39,7 +83,16 @@ const View: React.AbstractComponent< !hasTextAncestor, 'Nesting of within is not currently supported.', ); - return ; + return ( + + ); }} // Windows] diff --git a/vnext/src/Libraries/Components/View/ViewPropTypes.windows.js b/vnext/src/Libraries/Components/View/ViewPropTypes.windows.js index 61e0083a576..3203140279e 100644 --- a/vnext/src/Libraries/Components/View/ViewPropTypes.windows.js +++ b/vnext/src/Libraries/Components/View/ViewPropTypes.windows.js @@ -395,9 +395,11 @@ type WindowsViewProps = $ReadOnly<{| * @platform windows */ onKeyUp?: ?(e: KeyEvent) => void, + onKeyUpCapture?: ?(e: KeyEvent) => void, keyUpEvents?: ?$ReadOnlyArray, onKeyDown?: ?(e: KeyEvent) => void, + onKeyDownCapture?: ?(e: KeyEvent) => void, keyDownEvents?: ?$ReadOnlyArray, /** * Specifies the Tooltip for the view From c9df2190bffd99f7d001d1dcb202247d469aa5ee Mon Sep 17 00:00:00 2001 From: Igor Klemenski Date: Mon, 21 Jun 2021 18:58:36 -0700 Subject: [PATCH 2/5] Change files --- ...ative-windows-1c57a8ec-8618-42b7-84a2-d786d50b5108.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-1c57a8ec-8618-42b7-84a2-d786d50b5108.json diff --git a/change/react-native-windows-1c57a8ec-8618-42b7-84a2-d786d50b5108.json b/change/react-native-windows-1c57a8ec-8618-42b7-84a2-d786d50b5108.json new file mode 100644 index 00000000000..230e4684336 --- /dev/null +++ b/change/react-native-windows-1c57a8ec-8618-42b7-84a2-d786d50b5108.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Match native View.keyDownEvents behavior in JS.", + "packageName": "react-native-windows", + "email": "igklemen@microsoft.com", + "dependentChangeType": "patch" +} From 03542f1162e911c352d459bbc18b326b3d96d2bc Mon Sep 17 00:00:00 2001 From: Igor Klemenski Date: Tue, 22 Jun 2021 13:48:39 -0700 Subject: [PATCH 3/5] Fix flow --- vnext/src/Libraries/Components/View/View.windows.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vnext/src/Libraries/Components/View/View.windows.js b/vnext/src/Libraries/Components/View/View.windows.js index 964f04f2aa1..e02d25481d0 100644 --- a/vnext/src/Libraries/Components/View/View.windows.js +++ b/vnext/src/Libraries/Components/View/View.windows.js @@ -14,6 +14,9 @@ import ViewNativeComponent from './ViewNativeComponent'; import TextAncestor from '../../Text/TextAncestor'; import * as React from 'react'; import invariant from 'invariant'; // [Windows] +// [Windows +import type {KeyEvent} from '../../Types/CoreEventTypes'; +// Windows] export type Props = ViewProps; @@ -29,7 +32,7 @@ const View: React.AbstractComponent< React.ElementRef, > = React.forwardRef((props: ViewProps, forwardedRef) => { const _keyDown = (event: KeyEvent) => { - if (props.keyDownEvents && !event.isPropagationStopped()) { + if (props.keyDownEvents && !event.isPropagationStopped) { for (const el of props.keyDownEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { event.stopPropagation(); @@ -40,7 +43,7 @@ const View: React.AbstractComponent< }; const _keyUp = (event: KeyEvent) => { - if (props.keyUpEvents && !event.isPropagationStopped()) { + if (props.keyUpEvents && !event.isPropagationStopped) { for (const el of props.keyUpEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { event.stopPropagation(); @@ -51,7 +54,7 @@ const View: React.AbstractComponent< }; const _keyDownCapture = (event: KeyEvent) => { - if (props.keyDownEvents && !event.isPropagationStopped()) { + if (props.keyDownEvents && !event.isPropagationStopped) { for (const el of props.keyDownEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { event.stopPropagation(); @@ -62,8 +65,8 @@ const View: React.AbstractComponent< }; const _keyUpCapture = (event: KeyEvent) => { - if (props.keyUpEvents) { - for (const el of props.keyUpEvents && !event.isPropagationStopped()) { + if (props.keyUpEvents && !event.isPropagationStopped) { + for (const el of props.keyUpEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { event.stopPropagation(); } From 017845e417f1621c7b831224e48463f7154a8010 Mon Sep 17 00:00:00 2001 From: Igor Klemenski Date: Mon, 28 Jun 2021 12:46:12 -0700 Subject: [PATCH 4/5] add callbacks to textinput --- .../Pressable/PressableExample.windows.js | 2 +- .../TextInput/TextInputExample.windows.js | 52 ++++++++++++++++++- .../TextInput/TextInputSharedExamples.js | 1 - .../Components/TextInput/TextInput.windows.js | 48 +++++++++++++++++ .../Libraries/Components/View/View.windows.js | 8 +-- 5 files changed, 104 insertions(+), 7 deletions(-) diff --git a/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js index fe6b6b1b133..873bf2fa1a0 100644 --- a/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/Pressable/PressableExample.windows.js @@ -646,7 +646,7 @@ exports.examples = [ description: ('You can intercept routed KeyDown/KeyUp events by specifying the onKeyDownCapture/onKeyUpCapture callbacks.' + " In the example below, a is wrapper in a , and each specifies onKeyDown and onKeyDownCapture callbacks. Set focus to the 'Press me' element by tabbing into it, and start pressing letters on the keyboard to observe the event log below." + " Additionally, because the keyDownEvents prop is specified - keyDownEvents={[{code: 'KeyW', handledEventPhase: 3}, {code: 'KeyE', handledEventPhase: 1}]} - " + - 'for these keys the event routing will be interrupted at the phase specified (3 - bubbling, 1 - capturing) to match processing on the native side.': string), + 'for these keys the event routing will be interrupted (by a call to event.stopPropagation()) at the phase specified (3 - bubbling, 1 - capturing) to match processing on the native side.': string), render: function(): React.Node { return ; }, diff --git a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js index f06629623dc..f28f3c299a3 100644 --- a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js @@ -18,8 +18,9 @@ const { View, StyleSheet, Slider, - Switch, + Switch } = require('react-native'); +const {useState} = React; const TextInputSharedExamples = require('./TextInputSharedExamples'); @@ -156,6 +157,49 @@ class PressInOutEvents extends React.Component< } } +function PropagationSample() { + const [eventLog, setEventLog] = useState([]); + + function logEvent(eventName) { + const limit = 6; + setEventLog(current => { + return [eventName].concat(current.slice(0, limit - 1)); + }); + console.log(eventName); + } + return ( + <> + logEvent('outer keyDown ' + event.nativeEvent.code)} + onKeyDownCapture={event => + logEvent('outer keyDownCapture ' + event.nativeEvent.code) + }> + some text to focus on + logEvent('textinput keyDown ' + event.nativeEvent.code)} + onKeyUp={event => logEvent('textinput keyUp ' + event.nativeEvent.code)} + keyDownEvents={[ + {code: 'KeyW', handledEventPhase: 3}, + {code: 'KeyE', handledEventPhase: 1}, + ]} + /> + + + {eventLog.map((e, ii) => ( + {e} + ))} + + + ); +} + const styles = StyleSheet.create({ multiline: { height: 60, @@ -487,5 +531,11 @@ exports.examples = ([ ); }, }, + { + title: 'Stop propagation sample', + render: function(): React.Node { + return ; + }, + }, // Windows] ]: Array); diff --git a/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js b/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js index cd63ad0e379..edb7c141f7f 100644 --- a/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js +++ b/packages/@react-native/tester/js/examples/TextInput/TextInputSharedExamples.js @@ -470,7 +470,6 @@ module.exports = ([ ); diff --git a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js index ade042bbe69..8bd9d3a4380 100644 --- a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js +++ b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js @@ -1142,6 +1142,50 @@ function InternalTextInput(props: Props): React.Node { // TextInput handles onBlur and onFocus events // so omitting onBlur and onFocus pressability handlers here. const {onBlur, onFocus, ...eventHandlers} = usePressability(config) || {}; + const eventPhase = Object.freeze({Capturing:1, Bubbling:3}); + const _keyDown = (event: KeyEvent) => { + if (props.keyDownEvents && event.isPropagationStopped() !== true) { + for (const el of props.keyDownEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == eventPhase.Bubbling) { + event.stopPropagation(); + } + } + } + props.onKeyDown && props.onKeyDown(event); + }; + + const _keyUp = (event: KeyEvent) => { + if (props.keyUpEvents && event.isPropagationStopped() !== true) { + for (const el of props.keyUpEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { + event.stopPropagation(); + } + } + } + props.onKeyUp && props.onKeyUp(event); + }; + + const _keyDownCapture = (event: KeyEvent) => { + if (props.keyDownEvents && event.isPropagationStopped() !== true) { + for (const el of props.keyDownEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { + event.stopPropagation(); + } + } + } + props.onKeyDownCapture && props.onKeyDownCapture(event); + }; + + const _keyUpCapture = (event: KeyEvent) => { + if (props.keyUpEvents && event.isPropagationStopped() !== true) { + for (const el of props.keyUpEvents) { + if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { + event.stopPropagation(); + } + } + } + props.onKeyUpCapture && props.onKeyUpCapture(event); + }; if (Platform.OS === 'ios') { const RCTTextInputView = @@ -1245,6 +1289,10 @@ function InternalTextInput(props: Props): React.Node { onSelectionChangeShouldSetResponder={emptyFunctionThatReturnsTrue} selection={selection} text={text} + onKeyDown={_keyDown} + onKeyDownCapture={_keyDownCapture} + onKeyUp={_keyUp} + onKeyUpCapture={_keyUpCapture} /> ); } // Windows] diff --git a/vnext/src/Libraries/Components/View/View.windows.js b/vnext/src/Libraries/Components/View/View.windows.js index e02d25481d0..f441f1e6a13 100644 --- a/vnext/src/Libraries/Components/View/View.windows.js +++ b/vnext/src/Libraries/Components/View/View.windows.js @@ -32,7 +32,7 @@ const View: React.AbstractComponent< React.ElementRef, > = React.forwardRef((props: ViewProps, forwardedRef) => { const _keyDown = (event: KeyEvent) => { - if (props.keyDownEvents && !event.isPropagationStopped) { + if (props.keyDownEvents && event.isPropagationStopped() !== true) { for (const el of props.keyDownEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { event.stopPropagation(); @@ -43,7 +43,7 @@ const View: React.AbstractComponent< }; const _keyUp = (event: KeyEvent) => { - if (props.keyUpEvents && !event.isPropagationStopped) { + if (props.keyUpEvents && event.isPropagationStopped() !== true) { for (const el of props.keyUpEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 3) { event.stopPropagation(); @@ -54,7 +54,7 @@ const View: React.AbstractComponent< }; const _keyDownCapture = (event: KeyEvent) => { - if (props.keyDownEvents && !event.isPropagationStopped) { + if (props.keyDownEvents && event.isPropagationStopped() !== true) { for (const el of props.keyDownEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { event.stopPropagation(); @@ -65,7 +65,7 @@ const View: React.AbstractComponent< }; const _keyUpCapture = (event: KeyEvent) => { - if (props.keyUpEvents && !event.isPropagationStopped) { + if (props.keyUpEvents && event.isPropagationStopped() !== true) { for (const el of props.keyUpEvents) { if (event.nativeEvent.code == el.code && el.handledEventPhase == 1) { event.stopPropagation(); From 0e5a6056d7fab532068fd961d4b0651a1d956b48 Mon Sep 17 00:00:00 2001 From: Igor Klemenski Date: Tue, 6 Jul 2021 18:04:35 -0700 Subject: [PATCH 5/5] cleanup --- .../TextInput/TextInputExample.windows.js | 25 +++++++++++-------- .../Components/TextInput/TextInput.windows.js | 8 ++++-- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js index f28f3c299a3..4956c04ecb0 100644 --- a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js @@ -18,7 +18,7 @@ const { View, StyleSheet, Slider, - Switch + Switch, } = require('react-native'); const {useState} = React; @@ -169,12 +169,13 @@ function PropagationSample() { } return ( <> - logEvent('outer keyDown ' + event.nativeEvent.code)} onKeyDownCapture={event => logEvent('outer keyDownCapture ' + event.nativeEvent.code) @@ -183,8 +184,12 @@ function PropagationSample() { logEvent('textinput keyDown ' + event.nativeEvent.code)} - onKeyUp={event => logEvent('textinput keyUp ' + event.nativeEvent.code)} + onKeyDown={event => + logEvent('textinput keyDown ' + event.nativeEvent.code) + } + onKeyUp={event => + logEvent('textinput keyUp ' + event.nativeEvent.code) + } keyDownEvents={[ {code: 'KeyW', handledEventPhase: 3}, {code: 'KeyE', handledEventPhase: 1}, @@ -534,7 +539,7 @@ exports.examples = ([ { title: 'Stop propagation sample', render: function(): React.Node { - return ; + return ; }, }, // Windows] diff --git a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js index 8bd9d3a4380..4cb9200e34c 100644 --- a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js +++ b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js @@ -48,6 +48,7 @@ let RCTMultilineTextInputView; let RCTMultilineTextInputNativeCommands; let WindowsTextInput; // [Windows] let WindowsTextInputCommands; // [Windows] +import type {KeyEvent} from '../../Types/CoreEventTypes'; // [Windows] // [Windows if (Platform.OS === 'android') { @@ -1142,11 +1143,14 @@ function InternalTextInput(props: Props): React.Node { // TextInput handles onBlur and onFocus events // so omitting onBlur and onFocus pressability handlers here. const {onBlur, onFocus, ...eventHandlers} = usePressability(config) || {}; - const eventPhase = Object.freeze({Capturing:1, Bubbling:3}); + const eventPhase = Object.freeze({Capturing: 1, Bubbling: 3}); const _keyDown = (event: KeyEvent) => { if (props.keyDownEvents && event.isPropagationStopped() !== true) { for (const el of props.keyDownEvents) { - if (event.nativeEvent.code == el.code && el.handledEventPhase == eventPhase.Bubbling) { + if ( + event.nativeEvent.code == el.code && + el.handledEventPhase == eventPhase.Bubbling + ) { event.stopPropagation(); } }