@docyrus/ui-pro-ai-assistant 0.0.2 → 0.0.3

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 (307) hide show
  1. package/package.json +2 -3
  2. package/src/components/assistant-animations.tsx +0 -29
  3. package/src/components/assistant-dialogs.tsx +0 -235
  4. package/src/components/code-view.tsx +0 -278
  5. package/src/components/create-agent-task.tsx +0 -104
  6. package/src/components/create-new-work-version.tsx +0 -30
  7. package/src/components/extract-web.tsx +0 -160
  8. package/src/components/forward-to-agent.tsx +0 -90
  9. package/src/components/generate-chart.tsx +0 -101
  10. package/src/components/generative-action-button.tsx +0 -122
  11. package/src/components/generative-tool.tsx +0 -685
  12. package/src/components/generative-ui-object.tsx +0 -210
  13. package/src/components/input-area.tsx +0 -1209
  14. package/src/components/json-schema-layout.tsx +0 -326
  15. package/src/components/list-item-card.tsx +0 -92
  16. package/src/components/mermaid-diagram.tsx +0 -192
  17. package/src/components/preview-image.tsx +0 -47
  18. package/src/components/request-approval.tsx +0 -48
  19. package/src/components/request-user-input.tsx +0 -270
  20. package/src/components/search-web.tsx +0 -319
  21. package/src/components/sheet-command.tsx +0 -88
  22. package/src/components/shell-canvas.tsx +0 -122
  23. package/src/components/show-advanced-data-table.tsx +0 -352
  24. package/src/components/show-generated-content-options.tsx +0 -93
  25. package/src/components/show-people-cards.tsx +0 -180
  26. package/src/components/subagent-tool.tsx +0 -180
  27. package/src/components/text-editor-tool.tsx +0 -328
  28. package/src/components/work-canvas.tsx +0 -88
  29. package/src/components/work-card.tsx +0 -42
  30. package/src/declarations.d.ts +0 -1
  31. package/src/docy-assistant.tsx +0 -1962
  32. package/src/hooks/index.ts +0 -7
  33. package/src/hooks/use-assistant-api.ts +0 -507
  34. package/src/hooks/use-deployment-data.ts +0 -162
  35. package/src/hooks/use-project-state.ts +0 -347
  36. package/src/hooks/use-session-state.ts +0 -207
  37. package/src/hooks/use-speech-recognition.ts +0 -137
  38. package/src/hooks/use-ui-state.ts +0 -185
  39. package/src/hooks/use-works-state.ts +0 -146
  40. package/src/i18n/context.tsx +0 -253
  41. package/src/i18n/index.ts +0 -19
  42. package/src/i18n/locales/de.json +0 -198
  43. package/src/i18n/locales/el.json +0 -198
  44. package/src/i18n/locales/en.json +0 -226
  45. package/src/i18n/locales/es.json +0 -198
  46. package/src/i18n/locales/fr.json +0 -198
  47. package/src/i18n/locales/it.json +0 -198
  48. package/src/i18n/locales/pt.json +0 -198
  49. package/src/i18n/locales/sl.json +0 -198
  50. package/src/i18n/locales/tr.json +0 -211
  51. package/src/i18n/types.ts +0 -23
  52. package/src/i18n/use-translation.ts +0 -17
  53. package/src/index.ts +0 -18
  54. package/src/internal/plate-editor/editor/auth-context.ts +0 -11
  55. package/src/internal/plate-editor/editor/editor-base-kit.tsx +0 -39
  56. package/src/internal/plate-editor/editor/editor-kit.tsx +0 -89
  57. package/src/internal/plate-editor/editor/plate-editor.tsx +0 -75
  58. package/src/internal/plate-editor/editor/plate-types.ts +0 -126
  59. package/src/internal/plate-editor/editor/plugins/ai-kit.tsx +0 -172
  60. package/src/internal/plate-editor/editor/plugins/autoformat-kit.tsx +0 -211
  61. package/src/internal/plate-editor/editor/plugins/basic-blocks-base-kit.tsx +0 -26
  62. package/src/internal/plate-editor/editor/plugins/basic-blocks-kit.tsx +0 -51
  63. package/src/internal/plate-editor/editor/plugins/basic-marks-base-kit.tsx +0 -24
  64. package/src/internal/plate-editor/editor/plugins/basic-marks-kit.tsx +0 -38
  65. package/src/internal/plate-editor/editor/plugins/basic-nodes-kit.tsx +0 -6
  66. package/src/internal/plate-editor/editor/plugins/block-menu-kit.tsx +0 -14
  67. package/src/internal/plate-editor/editor/plugins/block-placeholder-kit.tsx +0 -17
  68. package/src/internal/plate-editor/editor/plugins/block-selection-kit.tsx +0 -31
  69. package/src/internal/plate-editor/editor/plugins/callout-base-kit.tsx +0 -5
  70. package/src/internal/plate-editor/editor/plugins/callout-kit.tsx +0 -7
  71. package/src/internal/plate-editor/editor/plugins/code-block-base-kit.tsx +0 -23
  72. package/src/internal/plate-editor/editor/plugins/code-block-kit.tsx +0 -26
  73. package/src/internal/plate-editor/editor/plugins/column-base-kit.tsx +0 -8
  74. package/src/internal/plate-editor/editor/plugins/column-kit.tsx +0 -7
  75. package/src/internal/plate-editor/editor/plugins/comment-base-kit.tsx +0 -5
  76. package/src/internal/plate-editor/editor/plugins/comment-kit.tsx +0 -174
  77. package/src/internal/plate-editor/editor/plugins/copilot-kit.tsx +0 -68
  78. package/src/internal/plate-editor/editor/plugins/cursor-overlay-kit.tsx +0 -13
  79. package/src/internal/plate-editor/editor/plugins/date-base-kit.tsx +0 -5
  80. package/src/internal/plate-editor/editor/plugins/date-kit.tsx +0 -7
  81. package/src/internal/plate-editor/editor/plugins/discussion-kit.tsx +0 -36
  82. package/src/internal/plate-editor/editor/plugins/dnd-kit.tsx +0 -27
  83. package/src/internal/plate-editor/editor/plugins/docx-export-kit.tsx +0 -43
  84. package/src/internal/plate-editor/editor/plugins/docx-kit.tsx +0 -6
  85. package/src/internal/plate-editor/editor/plugins/emoji-kit.tsx +0 -15
  86. package/src/internal/plate-editor/editor/plugins/exit-break-kit.tsx +0 -12
  87. package/src/internal/plate-editor/editor/plugins/floating-toolbar-kit.tsx +0 -19
  88. package/src/internal/plate-editor/editor/plugins/font-base-kit.tsx +0 -36
  89. package/src/internal/plate-editor/editor/plugins/font-kit.tsx +0 -47
  90. package/src/internal/plate-editor/editor/plugins/indent-base-kit.tsx +0 -19
  91. package/src/internal/plate-editor/editor/plugins/indent-kit.tsx +0 -22
  92. package/src/internal/plate-editor/editor/plugins/link-base-kit.tsx +0 -5
  93. package/src/internal/plate-editor/editor/plugins/link-kit.tsx +0 -35
  94. package/src/internal/plate-editor/editor/plugins/list-base-kit.tsx +0 -24
  95. package/src/internal/plate-editor/editor/plugins/list-kit.tsx +0 -27
  96. package/src/internal/plate-editor/editor/plugins/markdown-kit.tsx +0 -18
  97. package/src/internal/plate-editor/editor/plugins/math-base-kit.tsx +0 -8
  98. package/src/internal/plate-editor/editor/plugins/math-kit.tsx +0 -10
  99. package/src/internal/plate-editor/editor/plugins/media-base-kit.tsx +0 -37
  100. package/src/internal/plate-editor/editor/plugins/media-kit.tsx +0 -53
  101. package/src/internal/plate-editor/editor/plugins/mention-base-kit.tsx +0 -5
  102. package/src/internal/plate-editor/editor/plugins/mention-kit.tsx +0 -36
  103. package/src/internal/plate-editor/editor/plugins/slash-kit.tsx +0 -17
  104. package/src/internal/plate-editor/editor/plugins/suggestion-base-kit.tsx +0 -5
  105. package/src/internal/plate-editor/editor/plugins/suggestion-kit.tsx +0 -95
  106. package/src/internal/plate-editor/editor/plugins/table-base-kit.tsx +0 -20
  107. package/src/internal/plate-editor/editor/plugins/table-kit.tsx +0 -22
  108. package/src/internal/plate-editor/editor/plugins/toc-base-kit.tsx +0 -5
  109. package/src/internal/plate-editor/editor/plugins/toc-kit.tsx +0 -14
  110. package/src/internal/plate-editor/editor/plugins/toggle-base-kit.tsx +0 -5
  111. package/src/internal/plate-editor/editor/plugins/toggle-kit.tsx +0 -9
  112. package/src/internal/plate-editor/editor/transforms.ts +0 -165
  113. package/src/internal/plate-editor/editor/use-chat.ts +0 -152
  114. package/src/internal/plate-editor/hooks/index.ts +0 -3
  115. package/src/internal/plate-editor/hooks/use-copy-to-clipboard.ts +0 -31
  116. package/src/internal/plate-editor/hooks/use-is-touch-device.ts +0 -26
  117. package/src/internal/plate-editor/hooks/use-lock-scroll.ts +0 -21
  118. package/src/internal/plate-editor/hooks/use-media-query.ts +0 -44
  119. package/src/internal/plate-editor/hooks/use-mounted.ts +0 -18
  120. package/src/internal/plate-editor/hooks/use-on-click-outside.ts +0 -114
  121. package/src/internal/plate-editor/hooks/use-upload-file.ts +0 -81
  122. package/src/internal/plate-editor/i18n/context.tsx +0 -58
  123. package/src/internal/plate-editor/i18n/index.ts +0 -3
  124. package/src/internal/plate-editor/i18n/locales/de.json +0 -57
  125. package/src/internal/plate-editor/i18n/locales/el.json +0 -57
  126. package/src/internal/plate-editor/i18n/locales/en.json +0 -57
  127. package/src/internal/plate-editor/i18n/locales/es.json +0 -57
  128. package/src/internal/plate-editor/i18n/locales/fr.json +0 -57
  129. package/src/internal/plate-editor/i18n/locales/it.json +0 -57
  130. package/src/internal/plate-editor/i18n/locales/pt.json +0 -57
  131. package/src/internal/plate-editor/i18n/locales/sl.json +0 -57
  132. package/src/internal/plate-editor/i18n/locales/tr.json +0 -57
  133. package/src/internal/plate-editor/i18n/types.ts +0 -59
  134. package/src/internal/plate-editor/i18n/use-translation.ts +0 -22
  135. package/src/internal/plate-editor/index.ts +0 -39
  136. package/src/internal/plate-editor/lib/ai-output-converter.ts +0 -153
  137. package/src/internal/plate-editor/lib/download-file.ts +0 -17
  138. package/src/internal/plate-editor/plate-ui/ai-chat-editor.tsx +0 -24
  139. package/src/internal/plate-editor/plate-ui/ai-menu.tsx +0 -828
  140. package/src/internal/plate-editor/plate-ui/ai-node.tsx +0 -41
  141. package/src/internal/plate-editor/plate-ui/ai-toolbar-button.tsx +0 -25
  142. package/src/internal/plate-editor/plate-ui/alert-dialog.tsx +0 -145
  143. package/src/internal/plate-editor/plate-ui/align-toolbar-button.tsx +0 -88
  144. package/src/internal/plate-editor/plate-ui/avatar.tsx +0 -3
  145. package/src/internal/plate-editor/plate-ui/block-context-menu.tsx +0 -104
  146. package/src/internal/plate-editor/plate-ui/block-discussion.tsx +0 -364
  147. package/src/internal/plate-editor/plate-ui/block-draggable.tsx +0 -557
  148. package/src/internal/plate-editor/plate-ui/block-list-static.tsx +0 -77
  149. package/src/internal/plate-editor/plate-ui/block-list.tsx +0 -85
  150. package/src/internal/plate-editor/plate-ui/block-menu.tsx +0 -555
  151. package/src/internal/plate-editor/plate-ui/block-selection.tsx +0 -47
  152. package/src/internal/plate-editor/plate-ui/block-suggestion.tsx +0 -469
  153. package/src/internal/plate-editor/plate-ui/blockquote-node-static.tsx +0 -10
  154. package/src/internal/plate-editor/plate-ui/blockquote-node.tsx +0 -11
  155. package/src/internal/plate-editor/plate-ui/button.tsx +0 -201
  156. package/src/internal/plate-editor/plate-ui/calendar.tsx +0 -3
  157. package/src/internal/plate-editor/plate-ui/callout-node-static.tsx +0 -76
  158. package/src/internal/plate-editor/plate-ui/callout-node.tsx +0 -54
  159. package/src/internal/plate-editor/plate-ui/caption.tsx +0 -47
  160. package/src/internal/plate-editor/plate-ui/checkbox.tsx +0 -3
  161. package/src/internal/plate-editor/plate-ui/code-block-node-static.tsx +0 -172
  162. package/src/internal/plate-editor/plate-ui/code-block-node.tsx +0 -226
  163. package/src/internal/plate-editor/plate-ui/code-node-static.tsx +0 -11
  164. package/src/internal/plate-editor/plate-ui/code-node.tsx +0 -12
  165. package/src/internal/plate-editor/plate-ui/column-node-static.tsx +0 -65
  166. package/src/internal/plate-editor/plate-ui/column-node.tsx +0 -24
  167. package/src/internal/plate-editor/plate-ui/command.tsx +0 -202
  168. package/src/internal/plate-editor/plate-ui/comment-node-static.tsx +0 -12
  169. package/src/internal/plate-editor/plate-ui/comment-node.tsx +0 -45
  170. package/src/internal/plate-editor/plate-ui/comment-toolbar-button.tsx +0 -24
  171. package/src/internal/plate-editor/plate-ui/comment.tsx +0 -619
  172. package/src/internal/plate-editor/plate-ui/cursor-overlay.tsx +0 -85
  173. package/src/internal/plate-editor/plate-ui/date-node-static.tsx +0 -43
  174. package/src/internal/plate-editor/plate-ui/date-node.tsx +0 -54
  175. package/src/internal/plate-editor/plate-ui/dialog.tsx +0 -445
  176. package/src/internal/plate-editor/plate-ui/dropdown-menu.tsx +0 -264
  177. package/src/internal/plate-editor/plate-ui/editor-static.tsx +0 -40
  178. package/src/internal/plate-editor/plate-ui/editor.tsx +0 -146
  179. package/src/internal/plate-editor/plate-ui/emoji-node.tsx +0 -48
  180. package/src/internal/plate-editor/plate-ui/emoji-toolbar-button.tsx +0 -626
  181. package/src/internal/plate-editor/plate-ui/equation-node-static.tsx +0 -155
  182. package/src/internal/plate-editor/plate-ui/equation-node.tsx +0 -226
  183. package/src/internal/plate-editor/plate-ui/equation-toolbar-button.tsx +0 -26
  184. package/src/internal/plate-editor/plate-ui/export-toolbar-button.tsx +0 -206
  185. package/src/internal/plate-editor/plate-ui/fixed-toolbar-buttons.tsx +0 -157
  186. package/src/internal/plate-editor/plate-ui/fixed-toolbar.tsx +0 -25
  187. package/src/internal/plate-editor/plate-ui/floating-discussion.tsx +0 -1129
  188. package/src/internal/plate-editor/plate-ui/floating-toolbar-buttons.tsx +0 -129
  189. package/src/internal/plate-editor/plate-ui/floating-toolbar.tsx +0 -97
  190. package/src/internal/plate-editor/plate-ui/font-color-toolbar-button.tsx +0 -209
  191. package/src/internal/plate-editor/plate-ui/font-size-toolbar-button.tsx +0 -152
  192. package/src/internal/plate-editor/plate-ui/ghost-text.tsx +0 -20
  193. package/src/internal/plate-editor/plate-ui/heading-node-static.tsx +0 -52
  194. package/src/internal/plate-editor/plate-ui/heading-node.tsx +0 -56
  195. package/src/internal/plate-editor/plate-ui/highlight-node-static.tsx +0 -9
  196. package/src/internal/plate-editor/plate-ui/highlight-node.tsx +0 -11
  197. package/src/internal/plate-editor/plate-ui/history-toolbar-button.tsx +0 -50
  198. package/src/internal/plate-editor/plate-ui/hover-card.tsx +0 -7
  199. package/src/internal/plate-editor/plate-ui/hr-node-static.tsx +0 -18
  200. package/src/internal/plate-editor/plate-ui/hr-node.tsx +0 -28
  201. package/src/internal/plate-editor/plate-ui/import-toolbar-button.tsx +0 -122
  202. package/src/internal/plate-editor/plate-ui/indent-toolbar-button.tsx +0 -32
  203. package/src/internal/plate-editor/plate-ui/inline-combobox.tsx +0 -409
  204. package/src/internal/plate-editor/plate-ui/input.tsx +0 -37
  205. package/src/internal/plate-editor/plate-ui/insert-toolbar-button.tsx +0 -258
  206. package/src/internal/plate-editor/plate-ui/label.tsx +0 -1
  207. package/src/internal/plate-editor/plate-ui/line-height-toolbar-button.tsx +0 -69
  208. package/src/internal/plate-editor/plate-ui/link-node-static.tsx +0 -15
  209. package/src/internal/plate-editor/plate-ui/link-node.tsx +0 -33
  210. package/src/internal/plate-editor/plate-ui/link-toolbar-button.tsx +0 -28
  211. package/src/internal/plate-editor/plate-ui/link-toolbar.tsx +0 -147
  212. package/src/internal/plate-editor/plate-ui/list-toolbar-button.tsx +0 -177
  213. package/src/internal/plate-editor/plate-ui/mark-toolbar-button.tsx +0 -34
  214. package/src/internal/plate-editor/plate-ui/media-audio-node-static.tsx +0 -21
  215. package/src/internal/plate-editor/plate-ui/media-audio-node.tsx +0 -32
  216. package/src/internal/plate-editor/plate-ui/media-embed-node.tsx +0 -103
  217. package/src/internal/plate-editor/plate-ui/media-file-node-static.tsx +0 -30
  218. package/src/internal/plate-editor/plate-ui/media-file-node.tsx +0 -52
  219. package/src/internal/plate-editor/plate-ui/media-image-node-static.tsx +0 -37
  220. package/src/internal/plate-editor/plate-ui/media-image-node.tsx +0 -183
  221. package/src/internal/plate-editor/plate-ui/media-placeholder-node.tsx +0 -441
  222. package/src/internal/plate-editor/plate-ui/media-preview-dialog.tsx +0 -127
  223. package/src/internal/plate-editor/plate-ui/media-toolbar-button.tsx +0 -227
  224. package/src/internal/plate-editor/plate-ui/media-toolbar.tsx +0 -214
  225. package/src/internal/plate-editor/plate-ui/media-upload-toast.tsx +0 -73
  226. package/src/internal/plate-editor/plate-ui/media-video-node-static.tsx +0 -35
  227. package/src/internal/plate-editor/plate-ui/media-video-node.tsx +0 -119
  228. package/src/internal/plate-editor/plate-ui/mention-node-static.tsx +0 -46
  229. package/src/internal/plate-editor/plate-ui/mention-node.tsx +0 -79
  230. package/src/internal/plate-editor/plate-ui/menu.tsx +0 -539
  231. package/src/internal/plate-editor/plate-ui/mode-toolbar-button.tsx +0 -124
  232. package/src/internal/plate-editor/plate-ui/more-toolbar-button.tsx +0 -34
  233. package/src/internal/plate-editor/plate-ui/paragraph-node-static.tsx +0 -15
  234. package/src/internal/plate-editor/plate-ui/paragraph-node.tsx +0 -16
  235. package/src/internal/plate-editor/plate-ui/popover.tsx +0 -75
  236. package/src/internal/plate-editor/plate-ui/progress.tsx +0 -1
  237. package/src/internal/plate-editor/plate-ui/remote-cursor-overlay.tsx +0 -79
  238. package/src/internal/plate-editor/plate-ui/resize-handle.tsx +0 -86
  239. package/src/internal/plate-editor/plate-ui/separator.tsx +0 -41
  240. package/src/internal/plate-editor/plate-ui/slash-node.tsx +0 -433
  241. package/src/internal/plate-editor/plate-ui/spinner.tsx +0 -1
  242. package/src/internal/plate-editor/plate-ui/suggestion-node-static.tsx +0 -35
  243. package/src/internal/plate-editor/plate-ui/suggestion-node.tsx +0 -166
  244. package/src/internal/plate-editor/plate-ui/suggestion-toolbar-button.tsx +0 -24
  245. package/src/internal/plate-editor/plate-ui/table-node-static.tsx +0 -84
  246. package/src/internal/plate-editor/plate-ui/table-node.tsx +0 -283
  247. package/src/internal/plate-editor/plate-ui/table-toolbar-button.tsx +0 -252
  248. package/src/internal/plate-editor/plate-ui/tabs.tsx +0 -3
  249. package/src/internal/plate-editor/plate-ui/textarea.tsx +0 -57
  250. package/src/internal/plate-editor/plate-ui/toc-node-static.tsx +0 -142
  251. package/src/internal/plate-editor/plate-ui/toc-node.tsx +0 -57
  252. package/src/internal/plate-editor/plate-ui/toc-sidebar.tsx +0 -48
  253. package/src/internal/plate-editor/plate-ui/toggle-node-static.tsx +0 -18
  254. package/src/internal/plate-editor/plate-ui/toggle-node.tsx +0 -33
  255. package/src/internal/plate-editor/plate-ui/toggle-toolbar-button.tsx +0 -24
  256. package/src/internal/plate-editor/plate-ui/toggle.tsx +0 -3
  257. package/src/internal/plate-editor/plate-ui/toolbar.tsx +0 -378
  258. package/src/internal/plate-editor/plate-ui/tooltip.tsx +0 -148
  259. package/src/internal/plate-editor/plate-ui/turn-into-toolbar-button.tsx +0 -175
  260. package/src/internal/plate-editor/types/index.ts +0 -22
  261. package/src/internal/plate-editor/vite.ts +0 -284
  262. package/src/internal/sheets/components/univer-sheets.tsx +0 -1104
  263. package/src/internal/sheets/i18n/context.tsx +0 -183
  264. package/src/internal/sheets/i18n/index.ts +0 -19
  265. package/src/internal/sheets/i18n/locales/de.json +0 -21
  266. package/src/internal/sheets/i18n/locales/el.json +0 -21
  267. package/src/internal/sheets/i18n/locales/en.json +0 -21
  268. package/src/internal/sheets/i18n/locales/es.json +0 -21
  269. package/src/internal/sheets/i18n/locales/fr.json +0 -21
  270. package/src/internal/sheets/i18n/locales/it.json +0 -21
  271. package/src/internal/sheets/i18n/locales/pt.json +0 -21
  272. package/src/internal/sheets/i18n/locales/sl.json +0 -21
  273. package/src/internal/sheets/i18n/locales/tr.json +0 -21
  274. package/src/internal/sheets/i18n/types.ts +0 -23
  275. package/src/internal/sheets/i18n/use-translation.ts +0 -17
  276. package/src/internal/sheets/index.ts +0 -14
  277. package/src/internal/sheets/types/css.d.ts +0 -11
  278. package/src/internal/sheets/types/index.ts +0 -260
  279. package/src/internal/sheets/xlsx.ts +0 -1169
  280. package/src/lib/api-client.ts +0 -77
  281. package/src/lib/assistant-api-actions.ts +0 -549
  282. package/src/lib/assistant-config.tsx +0 -75
  283. package/src/lib/class-utils.ts +0 -40
  284. package/src/lib/index.ts +0 -7
  285. package/src/lib/message-utils.ts +0 -131
  286. package/src/tools/tools-schema.json +0 -512
  287. package/src/types/index.ts +0 -235
  288. package/src/views/assistant-view.tsx +0 -1137
  289. package/src/views/canvas-app.tsx +0 -839
  290. package/src/views/canvas-code.tsx +0 -93
  291. package/src/views/canvas-deep-research.tsx +0 -44
  292. package/src/views/canvas-image.tsx +0 -25
  293. package/src/views/canvas-record-view.tsx +0 -285
  294. package/src/views/canvas-spreadsheet.tsx +0 -125
  295. package/src/views/canvas-text.tsx +0 -52
  296. package/src/views/canvas.tsx +0 -274
  297. package/src/views/chat-panel.tsx +0 -149
  298. package/src/views/index.ts +0 -20
  299. package/src/views/memories-panel.tsx +0 -365
  300. package/src/views/message-list.tsx +0 -370
  301. package/src/views/project-detail.tsx +0 -257
  302. package/src/views/projects-panel.tsx +0 -131
  303. package/src/views/sessions-list.tsx +0 -98
  304. package/src/views/sidebar-content.tsx +0 -256
  305. package/src/views/work-detail.tsx +0 -98
  306. package/src/vite.ts +0 -64
  307. package/src/worker.ts +0 -203
@@ -1,828 +0,0 @@
1
- 'use client';
2
-
3
- import {
4
- useCallback, useEffect, useLayoutEffect, useMemo, useState, type ComponentType, type ReactNode
5
- } from 'react';
6
-
7
- import {
8
- AIChatPlugin,
9
- AIPlugin,
10
- useEditorChat,
11
- useLastAssistantMessage
12
- } from '@platejs/ai/react';
13
- import { BlockSelectionPlugin, useIsSelecting } from '@platejs/selection/react';
14
- import { getTransientSuggestionKey } from '@platejs/suggestion';
15
- import {
16
- AlbumIcon,
17
- ArrowUpIcon,
18
- BadgeHelpIcon,
19
- CheckIcon,
20
- CornerUpLeftIcon,
21
- FeatherIcon,
22
- LanguagesIcon,
23
- ListEnd,
24
- ListMinusIcon,
25
- ListPlusIcon,
26
- PenLineIcon,
27
- Wand,
28
- X
29
- } from 'lucide-react';
30
- import {
31
- isHotkey, KEYS, NodeApi, RangeApi, type NodeEntry
32
- } from 'platejs';
33
- import {
34
- type PlateEditor,
35
- useEditorPlugin,
36
- useEditorRef,
37
- useHotkeys,
38
- usePluginOption
39
- } from 'platejs/react';
40
-
41
- import { cn } from '@docyrus/ui-pro-shared/lib/utils';
42
-
43
- import { AIChatEditor } from './ai-chat-editor';
44
- import { Button } from './button';
45
- import {
46
- type Action,
47
- ComboboxContent,
48
- ComboboxInput,
49
- ComboboxList,
50
- filterMenuGroups,
51
- filterMenuItems,
52
- Menu,
53
- MenuContent,
54
- MenuGroup,
55
- MenuItem,
56
- MenuTrigger,
57
- useComboboxValueState,
58
- useMenuStore
59
- } from './menu';
60
- import { TextareaAutosize } from './textarea';
61
-
62
- /**
63
- * Returns the selected text when using a text selection (not block selection).
64
- * Returns null if block selection is active, selection is collapsed, or no editor selection.
65
- */
66
- function getSelectedText(editor: PlateEditor): string | null {
67
- // Block selection active — this is not a text selection
68
- const blockSelectedNodes = editor
69
- .getApi(BlockSelectionPlugin)
70
- .blockSelection.getNodes();
71
-
72
- if (blockSelectedNodes.length > 0) return null;
73
-
74
- const { selection } = editor;
75
-
76
- if (!selection || RangeApi.isCollapsed(selection)) return null;
77
-
78
- try {
79
- return editor.api.string(selection) || null;
80
- } catch {
81
- return null;
82
- }
83
- }
84
-
85
- export function AIMenu() {
86
- const { api, editor } = useEditorPlugin(AIChatPlugin);
87
- const open = usePluginOption(AIChatPlugin, 'open');
88
- const mode = usePluginOption(AIChatPlugin, 'mode');
89
- const isSelecting = useIsSelecting();
90
- const streaming = usePluginOption(AIChatPlugin, 'streaming');
91
-
92
- const [input, setInput] = useState('');
93
- const toolName = usePluginOption(AIChatPlugin, 'toolName');
94
- const chat = usePluginOption(AIChatPlugin, 'chat');
95
-
96
- const { messages, status } = chat;
97
-
98
- /*
99
- * Determine toolName for free-form custom input.
100
- * Our backend does not emit `data-toolName` events like the reference OpenAI
101
- * implementation, so toolName would stay null and nothing would render.
102
- * We pick the tool based on selection state — the same heuristic the reference
103
- * project's AI would choose in the vast majority of cases.
104
- */
105
- const handleSubmit = useCallback(
106
- (inputText: string) => {
107
- if (!inputText.trim()) return;
108
-
109
- // Follow-up messages: keep the existing toolName Plate.js already set.
110
- if (messages.length > 0) {
111
- void api.aiChat.submit(inputText);
112
- } else if (isSelecting) {
113
- // Text / block is selected → user wants to edit it.
114
- void api.aiChat.submit(inputText, { toolName: 'edit' });
115
- } else {
116
- // Cursor only → user wants to generate / insert new content.
117
- void api.aiChat.submit(inputText, {
118
- mode: 'insert',
119
- toolName: 'generate'
120
- });
121
- }
122
-
123
- setInput('');
124
- },
125
- [api, isSelecting, messages.length]
126
- );
127
-
128
- const isLoading = status === 'streaming' || status === 'submitted';
129
-
130
- const content = useLastAssistantMessage()?.parts.find(
131
- part => part.type === 'text'
132
- )?.text;
133
-
134
- const { show, store } = useMenuStore();
135
-
136
- useEffect(() => {
137
- if (streaming) {
138
- const anchor = api.aiChat.node({ anchor: true });
139
-
140
- setTimeout(() => {
141
- const anchorDom = editor.api.toDOMNode(anchor![0])!;
142
-
143
- store.setAnchorElement(anchorDom);
144
- }, 0);
145
- }
146
- // eslint-disable-next-line react-hooks/exhaustive-deps
147
- }, [streaming]);
148
-
149
- useEditorChat({
150
- chat,
151
- onOpenBlockSelection: (blocks: NodeEntry[]) => {
152
- show(editor.api.toDOMNode(blocks.at(-1)![0])!);
153
- },
154
- onOpenChange: (open) => {
155
- if (!open) {
156
- // Don't close when window loses focus (tab switch, alt-tab)
157
- if (document.hidden) return;
158
-
159
- store.hideAll();
160
- setInput('');
161
- }
162
- },
163
- onOpenCursor: () => {
164
- const [ancestor] = editor.api.block({ highest: true })!;
165
-
166
- if (!editor.api.isAt({ end: true }) && !editor.api.isEmpty(ancestor)) {
167
- editor
168
- .getApi(BlockSelectionPlugin)
169
- .blockSelection.set(ancestor.id as string);
170
- }
171
-
172
- show(editor.api.toDOMNode(ancestor)!);
173
- },
174
- onOpenSelection: () => {
175
- show(editor.api.toDOMNode(editor.api.blocks().at(-1)![0])!);
176
- }
177
- });
178
-
179
- useHotkeys('escape', () => {
180
- if (isLoading) {
181
- api.aiChat.stop();
182
- } else {
183
- api.aiChat.hide();
184
- }
185
- });
186
-
187
- useLayoutEffect(() => {
188
- if (toolName === 'edit' && mode === 'chat' && status === 'ready') {
189
- let anchorNode = editor.api.node({
190
- at: [],
191
- reverse: true,
192
- match: (n: Record<string, unknown>) => !!n[KEYS.suggestion] && !!n[getTransientSuggestionKey()]
193
- });
194
-
195
- if (!anchorNode) {
196
- anchorNode = editor
197
- .getApi(BlockSelectionPlugin)
198
- .blockSelection.getNodes({ selectionFallback: true, sort: true })
199
- .at(-1);
200
- }
201
- if (!anchorNode) return;
202
-
203
- // BUG
204
- setTimeout(() => {
205
- const block = editor.api.block({ at: anchorNode[1] });
206
- const domNode = editor.api.toDOMNode(block![0]!)!;
207
-
208
- store.setAnchorElement(domNode);
209
- }, 0);
210
- }
211
-
212
- // eslint-disable-next-line react-hooks/exhaustive-deps
213
- }, [status]);
214
-
215
- useEffect(() => {
216
- if (status === 'ready') {
217
- setInput('');
218
- }
219
- }, [status]);
220
-
221
- if (toolName === 'comment' && status === 'ready') return null;
222
-
223
- return (
224
- <Menu open={open} placement="bottom-start" store={store}>
225
- <MenuContent
226
- flip={false}
227
- onClickOutside={() => {
228
- api.aiChat.hide();
229
- }}
230
- variant="ai"
231
- wrapperProps={{
232
- /*
233
- * FIXME: It is best to set it to 100.
234
- * But it will cause a horizontal scrollbar to appear.
235
- * A method should be found to disable translate-x.
236
- */
237
- className: 'w-[98%]!'
238
- }}>
239
- <ComboboxContent variant="ai">
240
- {mode === 'chat'
241
- && isSelecting
242
- && content
243
- && toolName === 'generate' && <AIChatEditor content={content} />}
244
-
245
- <div className="flex gap-1.5 px-3 text-sm">
246
- {isLoading ? (
247
- <div className="flex grow select-none items-center gap-2 py-2 text-muted-foreground">
248
- {messages.length > 1 ? 'Editing' : 'Thinking'}
249
-
250
- <LoadingIcon />
251
- </div>
252
- ) : (
253
- <AIMenuCombobox
254
- input={input}
255
- onSubmit={handleSubmit}
256
- setInput={setInput} />
257
- )}
258
-
259
- <Button
260
- className="no-focus-ring mt-1 shrink-0"
261
- disabled={!isLoading && input.trim().length === 0}
262
- onClick={() => {
263
- if (isLoading) {
264
- api.aiChat.stop();
265
- } else {
266
- handleSubmit(input);
267
- }
268
- }}
269
- size="iconSm"
270
- variant="ghost">
271
- {isLoading ? <StopIcon /> : <SubmitIcon />}
272
- </Button>
273
- </div>
274
- </ComboboxContent>
275
-
276
- {!isLoading && (
277
- <ComboboxList
278
- className={cn('[&_.menu-item-icon]:text-purple-700')}
279
- variant="ai">
280
- <AIMenuItems input={input} setInput={setInput} store={store} />
281
- </ComboboxList>
282
- )}
283
- </MenuContent>
284
- </Menu>
285
- );
286
- }
287
-
288
- type EditorChatState
289
- = | 'cursorCommand'
290
- | 'cursorSuggestion'
291
- | 'selectionCommand'
292
- | 'selectionSuggestion';
293
-
294
- const GROUP = {
295
- LANGUAGES: 'group_languages',
296
- SELECTION_LANGUAGES: 'group_selection_languages'
297
- } as const;
298
-
299
- const aiChatItems = {
300
- accept: {
301
- icon: <CheckIcon />,
302
- label: 'Accept',
303
- value: 'accept',
304
- onSelect: ({ aiEditor, editor }) => {
305
- const { mode, toolName } = editor.getOptions(AIChatPlugin);
306
-
307
- if (mode === 'chat' && toolName === 'generate') {
308
- return editor
309
- .getTransforms(AIChatPlugin)
310
- .aiChat.replaceSelection(aiEditor);
311
- }
312
-
313
- editor.getTransforms(AIChatPlugin).aiChat.accept();
314
- setTimeout(() => {
315
- editor.tf.focus({ edge: 'end' });
316
- }, 0);
317
- }
318
- },
319
- continueWrite: {
320
- icon: <PenLineIcon />,
321
- label: 'Continue writing',
322
- value: 'continueWrite',
323
- onSelect: ({ editor, input }) => {
324
- const ancestorNode = editor.api.block({ highest: true });
325
-
326
- if (!ancestorNode) return;
327
-
328
- const isEmpty = NodeApi.string(ancestorNode[0]).trim().length === 0;
329
-
330
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
331
- mode: 'insert',
332
- prompt: isEmpty ? `<Document>
333
- {editor}
334
- </Document>
335
- Start writing a new paragraph AFTER <Document> ONLY ONE SENTENCE` : 'Continue writing AFTER <Block> ONLY ONE SENTENCE. DONT REPEAT THE TEXT.',
336
- toolName: 'generate'
337
- });
338
- }
339
- },
340
- discard: {
341
- icon: <X />,
342
- label: 'Discard',
343
- shortcut: 'Escape',
344
- value: 'discard',
345
- onSelect: ({ editor }) => {
346
- editor.getTransforms(AIPlugin).ai.undo();
347
- editor.getApi(AIChatPlugin).aiChat.hide();
348
- }
349
- },
350
- explain: {
351
- icon: <BadgeHelpIcon />,
352
- label: 'Explain',
353
- value: 'explain',
354
- onSelect: ({ editor, input }) => {
355
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
356
- prompt: {
357
- default: 'Explain {editor}',
358
- selecting: 'Explain'
359
- },
360
- toolName: 'generate'
361
- });
362
- }
363
- },
364
- fixSpelling: {
365
- icon: <CheckIcon />,
366
- label: 'Fix spelling & grammar',
367
- value: 'fixSpelling',
368
- onSelect: ({ editor, input }) => {
369
- const selectedText = getSelectedText(editor);
370
-
371
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
372
- prompt: selectedText ? `Fix spelling, grammar, and punctuation errors only in this selected text: "${selectedText}". Do not modify any other part of the content.` : 'Fix spelling, grammar, and punctuation errors within each block only, without changing meaning, tone, or adding new information.',
373
- toolName: 'edit'
374
- });
375
- }
376
- },
377
- [GROUP.LANGUAGES]: {
378
- component: TranslateMenuItems,
379
- filterItems: true,
380
- icon: <LanguagesIcon className="text-green-800" />,
381
- items: [
382
- { label: 'English', value: 'translate_english' },
383
- { label: 'Korean', value: 'translate_korean' },
384
- {
385
- label: 'Chinese, Simplified',
386
- value: 'translate_chinese_simplified'
387
- },
388
- {
389
- label: 'Chinese, Traditional',
390
- value: 'translate_chinese_traditional'
391
- },
392
- { label: 'Japanese', value: 'translate_japanese' },
393
- { label: 'Spanish', value: 'translate_spanish' },
394
- { label: 'Russian', value: 'translate_russian' },
395
- { label: 'French', value: 'translate_french' },
396
- { label: 'Portuguese', value: 'translate_portuguese' },
397
- { label: 'German', value: 'translate_german' },
398
- { label: 'Italian', value: 'translate_italian' },
399
- { label: 'Dutch', value: 'translate_dutch' },
400
- { label: 'Indonesian', value: 'translate_indonesian' },
401
- { label: 'Filipino', value: 'translate_filipino' },
402
- { label: 'Vietnamese', value: 'translate_vietnamese' },
403
- { label: 'Turkish', value: 'translate_turkish' },
404
- { label: 'Arabic', value: 'translate_arabic' }
405
- ],
406
- label: 'Languages',
407
- value: GROUP.LANGUAGES
408
- },
409
- [GROUP.SELECTION_LANGUAGES]: {
410
- component: TranslateMenuItems,
411
- filterItems: true,
412
- icon: <LanguagesIcon className="text-green-800" />,
413
- items: [
414
- { label: 'English', value: 'translate_english' },
415
- { label: 'Korean', value: 'translate_korean' },
416
- {
417
- label: 'Chinese, Simplified',
418
- value: 'translate_chinese_simplified'
419
- },
420
- {
421
- label: 'Chinese, Traditional',
422
- value: 'translate_chinese_traditional'
423
- },
424
- { label: 'Japanese', value: 'translate_japanese' },
425
- { label: 'Spanish', value: 'translate_spanish' },
426
- { label: 'Russian', value: 'translate_russian' },
427
- { label: 'French', value: 'translate_french' },
428
- { label: 'Portuguese', value: 'translate_portuguese' },
429
- { label: 'German', value: 'translate_german' },
430
- { label: 'Italian', value: 'translate_italian' },
431
- { label: 'Dutch', value: 'translate_dutch' },
432
- { label: 'Indonesian', value: 'translate_indonesian' },
433
- { label: 'Filipino', value: 'translate_filipino' },
434
- { label: 'Vietnamese', value: 'translate_vietnamese' },
435
- { label: 'Turkish', value: 'translate_turkish' },
436
- { label: 'Arabic', value: 'translate_arabic' }
437
- ],
438
- label: 'Languages',
439
- value: GROUP.LANGUAGES
440
- },
441
- improveWriting: {
442
- icon: <Wand />,
443
- label: 'Improve writing',
444
- value: 'improveWriting',
445
- onSelect: ({ editor, input }) => {
446
- const selectedText = getSelectedText(editor);
447
-
448
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
449
- prompt: selectedText ? `Improve the writing of this selected text only: "${selectedText}". Do not modify any other part of the content.` : 'Improve the writing for clarity and flow, without changing meaning or adding new information.',
450
- toolName: 'edit'
451
- });
452
- }
453
- },
454
- insertBelow: {
455
- icon: <ListEnd />,
456
- label: 'Insert below',
457
- value: 'insertBelow',
458
- onSelect: ({ aiEditor, editor }) => {
459
- const { selectedIds } = editor.getOptions(BlockSelectionPlugin);
460
-
461
- if (!selectedIds || selectedIds.size === 0) {
462
- const { chatNodes } = editor.getOptions(AIChatPlugin);
463
-
464
- if (chatNodes && chatNodes.length > 0) {
465
- const ids = chatNodes
466
- .map(n => n.id)
467
- .filter((id): id is string => typeof id === 'string');
468
-
469
- if (ids.length > 0) {
470
- editor.setOption(BlockSelectionPlugin, 'selectedIds', new Set(ids));
471
- }
472
- }
473
- }
474
-
475
- void editor
476
- .getTransforms(AIChatPlugin)
477
- .aiChat.insertBelow(aiEditor, { format: 'none' });
478
- }
479
- },
480
- makeLonger: {
481
- icon: <ListPlusIcon />,
482
- label: 'Make longer',
483
- value: 'makeLonger',
484
- onSelect: ({ editor, input }) => {
485
- const selectedText = getSelectedText(editor);
486
-
487
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
488
- prompt: selectedText ? `Make this selected text longer by elaborating on existing ideas: "${selectedText}". Do not modify any other part of the content.` : 'Make the content longer by elaborating on existing ideas within each block only, without changing meaning or adding new information.',
489
- toolName: 'edit'
490
- });
491
- }
492
- },
493
- makeShorter: {
494
- icon: <ListMinusIcon />,
495
- label: 'Make shorter',
496
- value: 'makeShorter',
497
- onSelect: ({ editor, input }) => {
498
- const selectedText = getSelectedText(editor);
499
-
500
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
501
- prompt: selectedText ? `Make this selected text shorter by reducing verbosity: "${selectedText}". Do not modify any other part of the content.` : 'Make the content shorter by reducing verbosity within each block only, without changing meaning or removing essential information.',
502
- toolName: 'edit'
503
- });
504
- }
505
- },
506
- simplifyLanguage: {
507
- icon: <FeatherIcon />,
508
- label: 'Simplify language',
509
- value: 'simplifyLanguage',
510
- onSelect: ({ editor, input }) => {
511
- const selectedText = getSelectedText(editor);
512
-
513
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
514
- prompt: selectedText ? `Simplify the language of this selected text only: "${selectedText}". Do not modify any other part of the content.` : 'Simplify the language by using clearer and more straightforward wording within each block only, without changing meaning or adding new information.',
515
- toolName: 'edit'
516
- });
517
- }
518
- },
519
- summarize: {
520
- icon: <AlbumIcon />,
521
- label: 'Add a summary',
522
- value: 'summarize',
523
- onSelect: ({ editor, input }) => {
524
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
525
- mode: 'insert',
526
- prompt: {
527
- default: 'Summarize {editor}',
528
- selecting: 'Summarize'
529
- },
530
- toolName: 'generate'
531
- });
532
- }
533
- },
534
- tryAgain: {
535
- icon: <CornerUpLeftIcon />,
536
- label: 'Try again',
537
- value: 'tryAgain',
538
- onSelect: ({ editor, store }) => {
539
- void editor.getApi(AIChatPlugin).aiChat.reload();
540
-
541
- setTimeout(() => {
542
- const anchor = editor
543
- .getApi(BlockSelectionPlugin)
544
- .blockSelection.getNodes({ selectionFallback: true, sort: true })
545
- .at(-1)!;
546
- const anchorDom = editor.api.toDOMNode(anchor[0])!;
547
-
548
- store.setAnchorElement(anchorDom);
549
- }, 0);
550
- }
551
- }
552
- } satisfies Record<
553
- string,
554
- {
555
- icon: ReactNode;
556
- label: string;
557
- value: string;
558
- component?: ComponentType<{ menuState: EditorChatState; input?: string }>;
559
- filterItems?: boolean;
560
- items?: { label: string; value: string }[];
561
- shortcut?: string;
562
- onSelect?: ({
563
- aiEditor,
564
- editor,
565
- input,
566
- store
567
- }: {
568
- aiEditor: PlateEditor;
569
- editor: PlateEditor;
570
- input: string;
571
- store: any;
572
- }) => void;
573
- }
574
- >;
575
-
576
- const menuStateItems = {
577
- cursorCommand: [
578
- {
579
- items: [aiChatItems.continueWrite, aiChatItems.summarize, aiChatItems.explain]
580
- }
581
- ],
582
- cursorSuggestion: [
583
- {
584
- items: [aiChatItems.accept, aiChatItems.discard, aiChatItems.tryAgain]
585
- }
586
- ],
587
- selectionCommand: [
588
- {
589
- items: [
590
- aiChatItems.improveWriting,
591
- aiChatItems.makeLonger,
592
- aiChatItems.makeShorter,
593
- aiChatItems.fixSpelling,
594
- aiChatItems.simplifyLanguage
595
- ]
596
- },
597
- {
598
- items: [aiChatItems[GROUP.SELECTION_LANGUAGES]]
599
- }
600
- ],
601
- selectionSuggestion: [
602
- {
603
- items: [
604
- aiChatItems.accept,
605
- aiChatItems.discard,
606
- aiChatItems.insertBelow,
607
- aiChatItems.tryAgain
608
- ]
609
- }
610
- ]
611
- };
612
-
613
- function AIMenuItems({
614
- input,
615
- setInput,
616
- store
617
- }: {
618
- input: string;
619
- store: any;
620
- setInput: (value: string) => void;
621
- }) {
622
- const editor = useEditorRef();
623
- const [searchValue] = useComboboxValueState();
624
- const { messages } = usePluginOption(AIChatPlugin, 'chat');
625
- const aiEditor = usePluginOption(AIChatPlugin, 'aiEditor')!;
626
- const isSelecting = useIsSelecting();
627
-
628
- const menuState = useMemo(() => {
629
- if (messages && messages.length > 0) {
630
- return isSelecting ? 'selectionSuggestion' : 'cursorSuggestion';
631
- }
632
-
633
- return isSelecting ? 'selectionCommand' : 'cursorCommand';
634
- }, [isSelecting, messages]);
635
-
636
- const menuGroups = useMemo(() => {
637
- const items = menuStateItems[menuState] || [];
638
-
639
- return filterMenuGroups(items, searchValue) || items;
640
- }, [menuState, searchValue]);
641
-
642
- return (
643
- <>
644
- {menuGroups.map((group, index) => (
645
- <MenuGroup key={index} label={group.label}>
646
- {group.items?.map((item: Action) => {
647
- const menuItem = (aiChatItems as any)[item.value!];
648
-
649
- if (menuItem.component) {
650
- const ItemComponent = menuItem.component;
651
-
652
- return (
653
- <ItemComponent
654
- input={input}
655
- key={item.value}
656
- menuState={menuState} />
657
- );
658
- }
659
-
660
- return (
661
- <MenuItem
662
- icon={menuItem.icon}
663
- key={item.value}
664
- label={menuItem.label}
665
- onClick={() => {
666
- menuItem.onSelect?.({
667
- aiEditor, editor, input, store
668
- });
669
- setInput('');
670
- }}
671
- shortcutEnter />
672
- );
673
- })}
674
- </MenuGroup>
675
- ))}
676
- </>
677
- );
678
- }
679
-
680
- function TranslateMenuItems({
681
- input = '',
682
- menuState
683
- }: {
684
- menuState: EditorChatState;
685
- input?: string;
686
- }) {
687
- const editor = useEditorRef();
688
- const [searchValue] = useComboboxValueState();
689
-
690
- const menuItems = useMemo(
691
- () => filterMenuItems(aiChatItems[GROUP.LANGUAGES], searchValue),
692
- [searchValue]
693
- );
694
-
695
- const handleTranslate = (value: string) => {
696
- if (menuState === 'cursorCommand') {
697
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
698
- mode: 'insert',
699
- prompt: `Translate to ${value} the "Block" content`,
700
- toolName: 'edit'
701
- });
702
-
703
- return;
704
- }
705
- if (menuState === 'selectionCommand') {
706
- void editor.getApi(AIChatPlugin).aiChat.submit(input, {
707
- prompt: `Translate to ${value}`,
708
- toolName: 'edit'
709
- });
710
-
711
- return;
712
- }
713
- };
714
-
715
- const content = (
716
- <>
717
- {menuItems.map(item => (
718
- <MenuItem
719
- icon={item.icon}
720
- key={item.value}
721
- label={item.label}
722
- onClick={() => handleTranslate(item.label!)}
723
- shortcutEnter />
724
- ))}
725
- </>
726
- );
727
-
728
- if (searchValue)
729
- return (
730
- <MenuGroup label={aiChatItems[GROUP.LANGUAGES].label}>
731
- {content}
732
- </MenuGroup>
733
- );
734
-
735
- return (
736
- <Menu
737
- trigger={
738
- <MenuTrigger
739
- icon={aiChatItems[GROUP.LANGUAGES].icon}
740
- label={aiChatItems[GROUP.LANGUAGES].label} />
741
- }>
742
- <MenuContent variant="aiSub">
743
- <MenuGroup>{content}</MenuGroup>
744
- </MenuContent>
745
- </Menu>
746
- );
747
- }
748
-
749
- function AIMenuCombobox({
750
- input,
751
- onSubmit,
752
- setInput
753
- }: {
754
- input: string;
755
- onSubmit: (value: string) => void;
756
- setInput: (value: string) => void;
757
- }) {
758
- const { api } = useEditorPlugin(AIChatPlugin);
759
- const [, setValue] = useComboboxValueState();
760
-
761
- useEffect(() => {
762
- setValue(input ?? '');
763
- }, [input, setValue]);
764
-
765
- return (
766
- <ComboboxInput autoFocus autoSelect="always">
767
- <TextareaAutosize
768
- className="grow"
769
- data-plate-focus
770
- onChange={e => setInput(e.target.value)}
771
- onKeyDown={(e) => {
772
- if (isHotkey('backspace')(e) && input?.length === 0) {
773
- e.preventDefault();
774
- api.aiChat.hide();
775
- }
776
- if (isHotkey('enter')(e) && !e.shiftKey) {
777
- e.preventDefault();
778
-
779
- if (input && input.length > 0) {
780
- onSubmit(input);
781
- }
782
- }
783
- }}
784
- placeholder="Ask AI anything..."
785
- variant="ai" />
786
- </ComboboxInput>
787
- );
788
- }
789
-
790
- function StopIcon() {
791
- return (
792
- <svg
793
- height="20"
794
- viewBox="0 0 20 20"
795
- width="20"
796
- xmlns="http://www.w3.org/2000/svg">
797
- <circle cx="10" cy="10" fill="black" r="10" />
798
- <rect fill="white" height="6" rx="1" width="6" x="7" y="7" />
799
- </svg>
800
- );
801
- }
802
-
803
- function SubmitIcon() {
804
- return (
805
- <div
806
- className={cn(
807
- 'flex size-5 items-center justify-center rounded-full bg-brand'
808
- )}>
809
- <ArrowUpIcon className="size-3! stroke-[3px] text-background" />
810
- </div>
811
- );
812
- }
813
-
814
- function LoadingIcon() {
815
- return (
816
- <div className="flex gap-0.5">
817
- {['#eab308', '#ea580c', '#6EB6F2'].map((color, index) => (
818
- <div
819
- className="size-1 animate-ai-bounce rounded-full"
820
- key={color}
821
- style={{
822
- animationDelay: `${index * 0.1}s`,
823
- backgroundColor: color
824
- }} />
825
- ))}
826
- </div>
827
- );
828
- }