diff --git a/packages/keystrokes/src/key-combo-state.ts b/packages/keystrokes/src/key-combo-state.ts index 5b2c33c..e70c5fb 100644 --- a/packages/keystrokes/src/key-combo-state.ts +++ b/packages/keystrokes/src/key-combo-state.ts @@ -129,6 +129,10 @@ export class KeyComboState { return this._sequenceIndex } + get sequenceLength() { + return this._parsedKeyCombo.length; + } + private _normalizedKeyCombo: string private _parsedKeyCombo: string[][][] private _handlerState: HandlerState< diff --git a/packages/keystrokes/src/keystrokes.ts b/packages/keystrokes/src/keystrokes.ts index 43b2155..81f3c97 100644 --- a/packages/keystrokes/src/keystrokes.ts +++ b/packages/keystrokes/src/keystrokes.ts @@ -99,6 +99,11 @@ export class Keystrokes< KeyComboState > + private _keyCombosPressedByKey: Map< + string, + KeyComboState[] + > + constructor( options: KeystrokesOptions< OriginalEvent, @@ -125,6 +130,7 @@ export class Keystrokes< this._activeKeyMap = new Map() this._watchedKeyComboStates = {} + this._keyCombosPressedByKey = new Map() this.bindEnvironment(options) } @@ -357,8 +363,31 @@ export class Keystrokes< this._updateKeyComboStates() - for (const keyComboState of this._keyComboStatesArray) - keyComboState.executePressed(event) + const pressedCombos = this._keyComboStatesArray.filter( + (combo) => combo.isPressed, + ) + + if (pressedCombos.length > 0) { + const maxSequenceLength = Math.max( + ...pressedCombos.map((combo) => combo.sequenceLength), + ) + + const activatedCombos: KeyComboState< + OriginalEvent, + KeyEventProps, + KeyComboEventProps + >[] = [] + for (const combo of pressedCombos) { + if (combo.sequenceLength === maxSequenceLength) { + combo.executePressed(event) + activatedCombos.push(combo) + } + } + + if (activatedCombos.length > 0) { + this._keyCombosPressedByKey.set(event.key, activatedCombos) + } + } } private _handleKeyRelease(event: KeyEvent) { @@ -402,8 +431,13 @@ export class Keystrokes< this._tryReleaseSelfReleasingKeys() this._updateKeyComboStates() - for (const keyComboState of this._keyComboStatesArray) - keyComboState.executeReleased(event) + const activatedCombos = this._keyCombosPressedByKey.get(event.key) + if (activatedCombos) { + for (const combo of activatedCombos) { + combo.executeReleased(event) + } + this._keyCombosPressedByKey.delete(event.key) + } } private _updateKeyComboStates() {