From ea0247e641fda48c5ed44d82cb305941baf41bd2 Mon Sep 17 00:00:00 2001 From: Michiel van der Geest Date: Wed, 18 Dec 2024 18:21:01 +0100 Subject: [PATCH 1/6] Added functionality to intercept key pres in the root App component. --- src/application.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/application.js b/src/application.js index 6641b63c..b53bae73 100644 --- a/src/application.js +++ b/src/application.js @@ -56,8 +56,15 @@ const Application = (config) => { config.hooks[symbols.init] = function () { const keyMap = { ...defaultKeyMap, ...Settings.get('keymap', {}) } - keyDownHandler = (e) => { + keyDownHandler = async (e) => { const key = keyMap[e.key] || keyMap[e.keyCode] || e.key || e.keyCode + // intercept key press if specified in main Application component + if (this[symbols.inputEvents].intercept !== undefined) { + e = await this[symbols.inputEvents].intercept.call(this, e) + // only pass on the key press to focused component when keyboard event is returned + if (e instanceof KeyboardEvent === false) return + } + Focus.input(key, e) clearTimeout(holdTimeout) holdTimeout = setTimeout(() => { From f20b3c0d8efaaf34319a68d0fe7036ccb5c0a27e Mon Sep 17 00:00:00 2001 From: Michiel van der Geest Date: Wed, 18 Dec 2024 18:28:45 +0100 Subject: [PATCH 2/6] Added intercept input method to ts definitions. --- index.d.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index 931f41c0..233c04d5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -88,7 +88,17 @@ declare module '@lightningjs/blits' { * Will be invoked when there is no dedicated function for a certain key */ // @ts-ignore - any?: (event: KeyboardEvent) => void + any?: (event: KeyboardEvent) => void, + /** + * Intercept key presses on the root Application component before being handled + * by the currently focussed component. + * + * Only when a KeyboardEvent (the original one, or a modified one) is returned from the + * intercept function, the Input event is passed on to the Component with focus. + * + * The intercept function can be asynchronous. + */ + intercept?: (event: KeyboardEvent) => KeyboardEvent | Promise | any } export interface Log { From 614a25c4687316173b981f00c8910dd26a7d51b1 Mon Sep 17 00:00:00 2001 From: Michiel van der Geest Date: Wed, 18 Dec 2024 18:51:19 +0100 Subject: [PATCH 3/6] Added documentation for intercept input method. --- CHANGELOG.md | 2 +- docs/components/user_input.md | 10 ++++++++++ index.d.ts | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23b20f60..ab2a26be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,7 +56,7 @@ _8 nov 2024_ - Fixed issue with watching nested state variables and global state - Upgraded to renderer 2.6.2 - Fixed issue with white background for Elements with falsy src attribute -- Fixed issue with calling focus on component that already is focussed +- Fixed issue with calling focus on component that already is focused ## v1.9.2 diff --git a/docs/components/user_input.md b/docs/components/user_input.md index 68d580e8..7e1fdf01 100644 --- a/docs/components/user_input.md +++ b/docs/components/user_input.md @@ -72,6 +72,16 @@ When a component handles a key press by having a corresponding function specifie } ``` +## Intercepting key input + +In addition to the Event handling chain explained above. Blits offers the option to _intercept_ key presses at the root level of the Application, before they reach a the focused Component. This can be useful in certains situation where you want to globally disable all key presses, or when implementing an override key press handler. + +The `intercept()` input-method can only be implemented in the `Blits.Application`-component. When present, the method acts as a _catch-all_ method, and will be executed for _all_ key presses. It receives the `KeyboardEvent` as its argument, allowing you to execute logic based on the key being pressed. + +Only when the `intercept()` input-method returns the `KeyboardEvent` (possibly modified), the keypress will continue to be handled (by the currently focused) Component. + +The `intercept`-method can als be an asynchronous method. + ## Key-up handling The functions specified in the `input` configuration are invoked when a key is _pressed down_ (i.e. the `keydown` event listener). But sometimes you may also want to execute some logic when a key is _released_ (i.e. the `keyup` event listener). diff --git a/index.d.ts b/index.d.ts index 233c04d5..8e566136 100644 --- a/index.d.ts +++ b/index.d.ts @@ -91,7 +91,7 @@ declare module '@lightningjs/blits' { any?: (event: KeyboardEvent) => void, /** * Intercept key presses on the root Application component before being handled - * by the currently focussed component. + * by the currently focused component. * * Only when a KeyboardEvent (the original one, or a modified one) is returned from the * intercept function, the Input event is passed on to the Component with focus. From 71cfeb3b7241715d65b6f2bd10191e99b99f5be3 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Gangumalla Date: Mon, 23 Dec 2024 14:40:47 +0530 Subject: [PATCH 4/6] Adding unknown for Index signature return type Input index singature Type is a function which returns void | undefined and all other custom properties Types should align with the index signature Type (including function return types as well). Here, the custom property intercept Type is a function that return value like KeyboardEvent, any, which are not part of index signature function return type so adding unknown as additional return type Signed-off-by: Suresh Kumar Gangumalla --- index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index 8e566136..066b9a3f 100644 --- a/index.d.ts +++ b/index.d.ts @@ -81,7 +81,7 @@ declare module '@lightningjs/blits' { } export interface Input { - [key: string]: (event: KeyboardEvent) => void | undefined, + [key: string]: (event: KeyboardEvent) => void | undefined | unknown, /** * Catch all input function * From d88298c61db6f15f4df2556876cfd93f1f5648be Mon Sep 17 00:00:00 2001 From: Michiel van der Geest Date: Mon, 6 Jan 2025 13:51:33 +0100 Subject: [PATCH 5/6] Added note about intercept being only available on root app component. --- index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.d.ts b/index.d.ts index 066b9a3f..00f056b6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -97,6 +97,8 @@ declare module '@lightningjs/blits' { * intercept function, the Input event is passed on to the Component with focus. * * The intercept function can be asynchronous. + * + * Note: the intercept input handler is only available on the Root App component (i.e. Blits.Application) */ intercept?: (event: KeyboardEvent) => KeyboardEvent | Promise | any } From 5b276c30b76e1c286eecc7bb3e6a14f768c7e463 Mon Sep 17 00:00:00 2001 From: Michiel van der Geest Date: Mon, 6 Jan 2025 15:38:30 +0100 Subject: [PATCH 6/6] Fixed some typos in docs. --- docs/components/user_input.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/components/user_input.md b/docs/components/user_input.md index 7e1fdf01..75c6447f 100644 --- a/docs/components/user_input.md +++ b/docs/components/user_input.md @@ -74,13 +74,13 @@ When a component handles a key press by having a corresponding function specifie ## Intercepting key input -In addition to the Event handling chain explained above. Blits offers the option to _intercept_ key presses at the root level of the Application, before they reach a the focused Component. This can be useful in certains situation where you want to globally disable all key presses, or when implementing an override key press handler. +In addition to the Event handling chain explained above. Blits offers the option to _intercept_ key presses at the root level of the Application, before they reach the currently focused Component. This can be useful in certain situation where you want to globally disable all key presses, or when implementing an override key press handler. The `intercept()` input-method can only be implemented in the `Blits.Application`-component. When present, the method acts as a _catch-all_ method, and will be executed for _all_ key presses. It receives the `KeyboardEvent` as its argument, allowing you to execute logic based on the key being pressed. -Only when the `intercept()` input-method returns the `KeyboardEvent` (possibly modified), the keypress will continue to be handled (by the currently focused) Component. +Only when the `intercept()` input-method returns the `KeyboardEvent` (possibly modified), the keypress will continue to be handled (by the currently focused Component). -The `intercept`-method can als be an asynchronous method. +The `intercept`-method can also be an asynchronous method. ## Key-up handling