@capillarytech/creatives-library 8.0.242-alpha.1 → 8.0.242-alpha.11

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 (255) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/config/app.js +1 -1
  4. package/constants/unified.js +2 -2
  5. package/initialReducer.js +0 -2
  6. package/package.json +1 -1
  7. package/services/api.js +5 -10
  8. package/services/tests/api.test.js +0 -18
  9. package/translations/en.json +4 -3
  10. package/utils/common.js +6 -5
  11. package/utils/commonUtils.js +1 -14
  12. package/utils/imageUrlUpload.js +141 -0
  13. package/utils/tests/commonUtil.test.js +0 -224
  14. package/utils/transformTemplateConfig.js +10 -0
  15. package/v2Components/CapDeviceContent/index.js +56 -61
  16. package/v2Components/CapImageUpload/constants.js +2 -0
  17. package/v2Components/CapImageUpload/index.js +65 -16
  18. package/v2Components/CapImageUpload/index.scss +4 -1
  19. package/v2Components/CapImageUpload/messages.js +5 -1
  20. package/v2Components/CapImageUrlUpload/constants.js +26 -0
  21. package/v2Components/CapImageUrlUpload/index.js +365 -0
  22. package/v2Components/CapImageUrlUpload/index.scss +35 -0
  23. package/v2Components/CapImageUrlUpload/messages.js +47 -0
  24. package/v2Components/CapTagList/index.js +1 -6
  25. package/v2Components/CapTagListWithInput/index.js +1 -5
  26. package/v2Components/CapTagListWithInput/messages.js +1 -1
  27. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  28. package/v2Components/ErrorInfoNote/index.js +72 -412
  29. package/v2Components/ErrorInfoNote/messages.js +0 -22
  30. package/v2Components/ErrorInfoNote/style.scss +2 -279
  31. package/v2Components/HtmlEditor/HTMLEditor.js +89 -210
  32. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1132
  33. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
  34. package/v2Components/HtmlEditor/_htmlEditor.scss +23 -8
  35. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -13
  37. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +139 -148
  38. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  39. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  40. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  41. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -1
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  47. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  48. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -10
  49. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  50. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +62 -87
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  52. package/v2Components/HtmlEditor/constants.js +20 -29
  53. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  54. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  55. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  56. package/v2Components/HtmlEditor/index.js +1 -1
  57. package/v2Components/HtmlEditor/messages.js +85 -95
  58. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +101 -99
  59. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  60. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -34
  61. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  62. package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
  63. package/v2Components/TemplatePreview/index.js +32 -47
  64. package/v2Components/TemplatePreview/messages.js +0 -4
  65. package/v2Components/TestAndPreviewSlidebox/index.js +25 -31
  66. package/v2Containers/App/constants.js +5 -0
  67. package/v2Containers/BeeEditor/index.js +80 -82
  68. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +4 -3
  69. package/v2Containers/CreativesContainer/SlideBoxContent.js +118 -148
  70. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -9
  71. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  72. package/v2Containers/CreativesContainer/constants.js +2 -1
  73. package/v2Containers/CreativesContainer/index.js +41 -173
  74. package/v2Containers/CreativesContainer/messages.js +4 -4
  75. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +210 -0
  76. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +354 -38
  77. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -36
  78. package/v2Containers/Email/actions.js +0 -7
  79. package/v2Containers/Email/constants.js +1 -5
  80. package/v2Containers/Email/index.js +0 -13
  81. package/v2Containers/Email/messages.js +0 -32
  82. package/v2Containers/Email/reducer.js +1 -12
  83. package/v2Containers/Email/sagas.js +6 -41
  84. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  85. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +7 -193
  86. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  87. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  88. package/v2Containers/EmailWrapper/constants.js +0 -2
  89. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +67 -436
  90. package/v2Containers/EmailWrapper/index.js +23 -99
  91. package/v2Containers/EmailWrapper/messages.js +1 -61
  92. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +1 -26
  93. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -111
  94. package/v2Containers/InApp/actions.js +0 -7
  95. package/v2Containers/InApp/constants.js +4 -20
  96. package/v2Containers/InApp/index.js +357 -800
  97. package/v2Containers/InApp/index.scss +3 -4
  98. package/v2Containers/InApp/messages.js +3 -7
  99. package/v2Containers/InApp/reducer.js +3 -21
  100. package/v2Containers/InApp/sagas.js +9 -29
  101. package/v2Containers/InApp/selectors.js +5 -25
  102. package/v2Containers/InApp/tests/index.test.js +50 -154
  103. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  104. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  105. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +12 -12
  106. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
  107. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +100 -77
  108. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +72 -63
  109. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +184 -150
  110. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +16 -12
  111. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +32 -28
  112. package/v2Containers/TagList/index.js +1 -67
  113. package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
  114. package/v2Containers/Templates/_templates.scss +202 -56
  115. package/v2Containers/Templates/actions.js +2 -1
  116. package/v2Containers/Templates/constants.js +1 -0
  117. package/v2Containers/Templates/index.js +278 -128
  118. package/v2Containers/Templates/messages.js +24 -4
  119. package/v2Containers/Templates/reducer.js +2 -0
  120. package/v2Containers/Templates/tests/index.test.js +10 -0
  121. package/v2Containers/TemplatesV2/index.js +8 -1
  122. package/v2Containers/TemplatesV2/messages.js +4 -0
  123. package/v2Containers/WebPush/Create/components/BrandIconSection.js +108 -0
  124. package/v2Containers/WebPush/Create/components/ButtonForm.js +172 -0
  125. package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
  126. package/v2Containers/WebPush/Create/components/ButtonList.js +145 -0
  127. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +164 -0
  128. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +463 -0
  129. package/v2Containers/WebPush/Create/components/FormActions.js +54 -0
  130. package/v2Containers/WebPush/Create/components/FormActions.test.js +163 -0
  131. package/v2Containers/WebPush/Create/components/MediaSection.js +142 -0
  132. package/v2Containers/WebPush/Create/components/MediaSection.test.js +341 -0
  133. package/v2Containers/WebPush/Create/components/MessageSection.js +103 -0
  134. package/v2Containers/WebPush/Create/components/MessageSection.test.js +268 -0
  135. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +87 -0
  136. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +210 -0
  137. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +54 -0
  138. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +143 -0
  139. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +86 -0
  140. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +16 -0
  141. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +41 -0
  142. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +54 -0
  143. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +37 -0
  144. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +21 -0
  145. package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
  146. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
  147. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
  148. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
  149. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
  150. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
  151. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +78 -0
  152. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +138 -0
  153. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +406 -0
  154. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +30 -0
  155. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +151 -0
  156. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +104 -0
  157. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +538 -0
  158. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +122 -0
  159. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +633 -0
  160. package/v2Containers/WebPush/Create/index.js +1056 -0
  161. package/v2Containers/WebPush/Create/index.scss +134 -0
  162. package/v2Containers/WebPush/Create/messages.js +203 -0
  163. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +228 -0
  164. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +294 -0
  165. package/v2Containers/WebPush/Create/preview/PreviewContent.js +90 -0
  166. package/v2Containers/WebPush/Create/preview/PreviewControls.js +305 -0
  167. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
  168. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +150 -0
  169. package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
  170. package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
  171. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +9 -0
  172. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +9 -0
  173. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  174. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  175. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
  176. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
  177. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +9 -0
  178. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +9 -0
  179. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
  180. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
  181. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +9 -0
  182. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +9 -0
  183. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +47 -0
  184. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +141 -0
  185. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
  186. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +68 -0
  187. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +61 -0
  188. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +99 -0
  189. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +733 -0
  190. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +571 -0
  191. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +81 -0
  192. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +81 -0
  193. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +50 -0
  194. package/v2Containers/WebPush/Create/preview/constants.js +637 -0
  195. package/v2Containers/WebPush/Create/preview/notification-container.scss +79 -0
  196. package/v2Containers/WebPush/Create/preview/preview.scss +351 -0
  197. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +370 -0
  198. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
  199. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
  200. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
  201. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +47 -0
  202. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
  203. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
  204. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
  205. package/v2Containers/WebPush/Create/preview/styles/_base.scss +207 -0
  206. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +153 -0
  207. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
  208. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +101 -0
  209. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +229 -0
  210. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
  211. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1081 -0
  212. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
  213. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
  214. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +131 -0
  215. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +112 -0
  216. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
  217. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +129 -0
  218. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +94 -0
  219. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +390 -0
  220. package/v2Containers/WebPush/Create/utils/previewUtils.js +89 -0
  221. package/v2Containers/WebPush/Create/utils/urlValidation.js +115 -0
  222. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
  223. package/v2Containers/WebPush/Create/utils/validation.js +75 -0
  224. package/v2Containers/WebPush/Create/utils/validation.test.js +283 -0
  225. package/v2Containers/WebPush/actions.js +60 -0
  226. package/v2Containers/WebPush/constants.js +128 -0
  227. package/v2Containers/WebPush/index.js +2 -0
  228. package/v2Containers/WebPush/reducer.js +104 -0
  229. package/v2Containers/WebPush/sagas.js +119 -0
  230. package/v2Containers/WebPush/selectors.js +65 -0
  231. package/v2Containers/WebPush/tests/reducer.test.js +863 -0
  232. package/v2Containers/WebPush/tests/sagas.test.js +566 -0
  233. package/v2Containers/WebPush/tests/selectors.test.js +843 -0
  234. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +528 -431
  235. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  236. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -362
  237. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  238. package/v2Containers/BeePopupEditor/constants.js +0 -10
  239. package/v2Containers/BeePopupEditor/index.js +0 -193
  240. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  241. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1045
  242. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  243. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  244. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  245. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
  246. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  247. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
  248. package/v2Containers/InAppWrapper/constants.js +0 -16
  249. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  250. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  251. package/v2Containers/InAppWrapper/index.js +0 -148
  252. package/v2Containers/InAppWrapper/messages.js +0 -49
  253. package/v2Containers/InappAdvance/index.js +0 -1099
  254. package/v2Containers/InappAdvance/index.scss +0 -10
  255. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -9,13 +9,13 @@ import { render, screen } from '@testing-library/react';
9
9
  import '@testing-library/jest-dom';
10
10
  import { DEVICE_TYPES } from '../../../constants';
11
11
 
12
- // Import after mocking
13
- import DeviceFrame from '../DeviceFrame';
14
-
15
12
  // Mock the entire DeviceFrame module to bypass image import issues
16
13
  jest.mock('../../../../assets/Android.png', () => 'mocked-android-frame.png');
17
14
  jest.mock('../../../../assets/iOS.png', () => 'mocked-ios-frame.png');
18
15
 
16
+ // Import after mocking
17
+ import DeviceFrame from '../DeviceFrame';
18
+
19
19
  describe('DeviceFrame', () => {
20
20
  describe('Basic Rendering', () => {
21
21
  it('renders without crashing', () => {
@@ -26,7 +26,7 @@ describe('DeviceFrame', () => {
26
26
  it('renders with default props', () => {
27
27
  const { container } = render(<DeviceFrame />);
28
28
  const frame = container.firstChild;
29
-
29
+
30
30
  expect(frame).toHaveClass('device-frame');
31
31
  expect(frame).toHaveClass('device-frame--android'); // Default device
32
32
  });
@@ -37,7 +37,7 @@ describe('DeviceFrame', () => {
37
37
  <div data-testid="child-content">Test Content</div>
38
38
  </DeviceFrame>
39
39
  );
40
-
40
+
41
41
  expect(screen.getByTestId('child-content')).toBeInTheDocument();
42
42
  expect(screen.getByTestId('child-content')).toHaveTextContent('Test Content');
43
43
  });
@@ -50,7 +50,7 @@ describe('DeviceFrame', () => {
50
50
  <div data-testid="child-3">Child 3</div>
51
51
  </DeviceFrame>
52
52
  );
53
-
53
+
54
54
  expect(screen.getByTestId('child-1')).toBeInTheDocument();
55
55
  expect(screen.getByTestId('child-2')).toBeInTheDocument();
56
56
  expect(screen.getByTestId('child-3')).toBeInTheDocument();
@@ -61,7 +61,7 @@ describe('DeviceFrame', () => {
61
61
  it('renders Android frame correctly', () => {
62
62
  const { container } = render(<DeviceFrame device={DEVICE_TYPES.ANDROID} />);
63
63
  const frame = container.firstChild;
64
-
64
+
65
65
  expect(frame).toHaveClass('device-frame--android');
66
66
  expect(frame.style.backgroundImage).toBeTruthy();
67
67
  expect(frame.style.backgroundImage).toMatch(/url\(/);
@@ -70,7 +70,7 @@ describe('DeviceFrame', () => {
70
70
  it('renders iOS frame correctly', () => {
71
71
  const { container } = render(<DeviceFrame device={DEVICE_TYPES.IOS} />);
72
72
  const frame = container.firstChild;
73
-
73
+
74
74
  expect(frame).toHaveClass('device-frame--ios');
75
75
  expect(frame.style.backgroundImage).toBeTruthy();
76
76
  expect(frame.style.backgroundImage).toMatch(/url\(/);
@@ -79,7 +79,7 @@ describe('DeviceFrame', () => {
79
79
  it('defaults to Android when no device specified', () => {
80
80
  const { container } = render(<DeviceFrame />);
81
81
  const frame = container.firstChild;
82
-
82
+
83
83
  expect(frame).toHaveClass('device-frame--android');
84
84
  expect(frame.style.backgroundImage).toBeTruthy();
85
85
  expect(frame.style.backgroundImage).toMatch(/url\(/);
@@ -102,7 +102,7 @@ describe('DeviceFrame', () => {
102
102
  it('applies correct dimensions', () => {
103
103
  const { container } = render(<DeviceFrame />);
104
104
  const frame = container.firstChild;
105
-
105
+
106
106
  expect(frame.style.width).toBe('450px');
107
107
  expect(frame.style.height).toBe('920px');
108
108
  });
@@ -117,7 +117,7 @@ describe('DeviceFrame', () => {
117
117
  <DeviceFrame device={DEVICE_TYPES.IOS} />
118
118
  );
119
119
  const iosFrame = iosContainer.firstChild;
120
-
120
+
121
121
  expect(androidFrame.style.width).toBe(iosFrame.style.width);
122
122
  expect(androidFrame.style.height).toBe(iosFrame.style.height);
123
123
  });
@@ -125,7 +125,7 @@ describe('DeviceFrame', () => {
125
125
  it('applies background styles correctly', () => {
126
126
  const { container } = render(<DeviceFrame />);
127
127
  const frame = container.firstChild;
128
-
128
+
129
129
  expect(frame.style.position).toBe('relative');
130
130
  expect(frame.style.display).toBe('inline-block');
131
131
  expect(frame.style.backgroundRepeat).toBe('no-repeat');
@@ -133,10 +133,19 @@ describe('DeviceFrame', () => {
133
133
  expect(frame.style.backgroundSize).toBe('contain');
134
134
  });
135
135
 
136
+ it('applies drop-shadow filter', () => {
137
+ const { container } = render(<DeviceFrame />);
138
+ const frame = container.firstChild;
139
+
140
+ expect(frame.style.filter).toContain('drop-shadow');
141
+ expect(frame.style.filter).toContain('brightness');
142
+ expect(frame.style.filter).toContain('contrast');
143
+ });
144
+
136
145
  it('sets correct background image for Android', () => {
137
146
  const { container } = render(<DeviceFrame device={DEVICE_TYPES.ANDROID} />);
138
147
  const frame = container.firstChild;
139
-
148
+
140
149
  // Verify background image is set (actual mock value may vary)
141
150
  expect(frame.style.backgroundImage).toBeTruthy();
142
151
  expect(frame.style.backgroundImage).toMatch(/^url\(.+\)$/);
@@ -145,7 +154,7 @@ describe('DeviceFrame', () => {
145
154
  it('sets correct background image for iOS', () => {
146
155
  const { container } = render(<DeviceFrame device={DEVICE_TYPES.IOS} />);
147
156
  const frame = container.firstChild;
148
-
157
+
149
158
  // Verify background image is set (actual mock value may vary)
150
159
  expect(frame.style.backgroundImage).toBeTruthy();
151
160
  expect(frame.style.backgroundImage).toMatch(/^url\(.+\)$/);
@@ -156,7 +165,7 @@ describe('DeviceFrame', () => {
156
165
  it('accepts and applies custom className', () => {
157
166
  const { container } = render(<DeviceFrame className="custom-frame" />);
158
167
  const frame = container.firstChild;
159
-
168
+
160
169
  expect(frame).toHaveClass('custom-frame');
161
170
  expect(frame).toHaveClass('device-frame'); // Base class still present
162
171
  });
@@ -166,7 +175,7 @@ describe('DeviceFrame', () => {
166
175
  <DeviceFrame className="custom-class another-class" />
167
176
  );
168
177
  const frame = container.firstChild;
169
-
178
+
170
179
  expect(frame).toHaveClass('custom-class');
171
180
  expect(frame).toHaveClass('another-class');
172
181
  expect(frame).toHaveClass('device-frame');
@@ -177,7 +186,7 @@ describe('DeviceFrame', () => {
177
186
  <DeviceFrame data-testid="custom-frame" aria-label="Device Preview" />
178
187
  );
179
188
  const frame = container.firstChild;
180
-
189
+
181
190
  expect(frame).toHaveAttribute('data-testid', 'custom-frame');
182
191
  expect(frame).toHaveAttribute('aria-label', 'Device Preview');
183
192
  });
@@ -186,7 +195,7 @@ describe('DeviceFrame', () => {
186
195
  const handleClick = jest.fn();
187
196
  const { container } = render(<DeviceFrame onClick={handleClick} />);
188
197
  const frame = container.firstChild;
189
-
198
+
190
199
  frame.click();
191
200
  expect(handleClick).toHaveBeenCalledTimes(1);
192
201
  });
@@ -195,7 +204,7 @@ describe('DeviceFrame', () => {
195
204
  const customStyle = { border: '2px solid red' };
196
205
  const { container } = render(<DeviceFrame style={customStyle} />);
197
206
  const frame = container.firstChild;
198
-
207
+
199
208
  // Note: inline styles from props override component styles
200
209
  expect(frame.style.border).toBe('2px solid red');
201
210
  });
@@ -261,7 +270,7 @@ describe('DeviceFrame', () => {
261
270
  it('renders with empty string className', () => {
262
271
  const { container } = render(<DeviceFrame className="" />);
263
272
  const frame = container.firstChild;
264
-
273
+
265
274
  expect(frame).toHaveClass('device-frame');
266
275
  });
267
276
 
@@ -274,7 +283,7 @@ describe('DeviceFrame', () => {
274
283
  </>
275
284
  </DeviceFrame>
276
285
  );
277
-
286
+
278
287
  expect(screen.getByTestId('fragment-child-1')).toBeInTheDocument();
279
288
  expect(screen.getByTestId('fragment-child-2')).toBeInTheDocument();
280
289
  });
@@ -289,7 +298,7 @@ describe('DeviceFrame', () => {
289
298
  </div>
290
299
  </DeviceFrame>
291
300
  );
292
-
301
+
293
302
  expect(screen.getByTestId('nested-child')).toBeInTheDocument();
294
303
  });
295
304
  });
@@ -297,7 +306,7 @@ describe('DeviceFrame', () => {
297
306
  describe('Component Structure', () => {
298
307
  it('renders a single root div element', () => {
299
308
  const { container } = render(<DeviceFrame />);
300
-
309
+
301
310
  expect(container.firstChild.tagName).toBe('DIV');
302
311
  expect(container.children).toHaveLength(1);
303
312
  });
@@ -307,8 +316,8 @@ describe('DeviceFrame', () => {
307
316
  <DeviceFrame device={DEVICE_TYPES.ANDROID} className="custom" />
308
317
  );
309
318
  const androidFrame = androidContainer.firstChild;
310
-
311
- const classes = androidFrame.className.split(' ').filter((c) => c);
319
+
320
+ const classes = androidFrame.className.split(' ').filter(c => c);
312
321
  expect(classes).toContain('device-frame');
313
322
  expect(classes).toContain('device-frame--android');
314
323
  expect(classes).toContain('custom');
@@ -317,7 +326,7 @@ describe('DeviceFrame', () => {
317
326
  it('applies styles as inline styles object', () => {
318
327
  const { container } = render(<DeviceFrame />);
319
328
  const frame = container.firstChild;
320
-
329
+
321
330
  // Verify style is an object
322
331
  expect(typeof frame.style).toBe('object');
323
332
  expect(frame.style).not.toBeNull();
@@ -334,7 +343,7 @@ describe('DeviceFrame', () => {
334
343
  />
335
344
  );
336
345
  const frame = container.firstChild;
337
-
346
+
338
347
  expect(frame).toHaveAttribute('role', 'img');
339
348
  expect(frame).toHaveAttribute('aria-label', 'Mobile Device Preview');
340
349
  expect(frame).toHaveAttribute('aria-describedby', 'device-description');
@@ -349,7 +358,7 @@ describe('DeviceFrame', () => {
349
358
  />
350
359
  );
351
360
  const frame = container.firstChild;
352
-
361
+
353
362
  expect(frame).toHaveAttribute('data-device', 'android');
354
363
  expect(frame).toHaveAttribute('data-testid', 'device-frame');
355
364
  expect(frame).toHaveAttribute('data-analytics', 'preview-frame');
@@ -369,7 +378,7 @@ describe('DeviceFrame', () => {
369
378
  </div>
370
379
  </DeviceFrame>
371
380
  );
372
-
381
+
373
382
  expect(screen.getByTestId('preview-iframe')).toBeInTheDocument();
374
383
  });
375
384
 
@@ -379,16 +388,16 @@ describe('DeviceFrame', () => {
379
388
  <div data-testid="content">Content</div>
380
389
  </DeviceFrame>
381
390
  );
382
-
391
+
383
392
  expect(container.firstChild).toHaveClass('device-frame--android');
384
393
  expect(screen.getByTestId('content')).toBeInTheDocument();
385
-
394
+
386
395
  rerender(
387
396
  <DeviceFrame device={DEVICE_TYPES.IOS}>
388
397
  <div data-testid="content">Content</div>
389
398
  </DeviceFrame>
390
399
  );
391
-
400
+
392
401
  expect(container.firstChild).toHaveClass('device-frame--ios');
393
402
  expect(screen.getByTestId('content')).toBeInTheDocument();
394
403
  });
@@ -399,16 +408,17 @@ describe('DeviceFrame', () => {
399
408
  <div data-testid="dynamic-content">Initial</div>
400
409
  </DeviceFrame>
401
410
  );
402
-
411
+
403
412
  expect(screen.getByTestId('dynamic-content')).toHaveTextContent('Initial');
404
-
413
+
405
414
  rerender(
406
415
  <DeviceFrame>
407
416
  <div data-testid="dynamic-content">Updated</div>
408
417
  </DeviceFrame>
409
418
  );
410
-
419
+
411
420
  expect(screen.getByTestId('dynamic-content')).toHaveTextContent('Updated');
412
421
  });
413
422
  });
414
423
  });
424
+
@@ -24,7 +24,7 @@ $empty-state-meta-opacity: 0.7;
24
24
  .inapp-preview-pane {
25
25
  height: 100%;
26
26
  position: relative;
27
- background-color: $CAP_G07;
27
+ background-color: $CAP_G08;
28
28
  background-image: radial-gradient(circle at 50% 50%, rgba($CAP_WHITE, 0.1) 0%, transparent 70%);
29
29
  display: flex;
30
30
  flex-direction: column;
@@ -123,9 +123,11 @@ $empty-state-meta-opacity: 0.7;
123
123
  .device-frame {
124
124
  position: relative;
125
125
  display: inline-block;
126
+ filter: drop-shadow(0 0.75rem 3rem rgba($CAP_G01, 0.25));
126
127
  transition: all 0.3s ease-in-out;
127
128
 
128
129
  &:hover {
130
+ filter: drop-shadow(0 1rem 3.5rem rgba($CAP_G01, 0.3));
129
131
  transform: translateY(-0.125rem);
130
132
  }
131
133
 
@@ -6,55 +6,55 @@ export const LAYOUT_TYPES = {
6
6
  MODAL: 'POPUP',
7
7
  HEADER: 'HEADER',
8
8
  FOOTER: 'FOOTER',
9
- FULLSCREEN: 'FULLSCREEN',
9
+ FULLSCREEN: 'FULLSCREEN'
10
10
  };
11
11
 
12
12
  export const LAYOUT_OPTIONS = [
13
13
  {
14
14
  value: LAYOUT_TYPES.MODAL,
15
15
  label: 'Modal',
16
- description: 'Content displayed in center like a modal dialog',
16
+ description: 'Content displayed in center like a modal dialog'
17
17
  },
18
18
  {
19
19
  value: LAYOUT_TYPES.HEADER,
20
20
  label: 'Top Banner',
21
- description: 'Content displayed at the top of the screen',
21
+ description: 'Content displayed at the top of the screen'
22
22
  },
23
23
  {
24
24
  value: LAYOUT_TYPES.FOOTER,
25
25
  label: 'Bottom Banner',
26
- description: 'Content displayed at the bottom of the screen',
26
+ description: 'Content displayed at the bottom of the screen'
27
27
  },
28
28
  {
29
29
  value: LAYOUT_TYPES.FULLSCREEN,
30
30
  label: 'Fullscreen',
31
- description: 'Content covers the entire screen',
32
- },
31
+ description: 'Content covers the entire screen'
32
+ }
33
33
  ];
34
34
 
35
35
  export const COMPONENT_SIZES = ['small', 'middle', 'large'];
36
36
 
37
37
  export const DEVICE_FRAMES = {
38
38
  ANDROID: 'android-frame.svg',
39
- IOS: 'ios-frame.svg',
39
+ IOS: 'ios-frame.svg'
40
40
  };
41
41
 
42
42
  // Screen area dimensions within device frames (accounting for PNG bezels)
43
43
  export const DEVICE_SCREEN_AREAS = {
44
44
  IOS: {
45
45
  // iOS screen area within 450x920 frame - accurate values for PNG asset
46
- top: '85px', // Top bezel including notch area
47
- left: '35px', // Side bezel width
48
- width: '380px', // Actual screen width within bezels
49
- height: '710px', // Actual screen height within bezels
46
+ top: '85px', // Top bezel including notch area
47
+ left: '35px', // Side bezel width
48
+ width: '380px', // Actual screen width within bezels
49
+ height: '710px' // Actual screen height within bezels
50
50
  },
51
51
  ANDROID: {
52
52
  // Android screen area within 450x920 frame - accurate values for PNG asset
53
- top: '85px', // Top bezel including status bar
54
- left: '35px', // Side bezel width (same as iOS for consistency)
55
- width: '380px', // Actual screen width within bezels
56
- height: '710px', // Actual screen height within bezels
57
- },
53
+ top: '85px', // Top bezel including status bar
54
+ left: '35px', // Side bezel width (same as iOS for consistency)
55
+ width: '380px', // Actual screen width within bezels
56
+ height: '710px' // Actual screen height within bezels
57
+ }
58
58
  };
59
59
 
60
60
  // Content positioning configurations within the screen area (not the full frame)
@@ -63,42 +63,42 @@ export const LAYOUT_POSITIONS = {
63
63
  top: '50%',
64
64
  left: '50%',
65
65
  transform: 'translate(-50%, -50%)',
66
- width: '85%', // Reduced to ensure content stays within screen
67
- height: '55%', // Reduced to ensure content stays within screen
66
+ width: '85%', // Reduced to ensure content stays within screen
67
+ height: '55%', // Reduced to ensure content stays within screen
68
68
  maxWidth: '320px', // Adjusted for screen area
69
69
  maxHeight: '380px',
70
- minHeight: '180px',
70
+ minHeight: '180px'
71
71
  },
72
72
  [LAYOUT_TYPES.HEADER]: {
73
- top: '2%', // More margin from top of screen
73
+ top: '2%', // More margin from top of screen
74
74
  left: '50%',
75
75
  transform: 'translateX(-50%)',
76
- width: '90%', // Reduced to stay within screen bounds
76
+ width: '90%', // Reduced to stay within screen bounds
77
77
  height: '22%',
78
78
  maxHeight: '160px',
79
- minHeight: '100px',
79
+ minHeight: '100px'
80
80
  },
81
81
  [LAYOUT_TYPES.FOOTER]: {
82
- bottom: '2%', // More margin from bottom of screen
82
+ bottom: '2%', // More margin from bottom of screen
83
83
  left: '50%',
84
84
  transform: 'translateX(-50%)',
85
- width: '90%', // Reduced to stay within screen bounds
85
+ width: '90%', // Reduced to stay within screen bounds
86
86
  height: '22%',
87
87
  maxHeight: '160px',
88
- minHeight: '100px',
88
+ minHeight: '100px'
89
89
  },
90
90
  [LAYOUT_TYPES.FULLSCREEN]: {
91
- top: '2%', // Small margin to account for screen bounds
91
+ top: '2%', // Small margin to account for screen bounds
92
92
  left: '2%',
93
- width: '96%', // Slightly smaller to ensure it stays within screen
94
- height: '96%',
95
- },
93
+ width: '96%', // Slightly smaller to ensure it stays within screen
94
+ height: '96%'
95
+ }
96
96
  };
97
97
 
98
98
  // Scroll position multipliers for adaptive scrolling in InAppPreviewPane
99
99
  export const SCROLL_POSITION_MULTIPLIERS = {
100
- [LAYOUT_TYPES.HEADER]: 0.0, // Top of screen
101
- [LAYOUT_TYPES.FOOTER]: 1.0, // Bottom of screen
102
- [LAYOUT_TYPES.MODAL]: 0.4, // Center-ish position
103
- [LAYOUT_TYPES.FULLSCREEN]: 0.3, // Slightly above center
100
+ [LAYOUT_TYPES.HEADER]: 0.0, // Top of screen
101
+ [LAYOUT_TYPES.FOOTER]: 1.0, // Bottom of screen
102
+ [LAYOUT_TYPES.MODAL]: 0.4, // Center-ish position
103
+ [LAYOUT_TYPES.FULLSCREEN]: 0.3 // Slightly above center
104
104
  };
@@ -2,9 +2,7 @@
2
2
  * InAppPreviewPane - Complete InApp preview with device frames and dynamic positioning
3
3
  */
4
4
 
5
- import React, {
6
- useMemo, useRef, useEffect, useCallback,
7
- } from 'react';
5
+ import React, { useMemo, useRef, useEffect, useCallback } from 'react';
8
6
  import PropTypes from 'prop-types';
9
7
  import { injectIntl, intlShape } from 'react-intl';
10
8
 
@@ -18,6 +16,7 @@ import ContentOverlay from './ContentOverlay';
18
16
  import { useEditorContext } from '../common/EditorContext';
19
17
 
20
18
  // Constants
19
+ import { DEVICE_TYPES } from '../../constants';
21
20
  import { LAYOUT_TYPES, SCROLL_POSITION_MULTIPLIERS } from './constants';
22
21
 
23
22
  // Styles
@@ -28,14 +27,14 @@ const InAppPreviewPane = ({
28
27
  className = '',
29
28
  isFullscreenMode = false,
30
29
  isModalContext = false,
31
- layoutType: propLayoutType = LAYOUT_TYPES.MODAL,
30
+ layoutType: propLayoutType = LAYOUT_TYPES.MODAL
32
31
  }) => {
33
32
  const {
34
33
  content,
35
34
  activeDevice,
36
35
  getDeviceContent,
37
36
  layoutType: contextLayoutType,
38
- isFullscreenMode: contextIsFullscreenMode,
37
+ isFullscreenMode: contextIsFullscreenMode
39
38
  } = useEditorContext();
40
39
 
41
40
  // Refs for adaptive scrolling
@@ -84,7 +83,7 @@ const InAppPreviewPane = ({
84
83
  requestAnimationFrame(() => {
85
84
  container.scrollTo({
86
85
  top: targetScrollTop,
87
- behavior: 'smooth',
86
+ behavior: 'smooth'
88
87
  });
89
88
  });
90
89
  } catch (error) {
@@ -174,7 +173,7 @@ InAppPreviewPane.propTypes = {
174
173
  className: PropTypes.string,
175
174
  isFullscreenMode: PropTypes.bool,
176
175
  isModalContext: PropTypes.bool,
177
- layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES)),
176
+ layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES))
178
177
  };
179
178
 
180
179
  export default injectIntl(InAppPreviewPane);
@@ -14,8 +14,8 @@
14
14
 
15
15
  &__mode-controls {
16
16
  position: absolute;
17
- top: 1.5rem;
18
- right: 2rem;
17
+ top: 0.5rem;
18
+ right: 0.5rem;
19
19
  z-index: 10;
20
20
  background-color: $CAP_G07;
21
21
  border-radius: 0.5rem;
@@ -59,7 +59,7 @@
59
59
 
60
60
  &:hover,
61
61
  &.preview-mode-group__btn--active {
62
- background-color: $CAP_WHITE;
62
+ background-color: rgba($CAP_WHITE, 0.5);
63
63
  }
64
64
  }
65
65
  }
@@ -191,6 +191,9 @@
191
191
  height: calc(100% - 2rem);
192
192
  color: $CAP_G10;
193
193
  text-align: center;
194
+ background-color: $CAP_WHITE;
195
+ border-radius: 0.25rem;
196
+ box-shadow: 0 0.0625rem 0.1875rem rgba($CAP_G01, 0.1);
194
197
  margin: 0;
195
198
  width: 100%;
196
199
 
@@ -55,7 +55,7 @@ const PreviewPane = ({
55
55
  className = '',
56
56
  isFullscreenMode = false,
57
57
  isModalContext = false,
58
- layoutType = LAYOUT_TYPES.MODAL,
58
+ layoutType = LAYOUT_TYPES.MODAL
59
59
  }) => {
60
60
  const { content, layout, variant } = useEditorContext();
61
61
 
@@ -124,11 +124,13 @@ const PreviewPane = ({
124
124
  }, [combinedContent]);
125
125
 
126
126
  // Cleanup blob URL on unmount
127
- useEffect(() => () => {
128
- if (blobUrlRef.current) {
129
- URL.revokeObjectURL(blobUrlRef.current);
130
- blobUrlRef.current = null;
131
- }
127
+ useEffect(() => {
128
+ return () => {
129
+ if (blobUrlRef.current) {
130
+ URL.revokeObjectURL(blobUrlRef.current);
131
+ blobUrlRef.current = null;
132
+ }
133
+ };
132
134
  }, []);
133
135
 
134
136
  // Generate CSS classes based on view mode
@@ -171,11 +173,10 @@ const PreviewPane = ({
171
173
  const renderEmptyState = () => (
172
174
  <div className="preview-empty">
173
175
  <div className="empty-content">
176
+ <div className="empty-icon">📝</div>
174
177
  <p>{intl.formatMessage(messages.startTypingHtml)}</p>
175
178
  <p className="preview-mode-info">
176
- {intl.formatMessage(messages.previewMode)}
177
- :
178
- {
179
+ {intl.formatMessage(messages.previewMode)}: {
179
180
  viewMode === PREVIEW_MODES.DESKTOP
180
181
  ? intl.formatMessage(messages.desktop)
181
182
  : viewMode === PREVIEW_MODES.MOBILE
@@ -222,7 +223,7 @@ PreviewPane.propTypes = {
222
223
  className: PropTypes.string,
223
224
  isFullscreenMode: PropTypes.bool,
224
225
  isModalContext: PropTypes.bool,
225
- layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES)),
226
+ layoutType: PropTypes.oneOf(Object.values(LAYOUT_TYPES))
226
227
  };
227
228
 
228
229
  export default injectIntl(PreviewPane);
@@ -161,7 +161,7 @@
161
161
 
162
162
  // Dragging state styling
163
163
  &--dragging &__splitter {
164
- background-color: map-get($CAP_SECONDARY, base);
164
+ background-color: map-get($CAP_PRIMARY, base);
165
165
  }
166
166
 
167
167
  &--dragging &__splitter-line {