@jupyter/chat 0.19.0-alpha.0 → 0.19.0-alpha.2
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.
- package/lib/active-cell-manager.js +4 -2
- package/lib/components/attachments.js +3 -3
- package/lib/components/chat.d.ts +3 -7
- package/lib/components/chat.js +9 -5
- package/lib/components/code-blocks/code-toolbar.js +8 -28
- package/lib/components/code-blocks/copy-button.js +4 -11
- package/lib/components/index.d.ts +1 -0
- package/lib/components/index.js +1 -0
- package/lib/components/input/buttons/attach-button.js +3 -10
- package/lib/components/input/buttons/cancel-button.js +6 -10
- package/lib/components/input/buttons/save-edit-button.js +6 -13
- package/lib/components/input/buttons/send-button.js +6 -23
- package/lib/components/input/buttons/stop-button.js +6 -23
- package/lib/components/input/chat-input.d.ts +0 -20
- package/lib/components/input/chat-input.js +21 -18
- package/lib/components/messages/footer.d.ts +5 -5
- package/lib/components/messages/footer.js +7 -2
- package/lib/components/messages/header.js +10 -8
- package/lib/components/messages/message-renderer.d.ts +0 -10
- package/lib/components/messages/message-renderer.js +5 -3
- package/lib/components/messages/message.d.ts +8 -4
- package/lib/components/messages/message.js +4 -2
- package/lib/components/messages/messages.d.ts +1 -39
- package/lib/components/messages/messages.js +31 -13
- package/lib/components/messages/navigation.d.ts +1 -2
- package/lib/components/messages/navigation.js +2 -1
- package/lib/components/messages/toolbar.js +12 -26
- package/lib/components/messages/welcome.d.ts +10 -2
- package/lib/components/messages/welcome.js +2 -1
- package/lib/components/mui-extras/tooltipped-button.d.ts +28 -1
- package/lib/components/mui-extras/tooltipped-button.js +34 -6
- package/lib/components/mui-extras/tooltipped-icon-button.d.ts +6 -1
- package/lib/components/mui-extras/tooltipped-icon-button.js +8 -7
- package/lib/context.d.ts +3 -2
- package/lib/context.js +9 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/tokens.d.ts +11 -0
- package/lib/tokens.js +9 -0
- package/lib/types.d.ts +4 -0
- package/lib/widgets/chat-widget.d.ts +5 -0
- package/lib/widgets/chat-widget.js +6 -0
- package/lib/widgets/multichat-panel.d.ts +1 -6
- package/lib/widgets/multichat-panel.js +3 -13
- package/package.json +1 -1
- package/src/active-cell-manager.ts +3 -1
- package/src/components/attachments.tsx +3 -3
- package/src/components/chat.tsx +13 -24
- package/src/components/code-blocks/code-toolbar.tsx +29 -55
- package/src/components/code-blocks/copy-button.tsx +13 -20
- package/src/components/index.ts +1 -0
- package/src/components/input/buttons/attach-button.tsx +5 -13
- package/src/components/input/buttons/cancel-button.tsx +11 -18
- package/src/components/input/buttons/save-edit-button.tsx +13 -22
- package/src/components/input/buttons/send-button.tsx +13 -34
- package/src/components/input/buttons/stop-button.tsx +13 -34
- package/src/components/input/chat-input.tsx +24 -38
- package/src/components/messages/footer.tsx +12 -10
- package/src/components/messages/header.tsx +23 -17
- package/src/components/messages/message-renderer.tsx +5 -13
- package/src/components/messages/message.tsx +4 -7
- package/src/components/messages/messages.tsx +73 -97
- package/src/components/messages/navigation.tsx +3 -3
- package/src/components/messages/toolbar.tsx +19 -33
- package/src/components/messages/welcome.tsx +13 -2
- package/src/components/mui-extras/tooltipped-button.tsx +44 -5
- package/src/components/mui-extras/tooltipped-icon-button.tsx +22 -6
- package/src/context.ts +15 -5
- package/src/index.ts +1 -0
- package/src/tokens.ts +24 -0
- package/src/types.ts +4 -0
- package/src/widgets/chat-widget.tsx +8 -0
- package/src/widgets/multichat-panel.tsx +7 -26
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
// import EditIcon from '@mui/icons-material/Edit';
|
|
7
7
|
import DeleteIcon from '@mui/icons-material/Delete';
|
|
8
|
-
import { Box
|
|
8
|
+
import { Box } from '@mui/material';
|
|
9
9
|
import React from 'react';
|
|
10
10
|
|
|
11
|
+
import { TooltippedIconButton } from '../mui-extras';
|
|
12
|
+
|
|
11
13
|
const TOOLBAR_CLASS = 'jp-chat-toolbar';
|
|
12
14
|
|
|
13
15
|
/**
|
|
@@ -18,43 +20,27 @@ export function MessageToolbar(props: MessageToolbar.IProps): JSX.Element {
|
|
|
18
20
|
|
|
19
21
|
// if (props.edit !== undefined) {
|
|
20
22
|
// const editButton = (
|
|
21
|
-
// <
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
// padding: 0,
|
|
30
|
-
// lineHeight: 0
|
|
31
|
-
// }}
|
|
32
|
-
// >
|
|
33
|
-
// <EditIcon sx={{ fontSize: '16px' }} />
|
|
34
|
-
// </IconButton>
|
|
35
|
-
// </span>
|
|
36
|
-
// </Tooltip>
|
|
23
|
+
// <TooltippedIconButton
|
|
24
|
+
// tooltip={'edit'}
|
|
25
|
+
// onClick={props.edit}
|
|
26
|
+
// aria-label={'Edit'}
|
|
27
|
+
// inputToolbar={false}
|
|
28
|
+
// >
|
|
29
|
+
// <EditIcon />
|
|
30
|
+
// </TooltippedIconButton>
|
|
37
31
|
// );
|
|
38
32
|
// buttons.push(editButton);
|
|
39
33
|
// }
|
|
40
34
|
if (props.delete !== undefined) {
|
|
41
35
|
const deleteButton = (
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
padding: 0,
|
|
51
|
-
lineHeight: 0
|
|
52
|
-
}}
|
|
53
|
-
>
|
|
54
|
-
<DeleteIcon sx={{ fontSize: '16px' }} />
|
|
55
|
-
</IconButton>
|
|
56
|
-
</span>
|
|
57
|
-
</Tooltip>
|
|
36
|
+
<TooltippedIconButton
|
|
37
|
+
tooltip={'Delete'}
|
|
38
|
+
onClick={props.delete}
|
|
39
|
+
aria-label={'Delete'}
|
|
40
|
+
inputToolbar={false}
|
|
41
|
+
>
|
|
42
|
+
<DeleteIcon />
|
|
43
|
+
</TooltippedIconButton>
|
|
58
44
|
);
|
|
59
45
|
buttons.push(deleteButton);
|
|
60
46
|
}
|
|
@@ -6,17 +6,28 @@
|
|
|
6
6
|
import { classes } from '@jupyterlab/ui-components';
|
|
7
7
|
import React, { useEffect, useRef } from 'react';
|
|
8
8
|
|
|
9
|
+
import { useChatContext } from '../../context';
|
|
9
10
|
import { MarkdownRenderer, MD_RENDERED_CLASS } from '../../markdown-renderer';
|
|
10
11
|
|
|
11
12
|
const WELCOME_MESSAGE_CLASS = 'jp-chat-welcome-message';
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* The component props.
|
|
16
|
+
*/
|
|
17
|
+
export interface IWelcomeMessageProps {
|
|
18
|
+
/**
|
|
19
|
+
* The content of the welcome message (markdown).
|
|
20
|
+
*/
|
|
21
|
+
content: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
/**
|
|
14
25
|
* The welcome message component.
|
|
15
26
|
* This message is displayed on top of the chat messages, and is rendered using a
|
|
16
27
|
* markdown renderer.
|
|
17
28
|
*/
|
|
18
|
-
export function WelcomeMessage(props:
|
|
19
|
-
const { rmRegistry } =
|
|
29
|
+
export function WelcomeMessage(props: IWelcomeMessageProps): JSX.Element {
|
|
30
|
+
const { rmRegistry } = useChatContext();
|
|
20
31
|
const content = props.content + '\n----\n';
|
|
21
32
|
|
|
22
33
|
// ref that tracks the content container to store the rendermime node in
|
|
@@ -3,17 +3,55 @@
|
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
Button,
|
|
8
|
+
ButtonOwnProps,
|
|
9
|
+
ButtonProps,
|
|
10
|
+
SxProps,
|
|
11
|
+
TooltipProps
|
|
12
|
+
} from '@mui/material';
|
|
7
13
|
import React from 'react';
|
|
8
14
|
|
|
9
15
|
import { ContrastingTooltip } from './contrasting-tooltip';
|
|
10
16
|
|
|
11
|
-
const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
|
|
17
|
+
export const TOOLTIPPED_WRAP_CLASS = 'jp-chat-tooltipped-wrap';
|
|
18
|
+
|
|
19
|
+
export const DEFAULT_BUTTON_PROPS: Partial<ButtonOwnProps> = {
|
|
20
|
+
size: 'small',
|
|
21
|
+
variant: 'contained'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const DEFAULT_BUTTON_SX = {
|
|
25
|
+
minWidth: '24px',
|
|
26
|
+
width: '24px',
|
|
27
|
+
height: '24px',
|
|
28
|
+
lineHeight: 0,
|
|
29
|
+
'&:disabled': {
|
|
30
|
+
opacity: 0.5
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const INPUT_TOOLBAR_BUTTON_SX = {
|
|
35
|
+
backgroundColor: 'var(--jp-brand-color1)',
|
|
36
|
+
color: 'white',
|
|
37
|
+
borderRadius: '4px',
|
|
38
|
+
boxShadow: 'none',
|
|
39
|
+
'&:hover': {
|
|
40
|
+
backgroundColor: 'var(--jp-brand-color0)',
|
|
41
|
+
boxShadow: 'none'
|
|
42
|
+
},
|
|
43
|
+
'&:disabled': {
|
|
44
|
+
backgroundColor: 'var(--jp-border-color2)',
|
|
45
|
+
color: 'var(--jp-ui-font-color3)',
|
|
46
|
+
opacity: 0.5
|
|
47
|
+
}
|
|
48
|
+
};
|
|
12
49
|
|
|
13
50
|
export type TooltippedButtonProps = {
|
|
14
51
|
onClick: React.MouseEventHandler<HTMLButtonElement>;
|
|
15
52
|
tooltip: string;
|
|
16
53
|
children: JSX.Element;
|
|
54
|
+
inputToolbar?: boolean;
|
|
17
55
|
disabled?: boolean;
|
|
18
56
|
placement?: TooltipProps['placement'];
|
|
19
57
|
/**
|
|
@@ -76,15 +114,16 @@ export function TooltippedButton(props: TooltippedButtonProps): JSX.Element {
|
|
|
76
114
|
*/}
|
|
77
115
|
<span style={{ cursor: 'default' }} className={TOOLTIPPED_WRAP_CLASS}>
|
|
78
116
|
<Button
|
|
117
|
+
{...DEFAULT_BUTTON_PROPS}
|
|
79
118
|
{...props.buttonProps}
|
|
80
119
|
onClick={props.onClick}
|
|
81
120
|
disabled={props.disabled}
|
|
82
121
|
sx={{
|
|
83
|
-
|
|
84
|
-
...(props.
|
|
122
|
+
...DEFAULT_BUTTON_SX,
|
|
123
|
+
...((props.inputToolbar ?? true) && INPUT_TOOLBAR_BUTTON_SX),
|
|
85
124
|
...props.sx
|
|
86
125
|
}}
|
|
87
|
-
aria-label={props['aria-label']}
|
|
126
|
+
aria-label={props['aria-label'] ?? props.tooltip}
|
|
88
127
|
>
|
|
89
128
|
{props.children}
|
|
90
129
|
</Button>
|
|
@@ -4,20 +4,34 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { classes } from '@jupyterlab/ui-components';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
IconButton,
|
|
9
|
+
IconButtonProps,
|
|
10
|
+
SvgIconOwnProps,
|
|
11
|
+
TooltipProps
|
|
12
|
+
} from '@mui/material';
|
|
8
13
|
import React from 'react';
|
|
9
14
|
|
|
10
15
|
import { ContrastingTooltip } from './contrasting-tooltip';
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
import {
|
|
17
|
+
DEFAULT_BUTTON_PROPS,
|
|
18
|
+
DEFAULT_BUTTON_SX,
|
|
19
|
+
INPUT_TOOLBAR_BUTTON_SX,
|
|
20
|
+
TOOLTIPPED_WRAP_CLASS
|
|
21
|
+
} from './tooltipped-button';
|
|
13
22
|
|
|
14
23
|
export type TooltippedIconButtonProps = {
|
|
15
24
|
onClick: () => unknown;
|
|
16
25
|
tooltip: string;
|
|
17
26
|
children: JSX.Element;
|
|
18
27
|
className?: string;
|
|
28
|
+
inputToolbar?: boolean;
|
|
19
29
|
disabled?: boolean;
|
|
20
30
|
placement?: TooltipProps['placement'];
|
|
31
|
+
/**
|
|
32
|
+
* The font size of the icon. By default it will be set to 'small'.
|
|
33
|
+
*/
|
|
34
|
+
fontSize?: SvgIconOwnProps['fontSize'];
|
|
21
35
|
/**
|
|
22
36
|
* The offset of the tooltip popup.
|
|
23
37
|
*
|
|
@@ -47,6 +61,8 @@ export type TooltippedIconButtonProps = {
|
|
|
47
61
|
export function TooltippedIconButton(
|
|
48
62
|
props: TooltippedIconButtonProps
|
|
49
63
|
): JSX.Element {
|
|
64
|
+
// Override the default icon font size from 'medium' to 'small'
|
|
65
|
+
props.children.props.fontSize = props.fontSize ?? 'small';
|
|
50
66
|
return (
|
|
51
67
|
<ContrastingTooltip
|
|
52
68
|
title={props.tooltip}
|
|
@@ -73,13 +89,13 @@ export function TooltippedIconButton(
|
|
|
73
89
|
*/}
|
|
74
90
|
<span className={classes(props.className, TOOLTIPPED_WRAP_CLASS)}>
|
|
75
91
|
<IconButton
|
|
92
|
+
{...DEFAULT_BUTTON_PROPS}
|
|
76
93
|
{...props.iconButtonProps}
|
|
77
94
|
onClick={props.onClick}
|
|
78
95
|
disabled={props.disabled}
|
|
79
96
|
sx={{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
...(props.disabled && { opacity: 0.5 })
|
|
97
|
+
...DEFAULT_BUTTON_SX,
|
|
98
|
+
...((props.inputToolbar ?? true) && INPUT_TOOLBAR_BUTTON_SX)
|
|
83
99
|
}}
|
|
84
100
|
aria-label={props['aria-label']}
|
|
85
101
|
>
|
package/src/context.ts
CHANGED
|
@@ -2,9 +2,19 @@
|
|
|
2
2
|
* Copyright (c) Jupyter Development Team.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
-
import { createContext } from 'react';
|
|
6
|
-
import { IAttachmentOpenerRegistry } from './registers';
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
import { createContext, useContext } from 'react';
|
|
7
|
+
|
|
8
|
+
import { Chat } from './components';
|
|
9
|
+
|
|
10
|
+
export const ChatReactContext = createContext<Chat.IChatProps | undefined>(
|
|
11
|
+
undefined
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
export function useChatContext(): Chat.IChatProps {
|
|
15
|
+
const context = useContext(ChatReactContext);
|
|
16
|
+
if (!context) {
|
|
17
|
+
throw new Error('The chat context is missing in the chat');
|
|
18
|
+
}
|
|
19
|
+
return context;
|
|
20
|
+
}
|
package/src/index.ts
CHANGED
package/src/tokens.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IWidgetTracker, MainAreaWidget } from '@jupyterlab/apputils';
|
|
7
|
+
import { Token } from '@lumino/coreutils';
|
|
8
|
+
|
|
9
|
+
import { ChatWidget } from './widgets';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* the chat tracker type.
|
|
13
|
+
*/
|
|
14
|
+
export type IChatTracker = IWidgetTracker<
|
|
15
|
+
ChatWidget | MainAreaWidget<ChatWidget>
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A chat tracker token.
|
|
20
|
+
*/
|
|
21
|
+
export const IChatTracker = new Token<IChatTracker>(
|
|
22
|
+
'@jupyter/chat:IChatTracker',
|
|
23
|
+
'The chat widget tracker'
|
|
24
|
+
);
|
package/src/types.ts
CHANGED
|
@@ -15,6 +15,7 @@ import { Chat, IInputToolbarRegistry, MESSAGE_CLASS } from '../components';
|
|
|
15
15
|
import { chatIcon } from '../icons';
|
|
16
16
|
import { IChatModel } from '../model';
|
|
17
17
|
import {
|
|
18
|
+
ChatArea,
|
|
18
19
|
IFileAttachment,
|
|
19
20
|
INotebookAttachment,
|
|
20
21
|
INotebookAttachmentCell
|
|
@@ -71,6 +72,13 @@ export class ChatWidget extends ReactWidget {
|
|
|
71
72
|
return this._chatOptions.model;
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
/**
|
|
76
|
+
* The area where the chat is opened.
|
|
77
|
+
*/
|
|
78
|
+
get area(): ChatArea | undefined {
|
|
79
|
+
return this._chatOptions.area;
|
|
80
|
+
}
|
|
81
|
+
|
|
74
82
|
/**
|
|
75
83
|
* Get the input toolbar registry (if it has been provided when creating the widget).
|
|
76
84
|
*/
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
* Originally adapted from jupyterlab-chat's ChatPanel
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { InputDialog
|
|
12
|
-
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
11
|
+
import { InputDialog } from '@jupyterlab/apputils';
|
|
13
12
|
import {
|
|
14
13
|
addIcon,
|
|
15
14
|
closeIcon,
|
|
@@ -34,11 +33,6 @@ import {
|
|
|
34
33
|
} from '../components';
|
|
35
34
|
import { chatIcon, readIcon } from '../icons';
|
|
36
35
|
import { IChatModel } from '../model';
|
|
37
|
-
import {
|
|
38
|
-
IAttachmentOpenerRegistry,
|
|
39
|
-
IChatCommandRegistry,
|
|
40
|
-
IMessageFooterRegistry
|
|
41
|
-
} from '../registers';
|
|
42
36
|
|
|
43
37
|
const SIDEPANEL_CLASS = 'jp-chat-sidepanel';
|
|
44
38
|
const ADD_BUTTON_CLASS = 'jp-chat-add';
|
|
@@ -58,13 +52,8 @@ export class MultiChatPanel extends SidePanel {
|
|
|
58
52
|
|
|
59
53
|
this.addClass(SIDEPANEL_CLASS);
|
|
60
54
|
|
|
61
|
-
this.
|
|
62
|
-
this._themeManager = options.themeManager;
|
|
63
|
-
this._chatCommandRegistry = options.chatCommandRegistry;
|
|
64
|
-
this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
|
|
55
|
+
this._chatOptions = options;
|
|
65
56
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
66
|
-
this._messageFooterRegistry = options.messageFooterRegistry;
|
|
67
|
-
this._welcomeMessage = options.welcomeMessage;
|
|
68
57
|
|
|
69
58
|
this._getChatNames = options.getChatNames;
|
|
70
59
|
this._createModel = options.createModel;
|
|
@@ -149,13 +138,8 @@ export class MultiChatPanel extends SidePanel {
|
|
|
149
138
|
// Create a new widget.
|
|
150
139
|
const widget = new ChatWidget({
|
|
151
140
|
model,
|
|
152
|
-
|
|
153
|
-
themeManager: this._themeManager,
|
|
154
|
-
chatCommandRegistry: this._chatCommandRegistry,
|
|
155
|
-
attachmentOpenerRegistry: this._attachmentOpenerRegistry,
|
|
141
|
+
...this._chatOptions,
|
|
156
142
|
inputToolbarRegistry,
|
|
157
|
-
messageFooterRegistry: this._messageFooterRegistry,
|
|
158
|
-
welcomeMessage: this._welcomeMessage,
|
|
159
143
|
area: 'sidebar'
|
|
160
144
|
});
|
|
161
145
|
|
|
@@ -267,13 +251,8 @@ export class MultiChatPanel extends SidePanel {
|
|
|
267
251
|
this
|
|
268
252
|
);
|
|
269
253
|
private _sectionAdded = new Signal<MultiChatPanel, ChatSection>(this);
|
|
270
|
-
private
|
|
271
|
-
private _themeManager?: IThemeManager | null;
|
|
272
|
-
private _chatCommandRegistry?: IChatCommandRegistry;
|
|
273
|
-
private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
254
|
+
private _chatOptions: Omit<Chat.IOptions, 'model' | 'inputToolbarRegistry'>;
|
|
274
255
|
private _inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
275
|
-
private _messageFooterRegistry?: IMessageFooterRegistry;
|
|
276
|
-
private _welcomeMessage?: string;
|
|
277
256
|
private _updateChatListDebouncer: Debouncer;
|
|
278
257
|
|
|
279
258
|
private _createModel?: (
|
|
@@ -568,7 +547,9 @@ function ChatSelect({
|
|
|
568
547
|
|
|
569
548
|
return (
|
|
570
549
|
<HTMLSelect onChange={handleChange} value="-">
|
|
571
|
-
<option value="-"
|
|
550
|
+
<option value="-" disabled hidden>
|
|
551
|
+
Open a chat
|
|
552
|
+
</option>
|
|
572
553
|
{Object.keys(chatNames).map(name => (
|
|
573
554
|
<option value={chatNames[name]}>{name}</option>
|
|
574
555
|
))}
|