@ai-stack/payloadcms 3.76.0-beta.0 → 3.76.0-beta.2

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 (349) hide show
  1. package/dist/ai/core/generateObject.js +1 -4
  2. package/dist/ai/core/generateObject.js.map +1 -1
  3. package/dist/ai/core/generateText.js +1 -5
  4. package/dist/ai/core/generateText.js.map +1 -1
  5. package/dist/ai/core/media/generateMedia.js +1 -4
  6. package/dist/ai/core/media/generateMedia.js.map +1 -1
  7. package/dist/ai/core/media/image/generateImage.js +4 -14
  8. package/dist/ai/core/media/image/generateImage.js.map +1 -1
  9. package/dist/ai/core/media/image/handlers/multimodal.js +21 -58
  10. package/dist/ai/core/media/image/handlers/multimodal.js.map +1 -1
  11. package/dist/ai/core/media/image/handlers/standard.js +17 -9
  12. package/dist/ai/core/media/image/handlers/standard.js.map +1 -1
  13. package/dist/ai/core/media/speech/generateSpeech.js +10 -11
  14. package/dist/ai/core/media/speech/generateSpeech.js.map +1 -1
  15. package/dist/ai/core/media/types.d.ts +3 -4
  16. package/dist/ai/core/media/types.js.map +1 -1
  17. package/dist/ai/core/streamObject.js +0 -3
  18. package/dist/ai/core/streamObject.js.map +1 -1
  19. package/dist/ai/core/streamText.js +1 -4
  20. package/dist/ai/core/streamText.js.map +1 -1
  21. package/dist/ai/core/types.d.ts +2 -2
  22. package/dist/ai/core/types.js.map +1 -1
  23. package/dist/ai/providers/blocks/anthropic.js +0 -42
  24. package/dist/ai/providers/blocks/anthropic.js.map +1 -1
  25. package/dist/ai/providers/blocks/elevenlabs.js +1 -106
  26. package/dist/ai/providers/blocks/elevenlabs.js.map +1 -1
  27. package/dist/ai/providers/blocks/fal.js +0 -118
  28. package/dist/ai/providers/blocks/fal.js.map +1 -1
  29. package/dist/ai/providers/blocks/google.js +2 -236
  30. package/dist/ai/providers/blocks/google.js.map +1 -1
  31. package/dist/ai/providers/blocks/openai-compatible.js +0 -144
  32. package/dist/ai/providers/blocks/openai-compatible.js.map +1 -1
  33. package/dist/ai/providers/blocks/openai.js +0 -200
  34. package/dist/ai/providers/blocks/openai.js.map +1 -1
  35. package/dist/ai/providers/blocks/xai.js +0 -53
  36. package/dist/ai/providers/blocks/xai.js.map +1 -1
  37. package/dist/ai/providers/index.d.ts +1 -1
  38. package/dist/ai/providers/index.js +0 -2
  39. package/dist/ai/providers/index.js.map +1 -1
  40. package/dist/ai/providers/registry.d.ts +24 -28
  41. package/dist/ai/providers/registry.js +186 -140
  42. package/dist/ai/providers/registry.js.map +1 -1
  43. package/dist/ai/providers/types.d.ts +12 -33
  44. package/dist/ai/providers/types.js +0 -1
  45. package/dist/ai/providers/types.js.map +1 -1
  46. package/dist/ai/schemas/lexicalJsonSchema.js +1 -1
  47. package/dist/ai/schemas/lexicalJsonSchema.js.map +1 -1
  48. package/dist/ai/utilities/filterEditorSchemaByNodes.js.map +1 -0
  49. package/dist/ai/utilities/generateFileNameByPrompt.js.map +1 -0
  50. package/dist/ai/utilities/isObjectSchema.js.map +1 -0
  51. package/dist/ai/utilities/nodeToSchemaMap.js.map +1 -0
  52. package/dist/ai/{prompts.d.ts → utilities/prompts.d.ts} +1 -1
  53. package/dist/ai/utilities/prompts.js.map +1 -0
  54. package/dist/ai/utilities/systemGenerate.js.map +1 -0
  55. package/dist/collections/AIJobs.js +3 -12
  56. package/dist/collections/AIJobs.js.map +1 -1
  57. package/dist/collections/AIProviders.d.ts +2 -0
  58. package/dist/collections/{AISettings.js → AIProviders.js} +54 -26
  59. package/dist/collections/AIProviders.js.map +1 -0
  60. package/dist/collections/Instructions.js +93 -57
  61. package/dist/collections/Instructions.js.map +1 -1
  62. package/dist/collections/shared.d.ts +30 -0
  63. package/dist/collections/shared.js +15 -0
  64. package/dist/collections/shared.js.map +1 -0
  65. package/dist/defaults.js +1 -1
  66. package/dist/defaults.js.map +1 -1
  67. package/dist/endpoints/fetchFields.js +15 -7
  68. package/dist/endpoints/fetchFields.js.map +1 -1
  69. package/dist/endpoints/fetchVoices.js +2 -2
  70. package/dist/endpoints/fetchVoices.js.map +1 -1
  71. package/dist/endpoints/generate.d.ts +7 -0
  72. package/dist/endpoints/generate.js +268 -0
  73. package/dist/endpoints/generate.js.map +1 -0
  74. package/dist/endpoints/index.js +9 -604
  75. package/dist/endpoints/index.js.map +1 -1
  76. package/dist/endpoints/promptMentions.d.ts +2 -0
  77. package/dist/endpoints/promptMentions.js +166 -0
  78. package/dist/endpoints/promptMentions.js.map +1 -0
  79. package/dist/endpoints/upload.d.ts +7 -0
  80. package/dist/endpoints/upload.js +294 -0
  81. package/dist/endpoints/upload.js.map +1 -0
  82. package/dist/endpoints/videogenWebhook.d.ts +7 -0
  83. package/dist/endpoints/videogenWebhook.js +132 -0
  84. package/dist/endpoints/videogenWebhook.js.map +1 -0
  85. package/dist/exports/client.d.ts +3 -2
  86. package/dist/exports/client.js +3 -2
  87. package/dist/exports/client.js.map +1 -1
  88. package/dist/exports/fields.d.ts +2 -1
  89. package/dist/exports/fields.js +2 -1
  90. package/dist/exports/fields.js.map +1 -1
  91. package/dist/fields/ArrayComposeField/ArrayComposeField.js +1 -1
  92. package/dist/fields/ArrayComposeField/ArrayComposeField.js.map +1 -1
  93. package/dist/fields/ArrayComposeField/ArrayComposeField.jsx +1 -1
  94. package/dist/fields/ComposeField/ComposeField.d.ts +1 -0
  95. package/dist/fields/ComposeField/ComposeField.js +18 -8
  96. package/dist/fields/ComposeField/ComposeField.js.map +1 -1
  97. package/dist/fields/ComposeField/ComposeField.jsx +12 -7
  98. package/dist/fields/PromptEditorField/feature.client.d.ts +1 -0
  99. package/dist/fields/PromptEditorField/feature.client.js +173 -0
  100. package/dist/fields/PromptEditorField/feature.client.js.map +1 -0
  101. package/dist/fields/PromptEditorField/feature.client.jsx +148 -0
  102. package/dist/fields/PromptEditorField/feature.server.d.ts +1 -0
  103. package/dist/fields/PromptEditorField/feature.server.js +30 -0
  104. package/dist/fields/PromptEditorField/feature.server.js.map +1 -0
  105. package/dist/fields/PromptField.d.ts +4 -0
  106. package/dist/fields/PromptField.js +18 -0
  107. package/dist/fields/PromptField.js.map +1 -0
  108. package/dist/fields/SelectField/SelectField.js +0 -1
  109. package/dist/fields/SelectField/SelectField.js.map +1 -1
  110. package/dist/fields/SelectField/SelectField.jsx +0 -1
  111. package/dist/index.d.ts +4 -3
  112. package/dist/index.js +4 -2
  113. package/dist/index.js.map +1 -1
  114. package/dist/libraries/handlebars/helpers.js +2 -2
  115. package/dist/libraries/handlebars/helpers.js.map +1 -1
  116. package/dist/libraries/handlebars/replacePlaceholders.js +5 -1
  117. package/dist/libraries/handlebars/replacePlaceholders.js.map +1 -1
  118. package/dist/payload-ai.d.ts +5 -19
  119. package/dist/plugin.js +19 -22
  120. package/dist/plugin.js.map +1 -1
  121. package/dist/providers/FieldProvider/FieldProvider.js +10 -19
  122. package/dist/providers/FieldProvider/FieldProvider.js.map +1 -1
  123. package/dist/providers/FieldProvider/FieldProvider.jsx +7 -17
  124. package/dist/providers/InstructionsProvider/InstructionsProvider.js +4 -1
  125. package/dist/providers/InstructionsProvider/InstructionsProvider.js.map +1 -1
  126. package/dist/providers/InstructionsProvider/InstructionsProvider.jsx +3 -0
  127. package/dist/providers/InstructionsProvider/useInstructions.js +1 -1
  128. package/dist/providers/InstructionsProvider/useInstructions.js.map +1 -1
  129. package/dist/translations/de.json +47 -0
  130. package/dist/translations/en.json +45 -2
  131. package/dist/translations/es.json +45 -2
  132. package/dist/translations/fa.json +45 -2
  133. package/dist/translations/fr.json +46 -3
  134. package/dist/translations/hi.json +47 -0
  135. package/dist/translations/index.d.ts +88 -26
  136. package/dist/translations/index.js +18 -32
  137. package/dist/translations/index.js.map +1 -1
  138. package/dist/translations/ja.json +47 -0
  139. package/dist/translations/nb.json +47 -0
  140. package/dist/translations/nl.json +47 -0
  141. package/dist/translations/pl.json +45 -2
  142. package/dist/translations/pt.json +47 -0
  143. package/dist/translations/ru.json +45 -2
  144. package/dist/translations/th.json +47 -0
  145. package/dist/translations/translation-schema.json +184 -11
  146. package/dist/translations/uk.json +45 -2
  147. package/dist/translations/zh.json +47 -0
  148. package/dist/types.d.ts +57 -31
  149. package/dist/types.js.map +1 -1
  150. package/dist/ui/Compose/Compose.js +42 -79
  151. package/dist/ui/Compose/Compose.js.map +1 -1
  152. package/dist/ui/Compose/Compose.jsx +32 -86
  153. package/dist/ui/Compose/ComposePlaceholder.js +1 -1
  154. package/dist/ui/Compose/ComposePlaceholder.js.map +1 -1
  155. package/dist/ui/Compose/ComposePlaceholder.jsx +1 -1
  156. package/dist/ui/Compose/{compose.module.css → compose.module.scss} +3 -5
  157. package/dist/ui/Compose/hooks/menu/Item.d.ts +1 -1
  158. package/dist/ui/Compose/hooks/menu/Item.js +7 -3
  159. package/dist/ui/Compose/hooks/menu/Item.js.map +1 -1
  160. package/dist/ui/Compose/hooks/menu/Item.jsx +11 -5
  161. package/dist/ui/Compose/hooks/menu/TranslateMenu.d.ts +5 -0
  162. package/dist/ui/Compose/hooks/menu/TranslateMenu.js +48 -5
  163. package/dist/ui/Compose/hooks/menu/TranslateMenu.js.map +1 -1
  164. package/dist/ui/Compose/hooks/menu/TranslateMenu.jsx +44 -6
  165. package/dist/ui/Compose/hooks/menu/items.d.ts +8 -8
  166. package/dist/ui/Compose/hooks/menu/itemsMap.d.ts +2 -1
  167. package/dist/ui/Compose/hooks/menu/itemsMap.js.map +1 -1
  168. package/dist/ui/Compose/hooks/menu/menu.module.scss +4 -1
  169. package/dist/ui/Compose/hooks/menu/types.d.ts +21 -0
  170. package/dist/ui/Compose/hooks/menu/types.js +3 -0
  171. package/dist/ui/Compose/hooks/menu/types.js.map +1 -0
  172. package/dist/ui/Compose/hooks/menu/useMenu.d.ts +2 -2
  173. package/dist/ui/Compose/hooks/menu/useMenu.js +45 -23
  174. package/dist/ui/Compose/hooks/menu/useMenu.js.map +1 -1
  175. package/dist/ui/Compose/hooks/menu/useMenu.jsx +43 -23
  176. package/dist/ui/Compose/hooks/mergeGeneratedValue.d.ts +14 -0
  177. package/dist/ui/Compose/hooks/mergeGeneratedValue.js +38 -0
  178. package/dist/ui/Compose/hooks/mergeGeneratedValue.js.map +1 -0
  179. package/dist/ui/Compose/hooks/useActiveFieldTracking.js +34 -0
  180. package/dist/ui/Compose/hooks/useActiveFieldTracking.js.map +1 -1
  181. package/dist/ui/Compose/hooks/useGenerate.js +37 -12
  182. package/dist/ui/Compose/hooks/useGenerate.js.map +1 -1
  183. package/dist/ui/Compose/hooks/useGenerateUpload.js +67 -19
  184. package/dist/ui/Compose/hooks/useGenerateUpload.js.map +1 -1
  185. package/dist/ui/Compose/hooks/useStreamingUpdate.js +4 -4
  186. package/dist/ui/Compose/hooks/useStreamingUpdate.js.map +1 -1
  187. package/dist/ui/ConfigDashboard/configDashboard.module.css +94 -0
  188. package/dist/ui/ConfigDashboard/index.d.ts +2 -0
  189. package/dist/ui/ConfigDashboard/index.js +159 -0
  190. package/dist/ui/ConfigDashboard/index.js.map +1 -0
  191. package/dist/ui/ConfigDashboard/index.jsx +122 -0
  192. package/dist/ui/DynamicModelSelect/index.js +6 -27
  193. package/dist/ui/DynamicModelSelect/index.js.map +1 -1
  194. package/dist/ui/DynamicModelSelect/index.jsx +6 -29
  195. package/dist/ui/DynamicProviderSelect/index.js +6 -27
  196. package/dist/ui/DynamicProviderSelect/index.js.map +1 -1
  197. package/dist/ui/DynamicProviderSelect/index.jsx +6 -29
  198. package/dist/ui/DynamicVoiceSelect/index.js +34 -83
  199. package/dist/ui/DynamicVoiceSelect/index.js.map +1 -1
  200. package/dist/ui/DynamicVoiceSelect/index.jsx +16 -53
  201. package/dist/ui/GlobalProviderOptions/index.d.ts +2 -0
  202. package/dist/ui/GlobalProviderOptions/index.js +118 -0
  203. package/dist/ui/GlobalProviderOptions/index.js.map +1 -0
  204. package/dist/ui/GlobalProviderOptions/index.jsx +60 -0
  205. package/dist/ui/Icons/Icons.js +1 -1
  206. package/dist/ui/Icons/Icons.js.map +1 -1
  207. package/dist/ui/Icons/Icons.jsx +1 -1
  208. package/dist/ui/Icons/LottieAnimation.js +1 -1
  209. package/dist/ui/Icons/LottieAnimation.js.map +1 -1
  210. package/dist/ui/Icons/LottieAnimation.jsx +1 -1
  211. package/dist/ui/InstructionProviderOptions/ProviderOptionsTree.d.ts +12 -0
  212. package/dist/ui/InstructionProviderOptions/ProviderOptionsTree.js +166 -0
  213. package/dist/ui/InstructionProviderOptions/ProviderOptionsTree.js.map +1 -0
  214. package/dist/ui/InstructionProviderOptions/ProviderOptionsTree.jsx +83 -0
  215. package/dist/ui/InstructionProviderOptions/index.d.ts +2 -0
  216. package/dist/ui/InstructionProviderOptions/index.js +157 -0
  217. package/dist/ui/InstructionProviderOptions/index.js.map +1 -0
  218. package/dist/ui/InstructionProviderOptions/index.jsx +92 -0
  219. package/dist/ui/VoicesFetcher/index.js.map +1 -1
  220. package/dist/ui/hooks/useAISettings.d.ts +26 -0
  221. package/dist/ui/hooks/useAISettings.js +73 -0
  222. package/dist/ui/hooks/useAISettings.js.map +1 -0
  223. package/dist/ui/providerOptions/updateProviderOptionsValue.d.ts +6 -0
  224. package/dist/ui/providerOptions/updateProviderOptionsValue.js +50 -0
  225. package/dist/ui/providerOptions/updateProviderOptionsValue.js.map +1 -0
  226. package/dist/ui/shared/handleSelectChange.d.ts +5 -0
  227. package/dist/ui/shared/handleSelectChange.js +12 -0
  228. package/dist/ui/shared/handleSelectChange.js.map +1 -0
  229. package/dist/ui/shared/types.d.ts +11 -0
  230. package/dist/ui/shared/types.js +5 -0
  231. package/dist/ui/shared/types.js.map +1 -0
  232. package/dist/utilities/ai/resolveEffectiveInstructionSettings.d.ts +15 -0
  233. package/dist/utilities/ai/resolveEffectiveInstructionSettings.js +136 -0
  234. package/dist/utilities/ai/resolveEffectiveInstructionSettings.js.map +1 -0
  235. package/dist/{endpoints → utilities}/buildPromptUtils.js +14 -5
  236. package/dist/utilities/buildPromptUtils.js.map +1 -0
  237. package/dist/utilities/buildSmartPrompt.js +3 -3
  238. package/dist/utilities/buildSmartPrompt.js.map +1 -1
  239. package/dist/utilities/fields/fieldToJsonSchema.js.map +1 -0
  240. package/dist/utilities/fields/getFieldBySchemaPath.js.map +1 -0
  241. package/dist/utilities/fields/getFieldInfo.js.map +1 -0
  242. package/dist/utilities/{updateFieldsConfig.js → fields/updateFieldsConfig.js} +8 -3
  243. package/dist/utilities/fields/updateFieldsConfig.js.map +1 -0
  244. package/dist/utilities/images/extractImageData.js.map +1 -0
  245. package/dist/utilities/images/extractPromptAttachments.js.map +1 -0
  246. package/dist/utilities/{fetchImages.d.ts → images/fetchImages.d.ts} +1 -1
  247. package/dist/utilities/images/fetchImages.js +49 -0
  248. package/dist/utilities/images/fetchImages.js.map +1 -0
  249. package/dist/utilities/images/resolveImageReferences.js +183 -0
  250. package/dist/utilities/images/resolveImageReferences.js.map +1 -0
  251. package/dist/utilities/init/autoSetupProviders.d.ts +3 -0
  252. package/dist/utilities/init/autoSetupProviders.js +216 -0
  253. package/dist/utilities/init/autoSetupProviders.js.map +1 -0
  254. package/dist/utilities/lexical/editorSchemaValidator.js.map +1 -0
  255. package/dist/utilities/lexical/lexicalToHTML.js.map +1 -0
  256. package/dist/utilities/lexical/lexicalToPromptTemplate.d.ts +2 -0
  257. package/dist/utilities/lexical/lexicalToPromptTemplate.js +50 -0
  258. package/dist/utilities/lexical/lexicalToPromptTemplate.js.map +1 -0
  259. package/dist/utilities/lexical/setSafeLexicalState.js.map +1 -0
  260. package/dist/utilities/lexical/stringToLexicalJSON.d.ts +2 -0
  261. package/dist/utilities/lexical/stringToLexicalJSON.js +39 -0
  262. package/dist/utilities/lexical/stringToLexicalJSON.js.map +1 -0
  263. package/dist/utilities/sanitizeLog.d.ts +1 -0
  264. package/dist/utilities/sanitizeLog.js +39 -0
  265. package/dist/utilities/sanitizeLog.js.map +1 -0
  266. package/dist/utilities/seedProperties.js +37 -22
  267. package/dist/utilities/seedProperties.js.map +1 -1
  268. package/package.json +5 -2
  269. package/dist/ai/analyse.d.ts +0 -1
  270. package/dist/ai/analyse.js +0 -3
  271. package/dist/ai/analyse.js.map +0 -1
  272. package/dist/ai/index.d.ts +0 -11
  273. package/dist/ai/index.js +0 -25
  274. package/dist/ai/index.js.map +0 -1
  275. package/dist/ai/prompts.js.map +0 -1
  276. package/dist/ai/utils/filterEditorSchemaByNodes.js.map +0 -1
  277. package/dist/ai/utils/generateFileNameByPrompt.js.map +0 -1
  278. package/dist/ai/utils/isObjectSchema.js.map +0 -1
  279. package/dist/ai/utils/nodeToSchemaMap.js.map +0 -1
  280. package/dist/ai/utils/systemGenerate.js.map +0 -1
  281. package/dist/collections/AISettings.d.ts +0 -2
  282. package/dist/collections/AISettings.js.map +0 -1
  283. package/dist/endpoints/buildPromptUtils.js.map +0 -1
  284. package/dist/endpoints/chat.d.ts +0 -4
  285. package/dist/fields/PromptEditorField/PromptEditorField.d.ts +0 -3
  286. package/dist/fields/PromptEditorField/PromptEditorField.js +0 -217
  287. package/dist/fields/PromptEditorField/PromptEditorField.js.map +0 -1
  288. package/dist/fields/PromptEditorField/PromptEditorField.jsx +0 -160
  289. package/dist/ui/AIConfigDashboard/index.d.ts +0 -2
  290. package/dist/ui/AIConfigDashboard/index.js +0 -222
  291. package/dist/ui/AIConfigDashboard/index.js.map +0 -1
  292. package/dist/ui/AIConfigDashboard/index.jsx +0 -170
  293. package/dist/ui/ProviderOptionsEditor/index.d.ts +0 -7
  294. package/dist/ui/ProviderOptionsEditor/index.js +0 -291
  295. package/dist/ui/ProviderOptionsEditor/index.js.map +0 -1
  296. package/dist/ui/ProviderOptionsEditor/index.jsx +0 -210
  297. package/dist/utilities/editorSchemaValidator.js.map +0 -1
  298. package/dist/utilities/extractImageData.js.map +0 -1
  299. package/dist/utilities/extractPromptAttachments.js.map +0 -1
  300. package/dist/utilities/fetchImages.js +0 -38
  301. package/dist/utilities/fetchImages.js.map +0 -1
  302. package/dist/utilities/fieldToJsonSchema.js.map +0 -1
  303. package/dist/utilities/getFieldBySchemaPath.js.map +0 -1
  304. package/dist/utilities/getFieldInfo.js.map +0 -1
  305. package/dist/utilities/getProviderOptionsFields.d.ts +0 -16
  306. package/dist/utilities/getProviderOptionsFields.js +0 -80
  307. package/dist/utilities/getProviderOptionsFields.js.map +0 -1
  308. package/dist/utilities/isPluginActivated.d.ts +0 -2
  309. package/dist/utilities/isPluginActivated.js +0 -5
  310. package/dist/utilities/isPluginActivated.js.map +0 -1
  311. package/dist/utilities/lexicalToHTML.js.map +0 -1
  312. package/dist/utilities/resolveImageReferences.js +0 -167
  313. package/dist/utilities/resolveImageReferences.js.map +0 -1
  314. package/dist/utilities/schemaConverter.d.ts +0 -3
  315. package/dist/utilities/schemaConverter.js +0 -93
  316. package/dist/utilities/schemaConverter.js.map +0 -1
  317. package/dist/utilities/setSafeLexicalState.js.map +0 -1
  318. package/dist/utilities/updateFieldsConfig.js.map +0 -1
  319. /package/dist/ai/{utils → utilities}/filterEditorSchemaByNodes.d.ts +0 -0
  320. /package/dist/ai/{utils → utilities}/filterEditorSchemaByNodes.js +0 -0
  321. /package/dist/ai/{utils → utilities}/generateFileNameByPrompt.d.ts +0 -0
  322. /package/dist/ai/{utils → utilities}/generateFileNameByPrompt.js +0 -0
  323. /package/dist/ai/{utils → utilities}/isObjectSchema.d.ts +0 -0
  324. /package/dist/ai/{utils → utilities}/isObjectSchema.js +0 -0
  325. /package/dist/ai/{utils → utilities}/nodeToSchemaMap.d.ts +0 -0
  326. /package/dist/ai/{utils → utilities}/nodeToSchemaMap.js +0 -0
  327. /package/dist/ai/{prompts.js → utilities/prompts.js} +0 -0
  328. /package/dist/ai/{utils → utilities}/systemGenerate.d.ts +0 -0
  329. /package/dist/ai/{utils → utilities}/systemGenerate.js +0 -0
  330. /package/dist/ui/Icons/{icons.module.css → icons.module.scss} +0 -0
  331. /package/dist/{endpoints → utilities}/buildPromptUtils.d.ts +0 -0
  332. /package/dist/utilities/{fieldToJsonSchema.d.ts → fields/fieldToJsonSchema.d.ts} +0 -0
  333. /package/dist/utilities/{fieldToJsonSchema.js → fields/fieldToJsonSchema.js} +0 -0
  334. /package/dist/utilities/{getFieldBySchemaPath.d.ts → fields/getFieldBySchemaPath.d.ts} +0 -0
  335. /package/dist/utilities/{getFieldBySchemaPath.js → fields/getFieldBySchemaPath.js} +0 -0
  336. /package/dist/utilities/{getFieldInfo.d.ts → fields/getFieldInfo.d.ts} +0 -0
  337. /package/dist/utilities/{getFieldInfo.js → fields/getFieldInfo.js} +0 -0
  338. /package/dist/utilities/{updateFieldsConfig.d.ts → fields/updateFieldsConfig.d.ts} +0 -0
  339. /package/dist/utilities/{extractImageData.d.ts → images/extractImageData.d.ts} +0 -0
  340. /package/dist/utilities/{extractImageData.js → images/extractImageData.js} +0 -0
  341. /package/dist/utilities/{extractPromptAttachments.d.ts → images/extractPromptAttachments.d.ts} +0 -0
  342. /package/dist/utilities/{extractPromptAttachments.js → images/extractPromptAttachments.js} +0 -0
  343. /package/dist/utilities/{resolveImageReferences.d.ts → images/resolveImageReferences.d.ts} +0 -0
  344. /package/dist/utilities/{editorSchemaValidator.d.ts → lexical/editorSchemaValidator.d.ts} +0 -0
  345. /package/dist/utilities/{editorSchemaValidator.js → lexical/editorSchemaValidator.js} +0 -0
  346. /package/dist/utilities/{lexicalToHTML.d.ts → lexical/lexicalToHTML.d.ts} +0 -0
  347. /package/dist/utilities/{lexicalToHTML.js → lexical/lexicalToHTML.js} +0 -0
  348. /package/dist/utilities/{setSafeLexicalState.d.ts → lexical/setSafeLexicalState.d.ts} +0 -0
  349. /package/dist/utilities/{setSafeLexicalState.js → lexical/setSafeLexicalState.js} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/itemsMap.ts"],"sourcesContent":["import type React from 'react'\n\nimport type { ActionMenuItems, BaseItemProps } from '../../../../types.js'\n\nimport { Compose, Expand, Proofread, Rephrase, Settings, Simplify, Summarize } from './items.js'\nimport { MemoizedTranslateMenu, TranslateMenu } from './TranslateMenu.js'\n\ntype MenuItemsMapType = {\n component: React.FC<BaseItemProps>\n excludedFor?: string[]\n loadingText?: string\n name: ActionMenuItems\n}\n\nexport const menuItemsMap: MenuItemsMapType[] = [\n { name: 'Proofread', component: Proofread, excludedFor: ['upload', 'array'], loadingText: 'Proofreading' },\n { name: 'Rephrase', component: Rephrase, excludedFor: ['upload', 'array'], loadingText: 'Rephrasing' },\n {\n name: 'Translate',\n component: MemoizedTranslateMenu,\n excludedFor: ['upload', 'array'],\n loadingText: 'Translating',\n },\n { name: 'Expand', component: Expand, excludedFor: ['upload', 'text', 'array'], loadingText: 'Expanding' },\n {\n // Turned off - WIP\n name: 'Summarize',\n component: Summarize,\n excludedFor: ['upload', 'text', 'richText', 'array'],\n loadingText: 'Summarizing',\n },\n { name: 'Simplify', component: Simplify, excludedFor: ['upload', 'array'], loadingText: 'Simplifying' },\n { name: 'Compose', component: Compose, loadingText: 'Composing' },\n { name: 'Settings', component: Settings },\n]\n"],"names":["Compose","Expand","Proofread","Rephrase","Settings","Simplify","Summarize","MemoizedTranslateMenu","menuItemsMap","name","component","excludedFor","loadingText"],"mappings":"AAIA,SAASA,OAAO,EAAEC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,SAAS,QAAQ,aAAY;AAChG,SAASC,qBAAqB,QAAuB,qBAAoB;AASzE,OAAO,MAAMC,eAAmC;IAC9C;QAAEC,MAAM;QAAaC,WAAWR;QAAWS,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAe;IACzG;QAAEH,MAAM;QAAYC,WAAWP;QAAUQ,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAa;IACrG;QACEH,MAAM;QACNC,WAAWH;QACXI,aAAa;YAAC;YAAU;SAAQ;QAChCC,aAAa;IACf;IACA;QAAEH,MAAM;QAAUC,WAAWT;QAAQU,aAAa;YAAC;YAAU;YAAQ;SAAQ;QAAEC,aAAa;IAAY;IACxG;QACE,mBAAmB;QACnBH,MAAM;QACNC,WAAWJ;QACXK,aAAa;YAAC;YAAU;YAAQ;YAAY;SAAQ;QACpDC,aAAa;IACf;IACA;QAAEH,MAAM;QAAYC,WAAWL;QAAUM,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAc;IACtG;QAAEH,MAAM;QAAWC,WAAWV;QAASY,aAAa;IAAY;IAChE;QAAEH,MAAM;QAAYC,WAAWN;IAAS;CACzC,CAAA"}
1
+ {"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/itemsMap.ts"],"sourcesContent":["import type React from 'react'\n\nimport type { ActionMenuItems } from '../../../../types.js'\nimport type { BaseItemProps } from './types.js'\n\nimport { Compose, Expand, Proofread, Rephrase, Settings, Simplify, Summarize } from './items.js'\nimport { MemoizedTranslateMenu, TranslateMenu } from './TranslateMenu.js'\n\ntype MenuItemsMapType = {\n component: React.FC<BaseItemProps>\n excludedFor?: string[]\n loadingText?: string\n name: ActionMenuItems\n}\n\nexport const menuItemsMap: MenuItemsMapType[] = [\n { name: 'Proofread', component: Proofread, excludedFor: ['upload', 'array'], loadingText: 'Proofreading' },\n { name: 'Rephrase', component: Rephrase, excludedFor: ['upload', 'array'], loadingText: 'Rephrasing' },\n {\n name: 'Translate',\n component: MemoizedTranslateMenu,\n excludedFor: ['upload', 'array'],\n loadingText: 'Translating',\n },\n { name: 'Expand', component: Expand, excludedFor: ['upload', 'text', 'array'], loadingText: 'Expanding' },\n {\n // Turned off - WIP\n name: 'Summarize',\n component: Summarize,\n excludedFor: ['upload', 'text', 'richText', 'array'],\n loadingText: 'Summarizing',\n },\n { name: 'Simplify', component: Simplify, excludedFor: ['upload', 'array'], loadingText: 'Simplifying' },\n { name: 'Compose', component: Compose, loadingText: 'Composing' },\n { name: 'Settings', component: Settings },\n]\n"],"names":["Compose","Expand","Proofread","Rephrase","Settings","Simplify","Summarize","MemoizedTranslateMenu","menuItemsMap","name","component","excludedFor","loadingText"],"mappings":"AAKA,SAASA,OAAO,EAAEC,MAAM,EAAEC,SAAS,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,SAAS,QAAQ,aAAY;AAChG,SAASC,qBAAqB,QAAuB,qBAAoB;AASzE,OAAO,MAAMC,eAAmC;IAC9C;QAAEC,MAAM;QAAaC,WAAWR;QAAWS,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAe;IACzG;QAAEH,MAAM;QAAYC,WAAWP;QAAUQ,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAa;IACrG;QACEH,MAAM;QACNC,WAAWH;QACXI,aAAa;YAAC;YAAU;SAAQ;QAChCC,aAAa;IACf;IACA;QAAEH,MAAM;QAAUC,WAAWT;QAAQU,aAAa;YAAC;YAAU;YAAQ;SAAQ;QAAEC,aAAa;IAAY;IACxG;QACE,mBAAmB;QACnBH,MAAM;QACNC,WAAWJ;QACXK,aAAa;YAAC;YAAU;YAAQ;YAAY;SAAQ;QACpDC,aAAa;IACf;IACA;QAAEH,MAAM;QAAYC,WAAWL;QAAUM,aAAa;YAAC;YAAU;SAAQ;QAAEC,aAAa;IAAc;IACtG;QAAEH,MAAM;QAAWC,WAAWV;QAASY,aAAa;IAAY;IAChE;QAAEH,MAAM;QAAYC,WAAWN;IAAS;CACzC,CAAA"}
@@ -26,6 +26,8 @@
26
26
  }
27
27
 
28
28
  .menu {
29
+ --popup-width: 150px;
30
+
29
31
  display: flex;
30
32
  gap: 1px;
31
33
  flex-direction: column;
@@ -49,7 +51,7 @@
49
51
 
50
52
  .subMenu {
51
53
  position: absolute;
52
- left: calc(var(--popup-width) + 12px);
54
+ left: calc(var(--popup-width) + 20px);
53
55
  width: calc(var(--popup-width) + 12px);
54
56
  top: 10px;
55
57
  height: calc(100% - 16px);
@@ -85,6 +87,7 @@
85
87
  color: var(--theme-elevation-800);
86
88
  border-radius: 0;
87
89
  -webkit-appearance: none;
90
+ appearance: none;
88
91
 
89
92
  font-size: inherit !important;
90
93
  height: auto !important;
@@ -0,0 +1,21 @@
1
+ import type { CSSProperties, MouseEventHandler } from 'react';
2
+ export type ActionMenuEvents = 'onCompose' | 'onExpand' | 'onProofread' | 'onRephrase' | 'onSettings' | 'onSimplify' | 'onSummarize' | 'onTone' | 'onTranslate';
3
+ export type UseMenuEvents = {
4
+ [key in ActionMenuEvents]?: (data?: unknown) => void;
5
+ };
6
+ export type UseMenuOptions = {
7
+ isConfigAllowed: boolean;
8
+ };
9
+ export type BaseItemProps<T = unknown> = {
10
+ children?: React.ReactNode;
11
+ className?: string;
12
+ disabled?: boolean;
13
+ hideIcon?: boolean;
14
+ isActive?: boolean;
15
+ isMenu?: boolean;
16
+ onClick: (data?: unknown) => void;
17
+ onMouseEnter?: MouseEventHandler<T> | undefined;
18
+ onMouseLeave?: MouseEventHandler<T> | undefined;
19
+ style?: CSSProperties | undefined;
20
+ title?: string;
21
+ };
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/types.ts"],"sourcesContent":["import type { CSSProperties, MouseEventHandler } from 'react'\n\n\nexport type ActionMenuEvents =\n | 'onCompose'\n | 'onExpand'\n | 'onProofread'\n | 'onRephrase'\n | 'onSettings'\n | 'onSimplify'\n | 'onSummarize'\n | 'onTone'\n | 'onTranslate'\n\nexport type UseMenuEvents = {\n [key in ActionMenuEvents]?: (data?: unknown) => void\n}\n\nexport type UseMenuOptions = {\n isConfigAllowed: boolean\n}\n\nexport type BaseItemProps<T = unknown> = {\n children?: React.ReactNode\n className?: string\n disabled?: boolean\n hideIcon?: boolean\n isActive?: boolean\n isMenu?: boolean\n onClick: (data?: unknown) => void\n onMouseEnter?: MouseEventHandler<T> | undefined\n onMouseLeave?: MouseEventHandler<T> | undefined\n style?: CSSProperties | undefined\n title?: string\n}\n"],"names":[],"mappings":"AAsBA,WAYC"}
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import type { UseMenuEvents, UseMenuOptions } from '../../../../types.js';
2
+ import type { UseMenuEvents, UseMenuOptions } from './types.js';
3
3
  export declare const useMenu: (menuEvents: UseMenuEvents, options: UseMenuOptions) => {
4
- ActiveComponent: ({ isLoading, loadingLabel, stop }: {
4
+ ActiveComponent: ({ isLoading, loadingLabel, stop, }: {
5
5
  isLoading: boolean;
6
6
  loadingLabel?: string;
7
7
  stop: () => void;
@@ -1,10 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useForm } from '@payloadcms/ui';
4
- import { getSiblingData } from 'payload/shared';
3
+ import { useConfig, useField, useLocale, useTranslation } from '@payloadcms/ui';
5
4
  import React, { useEffect, useMemo, useState } from 'react';
6
5
  import { useFieldProps } from '../../../../providers/FieldProvider/useFieldProps.js';
7
- import { Compose, Proofread, Rephrase } from './items.js';
6
+ import { Compose, Proofread, Rephrase, Translate } from './items.js';
8
7
  import { menuItemsMap } from './itemsMap.js';
9
8
  import styles from './menu.module.scss';
10
9
  const getActiveComponent = (ac)=>{
@@ -15,36 +14,47 @@ const getActiveComponent = (ac)=>{
15
14
  return Proofread;
16
15
  case 'Rephrase':
17
16
  return Rephrase;
17
+ case 'Translate':
18
+ return Translate;
18
19
  default:
19
20
  return Rephrase;
20
21
  }
21
22
  };
22
23
  export const useMenu = (menuEvents, options)=>{
23
24
  const { field: { type: fieldType } = {}, path } = useFieldProps();
24
- const { getData } = useForm();
25
+ const { value } = useField({
26
+ path: path || ''
27
+ });
28
+ const { config } = useConfig();
29
+ const locale = useLocale();
30
+ const { t } = useTranslation();
25
31
  const [activeComponent, setActiveComponent] = useState('Rephrase');
26
- // Check value once on mount or when path/type changes
32
+ // Check value whenever it changes
27
33
  useEffect(()=>{
28
34
  let hasValue = false;
29
35
  try {
30
- const data = getData();
31
- if (path) {
32
- const val = getSiblingData(data, path);
33
- hasValue = val !== undefined && val !== null;
34
- // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)
35
- // But for now, simple truthiness covers most cases or at least defaults safely
36
- if (fieldType === 'richText' && val && typeof val === 'object' && 'root' in val) {
37
- // Basic lexical check could go here if needed
38
- }
36
+ hasValue = value !== undefined && value !== null;
37
+ // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)
38
+ // But for now, simple truthiness covers most cases or at least defaults safely
39
+ if (fieldType === 'richText' && value && typeof value === 'object' && 'root' in value) {
40
+ // Basic lexical check could go here if needed
39
41
  }
40
42
  } catch (e) {
41
43
  // ignore
42
44
  }
43
45
  if (!hasValue) {
44
- setActiveComponent('Compose');
46
+ const defaultLocale = config?.localization ? config.localization.defaultLocale : undefined;
47
+ const translateItem = menuItemsMap.find((i)=>i.name === 'Translate');
48
+ const isTranslateExcluded = translateItem?.excludedFor?.includes(fieldType ?? '');
49
+ if (!isTranslateExcluded && locale?.code && defaultLocale && locale.code !== defaultLocale) {
50
+ setActiveComponent('Translate');
51
+ } else {
52
+ setActiveComponent('Compose');
53
+ }
45
54
  return;
46
55
  }
47
- if (menuItemsMap.some((i)=>i.excludedFor?.includes(fieldType ?? ''))) {
56
+ const rephraseItem = menuItemsMap.find((i)=>i.name === 'Rephrase');
57
+ if (rephraseItem?.excludedFor?.includes(fieldType ?? '')) {
48
58
  setActiveComponent('Compose');
49
59
  return;
50
60
  }
@@ -52,8 +62,9 @@ export const useMenu = (menuEvents, options)=>{
52
62
  setActiveComponent('Rephrase');
53
63
  }, [
54
64
  fieldType,
55
- getData,
56
- path
65
+ value,
66
+ locale?.code,
67
+ config?.localization
57
68
  ]);
58
69
  const MemoizedActiveComponent = useMemo(()=>{
59
70
  return ({ isLoading, loadingLabel, stop })=>{
@@ -65,7 +76,16 @@ export const useMenu = (menuEvents, options)=>{
65
76
  if (!isLoading) {
66
77
  const trigger = menuEvents[`on${activeComponent}`];
67
78
  if (typeof trigger === 'function') {
68
- trigger(data);
79
+ const isEvent = data && typeof data === 'object' && 'nativeEvent' in data;
80
+ const actualData = isEvent ? undefined : data;
81
+ if (activeComponent === 'Translate' && !actualData) {
82
+ trigger({
83
+ locale: locale?.code,
84
+ translateFromDefault: true
85
+ });
86
+ } else {
87
+ trigger(actualData);
88
+ }
69
89
  } else {
70
90
  console.error('No trigger found for', activeComponent);
71
91
  }
@@ -73,13 +93,15 @@ export const useMenu = (menuEvents, options)=>{
73
93
  stop();
74
94
  }
75
95
  },
76
- title: isLoading ? 'Click to stop' : activeItem.name,
77
- children: isLoading && (loadingLabel ?? activeItem.loadingText)
96
+ title: isLoading ? t('ai-plugin:general:clickToStop') : t(`ai-plugin:actions:${activeItem.name.toLowerCase()}`),
97
+ children: isLoading && (loadingLabel ?? (activeItem.loadingText ? t(`ai-plugin:actionLoading:${activeItem.loadingText.toLowerCase()}`) : null))
78
98
  });
79
99
  };
80
100
  }, [
81
101
  activeComponent,
82
- menuEvents
102
+ menuEvents,
103
+ t,
104
+ locale?.code
83
105
  ]);
84
106
  const filteredMenuItems = useMemo(()=>menuItemsMap.filter((i)=>{
85
107
  if (i.name === 'Settings' && !options.isConfigAllowed) {
@@ -105,7 +127,7 @@ export const useMenu = (menuEvents, options)=>{
105
127
  menuEvents[`on${i.name}`]?.(data);
106
128
  onClose();
107
129
  },
108
- children: isLoading && i.loadingText
130
+ children: isLoading && i.loadingText && t(`ai-plugin:actionLoading:${i.loadingText.toLowerCase()}`)
109
131
  }, i.name);
110
132
  })
111
133
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/useMenu.tsx"],"sourcesContent":["'use client'\n\nimport { useForm } from '@payloadcms/ui'\nimport { getSiblingData } from 'payload/shared'\nimport React, { useEffect, useMemo, useState } from 'react'\n\nimport type { ActionMenuItems, UseMenuEvents, UseMenuOptions } from '../../../../types.js'\n\nimport { useFieldProps } from '../../../../providers/FieldProvider/useFieldProps.js'\nimport { Compose, Proofread, Rephrase } from './items.js'\nimport { menuItemsMap } from './itemsMap.js'\nimport styles from './menu.module.scss'\n\nconst getActiveComponent = (ac: ActionMenuItems) => {\n switch (ac) {\n case 'Compose':\n return Compose\n case 'Proofread':\n return Proofread\n case 'Rephrase':\n return Rephrase\n default:\n return Rephrase\n }\n}\n\nexport const useMenu = (menuEvents: UseMenuEvents, options: UseMenuOptions) => {\n const { field: { type: fieldType } = {}, path } = useFieldProps()\n const { getData } = useForm()\n const [activeComponent, setActiveComponent] = useState<ActionMenuItems>('Rephrase')\n\n // Check value once on mount or when path/type changes\n useEffect(() => {\n let hasValue = false\n\n try {\n const data = getData()\n if (path) {\n const val = getSiblingData(data, path)\n hasValue = val !== undefined && val !== null\n // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)\n // But for now, simple truthiness covers most cases or at least defaults safely\n if (fieldType === 'richText' && val && typeof val === 'object' && 'root' in val) {\n // Basic lexical check could go here if needed\n }\n }\n } catch (e) {\n // ignore\n }\n\n if (!hasValue) {\n setActiveComponent('Compose')\n return\n }\n\n if (menuItemsMap.some((i) => i.excludedFor?.includes(fieldType ?? ''))) {\n setActiveComponent('Compose')\n return\n }\n\n // Default to Rephrase if value exists\n setActiveComponent('Rephrase')\n }, [fieldType, getData, path])\n\n const MemoizedActiveComponent = useMemo(() => {\n return ({ isLoading, loadingLabel, stop }: { isLoading: boolean; loadingLabel?: string; stop: () => void }) => {\n const ActiveComponent = getActiveComponent(activeComponent)\n const activeItem = menuItemsMap.find((i) => i.name === activeComponent)!\n return (\n <ActiveComponent\n hideIcon\n onClick={(data: unknown) => {\n if (!isLoading) {\n const trigger = menuEvents[`on${activeComponent}`]\n if (typeof trigger === 'function') {\n trigger(data)\n } else {\n console.error('No trigger found for', activeComponent)\n }\n } else {\n stop()\n }\n }}\n title={isLoading ? 'Click to stop' : activeItem.name}\n >\n {isLoading && (loadingLabel ?? activeItem.loadingText)}\n </ActiveComponent>\n )\n }\n }, [activeComponent, menuEvents])\n\n const filteredMenuItems = useMemo(\n () =>\n menuItemsMap.filter((i) => {\n if (i.name === 'Settings' && !options.isConfigAllowed) {\n return false\n } // Disable settings if a user role is not permitted\n return i.name !== activeComponent && !i.excludedFor?.includes(fieldType ?? '')\n }),\n [activeComponent, fieldType, options.isConfigAllowed],\n )\n\n const MemoizedMenu = useMemo(() => {\n return ({ isLoading, onClose }: { isLoading: boolean; onClose: () => void }) => (\n <div className={styles.menu}>\n {filteredMenuItems.map((i) => {\n const Action = i.component\n return (\n <Action\n disabled={isLoading}\n key={i.name}\n onClick={(data: unknown) => {\n if (i.name !== 'Settings') {\n setActiveComponent(i.name)\n }\n\n menuEvents[`on${i.name}`]?.(data)\n onClose()\n }}\n >\n {isLoading && i.loadingText}\n </Action>\n )\n })}\n </div>\n )\n }, [filteredMenuItems, menuEvents])\n\n return {\n ActiveComponent: MemoizedActiveComponent,\n Menu: MemoizedMenu,\n }\n}\n\n"],"names":["useForm","getSiblingData","React","useEffect","useMemo","useState","useFieldProps","Compose","Proofread","Rephrase","menuItemsMap","styles","getActiveComponent","ac","useMenu","menuEvents","options","field","type","fieldType","path","getData","activeComponent","setActiveComponent","hasValue","data","val","undefined","e","some","i","excludedFor","includes","MemoizedActiveComponent","isLoading","loadingLabel","stop","ActiveComponent","activeItem","find","name","hideIcon","onClick","trigger","console","error","title","loadingText","filteredMenuItems","filter","isConfigAllowed","MemoizedMenu","onClose","div","className","menu","map","Action","component","disabled","Menu"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../src/ui/Compose/hooks/menu/useMenu.tsx"],"sourcesContent":["'use client'\n\nimport { useConfig, useField, useLocale, useTranslation } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useState } from 'react'\n\nimport type {\n PluginAITranslationKeys,\n PluginAITranslations,\n} from '../../../../translations/index.js'\nimport type { ActionMenuItems } from '../../../../types.js'\nimport type { UseMenuEvents, UseMenuOptions } from './types.js'\n\nimport { useFieldProps } from '../../../../providers/FieldProvider/useFieldProps.js'\nimport { Compose, Proofread, Rephrase, Translate } from './items.js'\nimport { menuItemsMap } from './itemsMap.js'\nimport styles from './menu.module.scss'\n\nconst getActiveComponent = (ac: ActionMenuItems) => {\n switch (ac) {\n case 'Compose':\n return Compose\n case 'Proofread':\n return Proofread\n case 'Rephrase':\n return Rephrase\n case 'Translate':\n return Translate\n default:\n return Rephrase\n }\n}\n\nexport const useMenu = (menuEvents: UseMenuEvents, options: UseMenuOptions) => {\n const { field: { type: fieldType } = {}, path } = useFieldProps()\n const { value } = useField<any>({ path: path || '' })\n const { config } = useConfig()\n const locale = useLocale()\n const { t } = useTranslation<PluginAITranslations, PluginAITranslationKeys>()\n const [activeComponent, setActiveComponent] = useState<ActionMenuItems>('Rephrase')\n\n // Check value whenever it changes\n useEffect(() => {\n let hasValue = false\n\n try {\n hasValue = value !== undefined && value !== null\n // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)\n // But for now, simple truthiness covers most cases or at least defaults safely\n if (fieldType === 'richText' && value && typeof value === 'object' && 'root' in value) {\n // Basic lexical check could go here if needed\n }\n } catch (e) {\n // ignore\n }\n\n if (!hasValue) {\n const defaultLocale = config?.localization ? config.localization.defaultLocale : undefined\n const translateItem = menuItemsMap.find((i) => i.name === 'Translate')\n const isTranslateExcluded = translateItem?.excludedFor?.includes(fieldType ?? '')\n\n if (!isTranslateExcluded && locale?.code && defaultLocale && locale.code !== defaultLocale) {\n setActiveComponent('Translate')\n } else {\n setActiveComponent('Compose')\n }\n return\n }\n\n const rephraseItem = menuItemsMap.find((i) => i.name === 'Rephrase')\n if (rephraseItem?.excludedFor?.includes(fieldType ?? '')) {\n setActiveComponent('Compose')\n return\n }\n\n // Default to Rephrase if value exists\n setActiveComponent('Rephrase')\n }, [fieldType, value, locale?.code, config?.localization])\n\n const MemoizedActiveComponent = useMemo(() => {\n return ({\n isLoading,\n loadingLabel,\n stop,\n }: {\n isLoading: boolean\n loadingLabel?: string\n stop: () => void\n }) => {\n const ActiveComponent = getActiveComponent(activeComponent)\n const activeItem = menuItemsMap.find((i) => i.name === activeComponent)!\n return (\n <ActiveComponent\n hideIcon\n onClick={(data: unknown) => {\n if (!isLoading) {\n const trigger = menuEvents[`on${activeComponent}`]\n if (typeof trigger === 'function') {\n const isEvent = data && typeof data === 'object' && 'nativeEvent' in data\n const actualData = isEvent ? undefined : data\n\n if (activeComponent === 'Translate' && !actualData) {\n trigger({ locale: locale?.code, translateFromDefault: true })\n } else {\n trigger(actualData)\n }\n } else {\n console.error('No trigger found for', activeComponent)\n }\n } else {\n stop()\n }\n }}\n title={\n isLoading\n ? t('ai-plugin:general:clickToStop' as any)\n : t(`ai-plugin:actions:${activeItem.name.toLowerCase()}` as any)\n }\n >\n {isLoading &&\n (loadingLabel ??\n (activeItem.loadingText ? t(`ai-plugin:actionLoading:${activeItem.loadingText.toLowerCase()}` as any) : null))}\n </ActiveComponent>\n )\n }\n }, [activeComponent, menuEvents, t, locale?.code])\n\n const filteredMenuItems = useMemo(\n () =>\n menuItemsMap.filter((i) => {\n if (i.name === 'Settings' && !options.isConfigAllowed) {\n return false\n } // Disable settings if a user role is not permitted\n return i.name !== activeComponent && !i.excludedFor?.includes(fieldType ?? '')\n }),\n [activeComponent, fieldType, options.isConfigAllowed],\n )\n\n const MemoizedMenu = useMemo(() => {\n return ({ isLoading, onClose }: { isLoading: boolean; onClose: () => void }) => (\n <div className={styles.menu}>\n {filteredMenuItems.map((i) => {\n const Action = i.component\n return (\n <Action\n disabled={isLoading}\n key={i.name}\n onClick={(data: unknown) => {\n if (i.name !== 'Settings') {\n setActiveComponent(i.name)\n }\n\n menuEvents[`on${i.name}`]?.(data)\n onClose()\n }}\n >\n {isLoading && i.loadingText && t(`ai-plugin:actionLoading:${i.loadingText.toLowerCase()}` as any)}\n </Action>\n )\n })}\n </div>\n )\n }, [filteredMenuItems, menuEvents])\n\n return {\n ActiveComponent: MemoizedActiveComponent,\n Menu: MemoizedMenu,\n }\n}\n"],"names":["useConfig","useField","useLocale","useTranslation","React","useEffect","useMemo","useState","useFieldProps","Compose","Proofread","Rephrase","Translate","menuItemsMap","styles","getActiveComponent","ac","useMenu","menuEvents","options","field","type","fieldType","path","value","config","locale","t","activeComponent","setActiveComponent","hasValue","undefined","e","defaultLocale","localization","translateItem","find","i","name","isTranslateExcluded","excludedFor","includes","code","rephraseItem","MemoizedActiveComponent","isLoading","loadingLabel","stop","ActiveComponent","activeItem","hideIcon","onClick","data","trigger","isEvent","actualData","translateFromDefault","console","error","title","toLowerCase","loadingText","filteredMenuItems","filter","isConfigAllowed","MemoizedMenu","onClose","div","className","menu","map","Action","component","disabled","Menu"],"mappings":"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"}
@@ -1,9 +1,8 @@
1
1
  'use client';
2
- import { useForm } from '@payloadcms/ui';
3
- import { getSiblingData } from 'payload/shared';
2
+ import { useConfig, useField, useLocale, useTranslation } from '@payloadcms/ui';
4
3
  import React, { useEffect, useMemo, useState } from 'react';
5
4
  import { useFieldProps } from '../../../../providers/FieldProvider/useFieldProps.js';
6
- import { Compose, Proofread, Rephrase } from './items.js';
5
+ import { Compose, Proofread, Rephrase, Translate } from './items.js';
7
6
  import { menuItemsMap } from './itemsMap.js';
8
7
  import styles from './menu.module.scss';
9
8
  const getActiveComponent = (ac) => {
@@ -14,52 +13,69 @@ const getActiveComponent = (ac) => {
14
13
  return Proofread;
15
14
  case 'Rephrase':
16
15
  return Rephrase;
16
+ case 'Translate':
17
+ return Translate;
17
18
  default:
18
19
  return Rephrase;
19
20
  }
20
21
  };
21
22
  export const useMenu = (menuEvents, options) => {
22
23
  const { field: { type: fieldType } = {}, path } = useFieldProps();
23
- const { getData } = useForm();
24
+ const { value } = useField({ path: path || '' });
25
+ const { config } = useConfig();
26
+ const locale = useLocale();
27
+ const { t } = useTranslation();
24
28
  const [activeComponent, setActiveComponent] = useState('Rephrase');
25
- // Check value once on mount or when path/type changes
29
+ // Check value whenever it changes
26
30
  useEffect(() => {
27
31
  let hasValue = false;
28
32
  try {
29
- const data = getData();
30
- if (path) {
31
- const val = getSiblingData(data, path);
32
- hasValue = val !== undefined && val !== null;
33
- // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)
34
- // But for now, simple truthiness covers most cases or at least defaults safely
35
- if (fieldType === 'richText' && val && typeof val === 'object' && 'root' in val) {
36
- // Basic lexical check could go here if needed
37
- }
33
+ hasValue = value !== undefined && value !== null;
34
+ // For richTextFields, we might need a more robust check (e.g. check for root.children.length > 0)
35
+ // But for now, simple truthiness covers most cases or at least defaults safely
36
+ if (fieldType === 'richText' && value && typeof value === 'object' && 'root' in value) {
37
+ // Basic lexical check could go here if needed
38
38
  }
39
39
  }
40
40
  catch (e) {
41
41
  // ignore
42
42
  }
43
43
  if (!hasValue) {
44
- setActiveComponent('Compose');
44
+ const defaultLocale = config?.localization ? config.localization.defaultLocale : undefined;
45
+ const translateItem = menuItemsMap.find((i) => i.name === 'Translate');
46
+ const isTranslateExcluded = translateItem?.excludedFor?.includes(fieldType ?? '');
47
+ if (!isTranslateExcluded && locale?.code && defaultLocale && locale.code !== defaultLocale) {
48
+ setActiveComponent('Translate');
49
+ }
50
+ else {
51
+ setActiveComponent('Compose');
52
+ }
45
53
  return;
46
54
  }
47
- if (menuItemsMap.some((i) => i.excludedFor?.includes(fieldType ?? ''))) {
55
+ const rephraseItem = menuItemsMap.find((i) => i.name === 'Rephrase');
56
+ if (rephraseItem?.excludedFor?.includes(fieldType ?? '')) {
48
57
  setActiveComponent('Compose');
49
58
  return;
50
59
  }
51
60
  // Default to Rephrase if value exists
52
61
  setActiveComponent('Rephrase');
53
- }, [fieldType, getData, path]);
62
+ }, [fieldType, value, locale?.code, config?.localization]);
54
63
  const MemoizedActiveComponent = useMemo(() => {
55
- return ({ isLoading, loadingLabel, stop }) => {
64
+ return ({ isLoading, loadingLabel, stop, }) => {
56
65
  const ActiveComponent = getActiveComponent(activeComponent);
57
66
  const activeItem = menuItemsMap.find((i) => i.name === activeComponent);
58
67
  return (<ActiveComponent hideIcon onClick={(data) => {
59
68
  if (!isLoading) {
60
69
  const trigger = menuEvents[`on${activeComponent}`];
61
70
  if (typeof trigger === 'function') {
62
- trigger(data);
71
+ const isEvent = data && typeof data === 'object' && 'nativeEvent' in data;
72
+ const actualData = isEvent ? undefined : data;
73
+ if (activeComponent === 'Translate' && !actualData) {
74
+ trigger({ locale: locale?.code, translateFromDefault: true });
75
+ }
76
+ else {
77
+ trigger(actualData);
78
+ }
63
79
  }
64
80
  else {
65
81
  console.error('No trigger found for', activeComponent);
@@ -68,11 +84,15 @@ export const useMenu = (menuEvents, options) => {
68
84
  else {
69
85
  stop();
70
86
  }
71
- }} title={isLoading ? 'Click to stop' : activeItem.name}>
72
- {isLoading && (loadingLabel ?? activeItem.loadingText)}
87
+ }} title={isLoading
88
+ ? t('ai-plugin:general:clickToStop')
89
+ : t(`ai-plugin:actions:${activeItem.name.toLowerCase()}`)}>
90
+ {isLoading &&
91
+ (loadingLabel ??
92
+ (activeItem.loadingText ? t(`ai-plugin:actionLoading:${activeItem.loadingText.toLowerCase()}`) : null))}
73
93
  </ActiveComponent>);
74
94
  };
75
- }, [activeComponent, menuEvents]);
95
+ }, [activeComponent, menuEvents, t, locale?.code]);
76
96
  const filteredMenuItems = useMemo(() => menuItemsMap.filter((i) => {
77
97
  if (i.name === 'Settings' && !options.isConfigAllowed) {
78
98
  return false;
@@ -90,7 +110,7 @@ export const useMenu = (menuEvents, options) => {
90
110
  menuEvents[`on${i.name}`]?.(data);
91
111
  onClose();
92
112
  }}>
93
- {isLoading && i.loadingText}
113
+ {isLoading && i.loadingText && t(`ai-plugin:actionLoading:${i.loadingText.toLowerCase()}`)}
94
114
  </Action>);
95
115
  })}
96
116
  </div>);
@@ -0,0 +1,14 @@
1
+ type MergeGeneratedValueArgs = {
2
+ appendGenerated: boolean;
3
+ currentValue: unknown;
4
+ generatedValue: unknown;
5
+ hasMany: boolean;
6
+ max?: number;
7
+ maxRows?: number;
8
+ };
9
+ type MergeGeneratedValueResult = {
10
+ truncated: boolean;
11
+ value: unknown;
12
+ };
13
+ export declare const mergeGeneratedValue: ({ appendGenerated, currentValue, generatedValue, hasMany, max, maxRows, }: MergeGeneratedValueArgs) => MergeGeneratedValueResult;
14
+ export {};
@@ -0,0 +1,38 @@
1
+ const toArray = (value)=>{
2
+ if (Array.isArray(value)) {
3
+ return value;
4
+ }
5
+ if (value === null || value === undefined || value === '') {
6
+ return [];
7
+ }
8
+ return [
9
+ value
10
+ ];
11
+ };
12
+ export const mergeGeneratedValue = ({ appendGenerated, currentValue, generatedValue, hasMany, max, maxRows })=>{
13
+ if (!appendGenerated || !hasMany) {
14
+ return {
15
+ truncated: false,
16
+ value: generatedValue
17
+ };
18
+ }
19
+ const current = toArray(currentValue);
20
+ const generated = toArray(generatedValue);
21
+ const merged = [
22
+ ...current,
23
+ ...generated
24
+ ];
25
+ const limit = typeof maxRows === 'number' ? maxRows : typeof max === 'number' ? max : undefined;
26
+ if (typeof limit === 'number' && limit >= 0 && merged.length > limit) {
27
+ return {
28
+ truncated: true,
29
+ value: merged.slice(0, limit)
30
+ };
31
+ }
32
+ return {
33
+ truncated: false,
34
+ value: merged
35
+ };
36
+ };
37
+
38
+ //# sourceMappingURL=mergeGeneratedValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/ui/Compose/hooks/mergeGeneratedValue.ts"],"sourcesContent":["type MergeGeneratedValueArgs = {\n appendGenerated: boolean\n currentValue: unknown\n generatedValue: unknown\n hasMany: boolean\n max?: number\n maxRows?: number\n}\n\ntype MergeGeneratedValueResult = {\n truncated: boolean\n value: unknown\n}\n\nconst toArray = (value: unknown): unknown[] => {\n if (Array.isArray(value)) {\n return value\n }\n\n if (value === null || value === undefined || value === '') {\n return []\n }\n\n return [value]\n}\n\nexport const mergeGeneratedValue = ({\n appendGenerated,\n currentValue,\n generatedValue,\n hasMany,\n max,\n maxRows,\n}: MergeGeneratedValueArgs): MergeGeneratedValueResult => {\n if (!appendGenerated || !hasMany) {\n return {\n truncated: false,\n value: generatedValue,\n }\n }\n\n const current = toArray(currentValue)\n const generated = toArray(generatedValue)\n\n const merged = [...current, ...generated]\n const limit = typeof maxRows === 'number' ? maxRows : typeof max === 'number' ? max : undefined\n\n if (typeof limit === 'number' && limit >= 0 && merged.length > limit) {\n return {\n truncated: true,\n value: merged.slice(0, limit),\n }\n }\n\n return {\n truncated: false,\n value: merged,\n }\n}\n"],"names":["toArray","value","Array","isArray","undefined","mergeGeneratedValue","appendGenerated","currentValue","generatedValue","hasMany","max","maxRows","truncated","current","generated","merged","limit","length","slice"],"mappings":"AAcA,MAAMA,UAAU,CAACC;IACf,IAAIC,MAAMC,OAAO,CAACF,QAAQ;QACxB,OAAOA;IACT;IAEA,IAAIA,UAAU,QAAQA,UAAUG,aAAaH,UAAU,IAAI;QACzD,OAAO,EAAE;IACX;IAEA,OAAO;QAACA;KAAM;AAChB;AAEA,OAAO,MAAMI,sBAAsB,CAAC,EAClCC,eAAe,EACfC,YAAY,EACZC,cAAc,EACdC,OAAO,EACPC,GAAG,EACHC,OAAO,EACiB;IACxB,IAAI,CAACL,mBAAmB,CAACG,SAAS;QAChC,OAAO;YACLG,WAAW;YACXX,OAAOO;QACT;IACF;IAEA,MAAMK,UAAUb,QAAQO;IACxB,MAAMO,YAAYd,QAAQQ;IAE1B,MAAMO,SAAS;WAAIF;WAAYC;KAAU;IACzC,MAAME,QAAQ,OAAOL,YAAY,WAAWA,UAAU,OAAOD,QAAQ,WAAWA,MAAMN;IAEtF,IAAI,OAAOY,UAAU,YAAYA,SAAS,KAAKD,OAAOE,MAAM,GAAGD,OAAO;QACpE,OAAO;YACLJ,WAAW;YACXX,OAAOc,OAAOG,KAAK,CAAC,GAAGF;QACzB;IACF;IAEA,OAAO;QACLJ,WAAW;QACXX,OAAOc;IACT;AACF,EAAC"}
@@ -15,6 +15,8 @@ const fieldTypeCache = new WeakMap();
15
15
  let pointerDownThrottleTimer = null;
16
16
  let focusDebounceTimer = null;
17
17
  let currentContainer = null;
18
+ let lastContainer = null // Track last valid container to restore if needed
19
+ ;
18
20
  let rafId = null // Track RAF to cancel if needed
19
21
  ;
20
22
  /**
@@ -106,6 +108,8 @@ let rafId = null // Track RAF to cancel if needed
106
108
  currentContainer?.classList.remove('ai-plugin-active');
107
109
  if (next) {
108
110
  next.classList.add('ai-plugin-active');
111
+ lastContainer = next // Update last known valid container
112
+ ;
109
113
  }
110
114
  currentContainer = next;
111
115
  };
@@ -113,6 +117,7 @@ const clearActiveContainer = ()=>{
113
117
  if (currentContainer) {
114
118
  currentContainer.classList.remove('ai-plugin-active');
115
119
  currentContainer = null;
120
+ // Note: We do NOT clear lastContainer here, allowing restoration
116
121
  }
117
122
  // Cancel any pending RAF
118
123
  if (rafId !== null) {
@@ -147,6 +152,23 @@ const isInteractiveElement = (element)=>{
147
152
  }
148
153
  return false;
149
154
  };
155
+ // Helper for interactive menu check
156
+ const checkInteractiveMenu = (e)=>{
157
+ // Check global flag first (most reliable for mouse/hover interactions)
158
+ if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE) {
159
+ return true;
160
+ }
161
+ const target = e.target;
162
+ // Check target directly
163
+ if (target && target instanceof Element && (target.classList.contains('ai-interactive-menu') || target.hasAttribute('data-ai-interactive'))) {
164
+ return true;
165
+ }
166
+ // Fallback: Check DOM path (for keyboard or specific events)
167
+ const path = e.composedPath();
168
+ return path.some((el)=>{
169
+ return el instanceof Element && (el.classList.contains('ai-interactive-menu') || el.hasAttribute('data-ai-interactive'));
170
+ });
171
+ };
150
172
  /**
151
173
  * Handle focus events - only activate if focus is on an interactive element within .field-type
152
174
  * Performance: Debounced by 10ms to handle rapid focus changes
@@ -163,6 +185,14 @@ const isInteractiveElement = (element)=>{
163
185
  if (!isInteractiveElement(target)) {
164
186
  return;
165
187
  }
188
+ // Check for interactive menu elements using composedPath for robustness
189
+ if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE || checkInteractiveMenu(e)) {
190
+ // If we lost the active state (e.g. due to pointerDown clearing it), restore it
191
+ if (!currentContainer && lastContainer?.isConnected) {
192
+ setActiveContainer(lastContainer);
193
+ }
194
+ return;
195
+ }
166
196
  // Clear any pending debounce
167
197
  if (focusDebounceTimer !== null) {
168
198
  clearTimeout(focusDebounceTimer);
@@ -182,6 +212,10 @@ const isInteractiveElement = (element)=>{
182
212
  if (!(target instanceof HTMLElement)) {
183
213
  return;
184
214
  }
215
+ // Check for interactive menu elements using composedPath
216
+ if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE || checkInteractiveMenu(e)) {
217
+ return;
218
+ }
185
219
  // Early exit if clicking within current container
186
220
  if (currentContainer?.isConnected && currentContainer.contains(target)) {
187
221
  return;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/ui/Compose/hooks/useActiveFieldTracking.ts"],"sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\n\n/**\n * Allowed field type classes that should show the active state\n */\nconst ALLOWED_FIELD_TYPES = ['upload', 'text', 'textarea', 'rich-text-lexical']\n\n// Performance optimization: Cache container and field type lookups\nconst containerCache = new WeakMap<HTMLElement, HTMLElement | null>()\nconst fieldTypeCache = new WeakMap<HTMLElement, boolean>()\n\n// Performance optimization: Throttle/debounce timers\nlet pointerDownThrottleTimer: null | number = null\nlet focusDebounceTimer: null | number = null\n\nlet currentContainer: HTMLElement | null = null\nlet rafId: null | number = null // Track RAF to cancel if needed\n\n/**\n * Safely escape CSS selector values\n */\nconst cssEscape = (value: string): string => {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value)\n }\n return value.replace(/([ #;?%&,.+*~':\"!^$[\\]()=>|/@])/g, '\\\\$1')\n}\n\n/**\n * Find container from React Select dropdown elements\n * Performance: Early exit if not in a listbox/option element\n */\nconst findContainerFromReactSelect = (target: HTMLElement): HTMLElement | null => {\n // Early exit if element doesn't have role indicator for React Select\n const role = target.getAttribute('role')\n if (!role || !['listbox', 'option'].includes(role)) {\n return null\n }\n\n const listbox = target.closest<HTMLElement>('[role=\"listbox\"]')\n if (!listbox?.id) {\n return null\n }\n\n const id = cssEscape(listbox.id)\n const selector = `[aria-controls=\"${id}\"], [aria-owns=\"${id}\"]`\n const control = document.querySelector<HTMLElement>(selector)\n\n return control?.closest<HTMLElement>('.field-type') ?? null\n}\n\n/**\n * Check if a container has one of the allowed field type classes\n * Performance: Uses WeakMap cache to avoid repeated class list checks\n */\nconst isAllowedFieldType = (container: HTMLElement): boolean => {\n // Check cache first\n if (fieldTypeCache.has(container)) {\n return fieldTypeCache.get(container)!\n }\n\n // Compute and cache result\n const result = ALLOWED_FIELD_TYPES.some(\n (type) =>\n container.classList.contains(type) || container.classList.contains(`field-type-${type}`),\n )\n\n fieldTypeCache.set(container, result)\n return result\n}\n\n/**\n * Resolve the .field-type container for a given event target\n * Only returns containers that match allowed field types\n * Performance: Uses WeakMap cache to avoid repeated DOM traversals\n */\nconst resolveContainerFromTarget = (target: EventTarget | null): HTMLElement | null => {\n if (!(target instanceof HTMLElement)) {\n return null\n }\n\n // Check cache first\n if (containerCache.has(target)) {\n const cached = containerCache.get(target)!\n // Validate cache entry is still in DOM\n if (!cached || cached.isConnected) {\n return cached\n }\n // Invalidate stale cache entry\n containerCache.delete(target)\n }\n\n // Perform lookup\n let container = target.closest<HTMLElement>('.field-type')\n\n // Fall back to React Select logic if needed\n if (!container) {\n container = findContainerFromReactSelect(target)\n }\n\n // Validate field type and cache result\n const result = container && isAllowedFieldType(container) ? container : null\n containerCache.set(target, result)\n\n return result\n}\n\n/**\n * Update the active container and toggle CSS class\n * - Avoids acting on disconnected nodes\n * - Avoids redundant class work\n */\nconst setActiveContainer = (next: HTMLElement | null): void => {\n // Normalize both references against disconnected nodes\n if (currentContainer && !currentContainer.isConnected) {\n currentContainer = null\n }\n if (next && !next.isConnected) {\n next = null\n }\n\n if (currentContainer === next) {\n return\n }\n\n currentContainer?.classList.remove('ai-plugin-active')\n if (next) {\n next.classList.add('ai-plugin-active')\n }\n currentContainer = next\n}\n\nconst clearActiveContainer = (): void => {\n if (currentContainer) {\n currentContainer.classList.remove('ai-plugin-active')\n currentContainer = null\n }\n\n // Cancel any pending RAF\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n}\n\nconst isInteractiveElement = (element: HTMLElement): boolean => {\n const tagName = element.tagName.toLowerCase()\n const interactiveTags = ['input', 'textarea', 'select', 'button']\n\n if (interactiveTags.includes(tagName)) {\n return true\n }\n\n // Check for contenteditable\n if (element.isContentEditable) {\n return true\n }\n\n // Check for elements with role=\"textbox\" or role=\"combobox\" (React Select)\n const role = element.getAttribute('role')\n if (role && ['combobox', 'listbox', 'searchbox', 'textbox'].includes(role)) {\n return true\n }\n\n return false\n}\n\n/**\n * Handle focus events - only activate if focus is on an interactive element within .field-type\n * Performance: Debounced by 10ms to handle rapid focus changes\n */\nconst onFocusIn = (e: FocusEvent): void => {\n const target = e.target\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n // Early exit if we're already inside the current container\n if (currentContainer?.isConnected && currentContainer.contains(target)) {\n return\n }\n\n // Only activate if the focused element is actually interactive\n if (!isInteractiveElement(target)) {\n return\n }\n\n // Clear any pending debounce\n if (focusDebounceTimer !== null) {\n clearTimeout(focusDebounceTimer)\n }\n\n // Debounce to reduce work during rapid focus changes (e.g., fast tabbing)\n focusDebounceTimer = window.setTimeout(() => {\n focusDebounceTimer = null\n const container = resolveContainerFromTarget(target)\n setActiveContainer(container)\n }, 10)\n}\n\n/**\n * Handle pointer/mouse events - only switch when clicking a different .field-type\n * Performance: Early exit for non-field clicks + 50ms throttling\n */\nconst onPointerDown = (e: PointerEvent): void => {\n const target = e.target\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n // Early exit if clicking within current container\n if (currentContainer?.isConnected && currentContainer.contains(target)) {\n return\n }\n\n // Performance: Quick check before expensive traversal\n // If click is nowhere near a field, just clear active state\n if (!target.closest('.field-type')) {\n if (currentContainer) {\n setActiveContainer(null)\n }\n return\n }\n\n // Throttle to prevent excessive work on rapid clicking\n if (pointerDownThrottleTimer !== null) {\n return\n }\n\n const container = resolveContainerFromTarget(target)\n setActiveContainer(container)\n\n // Set throttle timer for 50ms\n pointerDownThrottleTimer = window.setTimeout(() => {\n pointerDownThrottleTimer = null\n }, 50)\n}\n\n/**\n * Handle keyboard navigation (Tab key)\n */\nconst onKeyDown = (e: KeyboardEvent): void => {\n if (e.key !== 'Tab') {\n return\n }\n\n // Cancel any pending RAF to prevent queuing\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n\n // Defer until after focus has shifted\n rafId = requestAnimationFrame(() => {\n rafId = null\n const container = resolveContainerFromTarget(document.activeElement)\n setActiveContainer(container)\n })\n}\n\n/**\n * Handle visibility changes to properly cleanup when page is hidden\n */\nconst onVisibilityChange = (): void => {\n if (typeof document !== 'undefined' && document.hidden) {\n // Clear active state and cancel pending operations\n clearActiveContainer()\n }\n}\n\n/**\n * Initialize document-level listeners to track the active field container.\n * When a container is active, it receives the 'ai-plugin-active' class.\n */\nexport const useActiveFieldTracking = (): void => {\n useEffect(() => {\n if (typeof window === 'undefined') {\n return\n }\n\n const pluginWindow = window as {\n __aiComposeTracking?: boolean\n __aiComposeTrackingController?: AbortController\n __aiComposeTrackingCount?: number\n } & Window\n\n // Track number of mounted users of the hook\n pluginWindow.__aiComposeTrackingCount = (pluginWindow.__aiComposeTrackingCount ?? 0) + 1\n\n // Initialize listeners only once\n if (!pluginWindow.__aiComposeTracking) {\n const controller = new AbortController()\n pluginWindow.__aiComposeTrackingController = controller\n\n // Use capture for early handling\n document.addEventListener('focusin', onFocusIn, {\n capture: true,\n signal: controller.signal,\n })\n document.addEventListener('pointerdown', onPointerDown, {\n capture: true,\n passive: true,\n signal: controller.signal,\n })\n document.addEventListener('keydown', onKeyDown, {\n capture: true,\n signal: controller.signal,\n })\n document.addEventListener('visibilitychange', onVisibilityChange, {\n signal: controller.signal,\n })\n\n pluginWindow.__aiComposeTracking = true\n }\n\n return () => {\n // Decrement and cleanup when the last user unmounts\n pluginWindow.__aiComposeTrackingCount = (pluginWindow.__aiComposeTrackingCount ?? 1) - 1\n\n if ((pluginWindow.__aiComposeTrackingCount ?? 0) <= 0) {\n // Atomically remove all listeners\n pluginWindow.__aiComposeTrackingController?.abort()\n pluginWindow.__aiComposeTrackingController = undefined\n\n // Clear active state and cancel pending operations\n clearActiveContainer()\n\n // Reset all state\n pluginWindow.__aiComposeTracking = false\n pluginWindow.__aiComposeTrackingCount = 0\n }\n }\n }, [])\n}\n"],"names":["useEffect","ALLOWED_FIELD_TYPES","containerCache","WeakMap","fieldTypeCache","pointerDownThrottleTimer","focusDebounceTimer","currentContainer","rafId","cssEscape","value","CSS","escape","replace","findContainerFromReactSelect","target","role","getAttribute","includes","listbox","closest","id","selector","control","document","querySelector","isAllowedFieldType","container","has","get","result","some","type","classList","contains","set","resolveContainerFromTarget","HTMLElement","cached","isConnected","delete","setActiveContainer","next","remove","add","clearActiveContainer","cancelAnimationFrame","isInteractiveElement","element","tagName","toLowerCase","interactiveTags","isContentEditable","onFocusIn","e","clearTimeout","window","setTimeout","onPointerDown","onKeyDown","key","requestAnimationFrame","activeElement","onVisibilityChange","hidden","useActiveFieldTracking","pluginWindow","__aiComposeTrackingCount","__aiComposeTracking","controller","AbortController","__aiComposeTrackingController","addEventListener","capture","signal","passive","abort","undefined"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/ui/Compose/hooks/useActiveFieldTracking.ts"],"sourcesContent":["'use client'\n\nimport { useEffect } from 'react'\n\n/**\n * Allowed field type classes that should show the active state\n */\nconst ALLOWED_FIELD_TYPES = ['upload', 'text', 'textarea', 'rich-text-lexical']\n\n// Performance optimization: Cache container and field type lookups\nconst containerCache = new WeakMap<HTMLElement, HTMLElement | null>()\nconst fieldTypeCache = new WeakMap<HTMLElement, boolean>()\n\n// Performance optimization: Throttle/debounce timers\nlet pointerDownThrottleTimer: null | number = null\nlet focusDebounceTimer: null | number = null\n\nlet currentContainer: HTMLElement | null = null\nlet lastContainer: HTMLElement | null = null // Track last valid container to restore if needed\nlet rafId: null | number = null // Track RAF to cancel if needed\n\n/**\n * Safely escape CSS selector values\n */\nconst cssEscape = (value: string): string => {\n if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {\n return CSS.escape(value)\n }\n return value.replace(/([ #;?%&,.+*~':\"!^$[\\]()=>|/@])/g, '\\\\$1')\n}\n\n/**\n * Find container from React Select dropdown elements\n * Performance: Early exit if not in a listbox/option element\n */\nconst findContainerFromReactSelect = (target: HTMLElement): HTMLElement | null => {\n // Early exit if element doesn't have role indicator for React Select\n const role = target.getAttribute('role')\n if (!role || !['listbox', 'option'].includes(role)) {\n return null\n }\n\n const listbox = target.closest<HTMLElement>('[role=\"listbox\"]')\n if (!listbox?.id) {\n return null\n }\n\n const id = cssEscape(listbox.id)\n const selector = `[aria-controls=\"${id}\"], [aria-owns=\"${id}\"]`\n const control = document.querySelector<HTMLElement>(selector)\n\n return control?.closest<HTMLElement>('.field-type') ?? null\n}\n\n/**\n * Check if a container has one of the allowed field type classes\n * Performance: Uses WeakMap cache to avoid repeated class list checks\n */\nconst isAllowedFieldType = (container: HTMLElement): boolean => {\n // Check cache first\n if (fieldTypeCache.has(container)) {\n return fieldTypeCache.get(container)!\n }\n\n // Compute and cache result\n const result = ALLOWED_FIELD_TYPES.some(\n (type) =>\n container.classList.contains(type) || container.classList.contains(`field-type-${type}`),\n )\n\n fieldTypeCache.set(container, result)\n return result\n}\n\n/**\n * Resolve the .field-type container for a given event target\n * Only returns containers that match allowed field types\n * Performance: Uses WeakMap cache to avoid repeated DOM traversals\n */\nconst resolveContainerFromTarget = (target: EventTarget | null): HTMLElement | null => {\n if (!(target instanceof HTMLElement)) {\n return null\n }\n\n // Check cache first\n if (containerCache.has(target)) {\n const cached = containerCache.get(target)!\n // Validate cache entry is still in DOM\n if (!cached || cached.isConnected) {\n return cached\n }\n // Invalidate stale cache entry\n containerCache.delete(target)\n }\n\n // Perform lookup\n let container = target.closest<HTMLElement>('.field-type')\n\n // Fall back to React Select logic if needed\n if (!container) {\n container = findContainerFromReactSelect(target)\n }\n\n // Validate field type and cache result\n const result = container && isAllowedFieldType(container) ? container : null\n containerCache.set(target, result)\n\n return result\n}\n\n/**\n * Update the active container and toggle CSS class\n * - Avoids acting on disconnected nodes\n * - Avoids redundant class work\n */\nconst setActiveContainer = (next: HTMLElement | null): void => {\n // Normalize both references against disconnected nodes\n if (currentContainer && !currentContainer.isConnected) {\n currentContainer = null\n }\n if (next && !next.isConnected) {\n next = null\n }\n\n if (currentContainer === next) {\n return\n }\n\n currentContainer?.classList.remove('ai-plugin-active')\n if (next) {\n next.classList.add('ai-plugin-active')\n lastContainer = next // Update last known valid container\n }\n currentContainer = next\n}\n\nconst clearActiveContainer = (): void => {\n if (currentContainer) {\n currentContainer.classList.remove('ai-plugin-active')\n currentContainer = null\n // Note: We do NOT clear lastContainer here, allowing restoration\n }\n\n // Cancel any pending RAF\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n rafId = null\n }\n}\n\nconst isInteractiveElement = (element: HTMLElement): boolean => {\n const tagName = element.tagName.toLowerCase()\n const interactiveTags = ['input', 'textarea', 'select', 'button']\n\n if (interactiveTags.includes(tagName)) {\n return true\n }\n\n // Check for contenteditable\n if (element.isContentEditable) {\n return true\n }\n\n // Check for elements with role=\"textbox\" or role=\"combobox\" (React Select)\n const role = element.getAttribute('role')\n if (role && ['combobox', 'listbox', 'searchbox', 'textbox'].includes(role)) {\n return true\n }\n\n return false\n}\n\n// Helper for interactive menu check\nconst checkInteractiveMenu = (e: Event): boolean => {\n // Check global flag first (most reliable for mouse/hover interactions)\n if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE) {\n return true\n }\n\n const target = e.target as Element\n\n // Check target directly\n if (\n target &&\n target instanceof Element &&\n (target.classList.contains('ai-interactive-menu') || target.hasAttribute('data-ai-interactive'))\n ) {\n return true\n }\n\n // Fallback: Check DOM path (for keyboard or specific events)\n const path = e.composedPath()\n return path.some((el) => {\n return (\n el instanceof Element &&\n (el.classList.contains('ai-interactive-menu') || el.hasAttribute('data-ai-interactive'))\n )\n })\n}\n\n/**\n * Handle focus events - only activate if focus is on an interactive element within .field-type\n * Performance: Debounced by 10ms to handle rapid focus changes\n */\nconst onFocusIn = (e: FocusEvent): void => {\n const target = e.target\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n // Early exit if we're already inside the current container\n if (currentContainer?.isConnected && currentContainer.contains(target)) {\n return\n }\n\n // Only activate if the focused element is actually interactive\n if (!isInteractiveElement(target)) {\n return\n }\n\n // Check for interactive menu elements using composedPath for robustness\n if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE || checkInteractiveMenu(e)) {\n // If we lost the active state (e.g. due to pointerDown clearing it), restore it\n if (!currentContainer && lastContainer?.isConnected) {\n setActiveContainer(lastContainer)\n }\n return\n }\n\n // Clear any pending debounce\n if (focusDebounceTimer !== null) {\n clearTimeout(focusDebounceTimer)\n }\n\n // Debounce to reduce work during rapid focus changes (e.g., fast tabbing)\n focusDebounceTimer = window.setTimeout(() => {\n focusDebounceTimer = null\n const container = resolveContainerFromTarget(target)\n setActiveContainer(container)\n }, 10)\n}\n\n/**\n * Handle pointer/mouse events - only switch when clicking a different .field-type\n * Performance: Early exit for non-field clicks + 50ms throttling\n */\nconst onPointerDown = (e: PointerEvent): void => {\n const target = e.target\n if (!(target instanceof HTMLElement)) {\n return\n }\n\n // Check for interactive menu elements using composedPath\n if (typeof window !== 'undefined' && window.__AI_MENU_INTERACTIVE || checkInteractiveMenu(e)) {\n return\n }\n\n // Early exit if clicking within current container\n if (currentContainer?.isConnected && currentContainer.contains(target)) {\n return\n }\n\n // Performance: Quick check before expensive traversal\n // If click is nowhere near a field, just clear active state\n if (!target.closest('.field-type')) {\n if (currentContainer) {\n setActiveContainer(null)\n }\n return\n }\n\n // Throttle to prevent excessive work on rapid clicking\n if (pointerDownThrottleTimer !== null) {\n return\n }\n\n const container = resolveContainerFromTarget(target)\n setActiveContainer(container)\n\n // Set throttle timer for 50ms\n pointerDownThrottleTimer = window.setTimeout(() => {\n pointerDownThrottleTimer = null\n }, 50)\n}\n\n/**\n * Handle keyboard navigation (Tab key)\n */\nconst onKeyDown = (e: KeyboardEvent): void => {\n if (e.key !== 'Tab') {\n return\n }\n\n // Cancel any pending RAF to prevent queuing\n if (rafId !== null) {\n cancelAnimationFrame(rafId)\n }\n\n // Defer until after focus has shifted\n rafId = requestAnimationFrame(() => {\n rafId = null\n const container = resolveContainerFromTarget(document.activeElement)\n setActiveContainer(container)\n })\n}\n\n/**\n * Handle visibility changes to properly cleanup when page is hidden\n */\nconst onVisibilityChange = (): void => {\n if (typeof document !== 'undefined' && document.hidden) {\n // Clear active state and cancel pending operations\n clearActiveContainer()\n }\n}\n\n/**\n * Initialize document-level listeners to track the active field container.\n * When a container is active, it receives the 'ai-plugin-active' class.\n */\nexport const useActiveFieldTracking = (): void => {\n useEffect(() => {\n if (typeof window === 'undefined') {\n return\n }\n\n const pluginWindow = window as {\n __aiComposeTracking?: boolean\n __aiComposeTrackingController?: AbortController\n __aiComposeTrackingCount?: number\n } & Window\n\n // Track number of mounted users of the hook\n pluginWindow.__aiComposeTrackingCount = (pluginWindow.__aiComposeTrackingCount ?? 0) + 1\n\n // Initialize listeners only once\n if (!pluginWindow.__aiComposeTracking) {\n const controller = new AbortController()\n pluginWindow.__aiComposeTrackingController = controller\n\n // Use capture for early handling\n document.addEventListener('focusin', onFocusIn, {\n capture: true,\n signal: controller.signal,\n })\n document.addEventListener('pointerdown', onPointerDown, {\n capture: true,\n passive: true,\n signal: controller.signal,\n })\n document.addEventListener('keydown', onKeyDown, {\n capture: true,\n signal: controller.signal,\n })\n document.addEventListener('visibilitychange', onVisibilityChange, {\n signal: controller.signal,\n })\n\n pluginWindow.__aiComposeTracking = true\n }\n\n return () => {\n // Decrement and cleanup when the last user unmounts\n pluginWindow.__aiComposeTrackingCount = (pluginWindow.__aiComposeTrackingCount ?? 1) - 1\n\n if ((pluginWindow.__aiComposeTrackingCount ?? 0) <= 0) {\n // Atomically remove all listeners\n pluginWindow.__aiComposeTrackingController?.abort()\n pluginWindow.__aiComposeTrackingController = undefined\n\n // Clear active state and cancel pending operations\n clearActiveContainer()\n\n // Reset all state\n pluginWindow.__aiComposeTracking = false\n pluginWindow.__aiComposeTrackingCount = 0\n }\n }\n }, [])\n}\n"],"names":["useEffect","ALLOWED_FIELD_TYPES","containerCache","WeakMap","fieldTypeCache","pointerDownThrottleTimer","focusDebounceTimer","currentContainer","lastContainer","rafId","cssEscape","value","CSS","escape","replace","findContainerFromReactSelect","target","role","getAttribute","includes","listbox","closest","id","selector","control","document","querySelector","isAllowedFieldType","container","has","get","result","some","type","classList","contains","set","resolveContainerFromTarget","HTMLElement","cached","isConnected","delete","setActiveContainer","next","remove","add","clearActiveContainer","cancelAnimationFrame","isInteractiveElement","element","tagName","toLowerCase","interactiveTags","isContentEditable","checkInteractiveMenu","e","window","__AI_MENU_INTERACTIVE","Element","hasAttribute","path","composedPath","el","onFocusIn","clearTimeout","setTimeout","onPointerDown","onKeyDown","key","requestAnimationFrame","activeElement","onVisibilityChange","hidden","useActiveFieldTracking","pluginWindow","__aiComposeTrackingCount","__aiComposeTracking","controller","AbortController","__aiComposeTrackingController","addEventListener","capture","signal","passive","abort","undefined"],"mappings":"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"}