@gravity-ui/markdown-editor 13.17.0 → 13.18.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 +2 -0
- package/build/cjs/bundle/config/action-names.d.ts +1 -1
- package/build/cjs/bundle/config/action-names.js +1 -0
- package/build/cjs/bundle/config/icons.d.ts +1 -1
- package/build/cjs/bundle/config/icons.js +3 -0
- package/build/cjs/bundle/config/wysiwyg.d.ts +1 -0
- package/build/cjs/bundle/config/wysiwyg.js +13 -1
- package/build/cjs/extensions/behavior/Resizable/Resizable.css +38 -0
- package/build/cjs/extensions/behavior/Resizable/Resizable.d.ts +9 -0
- package/build/cjs/extensions/behavior/Resizable/Resizable.js +14 -0
- package/build/cjs/extensions/markdown/Table/actions/innerActions.d.ts +1 -1
- package/build/cjs/extensions/markdown/Table/plugins/TableCellContextPlugin/index.js +19 -9
- package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.css +18 -0
- package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.d.ts +8 -0
- package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.js +21 -0
- package/build/cjs/extensions/yfm/GPT/ErrorScreen/types.d.ts +14 -0
- package/build/cjs/extensions/yfm/GPT/ErrorScreen/types.js +2 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.css +75 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.d.ts +28 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.js +102 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.css +22 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.d.ts +3 -0
- package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.js +21 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.d.ts +1 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.js +5 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.css +8 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.d.ts +14 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.js +28 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/index.d.ts +2 -0
- package/build/cjs/extensions/yfm/GPT/IconRefuge/index.js +5 -0
- package/build/cjs/extensions/yfm/GPT/PresetList/PresetList.d.ts +9 -0
- package/build/cjs/extensions/yfm/GPT/PresetList/PresetList.js +29 -0
- package/build/cjs/extensions/yfm/GPT/PresetList/Presetlist.css +6 -0
- package/build/cjs/extensions/yfm/GPT/actions.d.ts +2 -0
- package/build/cjs/extensions/yfm/GPT/actions.js +14 -0
- package/build/cjs/extensions/yfm/GPT/commands.d.ts +2 -0
- package/build/cjs/extensions/yfm/GPT/commands.js +13 -0
- package/build/cjs/extensions/yfm/GPT/constants.d.ts +13 -0
- package/build/cjs/extensions/yfm/GPT/constants.js +15 -0
- package/build/cjs/extensions/yfm/GPT/gptExtension/gptExtension.d.ts +13 -0
- package/build/cjs/extensions/yfm/GPT/gptExtension/gptExtension.js +18 -0
- package/build/cjs/extensions/yfm/GPT/gptExtension/view.css +17 -0
- package/build/cjs/extensions/yfm/GPT/gptExtension/view.d.ts +36 -0
- package/build/cjs/extensions/yfm/GPT/gptExtension/view.js +171 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useGpt.d.ts +27 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useGpt.js +148 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useGptHotKeys.d.ts +2 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useGptHotKeys.js +8 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.d.ts +13 -0
- package/build/cjs/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.js +70 -0
- package/build/cjs/extensions/yfm/GPT/hooks/usePresetList.d.ts +14 -0
- package/build/cjs/extensions/yfm/GPT/hooks/usePresetList.js +36 -0
- package/build/cjs/extensions/yfm/GPT/index.d.ts +2 -0
- package/build/cjs/extensions/yfm/GPT/index.js +5 -0
- package/build/cjs/extensions/yfm/GPT/plugin.d.ts +13 -0
- package/build/cjs/extensions/yfm/GPT/plugin.js +47 -0
- package/build/cjs/extensions/yfm/GPT/toolbar.d.ts +3 -0
- package/build/cjs/extensions/yfm/GPT/toolbar.js +22 -0
- package/build/cjs/extensions/yfm/GPT/utils.d.ts +13 -0
- package/build/cjs/extensions/yfm/GPT/utils.js +31 -0
- package/build/cjs/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.css +6 -0
- package/build/cjs/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.d.ts +6 -1
- package/build/cjs/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.js +21 -37
- package/build/cjs/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/NodeView.d.ts +1 -1
- package/build/cjs/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/NodeView.js +62 -4
- package/build/cjs/extensions/yfm/Mermaid/MermaidNodeView/MermaidView.js +8 -7
- package/build/cjs/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.d.ts +1 -1
- package/build/cjs/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.js +0 -8
- package/build/cjs/extensions/yfm/index.d.ts +1 -0
- package/build/cjs/extensions/yfm/index.js +1 -0
- package/build/cjs/i18n/gpt/dialog/en.json +16 -0
- package/build/cjs/i18n/gpt/dialog/index.d.ts +19 -0
- package/build/cjs/i18n/gpt/dialog/index.js +8 -0
- package/build/cjs/i18n/gpt/dialog/ru.json +16 -0
- package/build/cjs/i18n/gpt/errors/en.json +5 -0
- package/build/cjs/i18n/gpt/errors/index.d.ts +8 -0
- package/build/cjs/i18n/gpt/errors/index.js +8 -0
- package/build/cjs/i18n/gpt/errors/ru.json +5 -0
- package/build/cjs/i18n/gpt/extension/en.json +6 -0
- package/build/cjs/i18n/gpt/extension/index.d.ts +9 -0
- package/build/cjs/i18n/gpt/extension/index.js +8 -0
- package/build/cjs/i18n/gpt/extension/ru.json +6 -0
- package/build/cjs/i18n/gpt/loading/en.json +3 -0
- package/build/cjs/i18n/gpt/loading/index.d.ts +6 -0
- package/build/cjs/i18n/gpt/loading/index.js +8 -0
- package/build/cjs/i18n/gpt/loading/ru.json +3 -0
- package/build/cjs/i18n/menubar/en.json +1 -0
- package/build/cjs/i18n/menubar/index.d.ts +2 -1
- package/build/cjs/i18n/menubar/ru.json +1 -0
- package/build/cjs/i18n/yfm-table/en.json +10 -1
- package/build/cjs/i18n/yfm-table/index.d.ts +10 -1
- package/build/cjs/i18n/yfm-table/ru.json +10 -1
- package/build/cjs/icons/GPT.d.ts +2 -0
- package/build/cjs/icons/GPT.js +22 -0
- package/build/cjs/icons/GPTLoading.d.ts +2 -0
- package/build/cjs/icons/GPTLoading.js +12 -0
- package/build/cjs/icons/index.d.ts +3 -1
- package/build/cjs/icons/index.js +5 -1
- package/build/cjs/react-utils/useAutoFocus.d.ts +1 -1
- package/build/cjs/react-utils/useAutoFocus.js +2 -2
- package/build/cjs/react-utils/useNodeEditing.d.ts +3 -2
- package/build/cjs/react-utils/useNodeEditing.js +1 -1
- package/build/cjs/react-utils/useNodeResizing.d.ts +22 -0
- package/build/cjs/react-utils/useNodeResizing.js +82 -0
- package/build/cjs/table-utils/commands/appendColumn.js +42 -33
- package/build/cjs/table-utils/commands/appendRow.js +40 -22
- package/build/cjs/table-utils/commands/removeColumn.js +18 -20
- package/build/cjs/table-utils/commands/removeRow.js +12 -9
- package/build/cjs/table-utils/table-desc.d.ts +53 -0
- package/build/cjs/table-utils/table-desc.js +149 -0
- package/build/cjs/table-utils/utils.d.ts +1 -1
- package/build/cjs/table-utils/utils.js +19 -12
- package/build/cjs/version.js +1 -1
- package/build/esm/bundle/config/action-names.d.ts +1 -1
- package/build/esm/bundle/config/action-names.js +1 -0
- package/build/esm/bundle/config/icons.d.ts +1 -1
- package/build/esm/bundle/config/icons.js +2 -0
- package/build/esm/bundle/config/wysiwyg.d.ts +1 -0
- package/build/esm/bundle/config/wysiwyg.js +12 -0
- package/build/esm/extensions/behavior/Resizable/Resizable.css +38 -0
- package/build/esm/extensions/behavior/Resizable/Resizable.d.ts +10 -0
- package/build/esm/extensions/behavior/Resizable/Resizable.js +10 -0
- package/build/esm/extensions/markdown/Table/actions/innerActions.d.ts +1 -1
- package/build/esm/extensions/markdown/Table/plugins/TableCellContextPlugin/index.js +19 -9
- package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.css +18 -0
- package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.d.ts +9 -0
- package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.js +17 -0
- package/build/esm/extensions/yfm/GPT/ErrorScreen/types.d.ts +14 -0
- package/build/esm/extensions/yfm/GPT/ErrorScreen/types.js +1 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.css +75 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.d.ts +29 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.js +98 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.css +22 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.d.ts +4 -0
- package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.js +17 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.d.ts +1 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.js +2 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.css +8 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.d.ts +15 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.js +25 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/index.d.ts +2 -0
- package/build/esm/extensions/yfm/GPT/IconRefuge/index.js +1 -0
- package/build/esm/extensions/yfm/GPT/PresetList/PresetList.d.ts +10 -0
- package/build/esm/extensions/yfm/GPT/PresetList/PresetList.js +25 -0
- package/build/esm/extensions/yfm/GPT/PresetList/Presetlist.css +6 -0
- package/build/esm/extensions/yfm/GPT/actions.d.ts +2 -0
- package/build/esm/extensions/yfm/GPT/actions.js +10 -0
- package/build/esm/extensions/yfm/GPT/commands.d.ts +2 -0
- package/build/esm/extensions/yfm/GPT/commands.js +9 -0
- package/build/esm/extensions/yfm/GPT/constants.d.ts +13 -0
- package/build/esm/extensions/yfm/GPT/constants.js +12 -0
- package/build/esm/extensions/yfm/GPT/gptExtension/gptExtension.d.ts +13 -0
- package/build/esm/extensions/yfm/GPT/gptExtension/gptExtension.js +14 -0
- package/build/esm/extensions/yfm/GPT/gptExtension/view.css +17 -0
- package/build/esm/extensions/yfm/GPT/gptExtension/view.d.ts +37 -0
- package/build/esm/extensions/yfm/GPT/gptExtension/view.js +167 -0
- package/build/esm/extensions/yfm/GPT/hooks/useGpt.d.ts +27 -0
- package/build/esm/extensions/yfm/GPT/hooks/useGpt.js +144 -0
- package/build/esm/extensions/yfm/GPT/hooks/useGptHotKeys.d.ts +2 -0
- package/build/esm/extensions/yfm/GPT/hooks/useGptHotKeys.js +4 -0
- package/build/esm/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.d.ts +13 -0
- package/build/esm/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.js +65 -0
- package/build/esm/extensions/yfm/GPT/hooks/usePresetList.d.ts +14 -0
- package/build/esm/extensions/yfm/GPT/hooks/usePresetList.js +32 -0
- package/build/esm/extensions/yfm/GPT/index.d.ts +2 -0
- package/build/esm/extensions/yfm/GPT/index.js +2 -0
- package/build/esm/extensions/yfm/GPT/plugin.d.ts +13 -0
- package/build/esm/extensions/yfm/GPT/plugin.js +43 -0
- package/build/esm/extensions/yfm/GPT/toolbar.d.ts +3 -0
- package/build/esm/extensions/yfm/GPT/toolbar.js +18 -0
- package/build/esm/extensions/yfm/GPT/utils.d.ts +13 -0
- package/build/esm/extensions/yfm/GPT/utils.js +23 -0
- package/build/esm/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.css +6 -0
- package/build/esm/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.d.ts +7 -1
- package/build/esm/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/ImgSettingsButton.js +23 -38
- package/build/esm/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/NodeView.d.ts +1 -1
- package/build/esm/extensions/yfm/ImgSize/plugins/ImgSizeNodeView/NodeView.js +63 -5
- package/build/esm/extensions/yfm/Mermaid/MermaidNodeView/MermaidView.js +5 -4
- package/build/esm/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.d.ts +1 -1
- package/build/esm/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.js +1 -9
- package/build/esm/extensions/yfm/index.d.ts +1 -0
- package/build/esm/extensions/yfm/index.js +1 -0
- package/build/esm/i18n/gpt/dialog/en.json +16 -0
- package/build/esm/i18n/gpt/dialog/index.d.ts +19 -0
- package/build/esm/i18n/gpt/dialog/index.js +4 -0
- package/build/esm/i18n/gpt/dialog/ru.json +16 -0
- package/build/esm/i18n/gpt/errors/en.json +5 -0
- package/build/esm/i18n/gpt/errors/index.d.ts +8 -0
- package/build/esm/i18n/gpt/errors/index.js +4 -0
- package/build/esm/i18n/gpt/errors/ru.json +5 -0
- package/build/esm/i18n/gpt/extension/en.json +6 -0
- package/build/esm/i18n/gpt/extension/index.d.ts +9 -0
- package/build/esm/i18n/gpt/extension/index.js +4 -0
- package/build/esm/i18n/gpt/extension/ru.json +6 -0
- package/build/esm/i18n/gpt/loading/en.json +3 -0
- package/build/esm/i18n/gpt/loading/index.d.ts +6 -0
- package/build/esm/i18n/gpt/loading/index.js +4 -0
- package/build/esm/i18n/gpt/loading/ru.json +3 -0
- package/build/esm/i18n/menubar/en.json +1 -0
- package/build/esm/i18n/menubar/index.d.ts +2 -1
- package/build/esm/i18n/menubar/ru.json +1 -0
- package/build/esm/i18n/yfm-table/en.json +10 -1
- package/build/esm/i18n/yfm-table/index.d.ts +10 -1
- package/build/esm/i18n/yfm-table/ru.json +10 -1
- package/build/esm/icons/GPT.d.ts +2 -0
- package/build/esm/icons/GPT.js +19 -0
- package/build/esm/icons/GPTLoading.d.ts +2 -0
- package/build/esm/icons/GPTLoading.js +9 -0
- package/build/esm/icons/index.d.ts +3 -1
- package/build/esm/icons/index.js +3 -1
- package/build/esm/react-utils/useAutoFocus.d.ts +1 -1
- package/build/esm/react-utils/useAutoFocus.js +2 -2
- package/build/esm/react-utils/useNodeEditing.d.ts +3 -2
- package/build/esm/react-utils/useNodeEditing.js +1 -1
- package/build/esm/react-utils/useNodeResizing.d.ts +22 -0
- package/build/esm/react-utils/useNodeResizing.js +77 -0
- package/build/esm/table-utils/commands/appendColumn.js +44 -35
- package/build/esm/table-utils/commands/appendRow.js +42 -24
- package/build/esm/table-utils/commands/removeColumn.js +18 -20
- package/build/esm/table-utils/commands/removeRow.js +14 -11
- package/build/esm/table-utils/table-desc.d.ts +53 -0
- package/build/esm/table-utils/table-desc.js +144 -0
- package/build/esm/table-utils/utils.d.ts +1 -1
- package/build/esm/table-utils/utils.js +18 -12
- package/build/esm/version.js +1 -1
- package/build/styles.css +190 -0
- package/package.json +3 -2
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
import { isEnter } from '../utils';
|
|
3
|
+
export const useGpt = ({ markup, promptPresets, onCustomPromptApply, onPromptPresetClick, onTryAgain, onLike, onDislike, onApplyResult, onUpdate, }) => {
|
|
4
|
+
const [answer, setAnswer] = useState();
|
|
5
|
+
const [lastRequestData, setLastRequestData] = useState();
|
|
6
|
+
const [customPrompt, setCustomPrompt] = useState('');
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
const [error, setError] = useState(false);
|
|
9
|
+
const [feedbackType, setFeedbackType] = useState(undefined);
|
|
10
|
+
const [feedbackTypeLoading, setFeedbackTypeLoading] = useState(undefined);
|
|
11
|
+
const makeRequest = useCallback(async (requestFunction, data) => {
|
|
12
|
+
if (!requestFunction) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
let result;
|
|
16
|
+
try {
|
|
17
|
+
setLoading(true);
|
|
18
|
+
setError(false);
|
|
19
|
+
setLastRequestData(data);
|
|
20
|
+
result = await requestFunction(data);
|
|
21
|
+
if (result) {
|
|
22
|
+
setAnswer(result);
|
|
23
|
+
setFeedbackType(undefined);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
console.error(error);
|
|
28
|
+
setError(true);
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
setLoading(false);
|
|
32
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(result);
|
|
33
|
+
}
|
|
34
|
+
}, [onUpdate]);
|
|
35
|
+
const handleLike = useCallback(async () => {
|
|
36
|
+
if (!onLike || !lastRequestData) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
setFeedbackType(undefined);
|
|
41
|
+
setFeedbackTypeLoading('like');
|
|
42
|
+
await onLike(lastRequestData);
|
|
43
|
+
setFeedbackType('like');
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error(error);
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
setFeedbackTypeLoading(undefined);
|
|
50
|
+
}
|
|
51
|
+
}, [lastRequestData, onLike]);
|
|
52
|
+
const handleDislike = useCallback(async () => {
|
|
53
|
+
if (!onDislike || !lastRequestData) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
setFeedbackType(undefined);
|
|
58
|
+
setFeedbackTypeLoading('dislike');
|
|
59
|
+
await onDislike(lastRequestData);
|
|
60
|
+
setFeedbackType('dislike');
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.error(error);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
setFeedbackTypeLoading(undefined);
|
|
67
|
+
}
|
|
68
|
+
}, [lastRequestData, onDislike]);
|
|
69
|
+
const handleCustomPromptApply = useCallback(async () => {
|
|
70
|
+
if (!customPrompt) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const gptRequestData = {
|
|
74
|
+
markup,
|
|
75
|
+
customPrompt,
|
|
76
|
+
};
|
|
77
|
+
await makeRequest(onCustomPromptApply, gptRequestData);
|
|
78
|
+
}, [customPrompt, makeRequest, markup, onCustomPromptApply]);
|
|
79
|
+
const handleCustomPromptKeyPress = useCallback(async (event) => {
|
|
80
|
+
if (!isEnter(event)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await handleCustomPromptApply();
|
|
84
|
+
}, [handleCustomPromptApply]);
|
|
85
|
+
const handlePresetClick = useCallback(async (data) => {
|
|
86
|
+
const gptRequestData = {
|
|
87
|
+
markup,
|
|
88
|
+
promptData: data,
|
|
89
|
+
};
|
|
90
|
+
await makeRequest(onPromptPresetClick, gptRequestData);
|
|
91
|
+
}, [makeRequest, markup, onPromptPresetClick]);
|
|
92
|
+
const handleTryAgain = useCallback(async () => {
|
|
93
|
+
if (!lastRequestData) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
await makeRequest(onTryAgain, lastRequestData);
|
|
97
|
+
}, [lastRequestData, makeRequest, onTryAgain]);
|
|
98
|
+
const handleApplyResult = useCallback(() => {
|
|
99
|
+
var _a;
|
|
100
|
+
onApplyResult((_a = answer === null || answer === void 0 ? void 0 : answer.rawText) !== null && _a !== void 0 ? _a : '');
|
|
101
|
+
}, [answer === null || answer === void 0 ? void 0 : answer.rawText, onApplyResult]);
|
|
102
|
+
const handleFreshStart = useCallback(() => {
|
|
103
|
+
setError(false);
|
|
104
|
+
setLastRequestData(undefined);
|
|
105
|
+
setAnswer(undefined);
|
|
106
|
+
setCustomPrompt('');
|
|
107
|
+
setFeedbackType(undefined);
|
|
108
|
+
onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(undefined);
|
|
109
|
+
}, [onUpdate]);
|
|
110
|
+
const showTryAgainButton = Boolean(lastRequestData && onTryAgain && !loading);
|
|
111
|
+
const showAnswer = Boolean(answer && !loading && !error);
|
|
112
|
+
const showError = error && !loading;
|
|
113
|
+
const showAnswerActions = (onLike || onDislike) && showAnswer;
|
|
114
|
+
let mode = 'custom-and-presets';
|
|
115
|
+
if (onCustomPromptApply && !(promptPresets === null || promptPresets === void 0 ? void 0 : promptPresets.length)) {
|
|
116
|
+
mode = 'only-custom';
|
|
117
|
+
}
|
|
118
|
+
else if (!onCustomPromptApply && (promptPresets === null || promptPresets === void 0 ? void 0 : promptPresets.length)) {
|
|
119
|
+
mode = 'only-presets';
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
answer,
|
|
123
|
+
customPrompt,
|
|
124
|
+
lastRequestData,
|
|
125
|
+
loading,
|
|
126
|
+
error,
|
|
127
|
+
mode,
|
|
128
|
+
feedbackType,
|
|
129
|
+
feedbackTypeLoading,
|
|
130
|
+
handleLike,
|
|
131
|
+
handleDislike,
|
|
132
|
+
handleCustomPromptUpdate: setCustomPrompt,
|
|
133
|
+
handleCustomPromptKeyPress,
|
|
134
|
+
handleCustomPromptApply,
|
|
135
|
+
handlePresetClick,
|
|
136
|
+
handleTryAgain,
|
|
137
|
+
handleFreshStart,
|
|
138
|
+
handleApplyResult,
|
|
139
|
+
showTryAgainButton,
|
|
140
|
+
showAnswer,
|
|
141
|
+
showError,
|
|
142
|
+
showAnswerActions,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
export declare type UseOverflowingContainerListItemsProps<ItemType extends unknown> = {
|
|
3
|
+
containerRef: RefObject<HTMLElement>;
|
|
4
|
+
items?: ItemType[];
|
|
5
|
+
itemSelector: string;
|
|
6
|
+
moreButtonSelector: string;
|
|
7
|
+
marginBetweenItems?: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function useOverflowingHorizontalItems<ItemType>({ containerRef, items, itemSelector, moreButtonSelector, marginBetweenItems, }: UseOverflowingContainerListItemsProps<ItemType>): {
|
|
10
|
+
visibleItems: ItemType[];
|
|
11
|
+
hiddenItems: ItemType[];
|
|
12
|
+
measured: boolean;
|
|
13
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { useLayoutEffect, useMemo, useState } from 'react';
|
|
2
|
+
import debounceFn from 'lodash/debounce';
|
|
3
|
+
export function useOverflowingHorizontalItems({ containerRef, items, itemSelector, moreButtonSelector, marginBetweenItems = 0, }) {
|
|
4
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
5
|
+
const [itemWidths, setItemWidths] = useState([]);
|
|
6
|
+
const [moreButtonWidth, setMoreButtonWidth] = useState(0);
|
|
7
|
+
useLayoutEffect(() => {
|
|
8
|
+
const measureItemSizes = () => {
|
|
9
|
+
var _a, _b, _c;
|
|
10
|
+
const itemElements = Array.from((_b = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(itemSelector)) !== null && _b !== void 0 ? _b : []);
|
|
11
|
+
const moreButton = (_c = containerRef.current) === null || _c === void 0 ? void 0 : _c.querySelector(moreButtonSelector);
|
|
12
|
+
setItemWidths(itemElements.map((item) => item.clientWidth));
|
|
13
|
+
if (moreButton) {
|
|
14
|
+
setMoreButtonWidth(moreButton.clientWidth);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
requestAnimationFrame(measureItemSizes);
|
|
18
|
+
}, [containerRef, itemSelector, moreButtonSelector]);
|
|
19
|
+
useLayoutEffect(() => {
|
|
20
|
+
const container = containerRef.current;
|
|
21
|
+
if (!container) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const updateContainerSize = (entries) => {
|
|
25
|
+
if (entries.length > 0) {
|
|
26
|
+
setContainerWidth(entries[0].contentRect.width);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const updateContainerSizeDebounced = debounceFn(updateContainerSize, 100);
|
|
30
|
+
const containerResizeObserver = new ResizeObserver(updateContainerSizeDebounced);
|
|
31
|
+
containerResizeObserver.observe(container);
|
|
32
|
+
return () => containerResizeObserver.unobserve(container);
|
|
33
|
+
}, [containerRef]);
|
|
34
|
+
const isMeasured = itemWidths.length > 0;
|
|
35
|
+
const { visibleItems, hiddenItems } = useMemo(() => {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
if (!isMeasured) {
|
|
38
|
+
return {
|
|
39
|
+
visibleItems: items !== null && items !== void 0 ? items : [],
|
|
40
|
+
hiddenItems: [],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const itemsCount = itemWidths.length;
|
|
44
|
+
let visibleItemsCount = 0;
|
|
45
|
+
const spaceForMoreButton = moreButtonWidth + marginBetweenItems;
|
|
46
|
+
let remainingContainerWidth = containerWidth;
|
|
47
|
+
for (const width of itemWidths) {
|
|
48
|
+
const itemWidthWithMargin = width + marginBetweenItems;
|
|
49
|
+
remainingContainerWidth -= itemWidthWithMargin;
|
|
50
|
+
if (remainingContainerWidth < spaceForMoreButton) {
|
|
51
|
+
const isMoreThanOneItemLeft = itemsCount !== visibleItemsCount + 1;
|
|
52
|
+
const hasNoSpaceForTheLastItem = remainingContainerWidth < 0;
|
|
53
|
+
if (isMoreThanOneItemLeft || hasNoSpaceForTheLastItem) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
visibleItemsCount++;
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
visibleItems: (_a = items === null || items === void 0 ? void 0 : items.slice(0, visibleItemsCount)) !== null && _a !== void 0 ? _a : [],
|
|
61
|
+
hiddenItems: (_b = items === null || items === void 0 ? void 0 : items.slice(visibleItemsCount)) !== null && _b !== void 0 ? _b : [],
|
|
62
|
+
};
|
|
63
|
+
}, [containerWidth, isMeasured, itemWidths, items, marginBetweenItems, moreButtonWidth]);
|
|
64
|
+
return { visibleItems, hiddenItems, measured: isMeasured };
|
|
65
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DropdownMenuItem } from '@gravity-ui/uikit';
|
|
2
|
+
import type { GptDialogProps } from '../GptDialog/GptDialog';
|
|
3
|
+
import type { PresetListProps } from '../PresetList/PresetList';
|
|
4
|
+
declare type UsePresetListProps = Pick<GptDialogProps, 'promptPresets'> & {
|
|
5
|
+
onPresetClick: PresetListProps['onPresetClick'];
|
|
6
|
+
};
|
|
7
|
+
export declare const usePresetList: ({ promptPresets, onPresetClick }: UsePresetListProps) => {
|
|
8
|
+
measured: boolean;
|
|
9
|
+
showMoreButton: boolean;
|
|
10
|
+
presetsContainerRef: import("react").RefObject<HTMLDivElement>;
|
|
11
|
+
visiblePresets: import("../ErrorScreen/types").PromptPreset<unknown>[];
|
|
12
|
+
hiddenPresets: DropdownMenuItem<unknown>[];
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useMemo, useRef } from 'react';
|
|
2
|
+
import { cnGptDialogPresetList } from '../PresetList/PresetList';
|
|
3
|
+
import { useOverflowingHorizontalItems } from './useOverflowingHorizontalItems';
|
|
4
|
+
export const usePresetList = ({ promptPresets, onPresetClick }) => {
|
|
5
|
+
const presetsContainerRef = useRef(null);
|
|
6
|
+
const { visibleItems, hiddenItems, measured } = useOverflowingHorizontalItems({
|
|
7
|
+
containerRef: presetsContainerRef,
|
|
8
|
+
items: promptPresets,
|
|
9
|
+
itemSelector: `.${cnGptDialogPresetList('preset')}`,
|
|
10
|
+
moreButtonSelector: `.${cnGptDialogPresetList('more-button-wrapper')}`,
|
|
11
|
+
marginBetweenItems: 8,
|
|
12
|
+
});
|
|
13
|
+
const hiddenPresets = useMemo(() => {
|
|
14
|
+
const items = [];
|
|
15
|
+
for (const item of hiddenItems) {
|
|
16
|
+
items.push({
|
|
17
|
+
text: item.display,
|
|
18
|
+
action: () => onPresetClick(item.data),
|
|
19
|
+
items: [],
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return items;
|
|
23
|
+
}, [onPresetClick, hiddenItems]);
|
|
24
|
+
const showMoreButton = !measured || hiddenPresets.length > 0;
|
|
25
|
+
return {
|
|
26
|
+
measured,
|
|
27
|
+
showMoreButton,
|
|
28
|
+
presetsContainerRef,
|
|
29
|
+
visiblePresets: visibleItems,
|
|
30
|
+
hiddenPresets,
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
+
import { DecorationSet } from 'prosemirror-view';
|
|
3
|
+
import type { GptWidgetDecoViewParams } from './gptExtension/view';
|
|
4
|
+
export declare type GptWidgetMeta = {
|
|
5
|
+
action: 'show';
|
|
6
|
+
from: number;
|
|
7
|
+
to: number;
|
|
8
|
+
} | {
|
|
9
|
+
action: 'hide';
|
|
10
|
+
};
|
|
11
|
+
declare const key: PluginKey<DecorationSet>;
|
|
12
|
+
export { key as pluginKey };
|
|
13
|
+
export declare const gptWidgetPlugin: (params: GptWidgetDecoViewParams) => Plugin;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
2
|
+
import { Decoration, DecorationSet } from 'prosemirror-view';
|
|
3
|
+
import { WIDGET_DECO_CLASS_NAME, WIDGET_DECO_SPEC_FLAG } from './constants';
|
|
4
|
+
import { GptWidgetDecoView } from './gptExtension/view';
|
|
5
|
+
const key = new PluginKey('gpt-widget');
|
|
6
|
+
export { key as pluginKey };
|
|
7
|
+
export const gptWidgetPlugin = (params) => {
|
|
8
|
+
return new Plugin({
|
|
9
|
+
key,
|
|
10
|
+
state: {
|
|
11
|
+
init: () => DecorationSet.empty,
|
|
12
|
+
apply: (tr, decos) => {
|
|
13
|
+
const meta = tr.getMeta(key);
|
|
14
|
+
const paramsGpt = params;
|
|
15
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'show') {
|
|
16
|
+
if (meta.to === meta.from) {
|
|
17
|
+
const spanElem = document.createElement('span');
|
|
18
|
+
spanElem.className = WIDGET_DECO_CLASS_NAME;
|
|
19
|
+
spanElem.textContent = ' ';
|
|
20
|
+
paramsGpt.disablePromptPresets = true;
|
|
21
|
+
return DecorationSet.create(tr.doc, [
|
|
22
|
+
Decoration.widget(meta.from, spanElem, {
|
|
23
|
+
[WIDGET_DECO_SPEC_FLAG]: true,
|
|
24
|
+
}),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
return DecorationSet.create(tr.doc, [
|
|
28
|
+
Decoration.inline(meta.from, meta.to, { nodeName: 'span', class: WIDGET_DECO_CLASS_NAME }, { [WIDGET_DECO_SPEC_FLAG]: true }),
|
|
29
|
+
]);
|
|
30
|
+
}
|
|
31
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'hide') {
|
|
32
|
+
paramsGpt.disablePromptPresets = false;
|
|
33
|
+
return DecorationSet.empty;
|
|
34
|
+
}
|
|
35
|
+
return decos.map(tr.mapping, tr.doc);
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
props: {
|
|
39
|
+
decorations: (state) => key.getState(state),
|
|
40
|
+
},
|
|
41
|
+
view: (view) => new GptWidgetDecoView(view, params),
|
|
42
|
+
});
|
|
43
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { cn } from '@bem-react/classname';
|
|
2
|
+
import { i18n } from '../../../i18n/gpt/extension';
|
|
3
|
+
import gptIcon from '../../../icons/GPT';
|
|
4
|
+
import { ToolbarDataType } from '../../../toolbar';
|
|
5
|
+
import { gptHotKeys } from './constants';
|
|
6
|
+
export const cnGptButton = cn('gpt-button');
|
|
7
|
+
export const wGptToolbarItem = {
|
|
8
|
+
type: ToolbarDataType.SingleButton,
|
|
9
|
+
id: 'gpt',
|
|
10
|
+
title: () => `${i18n('help-with-text')}`,
|
|
11
|
+
hotkey: gptHotKeys.openGptKeyTooltip,
|
|
12
|
+
icon: { data: gptIcon },
|
|
13
|
+
disabledPopoverVisible: false,
|
|
14
|
+
exec: (actionsStorage) => actionsStorage.actions.addGptWidget.run({}),
|
|
15
|
+
isActive: (actionsStorage) => actionsStorage.actions.addGptWidget.isActive(),
|
|
16
|
+
isEnable: (actionsStorage) => actionsStorage.actions.addGptWidget.isEnable(),
|
|
17
|
+
className: cnGptButton(),
|
|
18
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { GptDialogProps } from './GptDialog/GptDialog';
|
|
3
|
+
declare type CombinedKeyboardEvent = KeyboardEvent | React.KeyboardEvent;
|
|
4
|
+
export declare function getAlertGptInfo(gptAlert: GptDialogProps['gptAlertProps']): {
|
|
5
|
+
alertMessage: string;
|
|
6
|
+
alertTheme: import("@gravity-ui/uikit/build/esm/components/Alert/types").AlertTheme;
|
|
7
|
+
alertClassName: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare function getDisableReplaceButtonText(disablePromptPresets?: boolean): string;
|
|
10
|
+
export declare function getInputPlaceHolder(disablePromptPresets?: boolean, disabledPromptPlaceholder?: string, customPromptPlaceholder?: string): string | undefined;
|
|
11
|
+
export declare const isEnter: (event: CombinedKeyboardEvent) => boolean;
|
|
12
|
+
export declare function focusWithoutScroll(element?: HTMLElement | null): void;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { i18n } from '../../../i18n/gpt/dialog';
|
|
2
|
+
export function getAlertGptInfo(gptAlert) {
|
|
3
|
+
return {
|
|
4
|
+
alertMessage: (gptAlert === null || gptAlert === void 0 ? void 0 : gptAlert.message) || i18n('alert-gpt-presets-info'),
|
|
5
|
+
alertTheme: (gptAlert === null || gptAlert === void 0 ? void 0 : gptAlert.theme) || 'info',
|
|
6
|
+
alertClassName: gptAlert === null || gptAlert === void 0 ? void 0 : gptAlert.className,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function getDisableReplaceButtonText(disablePromptPresets) {
|
|
10
|
+
return disablePromptPresets ? i18n(`replace-disabled`) : i18n(`replace`);
|
|
11
|
+
}
|
|
12
|
+
export function getInputPlaceHolder(disablePromptPresets, disabledPromptPlaceholder, customPromptPlaceholder) {
|
|
13
|
+
return disablePromptPresets ? disabledPromptPlaceholder : customPromptPlaceholder;
|
|
14
|
+
}
|
|
15
|
+
export const isEnter = (event) => event.code === 'Enter' || event.code === 'NumpadEnter';
|
|
16
|
+
export function focusWithoutScroll(element) {
|
|
17
|
+
const x = window.scrollX;
|
|
18
|
+
const y = window.scrollY;
|
|
19
|
+
element === null || element === void 0 ? void 0 : element.focus({
|
|
20
|
+
preventScroll: true,
|
|
21
|
+
});
|
|
22
|
+
window.scrollTo(x, y);
|
|
23
|
+
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import React, { RefObject } from 'react';
|
|
2
2
|
import { Node } from 'prosemirror-model';
|
|
3
3
|
import { EditorView } from 'prosemirror-view';
|
|
4
|
+
import './ImgSettingsButton.css';
|
|
4
5
|
export declare const ImgSettingsButton: React.FC<{
|
|
5
6
|
node: Node;
|
|
6
7
|
view: EditorView;
|
|
7
8
|
getPos: () => number | undefined;
|
|
8
|
-
nodeRef: RefObject<HTMLElement>;
|
|
9
9
|
updateAttributes: (o: object) => void;
|
|
10
|
+
nodeRef: RefObject<HTMLDivElement>;
|
|
11
|
+
visible: boolean;
|
|
12
|
+
toggleEdit: () => void;
|
|
13
|
+
edit: boolean;
|
|
14
|
+
unsetEdit: () => void;
|
|
15
|
+
onDelete: () => void;
|
|
10
16
|
}>;
|
|
@@ -1,48 +1,33 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
2
|
import { Ellipsis } from '@gravity-ui/icons';
|
|
3
3
|
import { Button, Icon, Menu, Popup } from '@gravity-ui/uikit';
|
|
4
|
+
import { cn } from '../../../../../classname';
|
|
4
5
|
import { i18n as i18nCommon } from '../../../../../i18n/common';
|
|
5
6
|
import { useBooleanState } from '../../../../../react-utils/hooks';
|
|
6
|
-
import { useNodeEditing } from '../../../../../react-utils/useNodeEditing';
|
|
7
|
-
import { useNodeHovered } from '../../../../../react-utils/useNodeHovered';
|
|
8
|
-
import { removeNode } from '../../../../../utils/remove-node';
|
|
9
|
-
import { imageRendererKey } from '../../const';
|
|
10
7
|
import { ImageForm } from './ImageForm';
|
|
11
|
-
|
|
8
|
+
import './ImgSettingsButton.css';
|
|
9
|
+
const b = cn('img-settings-button');
|
|
10
|
+
export const ImgSettingsButton = function ({ node, view, updateAttributes, visible, edit, toggleEdit, nodeRef, unsetEdit, onDelete, }) {
|
|
12
11
|
const [popupOpen, setPopupOpen, unsetPopupOpen] = useBooleanState(false);
|
|
13
12
|
const placement = ['bottom-end', 'bottom-start'];
|
|
14
13
|
const buttonRef = useRef(null);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
React.createElement(Button, { onClick:
|
|
29
|
-
React.createElement(Icon, { data: Ellipsis })),
|
|
30
|
-
React.createElement(Popup, { open:
|
|
14
|
+
const handleEdit = () => {
|
|
15
|
+
toggleEdit();
|
|
16
|
+
unsetPopupOpen();
|
|
17
|
+
};
|
|
18
|
+
const isVisibleImageForm = edit;
|
|
19
|
+
const isVisibleEditButton = !edit && (visible || popupOpen);
|
|
20
|
+
const isVisiblePopup = !edit && popupOpen;
|
|
21
|
+
const handleEditButtonClick = (event) => {
|
|
22
|
+
event.preventDefault();
|
|
23
|
+
setPopupOpen();
|
|
24
|
+
};
|
|
25
|
+
return (React.createElement(React.Fragment, null,
|
|
26
|
+
isVisibleImageForm && (React.createElement(ImageForm, { node: node, view: view, updateAttributes: updateAttributes, dom: nodeRef, unsetEdit: unsetEdit })),
|
|
27
|
+
isVisibleEditButton && (React.createElement(Button, { onClick: handleEditButtonClick, ref: buttonRef, size: "s", view: 'raised', className: b() },
|
|
28
|
+
React.createElement(Icon, { data: Ellipsis }))),
|
|
29
|
+
React.createElement(Popup, { open: isVisiblePopup, anchorRef: buttonRef, onClose: unsetPopupOpen, placement: placement },
|
|
31
30
|
React.createElement(Menu, null,
|
|
32
|
-
React.createElement(Menu.Item, { onClick: ()
|
|
33
|
-
|
|
34
|
-
unsetPopupOpen();
|
|
35
|
-
} }, i18nCommon('edit')),
|
|
36
|
-
React.createElement(Menu.Item, { onClick: () => {
|
|
37
|
-
const pos = getPos();
|
|
38
|
-
if (pos === undefined)
|
|
39
|
-
return;
|
|
40
|
-
removeNode({
|
|
41
|
-
node,
|
|
42
|
-
pos,
|
|
43
|
-
tr: view.state.tr,
|
|
44
|
-
dispatch: view.dispatch,
|
|
45
|
-
});
|
|
46
|
-
view.focus();
|
|
47
|
-
} }, i18nCommon('delete')))))) : null;
|
|
31
|
+
React.createElement(Menu.Item, { onClick: handleEdit }, i18nCommon('edit')),
|
|
32
|
+
React.createElement(Menu.Item, { onClick: onDelete }, i18nCommon('delete'))))));
|
|
48
33
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { ReactNodeViewProps } from '../../../../../react-utils
|
|
2
|
+
import { ReactNodeViewProps } from '../../../../../react-utils';
|
|
3
3
|
import './ImgNodeView.css';
|
|
4
4
|
export declare const cnImgSizeNodeView: import("@bem-react/classname").ClassNameFormatter;
|
|
5
5
|
export declare const ImageNodeView: React.FC<ReactNodeViewProps>;
|
|
@@ -1,11 +1,69 @@
|
|
|
1
|
-
import React, { useRef } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
|
2
2
|
import { cn } from '../../../../../classname';
|
|
3
|
+
import { useNodeEditing, useNodeHovered } from '../../../../../react-utils';
|
|
4
|
+
import { useNodeResizing } from '../../../../../react-utils/useNodeResizing';
|
|
5
|
+
import { removeNode } from '../../../../../utils';
|
|
6
|
+
import { Resizable } from '../../../../behavior/Resizable/Resizable';
|
|
7
|
+
import { ImgSizeAttr } from '../../ImgSizeSpecs';
|
|
8
|
+
import { imageRendererKey } from '../../const';
|
|
3
9
|
import { ImgSettingsButton } from './ImgSettingsButton';
|
|
4
10
|
import './ImgNodeView.css';
|
|
5
11
|
export const cnImgSizeNodeView = cn('img-size-node-view');
|
|
6
12
|
export const ImageNodeView = ({ node, view, getPos, updateAttributes, }) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
const imageContainerRef = useRef(null);
|
|
14
|
+
const imageRef = useRef(null);
|
|
15
|
+
const alt = node.attrs[ImgSizeAttr.Alt] || '';
|
|
16
|
+
const initialHeight = node.attrs[ImgSizeAttr.Height];
|
|
17
|
+
const initialWidth = node.attrs[ImgSizeAttr.Width];
|
|
18
|
+
const src = node.attrs[ImgSizeAttr.Src] || '';
|
|
19
|
+
const title = node.attrs[ImgSizeAttr.Title] || '';
|
|
20
|
+
const isNodeHovered = useNodeHovered(imageContainerRef);
|
|
21
|
+
const [edit, setEditing, unsetEdit, toggleEdit] = useNodeEditing({
|
|
22
|
+
nodeRef: imageContainerRef,
|
|
23
|
+
view,
|
|
24
|
+
});
|
|
25
|
+
const handleResize = useCallback(({ width, height }) => {
|
|
26
|
+
updateAttributes({
|
|
27
|
+
width: width === undefined ? undefined : String(Math.round(width)),
|
|
28
|
+
height: height === undefined ? undefined : String(Math.round(height)),
|
|
29
|
+
name: title,
|
|
30
|
+
alt,
|
|
31
|
+
});
|
|
32
|
+
}, [alt, title, updateAttributes]);
|
|
33
|
+
const { state, startResizing } = useNodeResizing({
|
|
34
|
+
width: initialWidth,
|
|
35
|
+
height: initialHeight,
|
|
36
|
+
ref: imageRef,
|
|
37
|
+
onResize: handleResize,
|
|
38
|
+
});
|
|
39
|
+
const style = {
|
|
40
|
+
width: state.width ? `${state.width}px` : '',
|
|
41
|
+
height: state.height ? `${state.height}px` : '',
|
|
42
|
+
transition: 'width 0.15s ease-out, height 0.15s ease-out',
|
|
43
|
+
};
|
|
44
|
+
const handleDelete = useCallback(() => {
|
|
45
|
+
const pos = getPos();
|
|
46
|
+
if (pos === undefined)
|
|
47
|
+
return;
|
|
48
|
+
removeNode({
|
|
49
|
+
node,
|
|
50
|
+
pos,
|
|
51
|
+
tr: view.state.tr,
|
|
52
|
+
dispatch: view.dispatch,
|
|
53
|
+
});
|
|
54
|
+
view.focus();
|
|
55
|
+
}, [getPos, node, view]);
|
|
56
|
+
const createHandleResize = (direction) => (event) => {
|
|
57
|
+
startResizing(event, direction);
|
|
58
|
+
};
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
var _a;
|
|
61
|
+
if ((_a = imageRendererKey.getState(view.state)) === null || _a === void 0 ? void 0 : _a.linkAdded) {
|
|
62
|
+
setEditing();
|
|
63
|
+
}
|
|
64
|
+
}, [view, setEditing]);
|
|
65
|
+
return (React.createElement("div", { ref: imageContainerRef },
|
|
66
|
+
React.createElement(Resizable, { hover: isNodeHovered, resizing: state.resizing, onResizeLeft: createHandleResize('left'), onResizeRight: createHandleResize('right') },
|
|
67
|
+
React.createElement(ImgSettingsButton, { node: node, view: view, getPos: getPos, updateAttributes: updateAttributes, visible: isNodeHovered && !edit && !state.resizing, edit: edit, toggleEdit: toggleEdit, nodeRef: imageRef, onDelete: handleDelete, unsetEdit: unsetEdit }),
|
|
68
|
+
React.createElement("img", { ref: imageRef, src: src, alt: alt, style: style }))));
|
|
11
69
|
};
|
|
@@ -3,8 +3,9 @@ import { Ellipsis as DotsIcon } from '@gravity-ui/icons';
|
|
|
3
3
|
import { Button, Icon, Loader, Menu, Popup } from '@gravity-ui/uikit';
|
|
4
4
|
import { cn } from '../../../../classname';
|
|
5
5
|
import { TextAreaFixed as TextArea } from '../../../../forms/TextInput';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { i18n } from '../../../../i18n/common';
|
|
7
|
+
import { useBooleanState } from '../../../../react-utils';
|
|
8
|
+
import { removeNode } from '../../../../utils';
|
|
8
9
|
import { MermaidConsts } from '../MermaidSpecs/const';
|
|
9
10
|
export const cnMermaid = cn('Mermaid');
|
|
10
11
|
export const cnDiagramHelper = cn('MermaidHelper');
|
|
@@ -85,7 +86,7 @@ export const MermaidView = ({ onChange, node, getPos, view, getMermaidInstance }
|
|
|
85
86
|
React.createElement(Menu.Item, { onClick: () => {
|
|
86
87
|
toggleEditing();
|
|
87
88
|
toggleMenuOpen();
|
|
88
|
-
} },
|
|
89
|
+
} }, i18n('edit')),
|
|
89
90
|
React.createElement(Menu.Item, { onClick: () => {
|
|
90
91
|
const pos = getPos();
|
|
91
92
|
if (pos === undefined)
|
|
@@ -96,5 +97,5 @@ export const MermaidView = ({ onChange, node, getPos, view, getMermaidInstance }
|
|
|
96
97
|
tr: view.state.tr,
|
|
97
98
|
dispatch: view.dispatch,
|
|
98
99
|
});
|
|
99
|
-
} },
|
|
100
|
+
} }, i18n('remove')))))));
|
|
100
101
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const controlActions: Record<"deleteTable" | "
|
|
1
|
+
export declare const controlActions: Record<"deleteTable" | "deleteRow" | "deleteColumn" | "appendColumn" | "appendRow", import("../../../../../core").ActionSpec>;
|