@jupyter/chat 0.18.2 → 0.19.0-alpha.1
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 +47 -21
- package/lib/components/chat.d.ts +5 -0
- package/lib/components/chat.js +7 -6
- package/lib/components/code-blocks/code-toolbar.js +29 -10
- package/lib/components/code-blocks/copy-button.js +11 -3
- package/lib/components/input/buttons/attach-button.js +7 -2
- package/lib/components/input/buttons/cancel-button.js +12 -10
- package/lib/components/input/buttons/index.d.ts +2 -0
- package/lib/components/input/buttons/index.js +2 -0
- package/lib/components/input/buttons/save-edit-button.d.ts +6 -0
- package/lib/components/input/buttons/save-edit-button.js +51 -0
- package/lib/components/input/buttons/send-button.d.ts +1 -1
- package/lib/components/input/buttons/send-button.js +35 -122
- package/lib/components/input/buttons/stop-button.d.ts +6 -0
- package/lib/components/input/buttons/stop-button.js +63 -0
- package/lib/components/input/chat-input.d.ts +15 -0
- package/lib/components/input/chat-input.js +109 -46
- package/lib/components/input/index.d.ts +1 -0
- package/lib/components/input/index.js +1 -0
- package/lib/components/input/toolbar-registry.d.ts +10 -0
- package/lib/components/input/toolbar-registry.js +10 -1
- package/lib/components/input/use-chat-commands.js +9 -4
- package/lib/components/input/writing-indicator.d.ts +15 -0
- package/lib/components/input/writing-indicator.js +50 -0
- package/lib/components/messages/header.d.ts +4 -0
- package/lib/components/messages/header.js +4 -0
- package/lib/components/messages/index.d.ts +0 -1
- package/lib/components/messages/index.js +0 -1
- package/lib/components/messages/message.js +1 -1
- package/lib/components/messages/messages.d.ts +5 -0
- package/lib/components/messages/messages.js +24 -14
- package/lib/components/messages/toolbar.js +37 -15
- package/lib/input-model.d.ts +14 -0
- package/lib/input-model.js +12 -4
- package/lib/model.d.ts +8 -0
- package/lib/model.js +6 -0
- package/lib/types.d.ts +4 -0
- package/lib/widgets/chat-widget.d.ts +4 -0
- package/lib/widgets/chat-widget.js +36 -11
- package/lib/widgets/multichat-panel.js +2 -1
- package/package.json +1 -1
- package/src/active-cell-manager.ts +3 -1
- package/src/components/attachments.tsx +70 -33
- package/src/components/chat.tsx +13 -4
- package/src/components/code-blocks/code-toolbar.tsx +56 -28
- package/src/components/code-blocks/copy-button.tsx +21 -12
- package/src/components/input/buttons/attach-button.tsx +8 -2
- package/src/components/input/buttons/cancel-button.tsx +20 -15
- package/src/components/input/buttons/index.ts +2 -0
- package/src/components/input/buttons/save-edit-button.tsx +75 -0
- package/src/components/input/buttons/send-button.tsx +50 -167
- package/src/components/input/buttons/stop-button.tsx +88 -0
- package/src/components/input/chat-input.tsx +188 -83
- package/src/components/input/index.ts +1 -0
- package/src/components/input/toolbar-registry.tsx +25 -1
- package/src/components/input/use-chat-commands.tsx +25 -5
- package/src/components/input/writing-indicator.tsx +83 -0
- package/src/components/messages/header.tsx +8 -0
- package/src/components/messages/index.ts +0 -1
- package/src/components/messages/message.tsx +1 -0
- package/src/components/messages/messages.tsx +63 -39
- package/src/components/messages/toolbar.tsx +51 -21
- package/src/input-model.ts +21 -0
- package/src/model.ts +12 -0
- package/src/types.ts +5 -0
- package/src/widgets/chat-widget.tsx +43 -12
- package/src/widgets/multichat-panel.tsx +2 -1
- package/style/chat.css +13 -141
- package/style/input.css +0 -58
- package/lib/components/messages/writers.d.ts +0 -16
- package/lib/components/messages/writers.js +0 -39
- package/src/components/messages/writers.tsx +0 -81
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
7
|
+
import { IconButton, Tooltip } from '@mui/material';
|
|
7
8
|
import React from 'react';
|
|
8
9
|
|
|
9
10
|
import { InputToolbarRegistry } from '../toolbar-registry';
|
|
10
|
-
import { TooltippedButton } from '../../mui-extras/tooltipped-button';
|
|
11
11
|
|
|
12
12
|
const CANCEL_BUTTON_CLASS = 'jp-chat-cancel-button';
|
|
13
13
|
|
|
@@ -20,19 +20,24 @@ export function CancelButton(
|
|
|
20
20
|
if (!props.model.cancel) {
|
|
21
21
|
return <></>;
|
|
22
22
|
}
|
|
23
|
-
const tooltip = 'Cancel
|
|
23
|
+
const tooltip = 'Cancel editing';
|
|
24
24
|
return (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
25
|
+
<Tooltip title={tooltip} placement="top" arrow>
|
|
26
|
+
<span>
|
|
27
|
+
<IconButton
|
|
28
|
+
onClick={props.model.cancel}
|
|
29
|
+
className={CANCEL_BUTTON_CLASS}
|
|
30
|
+
aria-label={tooltip}
|
|
31
|
+
sx={{
|
|
32
|
+
width: '24px',
|
|
33
|
+
height: '24px',
|
|
34
|
+
padding: 0,
|
|
35
|
+
lineHeight: 0
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<CloseIcon sx={{ fontSize: '16px' }} />
|
|
39
|
+
</IconButton>
|
|
40
|
+
</span>
|
|
41
|
+
</Tooltip>
|
|
37
42
|
);
|
|
38
43
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import CheckIcon from '@mui/icons-material/Check';
|
|
7
|
+
import { IconButton, Tooltip } from '@mui/material';
|
|
8
|
+
import React, { useEffect, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import { InputToolbarRegistry } from '../toolbar-registry';
|
|
11
|
+
|
|
12
|
+
const SAVE_EDIT_BUTTON_CLASS = 'jp-chat-save-edit-button';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The save edit button.
|
|
16
|
+
*/
|
|
17
|
+
export function SaveEditButton(
|
|
18
|
+
props: InputToolbarRegistry.IToolbarItemProps
|
|
19
|
+
): JSX.Element {
|
|
20
|
+
const { model, chatCommandRegistry, edit } = props;
|
|
21
|
+
|
|
22
|
+
// Don't show this button when not in edit mode
|
|
23
|
+
if (!edit) {
|
|
24
|
+
return <></>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const [disabled, setDisabled] = useState(false);
|
|
28
|
+
const tooltip = 'Save edits';
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
const inputChanged = () => {
|
|
32
|
+
const inputExist = !!model.value.trim() || model.attachments.length;
|
|
33
|
+
setDisabled(!inputExist);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
model.valueChanged.connect(inputChanged);
|
|
37
|
+
model.attachmentsChanged?.connect(inputChanged);
|
|
38
|
+
|
|
39
|
+
inputChanged();
|
|
40
|
+
|
|
41
|
+
return () => {
|
|
42
|
+
model.valueChanged.disconnect(inputChanged);
|
|
43
|
+
model.attachmentsChanged?.disconnect(inputChanged);
|
|
44
|
+
};
|
|
45
|
+
}, [model]);
|
|
46
|
+
|
|
47
|
+
async function save() {
|
|
48
|
+
await chatCommandRegistry?.onSubmit(model);
|
|
49
|
+
model.send(model.value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<Tooltip title={tooltip} placement="top" arrow>
|
|
54
|
+
<span>
|
|
55
|
+
<IconButton
|
|
56
|
+
onClick={save}
|
|
57
|
+
disabled={disabled}
|
|
58
|
+
className={SAVE_EDIT_BUTTON_CLASS}
|
|
59
|
+
aria-label={tooltip}
|
|
60
|
+
sx={{
|
|
61
|
+
width: '24px',
|
|
62
|
+
height: '24px',
|
|
63
|
+
padding: 0,
|
|
64
|
+
lineHeight: 0,
|
|
65
|
+
'&.Mui-disabled': {
|
|
66
|
+
opacity: 0.5
|
|
67
|
+
}
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<CheckIcon sx={{ fontSize: '16px' }} />
|
|
71
|
+
</IconButton>
|
|
72
|
+
</span>
|
|
73
|
+
</Tooltip>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
@@ -3,47 +3,31 @@
|
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import React, { useCallback, useEffect, useState } from 'react';
|
|
6
|
+
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
|
|
7
|
+
import { Button, Tooltip } from '@mui/material';
|
|
8
|
+
import React, { useEffect, useState } from 'react';
|
|
10
9
|
|
|
11
10
|
import { InputToolbarRegistry } from '../toolbar-registry';
|
|
12
|
-
import { TooltippedButton } from '../../mui-extras/tooltipped-button';
|
|
13
|
-
import { includeSelectionIcon } from '../../../icons';
|
|
14
11
|
import { IInputModel, InputModel } from '../../../input-model';
|
|
15
12
|
|
|
16
13
|
const SEND_BUTTON_CLASS = 'jp-chat-send-button';
|
|
17
|
-
const SEND_INCLUDE_OPENER_CLASS = 'jp-chat-send-include-opener';
|
|
18
|
-
const SEND_INCLUDE_LI_CLASS = 'jp-chat-send-include';
|
|
19
14
|
|
|
20
15
|
/**
|
|
21
|
-
* The send button
|
|
16
|
+
* The send button.
|
|
22
17
|
*/
|
|
23
18
|
export function SendButton(
|
|
24
19
|
props: InputToolbarRegistry.IToolbarItemProps
|
|
25
20
|
): JSX.Element {
|
|
26
|
-
const { model, chatCommandRegistry } = props;
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const { model, chatModel, chatCommandRegistry, edit } = props;
|
|
22
|
+
|
|
23
|
+
// Don't show this button when in edit mode
|
|
24
|
+
if (edit) {
|
|
25
|
+
return <></>;
|
|
26
|
+
}
|
|
29
27
|
|
|
30
|
-
const [menuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>(null);
|
|
31
|
-
const [menuOpen, setMenuOpen] = useState(false);
|
|
32
28
|
const [disabled, setDisabled] = useState(false);
|
|
33
29
|
const [tooltip, setTooltip] = useState<string>('');
|
|
34
30
|
|
|
35
|
-
const openMenu = useCallback((el: HTMLElement | null) => {
|
|
36
|
-
setMenuAnchorEl(el);
|
|
37
|
-
setMenuOpen(true);
|
|
38
|
-
}, []);
|
|
39
|
-
|
|
40
|
-
const closeMenu = useCallback(() => {
|
|
41
|
-
setMenuOpen(false);
|
|
42
|
-
}, []);
|
|
43
|
-
|
|
44
|
-
const [selectionTooltip, setSelectionTooltip] = useState<string>('');
|
|
45
|
-
const [disableInclude, setDisableInclude] = useState<boolean>(true);
|
|
46
|
-
|
|
47
31
|
useEffect(() => {
|
|
48
32
|
const inputChanged = () => {
|
|
49
33
|
const inputExist = !!model.value.trim() || model.attachments.length;
|
|
@@ -71,153 +55,52 @@ export function SendButton(
|
|
|
71
55
|
};
|
|
72
56
|
}, [model]);
|
|
73
57
|
|
|
74
|
-
useEffect(() => {
|
|
75
|
-
/**
|
|
76
|
-
* Enable or disable the include selection button, and adapt the tooltip.
|
|
77
|
-
*/
|
|
78
|
-
const toggleIncludeState = () => {
|
|
79
|
-
setDisableInclude(
|
|
80
|
-
!(selectionWatcher?.selection || activeCellManager?.available)
|
|
81
|
-
);
|
|
82
|
-
const tooltip = selectionWatcher?.selection
|
|
83
|
-
? `${selectionWatcher.selection.numLines} line(s) selected`
|
|
84
|
-
: activeCellManager?.available
|
|
85
|
-
? 'Code from 1 active cell'
|
|
86
|
-
: 'No selection or active cell';
|
|
87
|
-
setSelectionTooltip(tooltip);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
if (!hideIncludeSelection) {
|
|
91
|
-
selectionWatcher?.selectionChanged.connect(toggleIncludeState);
|
|
92
|
-
activeCellManager?.availabilityChanged.connect(toggleIncludeState);
|
|
93
|
-
toggleIncludeState();
|
|
94
|
-
}
|
|
95
|
-
return () => {
|
|
96
|
-
selectionWatcher?.selectionChanged.disconnect(toggleIncludeState);
|
|
97
|
-
activeCellManager?.availabilityChanged.disconnect(toggleIncludeState);
|
|
98
|
-
};
|
|
99
|
-
}, [activeCellManager, selectionWatcher]);
|
|
100
|
-
|
|
101
58
|
async function send() {
|
|
59
|
+
// Run all command providers
|
|
102
60
|
await chatCommandRegistry?.onSubmit(model);
|
|
103
|
-
model.send(model.value);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function sendWithSelection() {
|
|
107
|
-
let source = '';
|
|
108
|
-
|
|
109
|
-
// Run all chat command providers
|
|
110
|
-
await chatCommandRegistry?.onSubmit(model);
|
|
111
|
-
|
|
112
|
-
let language: string | undefined;
|
|
113
|
-
if (selectionWatcher?.selection) {
|
|
114
|
-
// Append the selected text if exists.
|
|
115
|
-
source = selectionWatcher.selection.text;
|
|
116
|
-
language = selectionWatcher.selection.language;
|
|
117
|
-
} else if (activeCellManager?.available) {
|
|
118
|
-
// Append the active cell content if exists.
|
|
119
|
-
const content = activeCellManager.getContent(false);
|
|
120
|
-
source = content!.source;
|
|
121
|
-
language = content?.language;
|
|
122
|
-
}
|
|
123
|
-
let content = model.value;
|
|
124
|
-
if (source) {
|
|
125
|
-
content += `
|
|
126
61
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
model.send(content);
|
|
133
|
-
closeMenu();
|
|
62
|
+
// send message through chat model
|
|
63
|
+
await chatModel?.sendMessage({
|
|
64
|
+
body: model.value
|
|
65
|
+
});
|
|
66
|
+
// clear input model value & re-focus
|
|
134
67
|
model.value = '';
|
|
68
|
+
model.focus();
|
|
135
69
|
}
|
|
136
70
|
|
|
137
71
|
return (
|
|
138
|
-
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
className: SEND_INCLUDE_OPENER_CLASS
|
|
172
|
-
}}
|
|
173
|
-
>
|
|
174
|
-
<KeyboardArrowDown />
|
|
175
|
-
</TooltippedButton>
|
|
176
|
-
<Menu
|
|
177
|
-
open={menuOpen}
|
|
178
|
-
onClose={closeMenu}
|
|
179
|
-
anchorEl={menuAnchorEl}
|
|
180
|
-
anchorOrigin={{
|
|
181
|
-
vertical: 'top',
|
|
182
|
-
horizontal: 'right'
|
|
183
|
-
}}
|
|
184
|
-
transformOrigin={{
|
|
185
|
-
vertical: 'bottom',
|
|
186
|
-
horizontal: 'right'
|
|
187
|
-
}}
|
|
188
|
-
sx={{
|
|
189
|
-
'& .MuiMenuItem-root': {
|
|
190
|
-
display: 'flex',
|
|
191
|
-
alignItems: 'center',
|
|
192
|
-
gap: '8px'
|
|
193
|
-
},
|
|
194
|
-
'& svg': {
|
|
195
|
-
lineHeight: 0
|
|
196
|
-
}
|
|
197
|
-
}}
|
|
198
|
-
>
|
|
199
|
-
<MenuItem
|
|
200
|
-
onClick={e => {
|
|
201
|
-
sendWithSelection();
|
|
202
|
-
// prevent sending second message with no selection
|
|
203
|
-
e.stopPropagation();
|
|
204
|
-
}}
|
|
205
|
-
disabled={disableInclude}
|
|
206
|
-
className={SEND_INCLUDE_LI_CLASS}
|
|
207
|
-
>
|
|
208
|
-
<includeSelectionIcon.react />
|
|
209
|
-
<Box>
|
|
210
|
-
<Typography display="block">
|
|
211
|
-
Send message with selection
|
|
212
|
-
</Typography>
|
|
213
|
-
<Typography display="block" sx={{ opacity: 0.618 }}>
|
|
214
|
-
{selectionTooltip}
|
|
215
|
-
</Typography>
|
|
216
|
-
</Box>
|
|
217
|
-
</MenuItem>
|
|
218
|
-
</Menu>
|
|
219
|
-
</>
|
|
220
|
-
)}
|
|
221
|
-
</>
|
|
72
|
+
<Tooltip title={tooltip} placement="top" arrow>
|
|
73
|
+
<span>
|
|
74
|
+
<Button
|
|
75
|
+
onClick={send}
|
|
76
|
+
disabled={disabled}
|
|
77
|
+
size="small"
|
|
78
|
+
variant="contained"
|
|
79
|
+
className={SEND_BUTTON_CLASS}
|
|
80
|
+
aria-label={tooltip}
|
|
81
|
+
sx={{
|
|
82
|
+
backgroundColor: 'var(--jp-brand-color1)',
|
|
83
|
+
color: 'white',
|
|
84
|
+
minWidth: '24px',
|
|
85
|
+
width: '24px',
|
|
86
|
+
height: '24px',
|
|
87
|
+
borderRadius: '4px',
|
|
88
|
+
boxShadow: 'none',
|
|
89
|
+
lineHeight: 0,
|
|
90
|
+
'&:hover': {
|
|
91
|
+
backgroundColor: 'var(--jp-brand-color0)',
|
|
92
|
+
boxShadow: 'none'
|
|
93
|
+
},
|
|
94
|
+
'&.Mui-disabled': {
|
|
95
|
+
backgroundColor: 'var(--jp-border-color2)',
|
|
96
|
+
color: 'var(--jp-ui-font-color3)',
|
|
97
|
+
opacity: 0.5
|
|
98
|
+
}
|
|
99
|
+
}}
|
|
100
|
+
>
|
|
101
|
+
<ArrowUpwardIcon sx={{ fontSize: '16px' }} />
|
|
102
|
+
</Button>
|
|
103
|
+
</span>
|
|
104
|
+
</Tooltip>
|
|
222
105
|
);
|
|
223
106
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import StopIcon from '@mui/icons-material/Stop';
|
|
7
|
+
import { Button, Tooltip } from '@mui/material';
|
|
8
|
+
import React, { useEffect, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
import { InputToolbarRegistry } from '../toolbar-registry';
|
|
11
|
+
|
|
12
|
+
const STOP_BUTTON_CLASS = 'jp-chat-stop-button';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The stop button.
|
|
16
|
+
*/
|
|
17
|
+
export function StopButton(
|
|
18
|
+
props: InputToolbarRegistry.IToolbarItemProps
|
|
19
|
+
): JSX.Element {
|
|
20
|
+
const { chatModel } = props;
|
|
21
|
+
const [disabled, setDisabled] = useState(true);
|
|
22
|
+
const tooltip = 'Stop generating';
|
|
23
|
+
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (!chatModel) {
|
|
26
|
+
setDisabled(true);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const checkWriters = () => {
|
|
31
|
+
// Check if there's at least one AI agent writer (bot)
|
|
32
|
+
const hasAIWriter = chatModel.writers.some(writer => writer.user.bot);
|
|
33
|
+
setDisabled(!hasAIWriter);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Check initially
|
|
37
|
+
checkWriters();
|
|
38
|
+
|
|
39
|
+
// Listen to writers changes
|
|
40
|
+
chatModel.writersChanged?.connect(checkWriters);
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
chatModel.writersChanged?.disconnect(checkWriters);
|
|
44
|
+
};
|
|
45
|
+
}, [chatModel]);
|
|
46
|
+
|
|
47
|
+
function stop() {
|
|
48
|
+
// TODO: Implement stop functionality
|
|
49
|
+
// This will need to be implemented based on how the chat model handles stopping AI responses
|
|
50
|
+
console.log('Stop button clicked');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Tooltip title={tooltip} placement="top" arrow>
|
|
55
|
+
<span>
|
|
56
|
+
<Button
|
|
57
|
+
onClick={stop}
|
|
58
|
+
disabled={disabled}
|
|
59
|
+
size="small"
|
|
60
|
+
variant="contained"
|
|
61
|
+
className={STOP_BUTTON_CLASS}
|
|
62
|
+
aria-label={tooltip}
|
|
63
|
+
sx={{
|
|
64
|
+
backgroundColor: 'var(--jp-error-color1)',
|
|
65
|
+
color: 'white',
|
|
66
|
+
minWidth: '24px',
|
|
67
|
+
width: '24px',
|
|
68
|
+
height: '24px',
|
|
69
|
+
borderRadius: '4px',
|
|
70
|
+
boxShadow: 'none',
|
|
71
|
+
lineHeight: 0,
|
|
72
|
+
'&:hover': {
|
|
73
|
+
backgroundColor: 'var(--jp-error-color0)',
|
|
74
|
+
boxShadow: 'none'
|
|
75
|
+
},
|
|
76
|
+
'&.Mui-disabled': {
|
|
77
|
+
backgroundColor: 'var(--jp-border-color2)',
|
|
78
|
+
color: 'var(--jp-ui-font-color3)',
|
|
79
|
+
opacity: 0.5
|
|
80
|
+
}
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
<StopIcon sx={{ fontSize: '16px' }} />
|
|
84
|
+
</Button>
|
|
85
|
+
</span>
|
|
86
|
+
</Tooltip>
|
|
87
|
+
);
|
|
88
|
+
}
|