diff --git a/src/client/app/common/hotkey.ts b/src/client/app/common/hotkey.ts
index 10cbeea543..62726887d1 100644
--- a/src/client/app/common/hotkey.ts
+++ b/src/client/app/common/hotkey.ts
@@ -13,8 +13,10 @@ const getKeyMap = keymap => Object.keys(keymap).map(input => {
 			case 'meta':
 				result[keyName] = true;
 				break;
-			default:
+			default: {
 				result.keyCode = keyCode(keyName);
+				if (!Array.isArray(result.keyCode)) result.keyCode = [result.keyCode];
+			}
 		}
 	});
 
@@ -45,7 +47,7 @@ export default {
 					for (const hotkey of el._keymap) {
 						if (el._hotkey_global && reservedKeyCodes.includes(`'${e.keyCode}'`)) break;
 
-						const callback = hotkey.keyCode === e.keyCode &&
+						const callback = hotkey.keyCode.includes(e.keyCode) &&
 							!!hotkey.ctrl === e.ctrlKey &&
 							!!hotkey.alt === e.altKey &&
 							!!hotkey.shift === e.shiftKey &&
diff --git a/src/client/app/common/keycode.ts b/src/client/app/common/keycode.ts
index c5ea6cb484..0324a5389a 100644
--- a/src/client/app/common/keycode.ts
+++ b/src/client/app/common/keycode.ts
@@ -67,8 +67,7 @@ export const codes = {
 	'left command': 91,
 	'right command': 93,
 	'numpad *': 106,
-	// 'numpad +': 107,
-	'numpad +': 43,
+	'numpad plus': [43, 107],
 	'numpad add': 43, // as a trick
 	'numpad -': 109,
 	'numpad .': 110,
diff --git a/src/client/app/common/views/components/reaction-picker.vue b/src/client/app/common/views/components/reaction-picker.vue
index c329241d8a..4e27fb36e3 100644
--- a/src/client/app/common/views/components/reaction-picker.vue
+++ b/src/client/app/common/views/components/reaction-picker.vue
@@ -3,7 +3,7 @@
 	<div class="backdrop" ref="backdrop" @click="close"></div>
 	<div class="popover" :class="{ compact, big }" ref="popover">
 		<p v-if="!compact">{{ title }}</p>
-		<div>
+		<div ref="buttons" :class="{ showFocus }">
 			<button @click="react('like')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="1" title="%i18n:common.reactions.like%"><mk-reaction-icon reaction='like'/></button>
 			<button @click="react('love')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="2" title="%i18n:common.reactions.love%"><mk-reaction-icon reaction='love'/></button>
 			<button @click="react('laugh')" @mouseover="onMouseover" @mouseout="onMouseout" tabindex="3" title="%i18n:common.reactions.laugh%"><mk-reaction-icon reaction='laugh'/></button>
@@ -50,12 +50,19 @@ export default Vue.extend({
 			type: Boolean,
 			required: false,
 			default: false
+		},
+
+		showFocus: {
+			type: Boolean,
+			required: false,
+			default: false
 		}
 	},
 
 	data() {
 		return {
-			title: placeholder
+			title: placeholder,
+			focus: null
 		};
 	},
 
@@ -63,6 +70,9 @@ export default Vue.extend({
 		keymap(): any {
 			return {
 				'esc': this.close,
+				'enter': this.choose,
+				'space': this.choose,
+				'numpad plus': this.choose,
 				'1': () => this.react('like'),
 				'numpad 1': () => this.react('like'),
 				'2': () => this.react('love'),
@@ -83,12 +93,24 @@ export default Vue.extend({
 				'numpad 9': () => this.react('rip'),
 				'0': () => this.react('pudding'),
 				'numpad 0': () => this.react('pudding'),
+				'up': this.focusUp,
+				'right': this.focusRight,
+				'down': this.focusDown,
+				'left': this.focusLeft,
 			};
 		}
 	},
 
+	watch: {
+		focus(i) {
+			this.$refs.buttons.childNodes[i].focus();
+		}
+	},
+
 	mounted() {
 		this.$nextTick(() => {
+			this.focus = 0;
+
 			const popover = this.$refs.popover as any;
 
 			const rect = this.source.getBoundingClientRect();
@@ -164,6 +186,26 @@ export default Vue.extend({
 					this.destroyDom();
 				}
 			});
+		},
+
+		focusUp() {
+			this.focus = this.focus == 0 ? 9 : this.focus < 5 ? (this.focus + 4) : (this.focus - 5);
+		},
+
+		focusDown() {
+			this.focus = this.focus == 9 ? 0 : this.focus >= 5 ? (this.focus - 4) : (this.focus + 5);
+		},
+
+		focusRight() {
+			this.focus = this.focus == 9 ? 0 : (this.focus + 1);
+		},
+
+		focusLeft() {
+			this.focus = this.focus == 0 ? 9 : (this.focus - 1);
+		},
+
+		choose() {
+			this.$refs.buttons.childNodes[this.focus].click();
 		}
 	}
 });
@@ -249,6 +291,21 @@ root(isDark)
 			width 240px
 			text-align center
 
+			&.showFocus
+				> button:focus
+					z-index 1
+
+					&:after
+						content ""
+						pointer-events none
+						position absolute
+						top 0
+						right 0
+						bottom 0
+						left 0
+						border 2px solid rgba($theme-color, 0.3)
+						border-radius 4px
+
 			> button
 				padding 0
 				width 40px
diff --git a/src/client/app/desktop/views/components/notes.note.vue b/src/client/app/desktop/views/components/notes.note.vue
index fadf47e628..b8c5f31511 100644
--- a/src/client/app/desktop/views/components/notes.note.vue
+++ b/src/client/app/desktop/views/components/notes.note.vue
@@ -48,7 +48,7 @@
 				<button class="renoteButton" @click="renote" title="%i18n:@renote%">
 					%fa:retweet%<p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
 				</button>
-				<button class="reactionButton" :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:@add-reaction%">
+				<button class="reactionButton" :class="{ reacted: p.myReaction != null }" @click="react()" ref="reactButton" title="%i18n:@add-reaction%">
 					%fa:plus%<p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 				</button>
 				<button @click="menu" ref="menuButton">
@@ -114,7 +114,8 @@ export default Vue.extend({
 		keymap(): any {
 			return {
 				'r': this.reply,
-				'a': this.react,
+				'a': () => this.react(true),
+				'numpad plus': () => this.react(true),
 				'n': this.renote,
 				'up': this.focusBefore,
 				'shift+tab': this.focusBefore,
@@ -244,10 +245,12 @@ export default Vue.extend({
 			}).$once('closed', this.focus);
 		},
 
-		react() {
+		react(viaKeyboard = false) {
+			this.blur();
 			(this as any).os.new(MkReactionPicker, {
 				source: this.$refs.reactButton,
-				note: this.p
+				note: this.p,
+				showFocus: viaKeyboard
 			}).$once('closed', this.focus);
 		},
 
@@ -262,6 +265,10 @@ export default Vue.extend({
 			this.$el.focus();
 		},
 
+		blur() {
+			this.$el.blur();
+		},
+
 		focusBefore() {
 			focus(this.$el, e => e.previousElementSibling);
 		},