@automattic/jetpack-ai-client 0.25.7 → 0.26.1

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 (227) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/build/components/ai-icon/index.d.ts +10 -0
  3. package/build/components/ai-icon/index.js +16 -0
  4. package/build/components/ai-image/components/ai-image-modal.d.ts +57 -0
  5. package/build/components/ai-image/components/ai-image-modal.js +92 -0
  6. package/build/components/ai-image/components/carrousel.d.ts +28 -0
  7. package/build/components/ai-image/components/carrousel.js +69 -0
  8. package/build/components/ai-image/components/usage-counter.d.ts +16 -0
  9. package/build/components/ai-image/components/usage-counter.js +29 -0
  10. package/build/components/ai-image/featured-image.d.ts +17 -0
  11. package/build/components/ai-image/featured-image.js +278 -0
  12. package/build/components/ai-image/general-purpose-image.d.ts +23 -0
  13. package/build/components/ai-image/general-purpose-image.js +184 -0
  14. package/build/components/ai-image/hooks/use-ai-image.d.ts +48 -0
  15. package/build/components/ai-image/hooks/use-ai-image.js +219 -0
  16. package/build/components/ai-image/hooks/use-site-type.d.ts +6 -0
  17. package/build/components/ai-image/hooks/use-site-type.js +23 -0
  18. package/build/components/ai-image/index.d.ts +4 -0
  19. package/build/components/ai-image/index.js +4 -0
  20. package/build/components/ai-image/types.d.ts +16 -0
  21. package/build/components/ai-image/types.js +6 -0
  22. package/build/{ai-client/src/components → components}/index.d.ts +4 -0
  23. package/build/{ai-client/src/components → components}/index.js +4 -0
  24. package/build/components/modal/index.d.ts +18 -0
  25. package/build/components/modal/index.js +23 -0
  26. package/build/components/quota-exceeded-message/index.d.ts +13 -0
  27. package/build/components/quota-exceeded-message/index.js +152 -0
  28. package/build/components/quota-exceeded-message/light-nudge.d.ts +11 -0
  29. package/build/components/quota-exceeded-message/light-nudge.js +8 -0
  30. package/build/{ai-client/src/constants.d.ts → constants.d.ts} +3 -0
  31. package/build/{ai-client/src/constants.js → constants.js} +4 -0
  32. package/build/hooks/use-ai-checkout/index.d.ts +13 -0
  33. package/build/hooks/use-ai-checkout/index.js +41 -0
  34. package/build/hooks/use-ai-feature/index.d.ts +33 -0
  35. package/build/hooks/use-ai-feature/index.js +37 -0
  36. package/build/hooks/use-post-content.d.ts +5 -0
  37. package/build/hooks/use-post-content.js +20 -0
  38. package/build/hooks/use-save-to-media-library.d.ts +12 -0
  39. package/build/hooks/use-save-to-media-library.js +74 -0
  40. package/build/{ai-client/src/index.d.ts → index.d.ts} +3 -0
  41. package/build/{ai-client/src/index.js → index.js} +3 -0
  42. package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.js +1 -1
  43. package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.js +1 -1
  44. package/package.json +20 -14
  45. package/src/components/ai-icon/index.tsx +39 -0
  46. package/src/components/ai-image/components/ai-image-modal.scss +88 -0
  47. package/src/components/ai-image/components/ai-image-modal.tsx +240 -0
  48. package/src/components/ai-image/components/carrousel.scss +163 -0
  49. package/src/components/ai-image/components/carrousel.tsx +217 -0
  50. package/src/components/ai-image/components/usage-counter.scss +19 -0
  51. package/src/components/ai-image/components/usage-counter.tsx +54 -0
  52. package/src/components/ai-image/featured-image.tsx +439 -0
  53. package/src/components/ai-image/general-purpose-image.tsx +303 -0
  54. package/src/components/ai-image/hooks/use-ai-image.ts +339 -0
  55. package/src/components/ai-image/hooks/use-site-type.ts +26 -0
  56. package/src/components/ai-image/index.ts +10 -0
  57. package/src/components/ai-image/style.scss +95 -0
  58. package/src/components/ai-image/types.ts +19 -0
  59. package/src/components/index.ts +12 -0
  60. package/src/components/modal/index.tsx +70 -0
  61. package/src/components/modal/style.scss +45 -0
  62. package/src/components/quota-exceeded-message/index.tsx +319 -0
  63. package/src/components/quota-exceeded-message/light-nudge.tsx +38 -0
  64. package/src/components/quota-exceeded-message/style.scss +35 -0
  65. package/src/constants.ts +5 -0
  66. package/src/hooks/use-ai-checkout/index.ts +65 -0
  67. package/src/hooks/use-ai-feature/Readme.md +20 -0
  68. package/src/hooks/use-ai-feature/index.ts +62 -0
  69. package/src/hooks/use-post-content.ts +27 -0
  70. package/src/hooks/use-save-to-media-library.ts +100 -0
  71. package/src/index.ts +3 -0
  72. package/src/logo-generator/components/upgrade-screen.tsx +1 -1
  73. package/src/logo-generator/hooks/use-fair-usage-notice-message.tsx +1 -1
  74. package/build/components/tools/jp-redirect/index.d.ts +0 -20
  75. package/build/components/tools/jp-redirect/index.js +0 -50
  76. package/build/components/tools/jp-redirect/types.d.ts +0 -39
  77. package/build/components/tools/jp-redirect/types.js +0 -1
  78. /package/build/{ai-client/src/api-fetch → api-fetch}/index.d.ts +0 -0
  79. /package/build/{ai-client/src/api-fetch → api-fetch}/index.js +0 -0
  80. /package/build/{ai-client/src/ask-question → ask-question}/index.d.ts +0 -0
  81. /package/build/{ai-client/src/ask-question → ask-question}/index.js +0 -0
  82. /package/build/{ai-client/src/ask-question → ask-question}/sync.d.ts +0 -0
  83. /package/build/{ai-client/src/ask-question → ask-question}/sync.js +0 -0
  84. /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.d.ts +0 -0
  85. /package/build/{ai-client/src/audio-transcription → audio-transcription}/index.js +0 -0
  86. /package/build/{ai-client/src/components → components}/ai-control/ai-control.d.ts +0 -0
  87. /package/build/{ai-client/src/components → components}/ai-control/ai-control.js +0 -0
  88. /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.d.ts +0 -0
  89. /package/build/{ai-client/src/components → components}/ai-control/block-ai-control.js +0 -0
  90. /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.d.ts +0 -0
  91. /package/build/{ai-client/src/components → components}/ai-control/extension-ai-control.js +0 -0
  92. /package/build/{ai-client/src/components → components}/ai-control/index.d.ts +0 -0
  93. /package/build/{ai-client/src/components → components}/ai-control/index.js +0 -0
  94. /package/build/{ai-client/src/components → components}/ai-feedback/index.d.ts +0 -0
  95. /package/build/{ai-client/src/components → components}/ai-feedback/index.js +0 -0
  96. /package/build/{ai-client/src/components → components}/ai-modal-footer/index.d.ts +0 -0
  97. /package/build/{ai-client/src/components → components}/ai-modal-footer/index.js +0 -0
  98. /package/build/{ai-client/src/components → components}/ai-status-indicator/index.d.ts +0 -0
  99. /package/build/{ai-client/src/components → components}/ai-status-indicator/index.js +0 -0
  100. /package/build/{ai-client/src/components → components}/audio-duration-display/index.d.ts +0 -0
  101. /package/build/{ai-client/src/components → components}/audio-duration-display/index.js +0 -0
  102. /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.d.ts +0 -0
  103. /package/build/{ai-client/src/components → components}/audio-duration-display/lib/media.js +0 -0
  104. /package/build/{ai-client/src/components → components}/message/index.d.ts +0 -0
  105. /package/build/{ai-client/src/components → components}/message/index.js +0 -0
  106. /package/build/{ai-client/src/data-flow → data-flow}/context.d.ts +0 -0
  107. /package/build/{ai-client/src/data-flow → data-flow}/context.js +0 -0
  108. /package/build/{ai-client/src/data-flow → data-flow}/index.d.ts +0 -0
  109. /package/build/{ai-client/src/data-flow → data-flow}/index.js +0 -0
  110. /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.d.ts +0 -0
  111. /package/build/{ai-client/src/data-flow → data-flow}/use-ai-context.js +0 -0
  112. /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.d.ts +0 -0
  113. /package/build/{ai-client/src/data-flow → data-flow}/with-ai-assistant-data.js +0 -0
  114. /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.d.ts +0 -0
  115. /package/build/{ai-client/src/hooks → hooks}/use-ai-suggestions/index.js +0 -0
  116. /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.d.ts +0 -0
  117. /package/build/{ai-client/src/hooks → hooks}/use-audio-transcription/index.js +0 -0
  118. /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.d.ts +0 -0
  119. /package/build/{ai-client/src/hooks → hooks}/use-audio-validation/index.js +0 -0
  120. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.d.ts +0 -0
  121. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/constants.js +0 -0
  122. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.d.ts +0 -0
  123. /package/build/{ai-client/src/hooks → hooks}/use-image-generator/index.js +0 -0
  124. /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.d.ts +0 -0
  125. /package/build/{ai-client/src/hooks → hooks}/use-media-recording/index.js +0 -0
  126. /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.d.ts +0 -0
  127. /package/build/{ai-client/src/hooks → hooks}/use-save-to-media-library/index.js +0 -0
  128. /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.d.ts +0 -0
  129. /package/build/{ai-client/src/hooks → hooks}/use-transcription-post-processing/index.js +0 -0
  130. /package/build/{ai-client/src/icons → icons}/ai-assistant.d.ts +0 -0
  131. /package/build/{ai-client/src/icons → icons}/ai-assistant.js +0 -0
  132. /package/build/{ai-client/src/icons → icons}/error-exclamation.d.ts +0 -0
  133. /package/build/{ai-client/src/icons → icons}/error-exclamation.js +0 -0
  134. /package/build/{ai-client/src/icons → icons}/index.d.ts +0 -0
  135. /package/build/{ai-client/src/icons → icons}/index.js +0 -0
  136. /package/build/{ai-client/src/icons → icons}/mic.d.ts +0 -0
  137. /package/build/{ai-client/src/icons → icons}/mic.js +0 -0
  138. /package/build/{ai-client/src/icons → icons}/origami-plane.d.ts +0 -0
  139. /package/build/{ai-client/src/icons → icons}/origami-plane.js +0 -0
  140. /package/build/{ai-client/src/icons → icons}/player-pause.d.ts +0 -0
  141. /package/build/{ai-client/src/icons → icons}/player-pause.js +0 -0
  142. /package/build/{ai-client/src/icons → icons}/player-play.d.ts +0 -0
  143. /package/build/{ai-client/src/icons → icons}/player-play.js +0 -0
  144. /package/build/{ai-client/src/icons → icons}/player-stop.d.ts +0 -0
  145. /package/build/{ai-client/src/icons → icons}/player-stop.js +0 -0
  146. /package/build/{ai-client/src/icons → icons}/speak-tone.d.ts +0 -0
  147. /package/build/{ai-client/src/icons → icons}/speak-tone.js +0 -0
  148. /package/build/{ai-client/src/jwt → jwt}/index.d.ts +0 -0
  149. /package/build/{ai-client/src/jwt → jwt}/index.js +0 -0
  150. /package/build/{ai-client/src/libs → libs}/index.d.ts +0 -0
  151. /package/build/{ai-client/src/libs → libs}/index.js +0 -0
  152. /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.d.ts +0 -0
  153. /package/build/{ai-client/src/libs → libs}/map-action-to-human-text.js +0 -0
  154. /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.d.ts +0 -0
  155. /package/build/{ai-client/src/libs → libs}/markdown/html-to-markdown.js +0 -0
  156. /package/build/{ai-client/src/libs → libs}/markdown/index.d.ts +0 -0
  157. /package/build/{ai-client/src/libs → libs}/markdown/index.js +0 -0
  158. /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.d.ts +0 -0
  159. /package/build/{ai-client/src/libs → libs}/markdown/markdown-to-html.js +0 -0
  160. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.d.ts +0 -0
  161. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/ai.js +0 -0
  162. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.d.ts +0 -0
  163. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/check.js +0 -0
  164. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.d.ts +0 -0
  165. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/logo.js +0 -0
  166. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.d.ts +0 -0
  167. /package/build/{ai-client/src/logo-generator → logo-generator}/assets/icons/media.js +0 -0
  168. /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.d.ts +0 -0
  169. /package/build/{ai-client/src/logo-generator → logo-generator}/components/fair-usage-notice.js +0 -0
  170. /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.d.ts +0 -0
  171. /package/build/{ai-client/src/logo-generator → logo-generator}/components/feature-fetch-failure-screen.js +0 -0
  172. /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.d.ts +0 -0
  173. /package/build/{ai-client/src/logo-generator → logo-generator}/components/first-load-screen.js +0 -0
  174. /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.d.ts +0 -0
  175. /package/build/{ai-client/src/logo-generator → logo-generator}/components/generator-modal.js +0 -0
  176. /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.d.ts +0 -0
  177. /package/build/{ai-client/src/logo-generator → logo-generator}/components/history-carousel.js +0 -0
  178. /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.d.ts +0 -0
  179. /package/build/{ai-client/src/logo-generator → logo-generator}/components/image-loader.js +0 -0
  180. /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.d.ts +0 -0
  181. /package/build/{ai-client/src/logo-generator → logo-generator}/components/logo-presenter.js +0 -0
  182. /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.d.ts +0 -0
  183. /package/build/{ai-client/src/logo-generator → logo-generator}/components/prompt.js +0 -0
  184. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.d.ts +0 -0
  185. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-nudge.js +0 -0
  186. /package/build/{ai-client/src/logo-generator → logo-generator}/components/upgrade-screen.d.ts +0 -0
  187. /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.d.ts +0 -0
  188. /package/build/{ai-client/src/logo-generator → logo-generator}/components/visit-site-banner.js +0 -0
  189. /package/build/{ai-client/src/logo-generator → logo-generator}/constants.d.ts +0 -0
  190. /package/build/{ai-client/src/logo-generator → logo-generator}/constants.js +0 -0
  191. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.d.ts +0 -0
  192. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-checkout.js +0 -0
  193. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-fair-usage-notice-message.d.ts +0 -0
  194. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.d.ts +0 -0
  195. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-logo-generator.js +0 -0
  196. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.d.ts +0 -0
  197. /package/build/{ai-client/src/logo-generator → logo-generator}/hooks/use-request-errors.js +0 -0
  198. /package/build/{ai-client/src/logo-generator → logo-generator}/index.d.ts +0 -0
  199. /package/build/{ai-client/src/logo-generator → logo-generator}/index.js +0 -0
  200. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.d.ts +0 -0
  201. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/logo-storage.js +0 -0
  202. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.d.ts +0 -0
  203. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/media-exists.js +0 -0
  204. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.d.ts +0 -0
  205. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/set-site-logo.js +0 -0
  206. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.d.ts +0 -0
  207. /package/build/{ai-client/src/logo-generator → logo-generator}/lib/wpcom-limited-request.js +0 -0
  208. /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.d.ts +0 -0
  209. /package/build/{ai-client/src/logo-generator → logo-generator}/store/actions.js +0 -0
  210. /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.d.ts +0 -0
  211. /package/build/{ai-client/src/logo-generator → logo-generator}/store/constants.js +0 -0
  212. /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.d.ts +0 -0
  213. /package/build/{ai-client/src/logo-generator → logo-generator}/store/index.js +0 -0
  214. /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.d.ts +0 -0
  215. /package/build/{ai-client/src/logo-generator → logo-generator}/store/initial-state.js +0 -0
  216. /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.d.ts +0 -0
  217. /package/build/{ai-client/src/logo-generator → logo-generator}/store/reducer.js +0 -0
  218. /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.d.ts +0 -0
  219. /package/build/{ai-client/src/logo-generator → logo-generator}/store/selectors.js +0 -0
  220. /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.d.ts +0 -0
  221. /package/build/{ai-client/src/logo-generator → logo-generator}/store/types.js +0 -0
  222. /package/build/{ai-client/src/logo-generator → logo-generator}/types.d.ts +0 -0
  223. /package/build/{ai-client/src/logo-generator → logo-generator}/types.js +0 -0
  224. /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.d.ts +0 -0
  225. /package/build/{ai-client/src/suggestions-event-source → suggestions-event-source}/index.js +0 -0
  226. /package/build/{ai-client/src/types.d.ts → types.d.ts} +0 -0
  227. /package/build/{ai-client/src/types.js → types.js} +0 -0
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import './style.scss';
5
+ /**
6
+ * The type for the callback function that is called when the user selects an image.
7
+ */
8
+ type SetImageCallbackProps = {
9
+ id: number;
10
+ url: string;
11
+ };
12
+ type GeneralPurposeImageProps = {
13
+ placement: string;
14
+ onClose?: () => void;
15
+ onSetImage?: (image: SetImageCallbackProps) => void;
16
+ };
17
+ /**
18
+ * GeneralPurposeImage component
19
+ * @param {GeneralPurposeImageProps} props - The component properties.
20
+ * @return {React.ReactElement} - rendered component.
21
+ */
22
+ export default function GeneralPurposeImage({ placement, onClose, onSetImage, }: GeneralPurposeImageProps): import("react/jsx-runtime").JSX.Element;
23
+ export {};
@@ -0,0 +1,184 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import { useAnalytics, PLAN_TYPE_UNLIMITED, usePlanType, } from '@automattic/jetpack-shared-extension-utils';
6
+ import { Button } from '@wordpress/components';
7
+ import { useCallback, useState } from '@wordpress/element';
8
+ import { __, sprintf } from '@wordpress/i18n';
9
+ import debugFactory from 'debug';
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import './style.scss';
14
+ import useAiFeature from '../../hooks/use-ai-feature/index.js';
15
+ import usePostContent from '../../hooks/use-post-content.js';
16
+ import useSaveToMediaLibrary from '../../hooks/use-save-to-media-library.js';
17
+ import AiImageModal from './components/ai-image-modal.js';
18
+ import useAiImage from './hooks/use-ai-image.js';
19
+ import useSiteType from './hooks/use-site-type.js';
20
+ import { IMAGE_GENERATION_MODEL_STABLE_DIFFUSION, IMAGE_GENERATION_MODEL_DALL_E_3, GENERAL_IMAGE_FEATURE_NAME, } from './types.js';
21
+ const debug = debugFactory('jetpack-ai:general-purpose-image');
22
+ /**
23
+ * GeneralPurposeImage component
24
+ * @param {GeneralPurposeImageProps} props - The component properties.
25
+ * @return {React.ReactElement} - rendered component.
26
+ */
27
+ export default function GeneralPurposeImage({ placement, onClose = () => { }, onSetImage = () => { }, }) {
28
+ const [isFeaturedImageModalVisible, setIsFeaturedImageModalVisible] = useState(true);
29
+ const siteType = useSiteType();
30
+ const postContent = usePostContent();
31
+ const { saveToMediaLibrary } = useSaveToMediaLibrary();
32
+ const { tracks } = useAnalytics();
33
+ const { recordEvent } = tracks;
34
+ const [prompt, setPrompt] = useState('');
35
+ // Get feature data
36
+ const { requireUpgrade, requestsCount, requestsLimit, currentTier, costs } = useAiFeature();
37
+ const planType = usePlanType(currentTier);
38
+ const generalImageCost = costs?.[GENERAL_IMAGE_FEATURE_NAME]?.activeModel ?? 10;
39
+ const generalImageActiveModel = generalImageCost === costs?.[GENERAL_IMAGE_FEATURE_NAME]?.stableDiffusion
40
+ ? IMAGE_GENERATION_MODEL_STABLE_DIFFUSION
41
+ : IMAGE_GENERATION_MODEL_DALL_E_3;
42
+ const isUnlimited = planType === PLAN_TYPE_UNLIMITED;
43
+ const requestsBalance = requestsLimit - requestsCount;
44
+ const notEnoughRequests = requestsBalance < generalImageCost;
45
+ const { current, setCurrent, processImageGeneration, handlePreviousImage, handleNextImage, currentImage, currentPointer, images, pointer, imageStyles, guessStyle, } = useAiImage({
46
+ cost: generalImageCost,
47
+ autoStart: false,
48
+ type: 'general-image-generation',
49
+ feature: GENERAL_IMAGE_FEATURE_NAME,
50
+ });
51
+ const hasPrompt = prompt.length >= 3;
52
+ const disableInput = notEnoughRequests || currentPointer?.generating || requireUpgrade;
53
+ const disableAction = disableInput || !hasPrompt;
54
+ const handleModalClose = useCallback(() => {
55
+ setIsFeaturedImageModalVisible(false);
56
+ onClose?.();
57
+ }, [onClose]);
58
+ const handleGenerate = useCallback(async ({ userPrompt, style }) => {
59
+ debug('handleGenerate', userPrompt, style);
60
+ // track the generate image event
61
+ recordEvent('jetpack_ai_general_image_generation_generate_image', {
62
+ placement,
63
+ model: generalImageActiveModel,
64
+ site_type: siteType,
65
+ style,
66
+ });
67
+ processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
68
+ recordEvent('jetpack_ai_general_image_generation_error', {
69
+ placement,
70
+ error: error?.message,
71
+ model: generalImageActiveModel,
72
+ site_type: siteType,
73
+ style,
74
+ });
75
+ });
76
+ }, [
77
+ recordEvent,
78
+ placement,
79
+ generalImageActiveModel,
80
+ siteType,
81
+ processImageGeneration,
82
+ postContent,
83
+ notEnoughRequests,
84
+ ]);
85
+ const handleRegenerate = useCallback(({ userPrompt, style }) => {
86
+ debug('handleRegenerate', userPrompt);
87
+ // track the regenerate image event
88
+ recordEvent('jetpack_ai_general_image_generation_generate_another_image', {
89
+ placement,
90
+ model: generalImageActiveModel,
91
+ site_type: siteType,
92
+ style,
93
+ });
94
+ setCurrent(crrt => crrt + 1);
95
+ processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
96
+ recordEvent('jetpack_ai_general_image_generation_error', {
97
+ placement,
98
+ error: error?.message,
99
+ model: generalImageActiveModel,
100
+ site_type: siteType,
101
+ });
102
+ });
103
+ }, [
104
+ recordEvent,
105
+ placement,
106
+ generalImageActiveModel,
107
+ siteType,
108
+ processImageGeneration,
109
+ postContent,
110
+ notEnoughRequests,
111
+ setCurrent,
112
+ ]);
113
+ const handleTryAgain = useCallback(({ userPrompt, style }) => {
114
+ debug('handleTryAgain', userPrompt);
115
+ // track the try again event
116
+ recordEvent('jetpack_ai_general_image_generation_try_again', {
117
+ placement,
118
+ model: generalImageActiveModel,
119
+ site_type: siteType,
120
+ style,
121
+ });
122
+ processImageGeneration({ userPrompt, postContent, notEnoughRequests, style }).catch(error => {
123
+ recordEvent('jetpack_ai_general_image_generation_error', {
124
+ placement,
125
+ error: error?.message,
126
+ model: generalImageActiveModel,
127
+ site_type: siteType,
128
+ });
129
+ });
130
+ }, [
131
+ recordEvent,
132
+ placement,
133
+ generalImageActiveModel,
134
+ siteType,
135
+ processImageGeneration,
136
+ postContent,
137
+ notEnoughRequests,
138
+ ]);
139
+ const handleAccept = useCallback(() => {
140
+ // track the accept/use image event
141
+ recordEvent('jetpack_ai_general_image_generation_use_image', {
142
+ placement,
143
+ model: generalImageActiveModel,
144
+ site_type: siteType,
145
+ });
146
+ const setImage = image => {
147
+ onSetImage?.({ id: image.id, url: image.url });
148
+ handleModalClose();
149
+ };
150
+ // If the image is already in the media library, use it directly, if it failed for some reason
151
+ // save it to the media library and then use it.
152
+ if (currentImage?.libraryId) {
153
+ setImage({
154
+ id: currentImage?.libraryId,
155
+ url: currentImage?.libraryUrl,
156
+ });
157
+ }
158
+ else {
159
+ saveToMediaLibrary(currentImage?.image).then(image => {
160
+ setImage(image);
161
+ });
162
+ }
163
+ }, [
164
+ recordEvent,
165
+ placement,
166
+ generalImageActiveModel,
167
+ siteType,
168
+ currentImage?.libraryId,
169
+ currentImage?.libraryUrl,
170
+ currentImage?.image,
171
+ onSetImage,
172
+ handleModalClose,
173
+ saveToMediaLibrary,
174
+ ]);
175
+ const generateAgainText = __('Generate another image', 'jetpack-ai-client');
176
+ const generateText = __('Generate', 'jetpack-ai-client');
177
+ const upgradeDescription = notEnoughRequests
178
+ ? sprintf(
179
+ // Translators: %d is the cost of generating a featured image.
180
+ __("Image generation costs %d requests per image. You don't have enough requests to generate another image.", 'jetpack-ai-client'), generalImageCost)
181
+ : null;
182
+ const acceptButton = (_jsx(Button, { onClick: handleAccept, variant: "primary", disabled: !currentImage?.image || currentImage?.generating, children: __('Insert image', 'jetpack-ai-client') }));
183
+ return (_jsx(AiImageModal, { postContent: true, images: images, currentIndex: current, title: __('Generate an image with AI', 'jetpack-ai-client'), cost: generalImageCost, open: isFeaturedImageModalVisible, placement: placement, onClose: handleModalClose, onTryAgain: handleTryAgain, onGenerate: pointer?.current > 0 ? handleRegenerate : handleGenerate, generating: currentPointer?.generating, notEnoughRequests: notEnoughRequests, requireUpgrade: requireUpgrade, upgradeDescription: upgradeDescription, currentLimit: requestsLimit, currentUsage: requestsCount, isUnlimited: isUnlimited, hasError: Boolean(currentPointer?.error), handlePreviousImage: handlePreviousImage, handleNextImage: handleNextImage, acceptButton: acceptButton, generateButtonLabel: pointer?.current > 0 ? generateAgainText : generateText, instructionsPlaceholder: __("Describe the image you'd like to create and select a style.", 'jetpack-ai-client'), imageStyles: imageStyles, onGuessStyle: guessStyle, prompt: prompt, setPrompt: setPrompt, inputDisabled: disableInput, actionDisabled: disableAction }));
184
+ }
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { ImageStyleObject, ImageStyle } from '../../../hooks/use-image-generator/constants.js';
3
+ /**
4
+ * Types
5
+ */
6
+ import { FEATURED_IMAGE_FEATURE_NAME, GENERAL_IMAGE_FEATURE_NAME } from '../types.js';
7
+ import type { CarrouselImageData, CarrouselImages } from '../components/carrousel.js';
8
+ type AiImageType = 'featured-image-generation' | 'general-image-generation';
9
+ type AiImageFeature = typeof FEATURED_IMAGE_FEATURE_NAME | typeof GENERAL_IMAGE_FEATURE_NAME;
10
+ export type ImageResponse = {
11
+ image?: string;
12
+ libraryId?: string;
13
+ libraryUrl?: string;
14
+ revisedPrompt?: string;
15
+ };
16
+ type ProcessImageGenerationProps = {
17
+ userPrompt?: string | null;
18
+ postContent?: string | null;
19
+ notEnoughRequests: boolean;
20
+ style?: string;
21
+ };
22
+ type UseAiImageProps = {
23
+ feature: AiImageFeature;
24
+ type: AiImageType;
25
+ cost: number;
26
+ autoStart?: boolean;
27
+ previousMediaId?: number;
28
+ };
29
+ /**
30
+ * Hook to get properties for AiImage
31
+ *
32
+ * @param {UseAiImageProps} props - The component properties.
33
+ * @return {UseAiImageReturn} - Object containing properties for AiImage.
34
+ */
35
+ export default function useAiImage({ feature, type, cost, autoStart, previousMediaId, }: UseAiImageProps): {
36
+ current: number;
37
+ setCurrent: React.Dispatch<React.SetStateAction<number>>;
38
+ processImageGeneration: ({ userPrompt, postContent, notEnoughRequests, style, }: ProcessImageGenerationProps) => Promise<ImageResponse>;
39
+ handlePreviousImage: () => void;
40
+ handleNextImage: () => void;
41
+ currentImage: CarrouselImageData;
42
+ currentPointer: CarrouselImageData;
43
+ images: CarrouselImages;
44
+ pointer: React.MutableRefObject<number>;
45
+ imageStyles: ImageStyleObject[];
46
+ guessStyle: (prompt: string, requestType?: string, content?: string) => Promise<ImageStyle | null>;
47
+ };
48
+ export {};
@@ -0,0 +1,219 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { useDispatch, useSelect } from '@wordpress/data';
5
+ import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
6
+ import { __ } from '@wordpress/i18n';
7
+ import { cleanForSlug } from '@wordpress/url';
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import askQuestionSync from '../../../ask-question/sync.js';
12
+ import useAiFeature from '../../../hooks/use-ai-feature/index.js';
13
+ import useImageGenerator from '../../../hooks/use-image-generator/index.js';
14
+ import useSaveToMediaLibrary from '../../../hooks/use-save-to-media-library.js';
15
+ /**
16
+ * Types
17
+ */
18
+ import { FEATURED_IMAGE_FEATURE_NAME, } from '../types.js';
19
+ /**
20
+ * Hook to get properties for AiImage
21
+ *
22
+ * @param {UseAiImageProps} props - The component properties.
23
+ * @return {UseAiImageReturn} - Object containing properties for AiImage.
24
+ */
25
+ export default function useAiImage({ feature, type, cost, autoStart = true, previousMediaId, }) {
26
+ const { generateImageWithParameters } = useImageGenerator();
27
+ const { increaseRequestsCount, featuresControl } = useAiFeature();
28
+ const { saveToMediaLibrary } = useSaveToMediaLibrary();
29
+ const { createNotice } = useDispatch('core/notices');
30
+ /* Images Control */
31
+ // pointer keeps track of request/generation iteration
32
+ const pointer = useRef(0);
33
+ // and current keeps track of what is the image exposed at the moment
34
+ // TODO: should current be any relevant here? It's just modal/carrousel logic after all
35
+ const [current, setCurrent] = useState(0);
36
+ const [images, setImages] = useState([{ generating: autoStart }]);
37
+ // map feature-to-control prop, if this goes over 2 options, make a hook for it
38
+ const featureControl = feature === FEATURED_IMAGE_FEATURE_NAME ? 'featured-image' : 'image';
39
+ const imageFeatureControl = featuresControl?.[featureControl];
40
+ const imageStyles = imageFeatureControl?.styles;
41
+ /* Merge the image data with the new data. */
42
+ const updateImages = useCallback((data, index) => {
43
+ setImages(currentImages => {
44
+ const newImages = [...currentImages];
45
+ newImages[index] = {
46
+ ...newImages[index],
47
+ ...data,
48
+ };
49
+ return newImages;
50
+ });
51
+ }, []);
52
+ // the selec/useEffect combo...
53
+ const loadedMedia = useSelect((select) => select('core')?.getMedia?.(previousMediaId), [previousMediaId]);
54
+ useEffect(() => {
55
+ if (loadedMedia) {
56
+ updateImages({
57
+ image: loadedMedia.source_url,
58
+ libraryId: loadedMedia.id,
59
+ libraryUrl: loadedMedia.source_url,
60
+ generating: false,
61
+ }, pointer.current);
62
+ }
63
+ }, [loadedMedia, updateImages]);
64
+ /*
65
+ * Function to show a snackbar notice on the editor.
66
+ */
67
+ const showSnackbarNotice = useCallback((message) => {
68
+ createNotice('success', message, {
69
+ type: 'snackbar',
70
+ isDismissible: true,
71
+ });
72
+ }, [createNotice]);
73
+ /*
74
+ * Function to update the requests count after a featured image generation.
75
+ */
76
+ const updateRequestsCount = useCallback(() => {
77
+ increaseRequestsCount(cost);
78
+ }, [increaseRequestsCount, cost]);
79
+ /*
80
+ * Function to suggest a name for the image based on the user prompt.
81
+ */
82
+ const getImageNameSuggestion = useCallback((userPrompt) => {
83
+ if (!userPrompt) {
84
+ return 'image.png';
85
+ }
86
+ const truncatedPrompt = userPrompt.split(' ').slice(0, 10).join(' ');
87
+ return cleanForSlug(truncatedPrompt) + '.png';
88
+ }, []);
89
+ /*
90
+ * Function to generate a new image with the current value of the post content.
91
+ */
92
+ const processImageGeneration = useCallback(({ userPrompt, postContent, notEnoughRequests, style = null, }) => {
93
+ return new Promise((resolve, reject) => {
94
+ if (previousMediaId && pointer.current === 0) {
95
+ pointer.current++;
96
+ }
97
+ updateImages({ generating: true, error: null }, pointer.current);
98
+ // Ensure the site has enough requests to generate the image.
99
+ if (notEnoughRequests) {
100
+ updateImages({
101
+ generating: false,
102
+ error: new Error(__("You don't have enough requests to generate another image.", 'jetpack-ai-client')),
103
+ }, pointer.current);
104
+ resolve({});
105
+ return;
106
+ }
107
+ /**
108
+ * Make a generic call to backend and let it decide the model.
109
+ */
110
+ const generateImagePromise = generateImageWithParameters({
111
+ feature,
112
+ size: '1792x1024',
113
+ responseFormat: 'b64_json',
114
+ messages: [
115
+ {
116
+ role: 'jetpack-ai',
117
+ context: {
118
+ type,
119
+ request: userPrompt ? userPrompt : null,
120
+ content: postContent,
121
+ style,
122
+ },
123
+ },
124
+ ],
125
+ style: style || '',
126
+ });
127
+ const name = getImageNameSuggestion(userPrompt);
128
+ generateImagePromise
129
+ .then(result => {
130
+ if (result.data.length > 0) {
131
+ const image = 'data:image/png;base64,' + result.data[0].b64_json;
132
+ const prompt = userPrompt || null;
133
+ const revisedPrompt = result.data[0].revised_prompt || null;
134
+ updateImages({ image, prompt, revisedPrompt }, pointer.current);
135
+ updateRequestsCount();
136
+ saveToMediaLibrary(image, name)
137
+ .then(savedImage => {
138
+ showSnackbarNotice(__('Image saved to media library.', 'jetpack-ai-client'));
139
+ updateImages({ libraryId: savedImage?.id, libraryUrl: savedImage?.url, generating: false }, pointer.current);
140
+ pointer.current += 1;
141
+ resolve({
142
+ image,
143
+ libraryId: savedImage?.id,
144
+ libraryUrl: savedImage?.url,
145
+ revisedPrompt,
146
+ });
147
+ })
148
+ .catch(() => {
149
+ updateImages({ generating: false }, pointer.current);
150
+ pointer.current += 1;
151
+ resolve({ image });
152
+ });
153
+ }
154
+ })
155
+ .catch(e => {
156
+ updateImages({ generating: false, error: e }, pointer.current);
157
+ reject(e);
158
+ });
159
+ });
160
+ }, [
161
+ updateImages,
162
+ generateImageWithParameters,
163
+ feature,
164
+ type,
165
+ updateRequestsCount,
166
+ saveToMediaLibrary,
167
+ showSnackbarNotice,
168
+ getImageNameSuggestion,
169
+ previousMediaId,
170
+ ]);
171
+ const handlePreviousImage = useCallback(() => {
172
+ setCurrent(Math.max(current - 1, 0));
173
+ }, [current]);
174
+ const handleNextImage = useCallback(() => {
175
+ setCurrent(Math.min(current + 1, images.length - 1));
176
+ }, [current, images.length]);
177
+ const guessStyle = useCallback(async function (prompt, requestType = '', content = '') {
178
+ if (!imageStyles || !imageStyles.length) {
179
+ return null;
180
+ }
181
+ const messages = [
182
+ {
183
+ role: 'jetpack-ai',
184
+ context: {
185
+ type: requestType || 'general-image-guess-style',
186
+ request: prompt,
187
+ content,
188
+ },
189
+ },
190
+ ];
191
+ try {
192
+ const style = await askQuestionSync(messages, { feature: 'jetpack-ai-image-generator' });
193
+ if (!style) {
194
+ return null;
195
+ }
196
+ const styleObject = imageStyles.find(({ value }) => value === style);
197
+ if (!styleObject) {
198
+ return null;
199
+ }
200
+ return styleObject.value;
201
+ }
202
+ catch (error) {
203
+ Promise.reject(error);
204
+ }
205
+ }, [imageStyles]);
206
+ return {
207
+ current,
208
+ setCurrent,
209
+ processImageGeneration,
210
+ handlePreviousImage,
211
+ handleNextImage,
212
+ currentImage: images[current],
213
+ currentPointer: images[pointer.current],
214
+ images,
215
+ pointer,
216
+ imageStyles,
217
+ guessStyle,
218
+ };
219
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Hook to get the type of site.
3
+ *
4
+ * @return {string} - The type of site.
5
+ */
6
+ export default function useSiteType(): string;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import { isAtomicSite, isSimpleSite } from '@automattic/jetpack-shared-extension-utils';
5
+ import { useState } from '@wordpress/element';
6
+ /**
7
+ * Hook to get the type of site.
8
+ *
9
+ * @return {string} - The type of site.
10
+ */
11
+ export default function useSiteType() {
12
+ const getSiteType = () => {
13
+ if (isAtomicSite()) {
14
+ return 'atomic';
15
+ }
16
+ if (isSimpleSite()) {
17
+ return 'simple';
18
+ }
19
+ return 'jetpack';
20
+ };
21
+ const [siteType] = useState(getSiteType());
22
+ return siteType;
23
+ }
@@ -0,0 +1,4 @@
1
+ import FeaturedImage from './featured-image.js';
2
+ import GeneralPurposeImage from './general-purpose-image.js';
3
+ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON } from './types.js';
4
+ export { FeaturedImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, GeneralPurposeImage, };
@@ -0,0 +1,4 @@
1
+ import FeaturedImage from './featured-image.js';
2
+ import GeneralPurposeImage from './general-purpose-image.js';
3
+ import { PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON } from './types.js';
4
+ export { FeaturedImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, GeneralPurposeImage, };
@@ -0,0 +1,16 @@
1
+ export declare const FEATURED_IMAGE_FEATURE_NAME: "featured-post-image";
2
+ export declare const GENERAL_IMAGE_FEATURE_NAME: "general-image";
3
+ export declare const IMAGE_GENERATION_MODEL_STABLE_DIFFUSION: "stable-diffusion";
4
+ export declare const IMAGE_GENERATION_MODEL_DALL_E_3: "dall-e-3";
5
+ export declare const PLACEMENT_MEDIA_SOURCE_DROPDOWN: "media-source-dropdown";
6
+ export declare const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON: "block-placeholder-button";
7
+ export interface EditorSelectors {
8
+ getEditedPostAttribute: (attribute: string) => number;
9
+ isEditorPanelOpened: (panel: string) => boolean;
10
+ }
11
+ export interface CoreSelectors {
12
+ getMedia: (mediaId: number) => {
13
+ id: number;
14
+ source_url: string;
15
+ } | null;
16
+ }
@@ -0,0 +1,6 @@
1
+ export const FEATURED_IMAGE_FEATURE_NAME = 'featured-post-image';
2
+ export const GENERAL_IMAGE_FEATURE_NAME = 'general-image';
3
+ export const IMAGE_GENERATION_MODEL_STABLE_DIFFUSION = 'stable-diffusion';
4
+ export const IMAGE_GENERATION_MODEL_DALL_E_3 = 'dall-e-3';
5
+ export const PLACEMENT_MEDIA_SOURCE_DROPDOWN = 'media-source-dropdown';
6
+ export const PLACEMENT_BLOCK_PLACEHOLDER_BUTTON = 'block-placeholder-button';
@@ -1,6 +1,10 @@
1
1
  export { AIControl, BlockAIControl, ExtensionAIControl } from './ai-control/index.js';
2
2
  export { default as AiFeedbackThumbs } from './ai-feedback/index.js';
3
+ export { default as AiIcon, AiSVG } from './ai-icon/index.js';
4
+ export { FeaturedImage, GeneralPurposeImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, } from './ai-image/index.js';
3
5
  export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
4
6
  export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
5
7
  export { default as AiModalFooter } from './ai-modal-footer/index.js';
6
8
  export { GuidelineMessage, UpgradeMessage, ErrorMessage, default as FooterMessage, } from './message/index.js';
9
+ export { default as AiAssistantModal } from './modal/index.js';
10
+ export { default as QuotaExceededMessage, FairUsageNotice, } from './quota-exceeded-message/index.js';
@@ -1,6 +1,10 @@
1
1
  export { AIControl, BlockAIControl, ExtensionAIControl } from './ai-control/index.js';
2
2
  export { default as AiFeedbackThumbs } from './ai-feedback/index.js';
3
+ export { default as AiIcon, AiSVG } from './ai-icon/index.js';
4
+ export { FeaturedImage, GeneralPurposeImage, PLACEMENT_MEDIA_SOURCE_DROPDOWN, PLACEMENT_BLOCK_PLACEHOLDER_BUTTON, } from './ai-image/index.js';
3
5
  export { default as AiStatusIndicator } from './ai-status-indicator/index.js';
4
6
  export { default as AudioDurationDisplay } from './audio-duration-display/index.js';
5
7
  export { default as AiModalFooter } from './ai-modal-footer/index.js';
6
8
  export { GuidelineMessage, UpgradeMessage, ErrorMessage, default as FooterMessage, } from './message/index.js';
9
+ export { default as AiAssistantModal } from './modal/index.js';
10
+ export { default as QuotaExceededMessage, FairUsageNotice, } from './quota-exceeded-message/index.js';
@@ -0,0 +1,18 @@
1
+ /// <reference types="react" resolution-mode="require"/>
2
+ import type { RequestingStateProp } from '../../types.js';
3
+ import './style.scss';
4
+ type AiAssistantModalProps = {
5
+ children: React.ReactNode;
6
+ handleClose: () => void;
7
+ hideHeader?: boolean;
8
+ requestingState?: RequestingStateProp;
9
+ title?: string;
10
+ maxWidth?: number;
11
+ };
12
+ /**
13
+ * AiAssistantModal component
14
+ * @param {AiAssistantModalProps} props - The component properties.
15
+ * @return {React.ReactElement} - rendered component.
16
+ */
17
+ export default function AiAssistantModal({ children, handleClose, hideHeader, requestingState, title, maxWidth, }: AiAssistantModalProps): import("react/jsx-runtime").JSX.Element;
18
+ export {};
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * External dependencies
4
+ */
5
+ import { Modal, Button } from '@wordpress/components';
6
+ import { __ } from '@wordpress/i18n';
7
+ import { close } from '@wordpress/icons';
8
+ /**
9
+ * Internal dependencies
10
+ */
11
+ import AiStatusIndicator from '../ai-status-indicator/index.js';
12
+ import './style.scss';
13
+ const ModalHeader = ({ requestingState, onClose, title, }) => {
14
+ return (_jsxs("div", { className: "ai-assistant-modal__header", children: [_jsxs("div", { className: "ai-assistant-modal__title-wrapper", children: [_jsx(AiStatusIndicator, { state: requestingState }), _jsx("h1", { className: "ai-assistant-modal__title", children: title })] }), _jsx(Button, { icon: close, label: __('Close', 'jetpack-ai-client'), onClick: onClose })] }));
15
+ };
16
+ /**
17
+ * AiAssistantModal component
18
+ * @param {AiAssistantModalProps} props - The component properties.
19
+ * @return {React.ReactElement} - rendered component.
20
+ */
21
+ export default function AiAssistantModal({ children, handleClose, hideHeader = true, requestingState = 'init', title = __('AI Assistant', 'jetpack-ai-client'), maxWidth = 720, }) {
22
+ return (_jsx(Modal, { __experimentalHideHeader: hideHeader, className: "ai-assistant-modal", shouldCloseOnClickOutside: false, onRequestClose: handleClose, children: _jsxs("div", { className: "ai-assistant-modal__content", style: { maxWidth }, children: [_jsx(ModalHeader, { requestingState: requestingState, onClose: handleClose, title: title }), _jsx("hr", { className: "ai-assistant-modal__divider" }), children] }) }));
23
+ }
@@ -0,0 +1,13 @@
1
+ import './style.scss';
2
+ type FairUsageNoticeProps = {
3
+ variant?: 'error' | 'muted';
4
+ };
5
+ /**
6
+ * The fair usage notice component.
7
+ * @param {FairUsageNoticeProps} props - Fair usage notice component props.
8
+ * @param {FairUsageNoticeProps.variant} props.variant - The variant of the notice to render.
9
+ * @return {ReactElement} the Notice component with the fair usage message.
10
+ */
11
+ export declare const FairUsageNotice: ({ variant }: FairUsageNoticeProps) => import("react/jsx-runtime").JSX.Element;
12
+ declare const QuotaExceededMessage: (props: any) => import("react/jsx-runtime").JSX.Element;
13
+ export default QuotaExceededMessage;