@capillarytech/creatives-library 8.0.292-alpha.13 → 8.0.292-alpha.14

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.292-alpha.13",
4
+ "version": "8.0.292-alpha.14",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -305,13 +305,10 @@ const HTMLEditor = forwardRef(({
305
305
  apiValidationErrors, // Pass API validation errors to merge with client-side validation
306
306
  }, formatSanitizerMessage, formatValidatorMessage);
307
307
 
308
- // Expose validation and content state via ref (InApp: also expose getDeviceContent for Test and Preview)
308
+ // Expose validation and content state via ref
309
309
  useImperativeHandle(ref, () => ({
310
310
  getValidation: () => validation,
311
311
  getContent: () => currentContent,
312
- getDeviceContent: variant === HTML_EDITOR_VARIANTS.INAPP && typeof getDeviceContent === 'function'
313
- ? getDeviceContent
314
- : undefined,
315
312
  isContentEmpty: () => !currentContent || currentContent.trim() === '',
316
313
  getIssueCounts: () => {
317
314
  if (!validation || typeof validation.getAllIssues !== 'function') {
@@ -327,7 +324,7 @@ const HTMLEditor = forwardRef(({
327
324
  : countIssuesBySeverity(validation.getAllIssues()),
328
325
  })
329
326
  ,
330
- }), [validation, currentContent, apiValidationErrors, variant, getDeviceContent]);
327
+ }), [validation, currentContent, apiValidationErrors]);
331
328
 
332
329
  // Use ref to store callback to avoid infinite loops (callback in deps would cause re-runs)
333
330
  const onValidationChangeRef = useRef(onValidationChange);
@@ -835,5 +832,5 @@ HTMLEditor.defaultProps = {
835
832
  apiValidationErrors: null, // API validation errors from validateLiquidTemplateContent
836
833
  };
837
834
 
838
- // Export with injectIntl - forwardRef so parent (e.g. InApp) can use ref for getDeviceContent (Test and Preview)
839
- export default injectIntl(HTMLEditor, { forwardRef: true });
835
+ // Export with injectIntl - HTMLEditor uses forwardRef internally
836
+ export default injectIntl(HTMLEditor);
@@ -40,14 +40,14 @@ const LazyHTMLEditor = React.lazy(() =>
40
40
  *
41
41
  * This component wraps the HTMLEditor with React.lazy() and Suspense
42
42
  * to enable code splitting and reduce initial bundle size.
43
- * Forwards ref so parent (e.g. InApp) can call getDeviceContent for Test and Preview.
44
43
  */
45
- const HTMLEditorLazy = React.forwardRef((props, ref) => (
46
- <Suspense fallback={<HTMLEditorFallback />}>
47
- <LazyHTMLEditor {...props} ref={ref} />
48
- </Suspense>
49
- ));
50
- HTMLEditorLazy.displayName = 'HTMLEditorLazy';
44
+ const HTMLEditorLazy = (props) => {
45
+ return (
46
+ <Suspense fallback={<HTMLEditorFallback />}>
47
+ <LazyHTMLEditor {...props} />
48
+ </Suspense>
49
+ );
50
+ };
51
51
 
52
52
  // Forward all prop types from the original component
53
53
  HTMLEditorLazy.propTypes = {
@@ -61,7 +61,7 @@ import { validateInAppContent } from "../../utils/commonUtils";
61
61
  import { hasLiquidSupportFeature } from "../../utils/common";
62
62
  import formBuilderMessages from "../../v2Components/FormBuilder/messages";
63
63
  import HTMLEditor from "../../v2Components/HtmlEditor";
64
- import { HTML_EDITOR_VARIANTS, DEVICE_TYPES as HTML_DEVICE_TYPES } from "../../v2Components/HtmlEditor/constants";
64
+ import { HTML_EDITOR_VARIANTS } from "../../v2Components/HtmlEditor/constants";
65
65
  import { INAPP_EDITOR_TYPES } from "../InAppWrapper/constants";
66
66
  import InappAdvanced from "../InappAdvance/index";
67
67
  import { ErrorInfoNote } from "../../v2Components/ErrorInfoNote";
@@ -142,10 +142,13 @@ export const InApp = (props) => {
142
142
  const [isHTMLTemplate, setIsHTMLTemplate] = useState(false);
143
143
  // Version to force HTMLEditor remount on layout changes
144
144
  const [htmlEditorContentVersion, setHtmlEditorContentVersion] = useState(0);
145
- // Refs to store latest content before layout changes
145
+ // Refs to store latest content (kept in sync in handleHtmlContentChange so Test and Preview reads fresh content in library mode)
146
146
  const htmlContentAndroidRef = useRef(htmlContentAndroid);
147
147
  const htmlContentIosRef = useRef(htmlContentIos);
148
- const htmlEditorRef = useRef(null);
148
+ useEffect(() => {
149
+ htmlContentAndroidRef.current = htmlContentAndroid;
150
+ htmlContentIosRef.current = htmlContentIos;
151
+ }, [htmlContentAndroid, htmlContentIos]);
149
152
  const [accountId, setAccountId] = useState("");
150
153
  const [accessToken, setAccessToken] = useState("");
151
154
  const [accountName, setAccountName] = useState("");
@@ -173,24 +176,15 @@ export const InApp = (props) => {
173
176
  // TestAndPreviewSlidebox state
174
177
  const [showTestAndPreviewSlidebox, setShowTestAndPreviewSlidebox] = useState(false);
175
178
 
176
- // Get template content for TestAndPreviewSlidebox
177
- // Returns simple structure with preview fields only
178
- // Transformation to payload structure happens in prepareTestMessagePayload
179
- // Reference: Based on getPreviewSection() function (lines 490-530) which prepares content for TemplatePreview
179
+ // Get template content for TestAndPreviewSlidebox (same pattern as Mobile Push: read current content for preview)
180
+ // State is updated on every keystroke via onContentChange; refs are synced so we read fresh content in library mode too.
180
181
  const getTemplateContent = useCallback(() => {
181
- // For HTML template: prefer editor ref (source of truth) so library mode preview gets latest content
182
- let androidMsg = templateMessageAndroid;
183
- let iosMsg = templateMessageIos;
184
- if (isHTMLTemplate) {
185
- const getDeviceContentFromEditor = htmlEditorRef.current?.getDeviceContent;
186
- if (typeof getDeviceContentFromEditor === 'function') {
187
- androidMsg = getDeviceContentFromEditor(HTML_DEVICE_TYPES.ANDROID) ?? '';
188
- iosMsg = getDeviceContentFromEditor(HTML_DEVICE_TYPES.IOS) ?? '';
189
- } else {
190
- androidMsg = htmlContentAndroidRef.current ?? htmlContentAndroid ?? '';
191
- iosMsg = htmlContentIosRef.current ?? htmlContentIos ?? '';
192
- }
193
- }
182
+ const androidMsg = isHTMLTemplate
183
+ ? (htmlContentAndroidRef.current ?? htmlContentAndroid ?? '')
184
+ : templateMessageAndroid;
185
+ const iosMsg = isHTMLTemplate
186
+ ? (htmlContentIosRef.current ?? htmlContentIos ?? '')
187
+ : templateMessageIos;
194
188
 
195
189
  // Prepare Android content
196
190
  const androidMediaPreview = {};
@@ -1019,11 +1013,12 @@ export const InApp = (props) => {
1019
1013
  );
1020
1014
  };
1021
1015
 
1022
- // Handle HTML content changes from HTMLEditor
1016
+ // Handle HTML content changes from HTMLEditor - update state and refs so Test and Preview has fresh content (full + library mode)
1023
1017
  const handleHtmlContentChange = useCallback((deviceContent, changedDevice) => {
1024
1018
  // When "keep content same" is on, useInAppContent passes full deviceContent with both
1025
1019
  // android and ios set to the same value. We must update both states so preview shows
1026
1020
  // the synced content for each device. Otherwise only update the device that changed.
1021
+ // Refs are updated synchronously so getTemplateContent() reads latest when opening the slidebox.
1027
1022
 
1028
1023
  // Clear validation errors when content changes (similar to Bee Editor)
1029
1024
  if (changedDevice) {
@@ -1046,33 +1041,36 @@ export const InApp = (props) => {
1046
1041
  const isSyncUpdate = hasAndroid && hasIos;
1047
1042
 
1048
1043
  if (isSyncUpdate) {
1049
- // Sync mode: update both so preview shows same content for Android and iOS
1050
1044
  if (hasAndroid) {
1051
- setHtmlContentAndroid(deviceContent.android || '');
1045
+ const v = deviceContent.android || '';
1046
+ htmlContentAndroidRef.current = v;
1047
+ setHtmlContentAndroid(v);
1052
1048
  }
1053
1049
  if (hasIos) {
1054
- setHtmlContentIos(deviceContent.ios || '');
1050
+ const v = deviceContent.ios || '';
1051
+ htmlContentIosRef.current = v;
1052
+ setHtmlContentIos(v);
1055
1053
  }
1056
1054
  } else if (changedDevice) {
1057
- // Only one device changed
1058
1055
  if (changedDevice.toUpperCase() === ANDROID && hasAndroid) {
1059
- setHtmlContentAndroid(deviceContent.android || '');
1056
+ const v = deviceContent.android || '';
1057
+ htmlContentAndroidRef.current = v;
1058
+ setHtmlContentAndroid(v);
1060
1059
  } else if (changedDevice.toUpperCase() === IOS_CAPITAL && hasIos) {
1061
- setHtmlContentIos(deviceContent.ios || '');
1060
+ const v = deviceContent.ios || '';
1061
+ htmlContentIosRef.current = v;
1062
+ setHtmlContentIos(v);
1062
1063
  }
1063
1064
  } else {
1064
- // Fallback: update both if changedDevice not provided
1065
1065
  if (hasAndroid) {
1066
- setHtmlContentAndroid((prev) => {
1067
- const newValue = deviceContent.android || '';
1068
- return prev !== newValue ? newValue : prev;
1069
- });
1066
+ const newValue = deviceContent.android || '';
1067
+ htmlContentAndroidRef.current = newValue;
1068
+ setHtmlContentAndroid((prev) => (prev !== newValue ? newValue : prev));
1070
1069
  }
1071
1070
  if (hasIos) {
1072
- setHtmlContentIos((prev) => {
1073
- const newValue = deviceContent.ios || '';
1074
- return prev !== newValue ? newValue : prev;
1075
- });
1071
+ const newValue = deviceContent.ios || '';
1072
+ htmlContentIosRef.current = newValue;
1073
+ setHtmlContentIos((prev) => (prev !== newValue ? newValue : prev));
1076
1074
  }
1077
1075
  }
1078
1076
  }, [ANDROID, IOS_CAPITAL, setErrorMessage]);
@@ -1334,7 +1332,6 @@ export const InApp = (props) => {
1334
1332
  )}
1335
1333
  {shouldUseHTMLEditor ? (
1336
1334
  <HTMLEditor
1337
- ref={htmlEditorRef}
1338
1335
  key={`inapp-html-editor-v${htmlEditorContentVersion}`}
1339
1336
  variant={HTML_EDITOR_VARIANTS.INAPP}
1340
1337
  layoutType={templateLayoutType}