ai / ai/keyux

Scope the event handlers to the specific DOM element

Open
#22 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
546
Forks
28
PR merge metrics
No merged PRs in 30d

Description

Hey there!

We're developing some third-party widgets and decided to integrate KeyUX with them. However, we encountered an issue where KeyUX affects the host page, which is unintended behavior. To scope KeyUX to our widget's DOM elements, we wrap the window object and apply filtering within it, like this:

```js
/**
* @typedef {Parameters[0]} MinimalWindow
*/

/**
* @implements {MinimalWindow}
*/
class ScopedMinimalWindow {
/**
* @private
* @type {Map void>}
*/
_listeners = new Map();

/**
* @private
* @type {Node[]}
*/
_scope = [];

/**
* @param {'keydown' | 'keyup'} type
* @param {(event: Event) => void} listener
*/
addEventListener(type, listener) {
/** @param {Event} e */
const wrappedListener = (e) => {
const target = e.target;
if (!target) return;
if (
this._scope.some(
(el) => el === e.target || el.contains(/** @type {Node} */ (target))
)
) {
listener(e);
}
};
this._listeners.set(listener, wrappedListener);
window.addEventListener(type, wrappedListener);
}

/**
* @param {'keydown' | 'keyup'} type
* @param {(event: {}) => void} listener
*/
removeEventListener(type, listener) {
const wrappedListener = this._listeners.get(listener);
if (wrappedListener) {
window.removeEventListener(type, wrappedListener);
}
this._listeners.delete(listener);
}

get document() {
return window.document;
}

get navigator() {
return window.navigator;
}

/** @param {Node} scope */
registerScope(scope) {
this._scope.push(scope);
}

destroy() {
this._scope = [];
this._listeners.forEach((listener, originalListener) => {
window.removeEventListener("keydown", listener);
window.removeEventListener("keyup", listener);
this._listeners.delete(originalListener);
});
}
}

```

This approach works perfectly. However, I would like to ask your opinion on implementing scoping directly within KeyUX.

What do you think about this?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.