
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
An Angular module that provides a declarative API using components/directive to manage Keyboard shortcuts in scalable way.
See demo here:
demo
Compatible with Angular 14+
npm install --save ng-hotkeys
yarn add ng-hotkeys
import { HotKeysModule } from 'ng-hotkeys';
@NgModule({
declarations: [
],
imports: [
BrowserModule,
HotKeysModule.forRoot()
],
bootstrap: [AppComponent]
})
export class AppModule {
}
key combinations are used with meta keys like control, shift, command, etc... and are defined using plus(+) sign as a separator. there can be multiple combinations for the same command, so either of the key combination will trigger the callback. Since combinations uses the plus sign as a seperator, if you want to bind to the actual + charachater, you will need to use "plus" instead.
[
{
key: ["cmd + a"],
command: (output: ShortcutEventOutput) => console.log("command + a", output),
},
{
key: "ctrl + a",
preventDefault: true,
command: (output: ShortcutEventOutput) => console.log("control + a", output),
},
{
key: "ctrl + plus",
preventDefault: true,
command: (output: ShortcutEventOutput) => console.log("control + plus key", output),
}
]
Sequences can be used to support gmail like actions where you click "g" then "a", or "g" then "o" to perform certain actions.
The library can get very confused if you have a single key handler that uses the same key that a sequence starts with. This is because it can't tell if you are starting the sequence or if you are pressing that key on its own.
To counter this, there is a 500ms delay(only when single key is used in the beginning of another sequence, so it won't affect performance) . This gives the library time to wait for a more complete sequence, otherwise the single sequence will be triggered.
for example: binding both "? a" and "?", then clicking "?" will trigger the "?" callback, but only after 500ms delay. However, in all other cases there's no delay in execution of the callback (unless debounceTime is provided)
This library supports gmail style sequences:
[{
key: ["g a"],
command: (output: ShortcutEventOutput) => console.log("? a", output),
}]
konami code:
[{
key: ["up up down down left right left right b a enter"],
label: "Sequences",
description: "Konami code!",
command: (output: ShortcutEventOutput) => console.log("Konami code!!!", output),
}]
Sequences can be used inside components or directives and are declared without the plus(+) sign, for example:
key: ["a b c"]
will require clicking, a, then b, then c.
Component that can be used across the app to bind to various shortcuts
| Name | Type | Default | Description |
|---|---|---|---|
| shortcuts | ShortcutInput / ShortcutInput[] | [] | List of shortcut inputs types see types |
| disabled | boolean | false | disable the shortcuts for the component |
| Name | Input | Return | Description |
|---|---|---|---|
| select | string - key to listen to events (example: 'cmd + e') | Observable<ShortcutEventOutput> | Listen to specific key events (will only work for registered keys) |
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from "@angular/core";
import { ShortcutInput, ShortcutEventOutput, NgHotkeysComponent } from "ng-hotkeys";
@Component({
selector: 'demo-component',
template: "<ng-hotkeys [shortcuts]="shortcuts"></ng-hotkeys>"
})
export class DemoComponent implements AfterViewInit {
shortcuts: ShortcutInput[] = [];
@ViewChild('input') input: ElementRef;
ngAfterViewInit(): void {
this.shortcuts.push(
{
key: "ctrl + t",
preventDefault: true,
allowIn: [AllowIn.Textarea, AllowIn.Input],
command: e => console.log("clicked " , e.key)
},
{
key: ["? a"],
label: "Sequences",
description: "Sequence ? and a",
command: (output: ShortcutEventOutput) => console.log("? a", output),
preventDefault: true
},
{
key: ["up up down down left right left right b a enter"],
label: "Sequences",
description: "Konami code!",
command: (output: ShortcutEventOutput) => console.log("Konami code!!!", output),
},
{
key: "cmd + shift + f",
command: (output: ShortcutEventOutput) => console.log(output),
preventDefault: true,
throttleTime: 250,
target: this.input.nativeElement
},
{
key: ["cmd + =", "cmd + z"],
command: (output: ShortcutEventOutput) => console.log(output),
preventDefault: true
},
{
key: "cmd + f",
command: (output: ShortcutEventOutput) => console.log(output),
preventDefault: true
}
);
this.keyboard.select("cmd + f").subscribe(e => console.log(e));
}
@ViewChild(NgHotkeysComponent) private keyboard: NgHotkeysComponent;
}
@angular/animations ( npm install --save @angular/animations or yarn add @angular/animationsCan be used to show an help screen ( will be attached to body and be shown as a modal)
Should be placed in the root of your app, preferably in app.component.html
| Name | Type | default | description |
|---|---|---|---|
| key | string | none | The key to show/hide the help modal |
| keyDescription | string | none | Description to show in the menu shortcut list for the toggle shortcut |
| keyLabel | string | none | Label that can be used to group shortcuts together in the help menu |
| closeKey | string | none | Close key to be used to close the modal |
| closeKeyDescription | string | none | Description to show in the menu shortcut list for closing the modal shortcut |
| closeKeyLabel | string | none | Label that can be used to group shortcuts together in the help menu |
| title | string | "Keyboard shortcuts" | The title of the help screen |
| emptyMessage | string | "No shortcuts available" | What message to show when no commands are registered when help modal is opened. |
| disableScrolling | boolean | true | Whether to disable body scrolling when modal help screen is opened. |
| Name | Input | Return | Description |
|---|---|---|---|
| hide | void | NgHotkeysHelpComponent | Programmatically hide the modal |
| reveal | void | NgHotkeysHelpComponent | Programmatically hide the modal |
| visible | void | boolean | Check whether the modal is visible or not. |
| toggle | void | NgHotkeysHelpComponent | Programmatically toggle the modal visibility |
| Name | Input | Return | Description |
|---|---|---|---|
| select | string - key to listen to events (example: 'cmd + e') | Observable<ShortcutEventOutput> | Listen to specific key events (will only work for registered keys) |
app.component.ts
import { Component } from "@angular/core";
@Component({
selector: "app-root",
template: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
title = "Hello";
}
app.component.html
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<ng-hotkeys-help [key]="'f1'" [closeKey]="'escape'" [title]="'Help'"></ng-hotkeys-help>
</div>
Directive can only be used for focusable elements, such as textarea, select, input, etc...
The shortcut then will only be active while the element is in focus.
| Name | Type | default | description |
|---|---|---|---|
| ngHotKeys | Shortcut / Shortcut | [] | List of shortcuts see types |
| disabled | boolean | false | disable the shortcuts for the directive |
| disableScrolling | boolean | true | disable body scrolling while modal is open |
import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from "@angular/core";
import { ShortcutInput, ShortcutEventOutput, NgHotkeysComponent } from "ng-hotkeys";
@Component({
selector: 'demo-component',
template: "<input [ngHotKeys]="shortcuts" />"
})
export class DemoComponent implements AfterViewInit {
shortcuts: ShortcutInput[] = [];
@ViewChild('input') input: ElementRef;
ngAfterViewInit(): void {
this.shortcuts.push({
key: "cmd + e",
label: "test",
description: "hello world",
command: () => console.log('directive cmd + e'),
preventDefault: true
});
this.keyboard.select("cmd + f").subscribe(e => console.log(e));
}
@ViewChild(NgHotkeysComponent) private keyboard: NgHotkeysComponent;
}
Singleton service that can be used to render a custom help screen. (used to build the Built in help component)
Provides access to all registered shortcuts in the app using Observable that updates on shortcuts changes.
Since shortcuts can be added or removed during the lifecycle of the app, an observable data structure needed to be used.
| properties | type | description |
|---|---|---|
| shortcuts$ | Observable<{ key: string, label: string, description: string }[]> | Array of registered shortcuts across the whole app |
A singleton service that can be used globally to listen to any registered shortcut:
| Name | Input | Return | Description |
|---|---|---|---|
| select | string - key to listen to events (example: 'cmd + e') | Observable<ShortcutEventOutput> | Listen to specific key events (will only work for registered keys) |
export enum AllowIn {
Textarea = 'TEXTAREA',
Input = 'INPUT',
Select = "SELECT"
}
Used for Directive input
export interface Shortcut {
key: string | string[];
/**
* callback to be called when shortcut is pressed.
* @param event - the event out
*/
command(event: ShortcutEventOutput): any;
/**
* Description for the command can be used for rendering help menu.
*/
description?: string;
/**
* How much time to throttle in ms.
*/
throttleTime?: number;
/**
* Label, can be used for grouping commands.
*/
label?: string;
/**
* Prevent browser default, default: false
*/
preventDefault?: boolean;
}
Used for the component as input.
export interface ShortcutInput extends Shortcut {
/**
* textarea, select and input are ignored by default, this is used to override
* this behavior.
* allow in node names, accepts: ["TEXTAREA", "SELECT", "INPUT]
*/
allowIn?: AllowIn[];
/**
* Only trigger the command when the target is in focus.
*/
target?: HTMLElement;
}
type = ShortcutEventOutput {
event: KeyboardEvent;
key: string | string[];
}
npm run build-lib
npm run build-libnpm publish dist/ng-hotkeysThis project is licensed under the MIT License - see the LICENSE file for details
FAQs
ng-hotkeys for Angular 14+
The npm package ng-hotkeys receives a total of 1 weekly downloads. As such, ng-hotkeys popularity was classified as not popular.
We found that ng-hotkeys demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.