@dotcms/react 0.0.1-beta.2 → 0.0.1-beta.20

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/index.esm.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
- import { s as styleInject, f as functionUncurryThis, t as toString$4, r as requireObjectCoercible$1, a as toIntegerOrInfinity$1, i as iteratorDefine, b as internalState, c as createIterResultObject$2, d as fails$2, w as wellKnownSymbol$4, e as descriptors, g as classofRaw$1, h as aCallable$2, j as functionBindNative, m as makeBuiltInExports, o as objectDefineProperty, k as objectIsPrototypeOf, l as functionCall, n as anObject$4, p as getMethod$2, q as iterators, u as getBuiltIn$1, v as isCallable$2, x as classof$3, y as inspectSource$1, z as createPropertyDescriptor$2, A as isNullOrUndefined$1, B as tryToString$1, C as toObject$1, D as lengthOfArrayLike$1, E as global$3, F as defineBuiltIn$5, G as arraySlice$2, _ as _export, H as setToStringTag$2, I as iteratorCreateConstructor, J as isObject$1, K as objectCreate, L as hasOwnProperty_1, M as objectAssign } from './es.regexp.to-string.esm.js';
2
+ import { s as styleInject, a as anObject$6, f as functionCall, h as hasOwnProperty_1, o as objectIsPrototypeOf, b as functionName, d as defineBuiltIn$6, c as fails$3, t as toString$4, e as functionUncurryThis, r as requireObjectCoercible$1, g as toIntegerOrInfinity$1, i as iteratorDefine, j as internalState, k as createIterResultObject$2, w as wellKnownSymbol$4, l as descriptors, m as classofRaw$1, n as aCallable$2, p as functionBindNative, q as makeBuiltInExports, u as objectDefineProperty, v as getMethod$2, x as iterators, y as getBuiltIn$1, z as isCallable$2, A as classof$3, B as inspectSource$1, C as createPropertyDescriptor$2, D as isNullOrUndefined$1, E as tryToString$1, F as toObject$1, G as lengthOfArrayLike$1, H as global$3, I as arraySlice$2, _ as _export, J as setToStringTag$2, K as iteratorCreateConstructor, L as isObject$1, M as objectCreate, N as objectAssign } from './es.json.stringify.esm.js';
3
3
  import { useState, useEffect, createContext, useRef, useContext, createElement, forwardRef } from 'react';
4
- import { isInsideEditor, initEditor, updateNavigation, destroyEditor, DotCmsClient, postMessageToEditor, CLIENT_ACTIONS, NOTIFY_CLIENT, initInlineEditing } from '@dotcms/client';
4
+ import { isInsideEditor, initEditor, updateNavigation, destroyEditor, postMessageToEditor, CLIENT_ACTIONS, DotCmsClient, NOTIFY_CLIENT, initInlineEditing } from '@dotcms/client';
5
+ import { createUVESubscription } from '@dotcms/uve';
6
+ import { UVEEventType } from '@dotcms/uve/types';
5
7
  import { Editor } from '@tinymce/tinymce-react';
6
8
 
7
9
  var isPure = false;
@@ -49,12 +51,13 @@ const useDotcmsEditor = ({
49
51
  */
50
52
  useEffect(() => {
51
53
  const insideEditor = isInsideEditor();
52
- const client = DotCmsClient.instance;
53
54
  if (!insideEditor || !onReload) {
54
55
  return;
55
56
  }
56
- client.editor.on('changes', () => onReload == null ? void 0 : onReload());
57
- return () => client.editor.off('changes');
57
+ const {
58
+ unsubscribe
59
+ } = createUVESubscription(UVEEventType.CONTENT_CHANGES, () => onReload());
60
+ return () => unsubscribe();
58
61
  }, [onReload]);
59
62
  /**
60
63
  * Sends a message to the editor when the client is ready.
@@ -69,20 +72,21 @@ const useDotcmsEditor = ({
69
72
  });
70
73
  }, [pathname, editor]);
71
74
  /**
72
- * Updates the page asset when changes are made in the editor.
75
+ * Old
73
76
  */
74
77
  useEffect(() => {
75
78
  if (!isInsideEditor()) {
76
79
  return;
77
80
  }
78
- const client = DotCmsClient.instance;
79
- client.editor.on('changes', data => {
81
+ const {
82
+ unsubscribe
83
+ } = createUVESubscription(UVEEventType.CONTENT_CHANGES, data => {
80
84
  const pageAsset = data;
81
85
  setState(state => Object.assign({}, state, {
82
86
  pageAsset
83
87
  }));
84
88
  });
85
- return () => client.editor.off('changes');
89
+ return () => unsubscribe();
86
90
  }, []);
87
91
  return state;
88
92
  };
@@ -475,6 +479,63 @@ function DotcmsLayout(dotPageProps) {
475
479
  });
476
480
  }
477
481
 
482
+ var anObject$5 = anObject$6;
483
+
484
+ // `RegExp.prototype.flags` getter implementation
485
+ // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
486
+ var regexpFlags = function () {
487
+ var that = anObject$5(this);
488
+ var result = '';
489
+ if (that.hasIndices) result += 'd';
490
+ if (that.global) result += 'g';
491
+ if (that.ignoreCase) result += 'i';
492
+ if (that.multiline) result += 'm';
493
+ if (that.dotAll) result += 's';
494
+ if (that.unicode) result += 'u';
495
+ if (that.unicodeSets) result += 'v';
496
+ if (that.sticky) result += 'y';
497
+ return result;
498
+ };
499
+
500
+ var call$5 = functionCall;
501
+ var hasOwn$2 = hasOwnProperty_1;
502
+ var isPrototypeOf$1 = objectIsPrototypeOf;
503
+ var regExpFlags = regexpFlags;
504
+
505
+ var RegExpPrototype$1 = RegExp.prototype;
506
+
507
+ var regexpGetFlags = function (R) {
508
+ var flags = R.flags;
509
+ return flags === undefined && !('flags' in RegExpPrototype$1) && !hasOwn$2(R, 'flags') && isPrototypeOf$1(RegExpPrototype$1, R)
510
+ ? call$5(regExpFlags, R) : flags;
511
+ };
512
+
513
+ var PROPER_FUNCTION_NAME = functionName.PROPER;
514
+ var defineBuiltIn$5 = defineBuiltIn$6;
515
+ var anObject$4 = anObject$6;
516
+ var $toString$2 = toString$4;
517
+ var fails$2 = fails$3;
518
+ var getRegExpFlags = regexpGetFlags;
519
+
520
+ var TO_STRING = 'toString';
521
+ var RegExpPrototype = RegExp.prototype;
522
+ var nativeToString = RegExpPrototype[TO_STRING];
523
+
524
+ var NOT_GENERIC = fails$2(function () { return nativeToString.call({ source: 'a', flags: 'b' }) !== '/a/b'; });
525
+ // FF44- RegExp#toString has a wrong name
526
+ var INCORRECT_NAME = PROPER_FUNCTION_NAME && nativeToString.name !== TO_STRING;
527
+
528
+ // `RegExp.prototype.toString` method
529
+ // https://tc39.es/ecma262/#sec-regexp.prototype.tostring
530
+ if (NOT_GENERIC || INCORRECT_NAME) {
531
+ defineBuiltIn$5(RegExpPrototype, TO_STRING, function toString() {
532
+ var R = anObject$4(this);
533
+ var pattern = $toString$2(R.source);
534
+ var flags = $toString$2(getRegExpFlags(R));
535
+ return '/' + pattern + '/' + flags;
536
+ }, { unsafe: true });
537
+ }
538
+
478
539
  var uncurryThis$9 = functionUncurryThis;
479
540
  var toIntegerOrInfinity = toIntegerOrInfinity$1;
480
541
  var toString$3 = toString$4;
@@ -543,7 +604,7 @@ defineIterator(String, 'String', function (iterated) {
543
604
  return createIterResultObject$1(point, false);
544
605
  });
545
606
 
546
- var fails$1 = fails$2;
607
+ var fails$1 = fails$3;
547
608
  var wellKnownSymbol$3 = wellKnownSymbol$4;
548
609
  var DESCRIPTORS$5 = descriptors;
549
610
  var IS_PURE = isPure;
@@ -628,7 +689,7 @@ var anInstance$2 = function (it, Prototype) {
628
689
  };
629
690
 
630
691
  var call$4 = functionCall;
631
- var anObject$3 = anObject$4;
692
+ var anObject$3 = anObject$6;
632
693
  var getMethod$1 = getMethod$2;
633
694
 
634
695
  var iteratorClose$1 = function (iterator, kind, value) {
@@ -651,7 +712,7 @@ var iteratorClose$1 = function (iterator, kind, value) {
651
712
  return value;
652
713
  };
653
714
 
654
- var anObject$2 = anObject$4;
715
+ var anObject$2 = anObject$6;
655
716
  var iteratorClose = iteratorClose$1;
656
717
 
657
718
  // call something on iterator step with safe closing on error
@@ -675,7 +736,7 @@ var isArrayIteratorMethod$1 = function (it) {
675
736
  };
676
737
 
677
738
  var uncurryThis$6 = functionUncurryThis;
678
- var fails = fails$2;
739
+ var fails = fails$3;
679
740
  var isCallable$1 = isCallable$2;
680
741
  var classof$2 = classof$3;
681
742
  var getBuiltIn = getBuiltIn$1;
@@ -751,7 +812,7 @@ var getIteratorMethod$3 = function (it) {
751
812
 
752
813
  var call$3 = functionCall;
753
814
  var aCallable = aCallable$2;
754
- var anObject$1 = anObject$4;
815
+ var anObject$1 = anObject$6;
755
816
  var tryToString = tryToString$1;
756
817
  var getIteratorMethod$2 = getIteratorMethod$3;
757
818
 
@@ -1010,7 +1071,7 @@ var safeGetBuiltIn$1 = function (name) {
1010
1071
  return descriptor && descriptor.value;
1011
1072
  };
1012
1073
 
1013
- var defineBuiltIn$4 = defineBuiltIn$5;
1074
+ var defineBuiltIn$4 = defineBuiltIn$6;
1014
1075
 
1015
1076
  var defineBuiltIns$1 = function (target, src, options) {
1016
1077
  for (var key in src) defineBuiltIn$4(target, key, src[key], options);
@@ -1068,7 +1129,7 @@ var call$1 = functionCall;
1068
1129
  var uncurryThis$4 = functionUncurryThis;
1069
1130
  var DESCRIPTORS$2 = descriptors;
1070
1131
  var USE_NATIVE_URL$1 = urlConstructorDetection;
1071
- var defineBuiltIn$3 = defineBuiltIn$5;
1132
+ var defineBuiltIn$3 = defineBuiltIn$6;
1072
1133
  var defineBuiltInAccessor$2 = defineBuiltInAccessor$3;
1073
1134
  var defineBuiltIns = defineBuiltIns$1;
1074
1135
  var setToStringTag$1 = setToStringTag$2;
@@ -1079,7 +1140,7 @@ var isCallable = isCallable$2;
1079
1140
  var hasOwn$1 = hasOwnProperty_1;
1080
1141
  var bind$1 = functionBindContext;
1081
1142
  var classof = classof$3;
1082
- var anObject = anObject$4;
1143
+ var anObject = anObject$6;
1083
1144
  var isObject = isObject$1;
1084
1145
  var $toString$1 = toString$4;
1085
1146
  var create = objectCreate;
@@ -1483,7 +1544,7 @@ var USE_NATIVE_URL = urlConstructorDetection;
1483
1544
  var global = global$3;
1484
1545
  var bind = functionBindContext;
1485
1546
  var uncurryThis$3 = functionUncurryThis;
1486
- var defineBuiltIn$2 = defineBuiltIn$5;
1547
+ var defineBuiltIn$2 = defineBuiltIn$6;
1487
1548
  var defineBuiltInAccessor$1 = defineBuiltInAccessor$3;
1488
1549
  var anInstance = anInstance$2;
1489
1550
  var hasOwn = hasOwnProperty_1;
@@ -2534,7 +2595,7 @@ $({ target: 'URL', proto: true, enumerable: true }, {
2534
2595
  }
2535
2596
  });
2536
2597
 
2537
- var defineBuiltIn$1 = defineBuiltIn$5;
2598
+ var defineBuiltIn$1 = defineBuiltIn$6;
2538
2599
  var uncurryThis$2 = functionUncurryThis;
2539
2600
  var toString$1 = toString$4;
2540
2601
  var validateArgumentsLength$1 = validateArgumentsLength$4;
@@ -2583,7 +2644,7 @@ if (params$1 + '' !== 'a=2') {
2583
2644
  }, { enumerable: true, unsafe: true });
2584
2645
  }
2585
2646
 
2586
- var defineBuiltIn = defineBuiltIn$5;
2647
+ var defineBuiltIn = defineBuiltIn$6;
2587
2648
  var uncurryThis$1 = functionUncurryThis;
2588
2649
  var toString = toString$4;
2589
2650
  var validateArgumentsLength = validateArgumentsLength$4;
package/next.esm.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { jsxs, jsx } from 'react/jsx-runtime';
2
2
  import { createContext, useContext, useState, useEffect, useLayoutEffect, useRef, useMemo } from 'react';
3
- import { s as styleInject } from './es.regexp.to-string.esm.js';
3
+ import { s as styleInject } from './es.json.stringify.esm.js';
4
4
  import { getUVEState } from '@dotcms/uve';
5
+ import { DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_REACT, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getContainersData, getContentletsInContainer, getDotContainerAttributes, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
5
6
  import { UVE_MODE } from '@dotcms/uve/types';
6
7
 
7
8
  /**
@@ -20,18 +21,15 @@ const DotCMSPageContext = /*#__PURE__*/createContext({
20
21
  * A React hook that determines if the current environment is in development mode.
21
22
  *
22
23
  * The hook returns `true` if either:
23
- * - The context mode (or the optional `renderMode` argument) is set to 'development', or
24
- * - The application is running inside the DotCMS editor (as determined by `isInsideEditor()`).
24
+ * - The application is running inside the DotCMS editor (as determined by `getUVEState()`).
25
25
  *
26
- * @param {DotCMSPageRendererMode} [renderMode] - Optional override for the render mode.
27
26
  * @returns {boolean} - `true` if in development mode or inside the editor; otherwise, `false`.
28
27
  */
29
- const useIsDevMode = renderMode => {
28
+ const useIsDevMode = () => {
30
29
  const {
31
30
  mode
32
31
  } = useContext(DotCMSPageContext);
33
- const effectiveMode = renderMode != null ? renderMode : mode;
34
- const [isDevMode, setIsDevMode] = useState(effectiveMode === 'development');
32
+ const [isDevMode, setIsDevMode] = useState(mode === 'development');
35
33
  useEffect(() => {
36
34
  var _getUVEState;
37
35
  // Inside UVE we rely on the UVE state to determine if we are in development mode
@@ -41,9 +39,8 @@ const useIsDevMode = renderMode => {
41
39
  setIsDevMode(isUVEInEditor);
42
40
  return;
43
41
  }
44
- const effectiveMode = renderMode != null ? renderMode : mode;
45
- setIsDevMode(effectiveMode === 'development');
46
- }, [renderMode, mode]);
42
+ setIsDevMode(mode === DEVELOPMENT_MODE);
43
+ }, [mode]);
47
44
  return isDevMode;
48
45
  };
49
46
 
@@ -52,17 +49,12 @@ const useIsDevMode = renderMode => {
52
49
  *
53
50
  * @return {JSX.Element} Error message component
54
51
  */
55
- const ErrorMessage = ({
56
- mode
57
- }) => {
52
+ const ErrorMessage = () => {
53
+ const isDevMode = useIsDevMode();
58
54
  useEffect(() => {
59
55
  console.warn('Missing required layout.body property in page');
60
56
  }, []);
61
- const isDevMode = useIsDevMode(mode);
62
- if (!isDevMode) {
63
- return null;
64
- }
65
- return jsxs("div", {
57
+ return isDevMode && jsxs("div", {
66
58
  "data-testid": "error-message",
67
59
  style: {
68
60
  padding: '1rem',
@@ -97,207 +89,6 @@ var css_248z = ".Column-module_col-start-1__xylw6 {\n grid-column-start: 1;\n
97
89
  var styles = {"col-start-1":"Column-module_col-start-1__xylw6","col-start-2":"Column-module_col-start-2__Mod81","col-start-3":"Column-module_col-start-3__HHbXB","col-start-4":"Column-module_col-start-4__Uk-Qj","col-start-5":"Column-module_col-start-5__jlV8e","col-start-6":"Column-module_col-start-6__oi8k0","col-start-7":"Column-module_col-start-7__EmPky","col-start-8":"Column-module_col-start-8__hLI1h","col-start-9":"Column-module_col-start-9__Kcv9X","col-start-10":"Column-module_col-start-10__-MOrt","col-start-11":"Column-module_col-start-11__gDEQM","col-start-12":"Column-module_col-start-12__omVX6","col-end-1":"Column-module_col-end-1__Ho2y9","col-end-2":"Column-module_col-end-2__KwFu9","col-end-3":"Column-module_col-end-3__vfbJk","col-end-4":"Column-module_col-end-4__d4pyL","col-end-5":"Column-module_col-end-5__6yPd4","col-end-6":"Column-module_col-end-6__xQpAX","col-end-7":"Column-module_col-end-7__CCF7e","col-end-8":"Column-module_col-end-8__fVWEi","col-end-9":"Column-module_col-end-9__tpIGv","col-end-10":"Column-module_col-end-10__SX75K","col-end-11":"Column-module_col-end-11__9K1zv","col-end-12":"Column-module_col-end-12__oqTiE","col-end-13":"Column-module_col-end-13__L-nK9"};
98
90
  styleInject(css_248z);
99
91
 
100
- const endClassMap = {
101
- 1: 'col-end-1',
102
- 2: 'col-end-2',
103
- 3: 'col-end-3',
104
- 4: 'col-end-4',
105
- 5: 'col-end-5',
106
- 6: 'col-end-6',
107
- 7: 'col-end-7',
108
- 8: 'col-end-8',
109
- 9: 'col-end-9',
110
- 10: 'col-end-10',
111
- 11: 'col-end-11',
112
- 12: 'col-end-12',
113
- 13: 'col-end-13'
114
- };
115
- const startClassMap = {
116
- 1: 'col-start-1',
117
- 2: 'col-start-2',
118
- 3: 'col-start-3',
119
- 4: 'col-start-4',
120
- 5: 'col-start-5',
121
- 6: 'col-start-6',
122
- 7: 'col-start-7',
123
- 8: 'col-start-8',
124
- 9: 'col-start-9',
125
- 10: 'col-start-10',
126
- 11: 'col-start-11',
127
- 12: 'col-start-12'
128
- };
129
- /**
130
- * @internal
131
- *
132
- * Combine classes into a single string.
133
- *
134
- * @param {string[]} classes
135
- * @returns {string} Combined classes
136
- */
137
- const combineClasses = classes => classes.filter(Boolean).join(' ');
138
- /**
139
- * @internal
140
- *
141
- * Calculates and returns the CSS Grid positioning classes for a column based on its configuration.
142
- * Uses a 12-column grid system where columns are positioned using grid-column-start and grid-column-end.
143
- *
144
- * @example
145
- * ```typescript
146
- * const classes = getColumnPositionClasses({
147
- * leftOffset: 1, // Starts at the first column
148
- * width: 6 // Spans 6 columns
149
- * });
150
- * // Returns: { startClass: 'col-start-1', endClass: 'col-end-7' }
151
- * ```
152
- *
153
- * @param {DotPageAssetLayoutColumn} column - Column configuration object
154
- * @param {number} column.leftOffset - Starting position (0-based) in the grid
155
- * @param {number} column.width - Number of columns to span
156
- * @returns {{ startClass: string, endClass: string }} Object containing CSS class names for grid positioning
157
- */
158
- const getColumnPositionClasses = column => {
159
- const {
160
- leftOffset,
161
- width
162
- } = column;
163
- const startClass = startClassMap[leftOffset];
164
- const endClass = endClassMap[leftOffset + width];
165
- return {
166
- startClass,
167
- endClass
168
- };
169
- };
170
- /**
171
- * @internal
172
- *
173
- * Helper function that returns an object containing the dotCMS data attributes.
174
- * @param {DotCMSContentlet} contentlet - The contentlet to get the attributes for
175
- * @param {string} container - The container to get the attributes for
176
- * @returns {DotContentletAttributes} The dotCMS data attributes
177
- */
178
- function getDotContentletAttributes(contentlet, container) {
179
- return {
180
- 'data-dot-identifier': contentlet == null ? void 0 : contentlet.identifier,
181
- 'data-dot-basetype': contentlet == null ? void 0 : contentlet.baseType,
182
- 'data-dot-title': (contentlet == null ? void 0 : contentlet.widgetTitle) || (contentlet == null ? void 0 : contentlet.title),
183
- 'data-dot-inode': contentlet == null ? void 0 : contentlet.inode,
184
- 'data-dot-type': contentlet == null ? void 0 : contentlet.contentType,
185
- 'data-dot-container': container,
186
- 'data-dot-on-number-of-pages': contentlet == null ? void 0 : contentlet.onNumberOfPages
187
- };
188
- }
189
- /**
190
- * @internal
191
- *
192
- * Retrieves container data from a DotCMS page asset using the container reference.
193
- * This function processes the container information and returns a standardized format
194
- * for container editing.
195
- *
196
- * @param {DotCMSPageAsset} dotCMSPageAsset - The page asset containing all containers data
197
- * @param {DotCMSColumnContainer} columContainer - The container reference from the layout
198
- * @throws {Error} When page asset is invalid or container is not found
199
- * @returns {EditableContainerData} Formatted container data for editing
200
- *
201
- * @example
202
- * const containerData = getContainersData(pageAsset, containerRef);
203
- * // Returns: { uuid: '123', identifier: 'cont1', acceptTypes: 'type1,type2', maxContentlets: 5 }
204
- */
205
- const getContainersData = (dotCMSPageAsset, columContainer) => {
206
- var _containerStructures$, _container$parentPerm, _container$maxContent;
207
- const {
208
- identifier,
209
- uuid
210
- } = columContainer;
211
- const dotContainer = dotCMSPageAsset.containers[identifier];
212
- if (!dotContainer) {
213
- return null;
214
- }
215
- const {
216
- containerStructures,
217
- container
218
- } = dotContainer;
219
- const acceptTypes = (_containerStructures$ = containerStructures == null ? void 0 : containerStructures.map(structure => structure.contentTypeVar).join(',')) != null ? _containerStructures$ : '';
220
- const variantId = container == null || (_container$parentPerm = container.parentPermissionable) == null ? void 0 : _container$parentPerm.variantId;
221
- const maxContentlets = (_container$maxContent = container == null ? void 0 : container.maxContentlets) != null ? _container$maxContent : 0;
222
- const path = container == null ? void 0 : container.path;
223
- return {
224
- uuid,
225
- variantId,
226
- acceptTypes,
227
- maxContentlets,
228
- identifier: path != null ? path : identifier
229
- };
230
- };
231
- /**
232
- * @internal
233
- *
234
- * Retrieves the contentlets (content items) associated with a specific container.
235
- * Handles different UUID formats and provides warning for missing contentlets.
236
- *
237
- * @param {DotCMSPageAsset} dotCMSPageAsset - The page asset containing all containers data
238
- * @param {DotCMSColumnContainer} columContainer - The container reference from the layout
239
- * @returns {DotCMSContentlet[]} Array of contentlets in the container
240
- *
241
- * @example
242
- * const contentlets = getContentletsInContainer(pageAsset, containerRef);
243
- * // Returns: [{ identifier: 'cont1', ... }, { identifier: 'cont2', ... }]
244
- */
245
- const getContentletsInContainer = (dotCMSPageAsset, columContainer) => {
246
- const {
247
- identifier,
248
- uuid
249
- } = columContainer;
250
- const {
251
- contentlets
252
- } = dotCMSPageAsset.containers[identifier];
253
- const contentletsInContainer = contentlets[`uuid-${uuid}`] || contentlets[`uuid-dotParser_${uuid}`] || [];
254
- if (!contentletsInContainer) {
255
- console.warn(`We couldn't find the contentlets for the container with the identifier ${identifier} and the uuid ${uuid} becareful by adding content to this container.\nWe recommend to change the container in the layout and add the content again.`);
256
- }
257
- return contentletsInContainer;
258
- };
259
- /**
260
- * @internal
261
- *
262
- * Generates the required DotCMS data attributes for a container element.
263
- * These attributes are used by DotCMS for container identification and functionality.
264
- *
265
- * @param {EditableContainerData} params - Container data including uuid, identifier, acceptTypes, and maxContentlets
266
- * @returns {DotContainerAttributes} Object containing all necessary data attributes
267
- *
268
- * @example
269
- * const attributes = getDotContainerAttributes({
270
- * uuid: '123',
271
- * identifier: 'cont1',
272
- * acceptTypes: 'type1,type2',
273
- * maxContentlets: 5
274
- * });
275
- * // Returns: { 'data-dot-object': 'container', 'data-dot-identifier': 'cont1', ... }
276
- */
277
- function getDotContainerAttributes({
278
- uuid,
279
- identifier,
280
- acceptTypes,
281
- maxContentlets
282
- }) {
283
- return {
284
- 'data-dot-object': 'container',
285
- 'data-dot-accept-types': acceptTypes,
286
- 'data-dot-identifier': identifier,
287
- 'data-max-contentlets': maxContentlets.toString(),
288
- 'data-dot-uuid': uuid
289
- };
290
- }
291
-
292
- const EMPTY_CONTAINER_STYLE = {
293
- width: '100%',
294
- backgroundColor: '#ECF0FD',
295
- display: 'flex',
296
- justifyContent: 'center',
297
- alignItems: 'center',
298
- color: '#030E32',
299
- height: '10rem'
300
- };
301
92
  /**
302
93
  * @internal
303
94
  *
@@ -309,7 +100,7 @@ const EMPTY_CONTAINER_STYLE = {
309
100
  * @param {string} props.identifier - Container identifier
310
101
  * @returns {JSX.Element | null} Message about missing container or null in production
311
102
  */
312
- const ContainerNoFound = ({
103
+ const ContainerNotFound = ({
313
104
  identifier
314
105
  }) => {
315
106
  const isDevMode = useIsDevMode();
@@ -324,7 +115,7 @@ const ContainerNoFound = ({
324
115
  }
325
116
  return jsxs("div", {
326
117
  "data-testid": "container-not-found",
327
- style: EMPTY_CONTAINER_STYLE,
118
+ style: EMPTY_CONTAINER_STYLE_REACT,
328
119
  children: ["This container with identifier ", identifier, " was not found."]
329
120
  });
330
121
  };
@@ -342,7 +133,7 @@ const EmptyContainer = dotAttributes => {
342
133
  return null;
343
134
  }
344
135
  return jsx("div", Object.assign({}, dotAttributes, {
345
- style: EMPTY_CONTAINER_STYLE,
136
+ style: EMPTY_CONTAINER_STYLE_REACT,
346
137
  children: jsx("span", {
347
138
  "data-testid": "empty-container-message",
348
139
  children: "This container is empty."
@@ -493,7 +284,7 @@ function CustomComponent({
493
284
  if (UserComponent) {
494
285
  return jsx(UserComponent, Object.assign({}, contentlet));
495
286
  }
496
- const UserNoComponent = userComponents['CustomNoComponent'];
287
+ const UserNoComponent = userComponents[CUSTOM_NO_COMPONENT];
497
288
  return jsx(FallbackComponent, {
498
289
  UserNoComponent: UserNoComponent,
499
290
  contentlet: contentlet
@@ -528,7 +319,7 @@ function Container({
528
319
  const containerData = useMemo(() => getContainersData(pageAsset, container), [pageAsset, container]);
529
320
  const contentlets = useMemo(() => getContentletsInContainer(pageAsset, container), [pageAsset, container]);
530
321
  if (!containerData) {
531
- return jsx(ContainerNoFound, {
322
+ return jsx(ContainerNotFound, {
532
323
  identifier: container.identifier
533
324
  });
534
325
  }
@@ -598,7 +389,7 @@ function Column({
598
389
  const Row = ({
599
390
  row
600
391
  }) => {
601
- const customRowClass = `${row.styleClass || ''} ${styles$1.row}`;
392
+ const customRowClass = combineClasses([row.styleClass || '', styles$1.row]);
602
393
  return jsx("div", {
603
394
  className: "dot-row-container",
604
395
  children: jsx("div", {
@@ -614,28 +405,18 @@ const Row = ({
614
405
  /**
615
406
  * DotCMSLayoutBody component renders the layout body for a DotCMS page.
616
407
  *
617
- * It utilizes the page asset's layout body to render rows using the Row component.
618
- * If the layout body does not exist, it renders an error message.
619
- * It also provides context (DotCMSPageContext) with the page asset, optional user components,
620
- * and the renderer mode to its children.
408
+ * It utilizes the dotCMS page asset's layout body to render the page body.
409
+ * If the layout body does not exist, it renders an error message in the mode is `development`.
621
410
  *
622
411
  * @public
623
412
  * @component
624
413
  * @param {Object} props - Component properties.
625
414
  * @param {DotCMSPageAsset} props.page - The DotCMS page asset containing the layout information.
626
- * @param {Record<string, React.ComponentType<DotCMSContentlet>>} [props.components] - Optional mapping of custom components for content rendering.
415
+ * @param {Record<string, React.ComponentType<DotCMSContentlet>>} [props.components] - mapping of custom components for content rendering.
627
416
  * @param {DotCMSPageRendererMode} [props.mode='production'] - The renderer mode; defaults to 'production'. Alternate modes might trigger different behaviors.
628
417
  *
629
418
  * @returns {JSX.Element} The rendered DotCMS page body or an error message if the layout body is missing.
630
419
  *
631
- * -------------------------------------------------------------------
632
- *
633
- * El componente DotCMSLayoutBody renderiza el cuerpo del layout para una página de DotCMS.
634
- *
635
- * Utiliza el "body" del layout del asset de la página para renderizar las filas mediante el componente Row.
636
- * Si el "body" del layout no está presente, renderiza un mensaje de error.
637
- * También provee un contexto (DotCMSPageContext) con el asset de la página, componentes de usuario opcionales,
638
- * y el modo del renderizado para sus componentes hijos.
639
420
  */
640
421
  const DotCMSLayoutBody = ({
641
422
  page,
@@ -644,11 +425,6 @@ const DotCMSLayoutBody = ({
644
425
  }) => {
645
426
  var _page$layout;
646
427
  const dotCMSPageBody = page == null || (_page$layout = page.layout) == null ? void 0 : _page$layout.body;
647
- if (!dotCMSPageBody) {
648
- return jsx(ErrorMessage, {
649
- mode: _mode
650
- });
651
- }
652
428
  const contextValue = {
653
429
  pageAsset: page,
654
430
  userComponents: _components,
@@ -656,10 +432,93 @@ const DotCMSLayoutBody = ({
656
432
  };
657
433
  return jsx(DotCMSPageContext.Provider, {
658
434
  value: contextValue,
659
- children: dotCMSPageBody.rows.map((row, index) => jsx(Row, {
435
+ children: dotCMSPageBody ? dotCMSPageBody.rows.map((row, index) => jsx(Row, {
660
436
  row: row
661
- }, index))
437
+ }, index)) : jsx(ErrorMessage, {})
662
438
  });
663
439
  };
664
440
 
665
- export { DotCMSLayoutBody };
441
+ /**
442
+ * Custom hook to determine if the current UVE (Universal Visual Editor) mode
443
+ * matches the specified mode. This hook is useful for conditionally rendering
444
+ * components based on the UVE mode.
445
+ *
446
+ * @param {UVE_MODE} when - The UVE mode to check against.
447
+ * @returns {boolean} True if the current UVE mode matches the specified mode, otherwise false.
448
+ *
449
+ * @example
450
+ * // Basic usage: Check if the UVE is in edit mode
451
+ * const showInEditMode = useDotCMSShowWhen(UVE_MODE.EDIT);
452
+ * if (showInEditMode) {
453
+ * // Render edit-specific components
454
+ * }
455
+ *
456
+ * @example
457
+ * // Check if the UVE is in preview mode
458
+ * const showInPreviewMode = useDotCMSShowWhen(UVE_MODE.PREVIEW);
459
+ * if (showInPreviewMode) {
460
+ * // Render preview-specific components
461
+ * }
462
+ *
463
+ * @example
464
+ * // Check if the UVE is in live mode
465
+ * const showInLiveMode = useDotCMSShowWhen(UVE_MODE.LIVE);
466
+ * if (showInLiveMode) {
467
+ * // Render live-specific components
468
+ * }
469
+ */
470
+ const useDotCMSShowWhen = when => {
471
+ const [show, setShow] = useState(false);
472
+ useEffect(() => {
473
+ var _getUVEState;
474
+ setShow(((_getUVEState = getUVEState()) == null ? void 0 : _getUVEState.mode) === when);
475
+ }, [when]);
476
+ return show;
477
+ };
478
+
479
+ /**
480
+ * DotCMSShow component is used to conditionally render its children
481
+ * based on the Universal Visual Editor (UVE) mode. It checks if the UVE
482
+ * is in a specified mode and only renders its children in that case.
483
+ *
484
+ * @param {Object} props - The component props.
485
+ * @param {React.ReactNode} props.children - The children to be rendered when the condition is met.
486
+ * @param {UVE_MODE} [props.when=UVE_MODE.EDIT] - The UVE mode in which the children should be rendered.
487
+ * @returns {React.ReactNode | null} The children if the current UVE mode matches the `when` prop, otherwise null.
488
+ *
489
+ * @example
490
+ * // Basic usage: Render content only in edit mode
491
+ * <DotCMSShow when={UVE_MODE.EDIT}>
492
+ * <div>Edit Mode Content</div>
493
+ * </DotCMSShow>
494
+ *
495
+ * // This will render <div>Edit Mode Content</div> only if the UVE is in edit mode.
496
+ *
497
+ * @example
498
+ * // Render content in preview mode
499
+ * <DotCMSShow when={UVE_MODE.PREVIEW}>
500
+ * <MyCustomPreviewComponent />
501
+ * </DotCMSShow>
502
+ *
503
+ * // MyCustomPreviewComponent will only be rendered if the UVE is in preview mode.
504
+ *
505
+ * @example
506
+ * // Render content in live mode
507
+ * <DotCMSShow when={UVE_MODE.LIVE}>
508
+ * <LiveContentComponent />
509
+ * </DotCMSShow>
510
+ *
511
+ * // LiveContentComponent will only be rendered if the UVE is in live mode.
512
+ */
513
+ const DotCMSShow = ({
514
+ children,
515
+ when: _when = UVE_MODE.EDIT
516
+ }) => {
517
+ const show = useDotCMSShowWhen(_when);
518
+ if (!show) {
519
+ return null;
520
+ }
521
+ return children;
522
+ };
523
+
524
+ export { DotCMSLayoutBody, DotCMSShow, useDotCMSShowWhen };