@gravity-ui/markdown-editor 13.17.1 → 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.
Files changed (193) hide show
  1. package/README.md +2 -0
  2. package/build/cjs/bundle/config/action-names.d.ts +1 -1
  3. package/build/cjs/bundle/config/action-names.js +1 -0
  4. package/build/cjs/bundle/config/icons.d.ts +1 -1
  5. package/build/cjs/bundle/config/icons.js +3 -0
  6. package/build/cjs/bundle/config/wysiwyg.d.ts +1 -0
  7. package/build/cjs/bundle/config/wysiwyg.js +13 -1
  8. package/build/cjs/extensions/markdown/Table/actions/innerActions.d.ts +1 -1
  9. package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.css +18 -0
  10. package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.d.ts +8 -0
  11. package/build/cjs/extensions/yfm/GPT/ErrorScreen/ErrorScreen.js +21 -0
  12. package/build/cjs/extensions/yfm/GPT/ErrorScreen/types.d.ts +14 -0
  13. package/build/cjs/extensions/yfm/GPT/ErrorScreen/types.js +2 -0
  14. package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.css +75 -0
  15. package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.d.ts +28 -0
  16. package/build/cjs/extensions/yfm/GPT/GptDialog/GptDialog.js +102 -0
  17. package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.css +22 -0
  18. package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.d.ts +3 -0
  19. package/build/cjs/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.js +21 -0
  20. package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.d.ts +1 -0
  21. package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.js +5 -0
  22. package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.css +8 -0
  23. package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.d.ts +14 -0
  24. package/build/cjs/extensions/yfm/GPT/IconRefuge/IconRefuge.js +28 -0
  25. package/build/cjs/extensions/yfm/GPT/IconRefuge/index.d.ts +2 -0
  26. package/build/cjs/extensions/yfm/GPT/IconRefuge/index.js +5 -0
  27. package/build/cjs/extensions/yfm/GPT/PresetList/PresetList.d.ts +9 -0
  28. package/build/cjs/extensions/yfm/GPT/PresetList/PresetList.js +29 -0
  29. package/build/cjs/extensions/yfm/GPT/PresetList/Presetlist.css +6 -0
  30. package/build/cjs/extensions/yfm/GPT/actions.d.ts +2 -0
  31. package/build/cjs/extensions/yfm/GPT/actions.js +14 -0
  32. package/build/cjs/extensions/yfm/GPT/commands.d.ts +2 -0
  33. package/build/cjs/extensions/yfm/GPT/commands.js +13 -0
  34. package/build/cjs/extensions/yfm/GPT/constants.d.ts +13 -0
  35. package/build/cjs/extensions/yfm/GPT/constants.js +15 -0
  36. package/build/cjs/extensions/yfm/GPT/gptExtension/gptExtension.d.ts +13 -0
  37. package/build/cjs/extensions/yfm/GPT/gptExtension/gptExtension.js +18 -0
  38. package/build/cjs/extensions/yfm/GPT/gptExtension/view.css +17 -0
  39. package/build/cjs/extensions/yfm/GPT/gptExtension/view.d.ts +36 -0
  40. package/build/cjs/extensions/yfm/GPT/gptExtension/view.js +171 -0
  41. package/build/cjs/extensions/yfm/GPT/hooks/useGpt.d.ts +27 -0
  42. package/build/cjs/extensions/yfm/GPT/hooks/useGpt.js +148 -0
  43. package/build/cjs/extensions/yfm/GPT/hooks/useGptHotKeys.d.ts +2 -0
  44. package/build/cjs/extensions/yfm/GPT/hooks/useGptHotKeys.js +8 -0
  45. package/build/cjs/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.d.ts +13 -0
  46. package/build/cjs/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.js +70 -0
  47. package/build/cjs/extensions/yfm/GPT/hooks/usePresetList.d.ts +14 -0
  48. package/build/cjs/extensions/yfm/GPT/hooks/usePresetList.js +36 -0
  49. package/build/cjs/extensions/yfm/GPT/index.d.ts +2 -0
  50. package/build/cjs/extensions/yfm/GPT/index.js +5 -0
  51. package/build/cjs/extensions/yfm/GPT/plugin.d.ts +13 -0
  52. package/build/cjs/extensions/yfm/GPT/plugin.js +47 -0
  53. package/build/cjs/extensions/yfm/GPT/toolbar.d.ts +3 -0
  54. package/build/cjs/extensions/yfm/GPT/toolbar.js +22 -0
  55. package/build/cjs/extensions/yfm/GPT/utils.d.ts +13 -0
  56. package/build/cjs/extensions/yfm/GPT/utils.js +31 -0
  57. package/build/cjs/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.d.ts +1 -1
  58. package/build/cjs/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.js +0 -8
  59. package/build/cjs/extensions/yfm/index.d.ts +1 -0
  60. package/build/cjs/extensions/yfm/index.js +1 -0
  61. package/build/cjs/i18n/gpt/dialog/en.json +16 -0
  62. package/build/cjs/i18n/gpt/dialog/index.d.ts +19 -0
  63. package/build/cjs/i18n/gpt/dialog/index.js +8 -0
  64. package/build/cjs/i18n/gpt/dialog/ru.json +16 -0
  65. package/build/cjs/i18n/gpt/errors/en.json +5 -0
  66. package/build/cjs/i18n/gpt/errors/index.d.ts +8 -0
  67. package/build/cjs/i18n/gpt/errors/index.js +8 -0
  68. package/build/cjs/i18n/gpt/errors/ru.json +5 -0
  69. package/build/cjs/i18n/gpt/extension/en.json +6 -0
  70. package/build/cjs/i18n/gpt/extension/index.d.ts +9 -0
  71. package/build/cjs/i18n/gpt/extension/index.js +8 -0
  72. package/build/cjs/i18n/gpt/extension/ru.json +6 -0
  73. package/build/cjs/i18n/gpt/loading/en.json +3 -0
  74. package/build/cjs/i18n/gpt/loading/index.d.ts +6 -0
  75. package/build/cjs/i18n/gpt/loading/index.js +8 -0
  76. package/build/cjs/i18n/gpt/loading/ru.json +3 -0
  77. package/build/cjs/i18n/menubar/en.json +1 -0
  78. package/build/cjs/i18n/menubar/index.d.ts +2 -1
  79. package/build/cjs/i18n/menubar/ru.json +1 -0
  80. package/build/cjs/icons/GPT.d.ts +2 -0
  81. package/build/cjs/icons/GPT.js +22 -0
  82. package/build/cjs/icons/GPTLoading.d.ts +2 -0
  83. package/build/cjs/icons/GPTLoading.js +12 -0
  84. package/build/cjs/icons/index.d.ts +3 -1
  85. package/build/cjs/icons/index.js +5 -1
  86. package/build/cjs/react-utils/useAutoFocus.d.ts +1 -1
  87. package/build/cjs/react-utils/useAutoFocus.js +2 -2
  88. package/build/cjs/table-utils/commands/appendColumn.js +42 -33
  89. package/build/cjs/table-utils/commands/appendRow.js +40 -22
  90. package/build/cjs/table-utils/commands/removeColumn.js +18 -20
  91. package/build/cjs/table-utils/commands/removeRow.js +12 -9
  92. package/build/cjs/table-utils/table-desc.d.ts +53 -0
  93. package/build/cjs/table-utils/table-desc.js +149 -0
  94. package/build/cjs/table-utils/utils.d.ts +1 -1
  95. package/build/cjs/table-utils/utils.js +19 -12
  96. package/build/cjs/version.js +1 -1
  97. package/build/esm/bundle/config/action-names.d.ts +1 -1
  98. package/build/esm/bundle/config/action-names.js +1 -0
  99. package/build/esm/bundle/config/icons.d.ts +1 -1
  100. package/build/esm/bundle/config/icons.js +2 -0
  101. package/build/esm/bundle/config/wysiwyg.d.ts +1 -0
  102. package/build/esm/bundle/config/wysiwyg.js +12 -0
  103. package/build/esm/extensions/markdown/Table/actions/innerActions.d.ts +1 -1
  104. package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.css +18 -0
  105. package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.d.ts +9 -0
  106. package/build/esm/extensions/yfm/GPT/ErrorScreen/ErrorScreen.js +17 -0
  107. package/build/esm/extensions/yfm/GPT/ErrorScreen/types.d.ts +14 -0
  108. package/build/esm/extensions/yfm/GPT/ErrorScreen/types.js +1 -0
  109. package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.css +75 -0
  110. package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.d.ts +29 -0
  111. package/build/esm/extensions/yfm/GPT/GptDialog/GptDialog.js +98 -0
  112. package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.css +22 -0
  113. package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.d.ts +4 -0
  114. package/build/esm/extensions/yfm/GPT/GptDialog/LoadingScreen/LoadingScreen.js +17 -0
  115. package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.d.ts +1 -0
  116. package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.classname.js +2 -0
  117. package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.css +8 -0
  118. package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.d.ts +15 -0
  119. package/build/esm/extensions/yfm/GPT/IconRefuge/IconRefuge.js +25 -0
  120. package/build/esm/extensions/yfm/GPT/IconRefuge/index.d.ts +2 -0
  121. package/build/esm/extensions/yfm/GPT/IconRefuge/index.js +1 -0
  122. package/build/esm/extensions/yfm/GPT/PresetList/PresetList.d.ts +10 -0
  123. package/build/esm/extensions/yfm/GPT/PresetList/PresetList.js +25 -0
  124. package/build/esm/extensions/yfm/GPT/PresetList/Presetlist.css +6 -0
  125. package/build/esm/extensions/yfm/GPT/actions.d.ts +2 -0
  126. package/build/esm/extensions/yfm/GPT/actions.js +10 -0
  127. package/build/esm/extensions/yfm/GPT/commands.d.ts +2 -0
  128. package/build/esm/extensions/yfm/GPT/commands.js +9 -0
  129. package/build/esm/extensions/yfm/GPT/constants.d.ts +13 -0
  130. package/build/esm/extensions/yfm/GPT/constants.js +12 -0
  131. package/build/esm/extensions/yfm/GPT/gptExtension/gptExtension.d.ts +13 -0
  132. package/build/esm/extensions/yfm/GPT/gptExtension/gptExtension.js +14 -0
  133. package/build/esm/extensions/yfm/GPT/gptExtension/view.css +17 -0
  134. package/build/esm/extensions/yfm/GPT/gptExtension/view.d.ts +37 -0
  135. package/build/esm/extensions/yfm/GPT/gptExtension/view.js +167 -0
  136. package/build/esm/extensions/yfm/GPT/hooks/useGpt.d.ts +27 -0
  137. package/build/esm/extensions/yfm/GPT/hooks/useGpt.js +144 -0
  138. package/build/esm/extensions/yfm/GPT/hooks/useGptHotKeys.d.ts +2 -0
  139. package/build/esm/extensions/yfm/GPT/hooks/useGptHotKeys.js +4 -0
  140. package/build/esm/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.d.ts +13 -0
  141. package/build/esm/extensions/yfm/GPT/hooks/useOverflowingHorizontalItems.js +65 -0
  142. package/build/esm/extensions/yfm/GPT/hooks/usePresetList.d.ts +14 -0
  143. package/build/esm/extensions/yfm/GPT/hooks/usePresetList.js +32 -0
  144. package/build/esm/extensions/yfm/GPT/index.d.ts +2 -0
  145. package/build/esm/extensions/yfm/GPT/index.js +2 -0
  146. package/build/esm/extensions/yfm/GPT/plugin.d.ts +13 -0
  147. package/build/esm/extensions/yfm/GPT/plugin.js +43 -0
  148. package/build/esm/extensions/yfm/GPT/toolbar.d.ts +3 -0
  149. package/build/esm/extensions/yfm/GPT/toolbar.js +18 -0
  150. package/build/esm/extensions/yfm/GPT/utils.d.ts +13 -0
  151. package/build/esm/extensions/yfm/GPT/utils.js +23 -0
  152. package/build/esm/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.d.ts +1 -1
  153. package/build/esm/extensions/yfm/YfmTable/plugins/YfmTableControls/actions.js +1 -9
  154. package/build/esm/extensions/yfm/index.d.ts +1 -0
  155. package/build/esm/extensions/yfm/index.js +1 -0
  156. package/build/esm/i18n/gpt/dialog/en.json +16 -0
  157. package/build/esm/i18n/gpt/dialog/index.d.ts +19 -0
  158. package/build/esm/i18n/gpt/dialog/index.js +4 -0
  159. package/build/esm/i18n/gpt/dialog/ru.json +16 -0
  160. package/build/esm/i18n/gpt/errors/en.json +5 -0
  161. package/build/esm/i18n/gpt/errors/index.d.ts +8 -0
  162. package/build/esm/i18n/gpt/errors/index.js +4 -0
  163. package/build/esm/i18n/gpt/errors/ru.json +5 -0
  164. package/build/esm/i18n/gpt/extension/en.json +6 -0
  165. package/build/esm/i18n/gpt/extension/index.d.ts +9 -0
  166. package/build/esm/i18n/gpt/extension/index.js +4 -0
  167. package/build/esm/i18n/gpt/extension/ru.json +6 -0
  168. package/build/esm/i18n/gpt/loading/en.json +3 -0
  169. package/build/esm/i18n/gpt/loading/index.d.ts +6 -0
  170. package/build/esm/i18n/gpt/loading/index.js +4 -0
  171. package/build/esm/i18n/gpt/loading/ru.json +3 -0
  172. package/build/esm/i18n/menubar/en.json +1 -0
  173. package/build/esm/i18n/menubar/index.d.ts +2 -1
  174. package/build/esm/i18n/menubar/ru.json +1 -0
  175. package/build/esm/icons/GPT.d.ts +2 -0
  176. package/build/esm/icons/GPT.js +19 -0
  177. package/build/esm/icons/GPTLoading.d.ts +2 -0
  178. package/build/esm/icons/GPTLoading.js +9 -0
  179. package/build/esm/icons/index.d.ts +3 -1
  180. package/build/esm/icons/index.js +3 -1
  181. package/build/esm/react-utils/useAutoFocus.d.ts +1 -1
  182. package/build/esm/react-utils/useAutoFocus.js +2 -2
  183. package/build/esm/table-utils/commands/appendColumn.js +44 -35
  184. package/build/esm/table-utils/commands/appendRow.js +42 -24
  185. package/build/esm/table-utils/commands/removeColumn.js +18 -20
  186. package/build/esm/table-utils/commands/removeRow.js +14 -11
  187. package/build/esm/table-utils/table-desc.d.ts +53 -0
  188. package/build/esm/table-utils/table-desc.js +144 -0
  189. package/build/esm/table-utils/utils.d.ts +1 -1
  190. package/build/esm/table-utils/utils.js +18 -12
  191. package/build/esm/version.js +1 -1
  192. package/build/styles.css +146 -0
  193. package/package.json +2 -1
@@ -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,2 @@
1
+ import type { Options } from 'react-hotkeys-hook';
2
+ export declare function useGptHotKeys(key: string, callback: () => void, options?: Options, dependencies?: unknown[]): void;
@@ -0,0 +1,4 @@
1
+ import { useHotkeys } from 'react-hotkeys-hook';
2
+ export function useGptHotKeys(key, callback, options = {}, dependencies) {
3
+ useHotkeys(key, callback, Object.assign({ preventDefault: true }, options), dependencies);
4
+ }
@@ -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,2 @@
1
+ export * from './toolbar';
2
+ export * from './gptExtension/gptExtension';
@@ -0,0 +1,2 @@
1
+ export * from './toolbar';
2
+ export * from './gptExtension/gptExtension';
@@ -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,3 @@
1
+ import { type WToolbarSingleItemData } from '../../../toolbar';
2
+ export declare const cnGptButton: import("@bem-react/classname").ClassNameFormatter;
3
+ export declare const wGptToolbarItem: WToolbarSingleItemData;
@@ -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 +1 @@
1
- export declare const controlActions: Record<"deleteTable" | "addRow" | "deleteRow" | "addColumn" | "deleteColumn" | "appendColumn" | "appendRow", import("../../../../../core").ActionSpec>;
1
+ export declare const controlActions: Record<"deleteTable" | "deleteRow" | "deleteColumn" | "appendColumn" | "appendRow", import("../../../../../core").ActionSpec>;
@@ -1,4 +1,4 @@
1
- import { addColumnAfter, addRowAfter, appendColumn, appendRow, removeColumn, removeRow, } from '../../../../../table-utils';
1
+ import { appendColumn, appendRow, removeColumn, removeRow } from '../../../../../table-utils';
2
2
  import { defineActions } from '../../../../../utils/actions';
3
3
  import { removeNode } from '../../../../../utils/remove-node';
4
4
  import { tableControlsPluginKey } from './buttons';
@@ -20,18 +20,10 @@ const removeYfmTable = (state, dispatch, _, attrs) => {
20
20
  return true;
21
21
  };
22
22
  export const controlActions = defineActions({
23
- addRow: {
24
- isEnable: addRowAfter,
25
- run: addRowAfter,
26
- },
27
23
  deleteRow: {
28
24
  isEnable: removeRow,
29
25
  run: removeRow,
30
26
  },
31
- addColumn: {
32
- isEnable: addColumnAfter,
33
- run: addColumnAfter,
34
- },
35
27
  deleteColumn: {
36
28
  isEnable: removeColumn,
37
29
  run: removeColumn,
@@ -11,3 +11,4 @@ export * from './YfmHeading';
11
11
  export * from './YfmNote';
12
12
  export * from './YfmTable';
13
13
  export * from './YfmTabs';
14
+ export * from './GPT';
@@ -11,3 +11,4 @@ export * from './YfmHeading';
11
11
  export * from './YfmNote';
12
12
  export * from './YfmTable';
13
13
  export * from './YfmTabs';
14
+ export * from './GPT';
@@ -0,0 +1,16 @@
1
+ {
2
+ "answer-title": "What do you want to do with the response?",
3
+ "close-button": "Close",
4
+ "dislike": "Bad response",
5
+ "error": "An error occurred",
6
+ "feedback-message": "Thanks for your feedback!",
7
+ "fresh-start-button": "Start again",
8
+ "like": "Good response",
9
+ "more": "More",
10
+ "only-presets-title": "Help with text",
11
+ "refetch": "Try again",
12
+ "replace": "Replace the selected text",
13
+ "replace-disabled": "Insert text",
14
+ "try-again": "Try again",
15
+ "alert-gpt-presets-info": "Highlight text to see Yandex GPT presets"
16
+ }
@@ -0,0 +1,19 @@
1
+ export declare const i18n: <G extends "error" | "replace" | "answer-title" | "close-button" | "dislike" | "feedback-message" | "fresh-start-button" | "like" | "more" | "only-presets-title" | "refetch" | "replace-disabled" | "try-again" | "alert-gpt-presets-info", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ "answer-title": string;
5
+ "close-button": string;
6
+ dislike: string;
7
+ error: string;
8
+ "feedback-message": string;
9
+ "fresh-start-button": string;
10
+ like: string;
11
+ more: string;
12
+ "only-presets-title": string;
13
+ refetch: string;
14
+ replace: string;
15
+ "replace-disabled": string;
16
+ "try-again": string;
17
+ "alert-gpt-presets-info": string;
18
+ }[G] : string;
19
+ export declare type I18nKey = Parameters<typeof i18n>[0];
@@ -0,0 +1,4 @@
1
+ import { registerKeyset } from '../../i18n';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ export const i18n = registerKeyset('gpt-dialog', { en, ru });
@@ -0,0 +1,16 @@
1
+ {
2
+ "answer-title": "Что вы хотите сделать с ответом?",
3
+ "close-button": "Закрыть",
4
+ "dislike": "Плохой ответ",
5
+ "error": "Произошла ошибка",
6
+ "feedback-message": "Ваш голос учтён!",
7
+ "fresh-start-button": "Начать сначала",
8
+ "like": "Хороший ответ",
9
+ "more": "Ещё",
10
+ "only-presets-title": "Помощь с текстом",
11
+ "refetch": "Попробовать ещё",
12
+ "replace": "Заменить выделенный текст",
13
+ "replace-disabled": "Вставить текст",
14
+ "try-again": "Иначе",
15
+ "alert-gpt-presets-info": "Выделите текст, чтобы увидеть пресеты Yandex GPT"
16
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "error-text": "An error occurred while generating a reply, please retry the request",
3
+ "retry-button": "Try again",
4
+ "start-again-button": "To the beginning"
5
+ }
@@ -0,0 +1,8 @@
1
+ export declare const i18n: <G extends "error-text" | "retry-button" | "start-again-button", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ "error-text": string;
5
+ "retry-button": string;
6
+ "start-again-button": string;
7
+ }[G] : string;
8
+ export declare type I18nKey = Parameters<typeof i18n>[0];
@@ -0,0 +1,4 @@
1
+ import { registerKeyset } from '../../i18n';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ export const i18n = registerKeyset('gpt-dialog-error-screen', { en, ru });
@@ -0,0 +1,5 @@
1
+ {
2
+ "error-text": "Ошибка при генерации ответа, попробуйте повторить запрос",
3
+ "retry-button": "Повторить",
4
+ "start-again-button": "В начало"
5
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "confirm-cancel": "Cancel",
3
+ "confirm-ok": "Close",
4
+ "confirm-title": "Do you want to close the GPT editor?",
5
+ "help-with-text": "Help with text"
6
+ }
@@ -0,0 +1,9 @@
1
+ export declare const i18n: <G extends "confirm-cancel" | "confirm-ok" | "confirm-title" | "help-with-text", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ "confirm-cancel": string;
5
+ "confirm-ok": string;
6
+ "confirm-title": string;
7
+ "help-with-text": string;
8
+ }[G] : string;
9
+ export declare type I18nKey = Parameters<typeof i18n>[0];
@@ -0,0 +1,4 @@
1
+ import { registerKeyset } from '../../i18n';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ export const i18n = registerKeyset('gpt', { en, ru });
@@ -0,0 +1,6 @@
1
+ {
2
+ "confirm-cancel": "Отменить",
3
+ "confirm-ok": "Закрыть",
4
+ "confirm-title": "Хотите закрыть помощника GPT?",
5
+ "help-with-text": "Помощь с текстом"
6
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "loading-text": "GPT is generating a response..."
3
+ }
@@ -0,0 +1,6 @@
1
+ export declare const i18n: <G extends "loading-text", S extends string>(key: G | (string extends S ? S : never), params?: {
2
+ [key: string]: any;
3
+ } | undefined) => S extends G ? {
4
+ "loading-text": string;
5
+ }[G] : string;
6
+ export declare type I18nKey = Parameters<typeof i18n>[0];
@@ -0,0 +1,4 @@
1
+ import { registerKeyset } from '../../i18n';
2
+ import en from './en.json';
3
+ import ru from './ru.json';
4
+ export const i18n = registerKeyset('gpt-dialog-loading-screen', { en, ru });
@@ -0,0 +1,3 @@
1
+ {
2
+ "loading-text": "GPT генерирует ответ..."
3
+ }
@@ -19,6 +19,7 @@
19
19
  "file": "File",
20
20
  "folding-heading": "Collapsed section",
21
21
  "folding-heading_hint": "The text under the heading can be collapsed or expanded",
22
+ "gpt": "GPT widget",
22
23
  "heading": "Heading",
23
24
  "heading1": "Heading 1",
24
25
  "heading2": "Heading 2",
@@ -1,4 +1,4 @@
1
- export declare const i18n: <G extends "bold" | "code" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "colorify" | "mono" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "heading" | "note" | "file" | "codeblock" | "checkbox" | "emoji" | "list" | "tabs" | "math" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "undo" | "redo" | "math_inline" | "math_block" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "folding-heading" | "folding-heading_hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "mermaid" | "more_action" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
1
+ export declare const i18n: <G extends "bold" | "code" | "link" | "italic" | "strike" | "underline" | "mark" | "quote" | "colorify" | "mono" | "text" | "html" | "cut" | "table" | "image" | "code_inline" | "heading" | "note" | "file" | "codeblock" | "checkbox" | "emoji" | "list" | "tabs" | "math" | "heading1" | "heading2" | "heading3" | "heading4" | "heading5" | "heading6" | "gpt" | "undo" | "redo" | "math_inline" | "math_block" | "colorify__color_blue" | "colorify__color_default" | "colorify__color_gray" | "colorify__color_green" | "colorify__color_orange" | "colorify__color_red" | "colorify__color_violet" | "colorify__color_yellow" | "colorify__group_text" | "folding-heading" | "folding-heading_hint" | "hrule" | "list__action_lift" | "list__action_sink" | "list_action_disabled" | "mermaid" | "more_action" | "olist" | "ulist", S extends string>(key: G | (string extends S ? S : never), params?: {
2
2
  [key: string]: any;
3
3
  } | undefined) => S extends G ? {
4
4
  bold: string;
@@ -21,6 +21,7 @@ export declare const i18n: <G extends "bold" | "code" | "link" | "italic" | "str
21
21
  file: string;
22
22
  "folding-heading": string;
23
23
  "folding-heading_hint": string;
24
+ gpt: string;
24
25
  heading: string;
25
26
  heading1: string;
26
27
  heading2: string;
@@ -19,6 +19,7 @@
19
19
  "file": "Файл",
20
20
  "folding-heading": "Свёрнутый раздел",
21
21
  "folding-heading_hint": "Текст под заголовком можно свернуть или раскрыть",
22
+ "gpt": "GPT-виджет",
22
23
  "heading": "Заголовок",
23
24
  "heading1": "Заголовок 1",
24
25
  "heading2": "Заголовок 2",