Skip to content

Commit 5a50f60

Browse files
committed
refactor(chat): use key binding controller instead of handling keydown event
1 parent e614203 commit 5a50f60

File tree

2 files changed

+30
-44
lines changed

2 files changed

+30
-44
lines changed

src/components/chat/chat-message-list.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { state } from 'lit/decorators.js';
44
import { repeat } from 'lit/directives/repeat.js';
55
import { chatContext } from '../common/context.js';
66
import {
7+
addKeybindings,
78
arrowDown,
89
arrowUp,
910
endKey,
@@ -63,6 +64,15 @@ export default class IgcChatMessageListComponent extends LitElement {
6364
registerComponent(IgcChatMessageListComponent, IgcChatMessageComponent);
6465
}
6566

67+
constructor() {
68+
super();
69+
addKeybindings(this)
70+
.set(homeKey, this.navigateToMessage)
71+
.set(endKey, this.navigateToMessage)
72+
.set(arrowUp, this.navigateToMessage)
73+
.set(arrowDown, this.navigateToMessage);
74+
}
75+
6676
/**
6777
* Formats a date to a human-readable label.
6878
* Returns 'Today', 'Yesterday', or localized date string.
@@ -168,7 +178,7 @@ export default class IgcChatMessageListComponent extends LitElement {
168178
* @param e KeyboardEvent from user input
169179
* @private
170180
*/
171-
private handleKeyDown(e: KeyboardEvent) {
181+
private navigateToMessage(e: KeyboardEvent) {
172182
if (!this._chatState?.messages || this._chatState.messages.length === 0) {
173183
return;
174184
}
@@ -179,21 +189,21 @@ export default class IgcChatMessageListComponent extends LitElement {
179189
let activeMessageId = '';
180190

181191
switch (e.key) {
182-
case homeKey:
192+
case 'home':
183193
activeMessageId = this._chatState.sortedMessagesIds[0];
184194
break;
185-
case endKey:
195+
case 'end':
186196
activeMessageId =
187197
this._chatState.sortedMessagesIds[
188198
this._chatState.sortedMessagesIds.length - 1
189199
];
190200
break;
191-
case arrowUp:
201+
case 'arrowup':
192202
if (currentIndex > 0) {
193203
activeMessageId = this._chatState.sortedMessagesIds[currentIndex - 1];
194204
}
195205
break;
196-
case arrowDown:
206+
case 'arrowdown':
197207
if (currentIndex < this._chatState?.messages.length - 1) {
198208
activeMessageId = this._chatState.sortedMessagesIds[currentIndex + 1];
199209
}
@@ -258,10 +268,8 @@ export default class IgcChatMessageListComponent extends LitElement {
258268
aria-label="Message list"
259269
tabindex="0"
260270
@focusin=${this.handleFocusIn}
261-
@focusout=${this.handleFocusOut}
262-
@keydown=${this.handleKeyDown}
263-
>
264-
<div part="message-list">
271+
@focusout=${this.handleFocusOut}></div>
272+
<div class="message-list">
265273
${repeat(
266274
groupedMessages,
267275
(group) => group.date,
@@ -286,9 +294,11 @@ export default class IgcChatMessageListComponent extends LitElement {
286294
)}
287295
`
288296
)}
289-
${this._chatState?.options?.isComposing
290-
? this.renderLoadingTemplate()
291-
: nothing}
297+
${
298+
this._chatState?.options?.isComposing
299+
? this.renderLoadingTemplate()
300+
: nothing
301+
}
292302
</div>
293303
</div>
294304
`;

src/components/chat/chat.spec.ts

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,27 +1232,15 @@ describe('Chat', () => {
12321232
await nextFrame();
12331233

12341234
// Activates the previous message on `ArrowUp`
1235-
messageContainer.dispatchEvent(
1236-
new KeyboardEvent('keydown', {
1237-
key: arrowUp,
1238-
bubbles: true,
1239-
cancelable: true,
1240-
})
1241-
);
1242-
await nextFrame();
1235+
simulateKeyboard(messageContainer, arrowUp);
1236+
await elementUpdated(chat);
12431237
expect(messageContainer.getAttribute('aria-activedescendant')).to.equal(
12441238
'message-3'
12451239
);
12461240

12471241
// Activates the next message on `ArrowDown`
1248-
messageContainer.dispatchEvent(
1249-
new KeyboardEvent('keydown', {
1250-
key: arrowDown,
1251-
bubbles: true,
1252-
cancelable: true,
1253-
})
1254-
);
1255-
await nextFrame();
1242+
simulateKeyboard(messageContainer, arrowDown);
1243+
await elementUpdated(chat);
12561244
expect(messageContainer.getAttribute('aria-activedescendant')).to.equal(
12571245
'message-4'
12581246
);
@@ -1274,27 +1262,15 @@ describe('Chat', () => {
12741262
await nextFrame();
12751263

12761264
// Activates the first message on `Home`
1277-
messageContainer.dispatchEvent(
1278-
new KeyboardEvent('keydown', {
1279-
key: homeKey,
1280-
bubbles: true,
1281-
cancelable: true,
1282-
})
1283-
);
1284-
await nextFrame();
1265+
simulateKeyboard(messageContainer, homeKey);
1266+
await elementUpdated(chat);
12851267
expect(messageContainer.getAttribute('aria-activedescendant')).to.equal(
12861268
'message-1'
12871269
);
12881270

12891271
// Activates the last message on `End`
1290-
messageContainer.dispatchEvent(
1291-
new KeyboardEvent('keydown', {
1292-
key: endKey,
1293-
bubbles: true,
1294-
cancelable: true,
1295-
})
1296-
);
1297-
await nextFrame();
1272+
simulateKeyboard(messageContainer, endKey);
1273+
await elementUpdated(chat);
12981274
expect(messageContainer.getAttribute('aria-activedescendant')).to.equal(
12991275
'message-4'
13001276
);

0 commit comments

Comments
 (0)