Some apps show each button's shortcut only while the user holds a modifier, so the hints are there when the user reaches for the keyboard, and out of the way otherwise. injectHotkeyHint returns a signal that's true while the user holds modifiers that belong to a hotkey. It's an optional helper, and it doesn't register anything, so use it alongside injectHotkey.
import { Component } from '@angular/core'
import {
formatForDisplay,
injectHotkey,
injectHotkeyHint,
} from '@tanstack/angular-hotkeys'
const saveHotkey = 'Mod+S'
@Component({
selector: 'app-save-button',
template: `
<button (click)="save()">
Save
@if (showHint()) {
<kbd>{{ label }}</kbd>
}
</button>
`,
})
export class SaveButtonComponent {
readonly label = formatForDisplay(saveHotkey)
readonly showHint = injectHotkeyHint(saveHotkey)
constructor() {
injectHotkey(saveHotkey, () => this.save())
}
save() {
/* ... */
}
}While the user holds Command on macOS, or Control elsewhere, the button reads "Save ⌘ S" or "Save Ctrl+S". Formatting & Display covers labels and keycaps.
To show a hint only while every modifier is held, pass exact:
readonly showHint = injectHotkeyHint('Alt+Shift+[KeyK]', { exact: true }) // Needs Alt and ShiftIf the hotkey sets platform, pass the same platform to injectHotkeyHint, so Mod resolves the same way. The hotkey and the options can also be getters.
A sequence shows its hint while the user holds the modifiers of its first step:
readonly showHint = injectHotkeyHint(['Mod+K', 'Mod+C']) // true while Mod is heldPass an app hotkey to show the user's current hotkey, including one they changed. An app hotkey with no hotkey assigned shows no hint. A small component keeps every button's hint the same:
import { Component, computed, input } from '@angular/core'
import {
formatForDisplay,
injectAppHotkeys,
injectHotkeyHint,
} from '@tanstack/angular-hotkeys'
import type { AppHotkeyId } from '@tanstack/angular-hotkeys'
@Component({
selector: 'app-hint',
template: `
@if (showHint() && appHotkey().hotkey; as hotkey) {
<kbd>{{ format(hotkey) }}</kbd>
}
`,
})
export class HintComponent {
readonly id = input.required<AppHotkeyId>()
readonly appHotkeys = injectAppHotkeys()
readonly appHotkey = computed(() => this.appHotkeys()[this.id()])
readonly showHint = injectHotkeyHint(() => this.appHotkey())
readonly format = formatForDisplay
}<button (click)="save()">Save <app-hint id="doc.save" /></button>injectHotkeyHint only looks at held keys. It doesn't know whether the hotkey is enabled, its scope is active, or its target has focus. When a hotkey can be off, combine the hint with the same state:
readonly isDirty = signal(false)
private readonly hint = injectHotkeyHint(saveHotkey)
readonly showHint = computed(() => this.hint() && this.isDirty())
constructor() {
injectHotkey(saveHotkey, () => this.save(), () => ({ enabled: this.isDirty() }))
}To check outside a component, such as while drawing on a canvas, pass the held keys to matchesHeldModifiers. It takes the same options:
import { getKeyStateTracker, matchesHeldModifiers } from '@tanstack/angular-hotkeys'
const tracker = getKeyStateTracker()
matchesHeldModifiers('Mod+S', tracker.getHeldKeys()) // true while Mod is heldHeld Key State Helpers covers the tracker and the other held-key functions.
The Kitchen Sink example shows hints next to its navigation links and buttons while Alt or Option is held.