Search code examples
angulartypescriptangular-materialcustom-keyboardon-screen-keyboard

Shift key behaves like caps lock key in ngx-material-keyboard


I am using the ngx-material-keyboard in my Angular app.
I noticed that the shift key behaves strange, when tapped/clicked:

  • expected: after changing the lower case representation of letters to uppercase, on clicking one of those uppercase letters the keyboard switches automatically back to lowercase
  • observed: after changing the lower case representation of letters to uppercase, on clicking one of those uppercase letters the keyboard stays in uppercase (shift key behaves identical to caps lock key)

My expectation comes from the onscreen keyboards on my phone (e.g. in chat apps). Is my expectation valid and is my irritation justified?

Reproduce it yourself here: ngx-material-keyboard demo

As far as I can see, no one created an issue, which I find strange, so I am asking here, first (and no one seems to have addressed it in SO, as well).

Anybody knows how to fix this? (I forked the repo, hence I can change the code, but unfortunately, I can't figure out how the letter case switching is done and how to get the shift handler to switch to uppercase only for one click instead of permanently.)

Here are the code parts that I consider revelant:

In keyboard.compontents.ts:

public onShiftClick(): void {
    this.modifier = MatKeyboardComponent.invertShiftModifier(this.modifier);
    this.shiftClick.next();
}

private static invertShiftModifier(modifier: KeyboardModifier): KeyboardModifier {
    switch (modifier) {
        case KeyboardModifier.None:
            return KeyboardModifier.Shift;

        case KeyboardModifier.Alt:
            return KeyboardModifier.ShiftAlt;

        case KeyboardModifier.ShiftAlt:
            return KeyboardModifier.Alt;

        case KeyboardModifier.Shift:
            return KeyboardModifier.None;
    }
}

And in keyboard-key-component.ts:

public onClick(event: MouseEvent): void {
[...]

// TODO: if current modifier is KeyboardModifier.Shift
// do the invert
}

Solution

  • I was able to find a working solution, myself.
    The onClick() function already provides this.genericClick.emit(event). This emitter can be used to reset the shift after a click on one key. The solution also works correctly, if caps lock is active.

    In keyboard.component.html, add the genericClick:

    <vwlmz-keyboard-key class="mat-keyboard-col"
        [...]
        (enterClick)="onEnterClick()"
        (genericClick)="onKeyClick()" // add this line
        (capsClick)="onCapsClick()"
        (altClick)="onAltClick()"
        (shiftClick)="onShiftClick()"></vwlmz-keyboard-key>
    

    In keyboard.component.ts, add this:

    public enterClick: EventEmitter<void> = new EventEmitter<void>();
    
    public onKeyClick(): void {
        this.genericClick.next();
    
        // reset shift after clicking a key
        if (this.modifier === KeyboardModifier.Shift) {
            this.modifier = MatKeyboardComponent.invertShiftModifier(KeyboardModifier.Shift);
        }
    }