Skip to content

Commit e99b0b1

Browse files
authored
Fix chat focus behavior to allow copy/paste from messages (#268)
* using eventlistenr instead of onclick * adding selected condition * making input future-proof to interactive elemnts * adding to old import * refactor: simplify click event handling in ChatWidget
1 parent 7082c1f commit e99b0b1

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

packages/jupyter-chat/src/components/messages/messages.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import { IChatCommandRegistry, IMessageFooterRegistry } from '../../registers';
2121
import { IChatModel } from '../../model';
2222
import { IChatMessage, IUser } from '../../types';
2323

24+
export const MESSAGE_CLASS = 'jp-chat-message';
2425
const MESSAGES_BOX_CLASS = 'jp-chat-messages-container';
25-
const MESSAGE_CLASS = 'jp-chat-message';
2626
const MESSAGE_STACKED_CLASS = 'jp-chat-message-stacked';
2727

2828
/**

packages/jupyter-chat/src/widgets/chat-widget.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import React from 'react';
1111
import { Message } from '@lumino/messaging';
1212
import { Drag } from '@lumino/dragdrop';
1313

14-
import { Chat, IInputToolbarRegistry } from '../components';
14+
import { Chat, IInputToolbarRegistry, MESSAGE_CLASS } from '../components';
1515
import { chatIcon } from '../icons';
1616
import { IChatModel } from '../model';
1717
import {
@@ -40,7 +40,27 @@ export class ChatWidget extends ReactWidget {
4040

4141
this._chatOptions = options;
4242
this.id = `jupyter-chat::widget::${options.model.name}`;
43-
this.node.onclick = () => this.model.input.focus();
43+
this.node.addEventListener('click', (event: MouseEvent) => {
44+
const target = event.target as HTMLElement;
45+
if (this.node.contains(document.activeElement)) {
46+
return;
47+
}
48+
49+
const message = target.closest(`.${MESSAGE_CLASS}`);
50+
if (message) {
51+
const selection = window.getSelection();
52+
53+
if (
54+
selection &&
55+
selection.toString().trim() !== '' &&
56+
message.contains(selection.anchorNode)
57+
) {
58+
return;
59+
}
60+
}
61+
62+
this.model.input.focus();
63+
});
4464
}
4565

4666
/**

0 commit comments

Comments
 (0)