@jupyter/chat 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,11 +15,26 @@ export function ChatInput(props) {
15
15
  const autocompletion = useRef();
16
16
  const [input, setInput] = useState(props.value || '');
17
17
  const [sendWithShiftEnter, setSendWithShiftEnter] = useState((_a = model.config.sendWithShiftEnter) !== null && _a !== void 0 ? _a : false);
18
+ // store reference to the input element to enable focusing it easily
19
+ const inputRef = useRef();
18
20
  useEffect(() => {
19
- model.configChanged.connect((_, config) => {
21
+ var _a;
22
+ const configChanged = (_, config) => {
20
23
  var _a;
21
24
  setSendWithShiftEnter((_a = config.sendWithShiftEnter) !== null && _a !== void 0 ? _a : false);
22
- });
25
+ };
26
+ model.configChanged.connect(configChanged);
27
+ const focusInputElement = () => {
28
+ if (inputRef.current) {
29
+ inputRef.current.focus();
30
+ }
31
+ };
32
+ (_a = model.focusInputSignal) === null || _a === void 0 ? void 0 : _a.connect(focusInputElement);
33
+ return () => {
34
+ var _a, _b;
35
+ (_a = model.configChanged) === null || _a === void 0 ? void 0 : _a.disconnect(configChanged);
36
+ (_b = model.focusInputSignal) === null || _b === void 0 ? void 0 : _b.disconnect(focusInputElement);
37
+ };
23
38
  }, [model]);
24
39
  // The autocomplete commands options.
25
40
  const [commandOptions, setCommandOptions] = useState([]);
@@ -131,7 +146,7 @@ export function ChatInput(props) {
131
146
  padding: 2
132
147
  }
133
148
  }
134
- }, renderInput: params => (React.createElement(TextField, { ...params, fullWidth: true, variant: "outlined", multiline: true, onKeyDown: handleKeyDown, placeholder: "Start chatting", InputProps: {
149
+ }, renderInput: params => (React.createElement(TextField, { ...params, fullWidth: true, variant: "outlined", multiline: true, onKeyDown: handleKeyDown, placeholder: "Start chatting", inputRef: inputRef, InputProps: {
135
150
  ...params.InputProps,
136
151
  endAdornment: (React.createElement(InputAdornment, { position: "end" },
137
152
  props.onCancel && (React.createElement(IconButton, { size: "small", color: "primary", onClick: onCancel, title: 'Cancel edition', className: clsx(CANCEL_BUTTON_CLASS) },
package/lib/model.d.ts CHANGED
@@ -51,6 +51,10 @@ export interface IChatModel extends IDisposable {
51
51
  * A signal emitting when the viewport change.
52
52
  */
53
53
  readonly viewportChanged?: ISignal<IChatModel, number[]>;
54
+ /**
55
+ * A signal emitting when the focus is requested on the input.
56
+ */
57
+ readonly focusInputSignal?: ISignal<IChatModel, void>;
54
58
  /**
55
59
  * Send a message, to be defined depending on the chosen technology.
56
60
  * Default to no-op.
@@ -104,6 +108,10 @@ export interface IChatModel extends IDisposable {
104
108
  * @param count - the number of messages to delete.
105
109
  */
106
110
  messagesDeleted(index: number, count: number): void;
111
+ /**
112
+ * Function to request the focus on the input of the chat.
113
+ */
114
+ focusInput(): void;
107
115
  }
108
116
  /**
109
117
  * The default chat model implementation.
@@ -166,6 +174,10 @@ export declare class ChatModel implements IChatModel {
166
174
  * A signal emitting when the viewport change.
167
175
  */
168
176
  get viewportChanged(): ISignal<IChatModel, number[]>;
177
+ /**
178
+ * A signal emitting when the focus is requested on the input.
179
+ */
180
+ get focusInputSignal(): ISignal<IChatModel, void>;
169
181
  /**
170
182
  * Send a message, to be defined depending on the chosen technology.
171
183
  * Default to no-op.
@@ -207,6 +219,10 @@ export declare class ChatModel implements IChatModel {
207
219
  * @param count - the number of messages to delete.
208
220
  */
209
221
  messagesDeleted(index: number, count: number): void;
222
+ /**
223
+ * Function to request the focus on the input of the chat.
224
+ */
225
+ focusInput(): void;
210
226
  /**
211
227
  * Add unread messages to the list.
212
228
  * @param indexes - list of new indexes.
@@ -236,6 +252,7 @@ export declare class ChatModel implements IChatModel {
236
252
  private _configChanged;
237
253
  private _unreadChanged;
238
254
  private _viewportChanged;
255
+ private _focusInputSignal;
239
256
  }
240
257
  /**
241
258
  * The chat model namespace.
package/lib/model.js CHANGED
@@ -24,6 +24,7 @@ export class ChatModel {
24
24
  this._configChanged = new Signal(this);
25
25
  this._unreadChanged = new Signal(this);
26
26
  this._viewportChanged = new Signal(this);
27
+ this._focusInputSignal = new Signal(this);
27
28
  const config = (_a = options.config) !== null && _a !== void 0 ? _a : {};
28
29
  // Stack consecutive messages from the same user by default.
29
30
  this._config = { stackMessages: true, ...config };
@@ -172,6 +173,12 @@ export class ChatModel {
172
173
  get viewportChanged() {
173
174
  return this._viewportChanged;
174
175
  }
176
+ /**
177
+ * A signal emitting when the focus is requested on the input.
178
+ */
179
+ get focusInputSignal() {
180
+ return this._focusInputSignal;
181
+ }
175
182
  /**
176
183
  * Send a message, to be defined depending on the chosen technology.
177
184
  * Default to no-op.
@@ -268,6 +275,12 @@ export class ChatModel {
268
275
  this._messages.splice(index, count);
269
276
  this._messagesUpdated.emit();
270
277
  }
278
+ /**
279
+ * Function to request the focus on the input of the chat.
280
+ */
281
+ focusInput() {
282
+ this._focusInputSignal.emit();
283
+ }
271
284
  /**
272
285
  * Add unread messages to the list.
273
286
  * @param indexes - list of new indexes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jupyter/chat",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "A package that provides UI components that can be used to create a chat in a Jupyterlab extension.",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -70,6 +70,7 @@
70
70
  "react-dom": "^18.2.0"
71
71
  },
72
72
  "devDependencies": {
73
+ "@jupyterlab/testing": "^4.2.0",
73
74
  "@types/jest": "^29.2.0",
74
75
  "@types/json-schema": "^7.0.11",
75
76
  "@types/react": "^18.2.0",
@@ -102,20 +103,6 @@
102
103
  "publishConfig": {
103
104
  "access": "public"
104
105
  },
105
- "jupyterlab": {
106
- "discovery": {
107
- "server": {
108
- "managers": [
109
- "pip"
110
- ],
111
- "base": {
112
- "name": "jupyter_chat"
113
- }
114
- }
115
- },
116
- "extension": false,
117
- "schemaDir": "schema"
118
- },
119
106
  "eslintIgnore": [
120
107
  "node_modules",
121
108
  "dist",
@@ -18,7 +18,11 @@ import { Send, Cancel } from '@mui/icons-material';
18
18
  import clsx from 'clsx';
19
19
  import { IChatModel } from '../model';
20
20
  import { IAutocompletionRegistry } from '../registry';
21
- import { AutocompleteCommand, IAutocompletionCommandsProps } from '../types';
21
+ import {
22
+ AutocompleteCommand,
23
+ IAutocompletionCommandsProps,
24
+ IConfig
25
+ } from '../types';
22
26
 
23
27
  const INPUT_BOX_CLASS = 'jp-chat-input-container';
24
28
  const SEND_BUTTON_CLASS = 'jp-chat-send-button';
@@ -32,10 +36,26 @@ export function ChatInput(props: ChatInput.IProps): JSX.Element {
32
36
  model.config.sendWithShiftEnter ?? false
33
37
  );
34
38
 
39
+ // store reference to the input element to enable focusing it easily
40
+ const inputRef = useRef<HTMLInputElement>();
41
+
35
42
  useEffect(() => {
36
- model.configChanged.connect((_, config) => {
43
+ const configChanged = (_: IChatModel, config: IConfig) => {
37
44
  setSendWithShiftEnter(config.sendWithShiftEnter ?? false);
38
- });
45
+ };
46
+ model.configChanged.connect(configChanged);
47
+
48
+ const focusInputElement = () => {
49
+ if (inputRef.current) {
50
+ inputRef.current.focus();
51
+ }
52
+ };
53
+ model.focusInputSignal?.connect(focusInputElement);
54
+
55
+ return () => {
56
+ model.configChanged?.disconnect(configChanged);
57
+ model.focusInputSignal?.disconnect(focusInputElement);
58
+ };
39
59
  }, [model]);
40
60
 
41
61
  // The autocomplete commands options.
@@ -177,6 +197,7 @@ export function ChatInput(props: ChatInput.IProps): JSX.Element {
177
197
  multiline
178
198
  onKeyDown={handleKeyDown}
179
199
  placeholder="Start chatting"
200
+ inputRef={inputRef}
180
201
  InputProps={{
181
202
  ...params.InputProps,
182
203
  endAdornment: (
package/src/model.ts CHANGED
@@ -75,6 +75,11 @@ export interface IChatModel extends IDisposable {
75
75
  */
76
76
  readonly viewportChanged?: ISignal<IChatModel, number[]>;
77
77
 
78
+ /**
79
+ * A signal emitting when the focus is requested on the input.
80
+ */
81
+ readonly focusInputSignal?: ISignal<IChatModel, void>;
82
+
78
83
  /**
79
84
  * Send a message, to be defined depending on the chosen technology.
80
85
  * Default to no-op.
@@ -139,6 +144,11 @@ export interface IChatModel extends IDisposable {
139
144
  * @param count - the number of messages to delete.
140
145
  */
141
146
  messagesDeleted(index: number, count: number): void;
147
+
148
+ /**
149
+ * Function to request the focus on the input of the chat.
150
+ */
151
+ focusInput(): void;
142
152
  }
143
153
 
144
154
  /**
@@ -328,6 +338,13 @@ export class ChatModel implements IChatModel {
328
338
  return this._viewportChanged;
329
339
  }
330
340
 
341
+ /**
342
+ * A signal emitting when the focus is requested on the input.
343
+ */
344
+ get focusInputSignal(): ISignal<IChatModel, void> {
345
+ return this._focusInputSignal;
346
+ }
347
+
331
348
  /**
332
349
  * Send a message, to be defined depending on the chosen technology.
333
350
  * Default to no-op.
@@ -435,6 +452,13 @@ export class ChatModel implements IChatModel {
435
452
  this._messagesUpdated.emit();
436
453
  }
437
454
 
455
+ /**
456
+ * Function to request the focus on the input of the chat.
457
+ */
458
+ focusInput(): void {
459
+ this._focusInputSignal.emit();
460
+ }
461
+
438
462
  /**
439
463
  * Add unread messages to the list.
440
464
  * @param indexes - list of new indexes.
@@ -498,6 +522,7 @@ export class ChatModel implements IChatModel {
498
522
  private _configChanged = new Signal<IChatModel, IConfig>(this);
499
523
  private _unreadChanged = new Signal<IChatModel, number[]>(this);
500
524
  private _viewportChanged = new Signal<IChatModel, number[]>(this);
525
+ private _focusInputSignal = new Signal<ChatModel, void>(this);
501
526
  }
502
527
 
503
528
  /**