@notebook-intelligence/notebook-intelligence 3.1.0 → 4.0.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.
- package/README.md +21 -0
- package/lib/api.d.ts +11 -0
- package/lib/api.js +27 -8
- package/lib/chat-sidebar.js +63 -22
- package/lib/components/ask-user-question.d.ts +2 -0
- package/lib/components/ask-user-question.js +57 -0
- package/lib/components/checkbox.js +8 -3
- package/lib/components/settings-panel.js +143 -2
- package/lib/index.js +12 -8
- package/lib/tokens.d.ts +5 -2
- package/lib/tokens.js +3 -0
- package/package.json +1 -1
- package/src/api.ts +40 -12
- package/src/chat-sidebar.tsx +100 -36
- package/src/components/ask-user-question.tsx +101 -0
- package/src/components/checkbox.tsx +15 -4
- package/src/components/settings-panel.tsx +321 -1
- package/src/index.ts +16 -7
- package/src/tokens.ts +5 -2
- package/style/base.css +72 -0
- package/style/claude.svg +1 -0
package/lib/tokens.js
CHANGED
|
@@ -18,6 +18,7 @@ export var BackendMessageType;
|
|
|
18
18
|
BackendMessageType["RunUICommand"] = "run-ui-command";
|
|
19
19
|
BackendMessageType["GitHubCopilotLoginStatusChange"] = "github-copilot-login-status-change";
|
|
20
20
|
BackendMessageType["MCPServerStatusChange"] = "mcp-server-status-change";
|
|
21
|
+
BackendMessageType["ClaudeCodeStatusChange"] = "claude-code-status-change";
|
|
21
22
|
})(BackendMessageType || (BackendMessageType = {}));
|
|
22
23
|
export var ResponseStreamDataType;
|
|
23
24
|
(function (ResponseStreamDataType) {
|
|
@@ -30,6 +31,7 @@ export var ResponseStreamDataType;
|
|
|
30
31
|
ResponseStreamDataType["Anchor"] = "anchor";
|
|
31
32
|
ResponseStreamDataType["Progress"] = "progress";
|
|
32
33
|
ResponseStreamDataType["Confirmation"] = "confirmation";
|
|
34
|
+
ResponseStreamDataType["AskUserQuestion"] = "ask-user-question";
|
|
33
35
|
})(ResponseStreamDataType || (ResponseStreamDataType = {}));
|
|
34
36
|
export var ContextType;
|
|
35
37
|
(function (ContextType) {
|
|
@@ -58,6 +60,7 @@ export var BuiltinToolsetType;
|
|
|
58
60
|
BuiltinToolsetType["CommandExecute"] = "nbi-command-execute";
|
|
59
61
|
})(BuiltinToolsetType || (BuiltinToolsetType = {}));
|
|
60
62
|
export const GITHUB_COPILOT_PROVIDER_ID = 'github-copilot';
|
|
63
|
+
export const CLAUDE_CODE_CHAT_PARTICIPANT_ID = 'claude-code';
|
|
61
64
|
export var TelemetryEventType;
|
|
62
65
|
(function (TelemetryEventType) {
|
|
63
66
|
TelemetryEventType["InlineCompletionRequest"] = "inline-completion-request";
|
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -28,6 +28,17 @@ export interface IDeviceVerificationInfo {
|
|
|
28
28
|
userCode: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export enum ClaudeModelType {
|
|
32
|
+
Default = '',
|
|
33
|
+
ClaudeOpus45 = 'claude-opus-4-5',
|
|
34
|
+
ClaudeHaiku45 = 'claude-haiku-4-5'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export enum ClaudeToolType {
|
|
38
|
+
ClaudeCodeTools = 'claude-code:built-in-tools',
|
|
39
|
+
JupyterUITools = 'nbi:built-in-jupyter-ui-tools'
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
export class NBIConfig {
|
|
32
43
|
get userHomeDir(): string {
|
|
33
44
|
return this.capabilities.user_home_dir;
|
|
@@ -98,6 +109,14 @@ export class NBIConfig {
|
|
|
98
109
|
return this.capabilities.mcp_server_settings;
|
|
99
110
|
}
|
|
100
111
|
|
|
112
|
+
get claudeSettings(): any {
|
|
113
|
+
return this.capabilities.claude_settings;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get isInClaudeCodeMode(): boolean {
|
|
117
|
+
return this.claudeSettings.enabled === true;
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
capabilities: any = {};
|
|
102
121
|
chatParticipants: IChatParticipant[] = [];
|
|
103
122
|
|
|
@@ -124,7 +143,10 @@ export class NBIAPI {
|
|
|
124
143
|
|
|
125
144
|
this._messageReceived.connect((_, msg) => {
|
|
126
145
|
msg = JSON.parse(msg);
|
|
127
|
-
if (
|
|
146
|
+
if (
|
|
147
|
+
msg.type === BackendMessageType.MCPServerStatusChange ||
|
|
148
|
+
msg.type === BackendMessageType.ClaudeCodeStatusChange
|
|
149
|
+
) {
|
|
128
150
|
this.fetchCapabilities();
|
|
129
151
|
} else if (
|
|
130
152
|
msg.type === BackendMessageType.GitHubCopilotLoginStatusChange
|
|
@@ -178,20 +200,26 @@ export class NBIAPI {
|
|
|
178
200
|
}
|
|
179
201
|
|
|
180
202
|
static getChatEnabled() {
|
|
181
|
-
return
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
203
|
+
return (
|
|
204
|
+
this.config.isInClaudeCodeMode ||
|
|
205
|
+
(this.config.chatModel.provider === GITHUB_COPILOT_PROVIDER_ID
|
|
206
|
+
? !this.getGHLoginRequired()
|
|
207
|
+
: this.config.llmProviders.find(
|
|
208
|
+
provider => provider.id === this.config.chatModel.provider
|
|
209
|
+
))
|
|
210
|
+
);
|
|
186
211
|
}
|
|
187
212
|
|
|
188
213
|
static getInlineCompletionEnabled() {
|
|
189
|
-
return
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
214
|
+
return (
|
|
215
|
+
this.config.isInClaudeCodeMode ||
|
|
216
|
+
(this.config.inlineCompletionModel.provider === GITHUB_COPILOT_PROVIDER_ID
|
|
217
|
+
? !this.getGHLoginRequired()
|
|
218
|
+
: this.config.llmProviders.find(
|
|
219
|
+
provider =>
|
|
220
|
+
provider.id === this.config.inlineCompletionModel.provider
|
|
221
|
+
))
|
|
222
|
+
);
|
|
195
223
|
}
|
|
196
224
|
|
|
197
225
|
static async loginToGitHub() {
|
package/src/chat-sidebar.tsx
CHANGED
|
@@ -19,6 +19,7 @@ import { NBIAPI, GitHubCopilotLoginStatus } from './api';
|
|
|
19
19
|
import {
|
|
20
20
|
BackendMessageType,
|
|
21
21
|
BuiltinToolsetType,
|
|
22
|
+
CLAUDE_CODE_CHAT_PARTICIPANT_ID,
|
|
22
23
|
ContextType,
|
|
23
24
|
IActiveDocumentInfo,
|
|
24
25
|
ICellContents,
|
|
@@ -54,6 +55,8 @@ import {
|
|
|
54
55
|
import { extractLLMGeneratedCode, isDarkTheme } from './utils';
|
|
55
56
|
import { CheckBoxItem } from './components/checkbox';
|
|
56
57
|
import { mcpServerSettingsToEnabledState } from './components/mcp-util';
|
|
58
|
+
import claudeSvg from '../style/claude.svg';
|
|
59
|
+
import { AskUserQuestion } from './components/ask-user-question';
|
|
57
60
|
|
|
58
61
|
export enum RunChatCompletionType {
|
|
59
62
|
Chat,
|
|
@@ -449,6 +452,8 @@ function ChatResponse(props: any) {
|
|
|
449
452
|
: `Output (${Math.floor(item.reasoningTime)} s)`;
|
|
450
453
|
};
|
|
451
454
|
|
|
455
|
+
const chatParticipantId = msg.participant?.id || 'default';
|
|
456
|
+
|
|
452
457
|
return (
|
|
453
458
|
<div
|
|
454
459
|
className={`chat-message chat-message-${msg.from}`}
|
|
@@ -458,7 +463,7 @@ function ChatResponse(props: any) {
|
|
|
458
463
|
<div className="chat-message-from">
|
|
459
464
|
{msg.participant?.iconPath && (
|
|
460
465
|
<div
|
|
461
|
-
className={`chat-message-from-icon
|
|
466
|
+
className={`chat-message-from-icon chat-message-from-icon-${chatParticipantId} ${isDarkTheme() ? 'dark' : ''}`}
|
|
462
467
|
>
|
|
463
468
|
<img src={msg.participant.iconPath} />
|
|
464
469
|
</div>
|
|
@@ -624,6 +629,44 @@ function ChatResponse(props: any) {
|
|
|
624
629
|
</button>
|
|
625
630
|
</div>
|
|
626
631
|
);
|
|
632
|
+
case ResponseStreamDataType.AskUserQuestion:
|
|
633
|
+
return answeredForms.get(item.id) ===
|
|
634
|
+
'confirmed' ? null : answeredForms.get(item.id) ===
|
|
635
|
+
'canceled' ? (
|
|
636
|
+
<div>✖ Canceled</div>
|
|
637
|
+
) : (
|
|
638
|
+
<div
|
|
639
|
+
className="chat-confirmation-form ask-user-question"
|
|
640
|
+
key={`key-${index}`}
|
|
641
|
+
>
|
|
642
|
+
<AskUserQuestion
|
|
643
|
+
userQuestions={item}
|
|
644
|
+
onSubmit={(selectedAnswers: any) => {
|
|
645
|
+
markFormConfirmed(item.id);
|
|
646
|
+
runCommand('notebook-intelligence:chat-user-input', {
|
|
647
|
+
id: item.content.identifier.id,
|
|
648
|
+
data: {
|
|
649
|
+
callback_id: item.content.identifier.callback_id,
|
|
650
|
+
data: {
|
|
651
|
+
confirmed: true,
|
|
652
|
+
selectedAnswers
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
});
|
|
656
|
+
}}
|
|
657
|
+
onCancel={() => {
|
|
658
|
+
markFormCanceled(item.id);
|
|
659
|
+
runCommand('notebook-intelligence:chat-user-input', {
|
|
660
|
+
id: item.content.identifier.id,
|
|
661
|
+
data: {
|
|
662
|
+
callback_id: item.content.identifier.callback_id,
|
|
663
|
+
data: { confirmed: false }
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
}}
|
|
667
|
+
/>
|
|
668
|
+
</div>
|
|
669
|
+
);
|
|
627
670
|
}
|
|
628
671
|
return null;
|
|
629
672
|
})}
|
|
@@ -655,7 +698,7 @@ async function submitCompletionRequest(
|
|
|
655
698
|
request.content,
|
|
656
699
|
request.language || 'python',
|
|
657
700
|
request.currentDirectory || '',
|
|
658
|
-
request.filename || '
|
|
701
|
+
request.filename || '',
|
|
659
702
|
request.additionalContext || [],
|
|
660
703
|
request.chatMode,
|
|
661
704
|
request.toolSelections || {},
|
|
@@ -671,7 +714,7 @@ async function submitCompletionRequest(
|
|
|
671
714
|
request.content,
|
|
672
715
|
request.language || 'python',
|
|
673
716
|
request.currentDirectory || '',
|
|
674
|
-
request.filename || '
|
|
717
|
+
request.filename || '',
|
|
675
718
|
[],
|
|
676
719
|
'ask',
|
|
677
720
|
{},
|
|
@@ -686,7 +729,7 @@ async function submitCompletionRequest(
|
|
|
686
729
|
request.suffix || '',
|
|
687
730
|
request.existingCode || '',
|
|
688
731
|
request.language || 'python',
|
|
689
|
-
request.filename || '
|
|
732
|
+
request.filename || '',
|
|
690
733
|
responseEmitter
|
|
691
734
|
);
|
|
692
735
|
}
|
|
@@ -1169,23 +1212,35 @@ function SidebarComponent(props: any) {
|
|
|
1169
1212
|
useEffect(() => {
|
|
1170
1213
|
const prefixes: string[] = [];
|
|
1171
1214
|
|
|
1172
|
-
if (
|
|
1173
|
-
const
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
const
|
|
1178
|
-
if (participantPrefix !== '') {
|
|
1179
|
-
prefixes.push(participantPrefix);
|
|
1180
|
-
}
|
|
1181
|
-
const commandPrefix =
|
|
1182
|
-
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1215
|
+
if (NBIAPI.config.isInClaudeCodeMode) {
|
|
1216
|
+
const claudeChatParticipant = NBIAPI.config.chatParticipants.find(
|
|
1217
|
+
participant => participant.id === CLAUDE_CODE_CHAT_PARTICIPANT_ID
|
|
1218
|
+
);
|
|
1219
|
+
if (claudeChatParticipant) {
|
|
1220
|
+
const commands = claudeChatParticipant.commands;
|
|
1183
1221
|
for (const command of commands) {
|
|
1184
|
-
prefixes.push(
|
|
1222
|
+
prefixes.push(`/${command}`);
|
|
1185
1223
|
}
|
|
1186
1224
|
}
|
|
1187
1225
|
} else {
|
|
1188
|
-
|
|
1226
|
+
if (chatMode === 'ask') {
|
|
1227
|
+
const chatParticipants = NBIAPI.config.chatParticipants;
|
|
1228
|
+
for (const participant of chatParticipants) {
|
|
1229
|
+
const id = participant.id;
|
|
1230
|
+
const commands = participant.commands;
|
|
1231
|
+
const participantPrefix = id === 'default' ? '' : `@${id}`;
|
|
1232
|
+
if (participantPrefix !== '') {
|
|
1233
|
+
prefixes.push(participantPrefix);
|
|
1234
|
+
}
|
|
1235
|
+
const commandPrefix =
|
|
1236
|
+
participantPrefix === '' ? '' : `${participantPrefix} `;
|
|
1237
|
+
for (const command of commands) {
|
|
1238
|
+
prefixes.push(`${commandPrefix}/${command}`);
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
} else {
|
|
1242
|
+
prefixes.push('/clear');
|
|
1243
|
+
}
|
|
1189
1244
|
}
|
|
1190
1245
|
|
|
1191
1246
|
const mcpServers = NBIAPI.config.toolConfig.mcpServers;
|
|
@@ -1969,24 +2024,26 @@ function SidebarComponent(props: any) {
|
|
|
1969
2024
|
)}
|
|
1970
2025
|
<div style={{ flexGrow: 1 }}></div>
|
|
1971
2026
|
<div className="chat-mode-widgets-container">
|
|
1972
|
-
|
|
1973
|
-
<
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
2027
|
+
{!NBIAPI.config.isInClaudeCodeMode && (
|
|
2028
|
+
<div>
|
|
2029
|
+
<select
|
|
2030
|
+
className="chat-mode-select"
|
|
2031
|
+
title="Chat mode"
|
|
2032
|
+
value={chatMode}
|
|
2033
|
+
onChange={event => {
|
|
2034
|
+
if (event.target.value === 'ask') {
|
|
2035
|
+
setToolSelections(toolSelectionsEmpty);
|
|
2036
|
+
}
|
|
2037
|
+
setShowModeTools(false);
|
|
2038
|
+
setChatMode(event.target.value);
|
|
2039
|
+
}}
|
|
2040
|
+
>
|
|
2041
|
+
<option value="ask">Ask</option>
|
|
2042
|
+
<option value="agent">Agent</option>
|
|
2043
|
+
</select>
|
|
2044
|
+
</div>
|
|
2045
|
+
)}
|
|
2046
|
+
{chatMode !== 'ask' && !NBIAPI.config.isInClaudeCodeMode && (
|
|
1990
2047
|
<div
|
|
1991
2048
|
className={`user-input-footer-button tools-button ${unsafeToolSelected ? 'tools-button-warning' : selectedToolCount > 0 ? 'tools-button-active' : ''}`}
|
|
1992
2049
|
onClick={() => handleChatToolsButtonClick()}
|
|
@@ -2000,6 +2057,13 @@ function SidebarComponent(props: any) {
|
|
|
2000
2057
|
{selectedToolCount > 0 && <>{selectedToolCount}</>}
|
|
2001
2058
|
</div>
|
|
2002
2059
|
)}
|
|
2060
|
+
{NBIAPI.config.isInClaudeCodeMode && (
|
|
2061
|
+
<span
|
|
2062
|
+
title="Claude mode"
|
|
2063
|
+
className="claude-icon"
|
|
2064
|
+
dangerouslySetInnerHTML={{ __html: claudeSvg }}
|
|
2065
|
+
></span>
|
|
2066
|
+
)}
|
|
2003
2067
|
</div>
|
|
2004
2068
|
<div>
|
|
2005
2069
|
<button
|
|
@@ -2352,7 +2416,7 @@ function InlinePromptComponent(props: any) {
|
|
|
2352
2416
|
type: RunChatCompletionType.GenerateCode,
|
|
2353
2417
|
content: prompt,
|
|
2354
2418
|
language: props.language || 'python',
|
|
2355
|
-
filename: props.filename || '
|
|
2419
|
+
filename: props.filename || '',
|
|
2356
2420
|
prefix: props.prefix,
|
|
2357
2421
|
suffix: props.suffix,
|
|
2358
2422
|
existingCode: props.existingCode,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Copyright (c) Mehmet Bektas <mbektasgh@outlook.com>
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
|
|
5
|
+
export function AskUserQuestion(props: any) {
|
|
6
|
+
const userQuestions = props.userQuestions.content;
|
|
7
|
+
const [selectedAnswers, setSelectedAnswers] = useState<{
|
|
8
|
+
[key: string]: string[];
|
|
9
|
+
}>({});
|
|
10
|
+
|
|
11
|
+
const onOptionSelected = (question: any, option: any) => {
|
|
12
|
+
if (question.multiSelect) {
|
|
13
|
+
if (selectedAnswers[question.question]?.includes(option.label)) {
|
|
14
|
+
setSelectedAnswers({
|
|
15
|
+
...selectedAnswers,
|
|
16
|
+
[question.question]: (
|
|
17
|
+
selectedAnswers[question.question] ?? []
|
|
18
|
+
).filter((o: any) => o !== option.label)
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
setSelectedAnswers({
|
|
22
|
+
...selectedAnswers,
|
|
23
|
+
[question.question]: [
|
|
24
|
+
...(selectedAnswers[question.question] ?? []),
|
|
25
|
+
option.label
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
setSelectedAnswers({
|
|
31
|
+
...selectedAnswers,
|
|
32
|
+
[question.question]: [option.label]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<>
|
|
39
|
+
{userQuestions.title ? (
|
|
40
|
+
<div>
|
|
41
|
+
<b>{userQuestions.title}</b>
|
|
42
|
+
</div>
|
|
43
|
+
) : null}
|
|
44
|
+
{userQuestions.message ? <div>{userQuestions.message}</div> : null}
|
|
45
|
+
{userQuestions.questions.map((question: any) => (
|
|
46
|
+
<div className="ask-user-question-container" key={question.question}>
|
|
47
|
+
<form className="ask-user-question-form">
|
|
48
|
+
<div className="ask-user-question-question">
|
|
49
|
+
{question.question}
|
|
50
|
+
</div>
|
|
51
|
+
<div className="ask-user-question-header">{question.header}</div>
|
|
52
|
+
<div className="ask-user-question-options">
|
|
53
|
+
{question.options.map((option: any) => (
|
|
54
|
+
<div className="ask-user-question-option" key={option.label}>
|
|
55
|
+
<div>
|
|
56
|
+
<input
|
|
57
|
+
id={option.label}
|
|
58
|
+
type="checkbox"
|
|
59
|
+
checked={
|
|
60
|
+
selectedAnswers[question.question]?.includes(
|
|
61
|
+
option.label
|
|
62
|
+
) ?? false
|
|
63
|
+
}
|
|
64
|
+
onChange={() => onOptionSelected(question, option)}
|
|
65
|
+
/>
|
|
66
|
+
<label htmlFor={option.label}>{option.label}</label>
|
|
67
|
+
</div>
|
|
68
|
+
<div className="ask-user-question-option-description">
|
|
69
|
+
{option.description}
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
))}
|
|
73
|
+
</div>
|
|
74
|
+
</form>
|
|
75
|
+
</div>
|
|
76
|
+
))}
|
|
77
|
+
<div className="ask-user-question-footer">
|
|
78
|
+
<button
|
|
79
|
+
className="jp-Dialog-button jp-mod-accept jp-mod-styled"
|
|
80
|
+
onClick={() => {
|
|
81
|
+
props.onSubmit(selectedAnswers);
|
|
82
|
+
}}
|
|
83
|
+
>
|
|
84
|
+
<div className="jp-Dialog-buttonLabel">
|
|
85
|
+
{userQuestions.submitLabel}
|
|
86
|
+
</div>
|
|
87
|
+
</button>
|
|
88
|
+
<button
|
|
89
|
+
className="jp-Dialog-button jp-mod-reject jp-mod-styled"
|
|
90
|
+
onClick={() => {
|
|
91
|
+
props.onCancel();
|
|
92
|
+
}}
|
|
93
|
+
>
|
|
94
|
+
<div className="jp-Dialog-buttonLabel">
|
|
95
|
+
{userQuestions.cancelLabel}
|
|
96
|
+
</div>
|
|
97
|
+
</button>
|
|
98
|
+
</div>
|
|
99
|
+
</>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
@@ -6,20 +6,31 @@ import { MdOutlineCheckBoxOutlineBlank, MdCheckBox } from 'react-icons/md';
|
|
|
6
6
|
|
|
7
7
|
export function CheckBoxItem(props: any) {
|
|
8
8
|
const indent = props.indent || 0;
|
|
9
|
+
const disabled = props.disabled || false;
|
|
9
10
|
|
|
10
11
|
return (
|
|
11
12
|
<div
|
|
12
13
|
className={`checkbox-item checkbox-item-indent-${indent} ${props.header ? 'checkbox-item-header' : ''}`}
|
|
13
14
|
title={props.tooltip || props.title || ''}
|
|
14
|
-
onClick={event =>
|
|
15
|
+
onClick={event => {
|
|
16
|
+
if (!disabled) {
|
|
17
|
+
props.onClick(event);
|
|
18
|
+
}
|
|
19
|
+
}}
|
|
15
20
|
>
|
|
16
21
|
<div className="checkbox-item-toggle">
|
|
17
22
|
{props.checked ? (
|
|
18
|
-
<MdCheckBox
|
|
23
|
+
<MdCheckBox
|
|
24
|
+
className="checkbox-icon"
|
|
25
|
+
style={{ opacity: disabled ? 0.5 : 1 }}
|
|
26
|
+
/>
|
|
19
27
|
) : (
|
|
20
|
-
<MdOutlineCheckBoxOutlineBlank
|
|
28
|
+
<MdOutlineCheckBoxOutlineBlank
|
|
29
|
+
className="checkbox-icon"
|
|
30
|
+
style={{ opacity: disabled ? 0.5 : 1 }}
|
|
31
|
+
/>
|
|
21
32
|
)}
|
|
22
|
-
{props.label}
|
|
33
|
+
<span style={{ opacity: disabled ? 0.5 : 1 }}>{props.label}</span>
|
|
23
34
|
</div>
|
|
24
35
|
{props.title && (
|
|
25
36
|
<div className="checkbox-item-description">{props.title}</div>
|