addons/components/Kbd.tsxblame
View source
b69ab311/**
b69ab312 * Copyright (c) Meta Platforms, Inc. and affiliates.
b69ab313 *
b69ab314 * This source code is licensed under the MIT license found in the
b69ab315 * LICENSE file in the root directory of this source tree.
b69ab316 */
b69ab317
b69ab318import {KeyCode, Modifier} from './KeyboardShortcuts';
b69ab319import {isMac, isWindows} from './OperatingSystem';
b69ab3110
b69ab3111import './Kbd.css';
b69ab3112
b69ab3113/** Keyboard key, useful for rendering keyboard shortcuts */
b69ab3114export function Kbd({keycode, modifiers}: {keycode?: KeyCode; modifiers?: Array<Modifier>}) {
b69ab3115 return (
b69ab3116 <span className="kbd-group" title={asEntireString(keycode, modifiers)}>
b69ab3117 {modifiers
b69ab3118 ?.filter(modifier => modifier != Modifier.NONE)
b69ab3119 .map(modifier => (
b69ab3120 <kbd className="modifier" key={modifier}>
b69ab3121 {modifierToIcon[modifier]}
b69ab3122 </kbd>
b69ab3123 ))}
b69ab3124 {keycode != null && <kbd>{keycodeToString(keycode)}</kbd>}
b69ab3125 </span>
b69ab3126 );
b69ab3127}
b69ab3128
b69ab3129function keycodeToString(keycode: KeyCode): string {
b69ab3130 switch (keycode) {
b69ab3131 case KeyCode.QuestionMark:
b69ab3132 return '?';
b69ab3133 case KeyCode.SingleQuote:
b69ab3134 return "'";
b69ab3135 case KeyCode.Period:
b69ab3136 return '.';
b69ab3137 case KeyCode.Escape:
b69ab3138 return 'Esc';
b69ab3139 case KeyCode.Plus:
b69ab3140 return '+';
b69ab3141 case KeyCode.Minus:
b69ab3142 return '-';
b69ab3143 default:
b69ab3144 return String.fromCharCode(keycode).toUpperCase();
b69ab3145 }
b69ab3146}
b69ab3147
b69ab3148const modifierToIcon = isMac
b69ab3149 ? ({
b69ab3150 [Modifier.ALT]: '⌥',
b69ab3151 [Modifier.CMD]: '⌘',
b69ab3152 [Modifier.SHIFT]: '⇧',
b69ab3153 [Modifier.CTRL]: '⌃',
b69ab3154 [Modifier.NONE]: '',
b69ab3155 } as const)
b69ab3156 : ({
b69ab3157 [Modifier.ALT]: 'Alt',
b69ab3158 [Modifier.CMD]: isWindows ? 'Win' : 'Super',
b69ab3159 [Modifier.SHIFT]: 'Shift',
b69ab3160 [Modifier.CTRL]: 'Ctrl',
b69ab3161 [Modifier.NONE]: '',
b69ab3162 } as const);
b69ab3163
b69ab3164const modifierToString = {
b69ab3165 [Modifier.ALT]: 'Alt',
b69ab3166 [Modifier.CMD]: 'Command',
b69ab3167 [Modifier.SHIFT]: 'Shift',
b69ab3168 [Modifier.CTRL]: 'Control',
b69ab3169 [Modifier.NONE]: '',
b69ab3170} as const;
b69ab3171
b69ab3172function asEntireString(keycode?: KeyCode, modifiers?: Array<Modifier>): string {
b69ab3173 const result: Array<string> = [];
b69ab3174 for (const modifier of modifiers ?? []) {
b69ab3175 result.push(modifierToString[modifier]);
b69ab3176 }
b69ab3177 if (keycode != null) {
b69ab3178 result.push(keycodeToString(keycode));
b69ab3179 }
b69ab3180 return result.join(' + ');
b69ab3181}