camox 0.41.0 → 0.42.0

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 (60) hide show
  1. package/dist/core/components/lexical/SidebarLexicalEditor.js +42 -39
  2. package/dist/core/createApp.d.ts +16 -2
  3. package/dist/core/createBlock.js +11 -25
  4. package/dist/core/editing/BlockEditingRuntime.js +4 -4
  5. package/dist/core/editing/CompleteBlockEditingRuntime.js +5 -5
  6. package/dist/core/editing/createEditableBlock.d.ts +8 -1
  7. package/dist/core/editing/createEditableBlock.js +684 -644
  8. package/dist/core/hooks/useIsEditable.js +4 -7
  9. package/dist/core/hooks/useOverlayState.js +11 -0
  10. package/dist/core/hooks/useRequireDraftSource.js +7 -11
  11. package/dist/core/lib/fieldTypes.js +5 -5
  12. package/dist/core/lib/lexicalState.js +17 -1
  13. package/dist/features/preview/CamoxPreview.js +123 -137
  14. package/dist/features/preview/DerivedPreview.js +6 -9
  15. package/dist/features/preview/commentsEnabled.js +8 -0
  16. package/dist/features/preview/components/AddBlockSidebar.js +79 -89
  17. package/dist/features/preview/components/AssetLightbox.js +4 -11
  18. package/dist/features/preview/components/AttachedComments.js +194 -0
  19. package/dist/features/preview/components/BlockActionsPopover.js +19 -70
  20. package/dist/features/preview/components/CommentHeader.js +122 -0
  21. package/dist/features/preview/components/CommentSidebar.js +29 -0
  22. package/dist/features/preview/components/CommentTargetQuote.js +166 -0
  23. package/dist/features/preview/components/CreatePageModal.js +2 -8
  24. package/dist/features/preview/components/DerivedLayoutSidebar.js +4 -7
  25. package/dist/features/preview/components/ItemFieldsEditor.js +275 -204
  26. package/dist/features/preview/components/LeftSidebar.js +18 -18
  27. package/dist/features/preview/components/LinkFieldEditor.js +3 -4
  28. package/dist/features/preview/components/MobilePreviewDrawer.js +3 -3
  29. package/dist/features/preview/components/OverlayTracker.js +14 -20
  30. package/dist/features/preview/components/Overlays.js +28 -40
  31. package/dist/features/preview/components/PageEditorSidebar.js +231 -241
  32. package/dist/features/preview/components/PageInfoSidebar.js +126 -157
  33. package/dist/features/preview/components/PagePicker.js +13 -8
  34. package/dist/features/preview/components/PageTree.js +255 -319
  35. package/dist/features/preview/components/PreviewComments.js +56 -0
  36. package/dist/features/preview/components/PreviewPanel.js +149 -107
  37. package/dist/features/preview/components/PreviewToolbar.js +292 -246
  38. package/dist/features/preview/components/PreviewToolbarSpacer.js +43 -0
  39. package/dist/features/preview/components/PublicationRow.js +11 -24
  40. package/dist/features/preview/components/RightSidebar.js +14 -11
  41. package/dist/features/preview/components/SidebarSection.js +121 -0
  42. package/dist/features/preview/previewCommentsStore.js +115 -0
  43. package/dist/features/preview/previewSelection.js +75 -0
  44. package/dist/features/preview/previewStore.js +32 -63
  45. package/dist/features/provider/AuthenticatedCamoxProvider.js +46 -34
  46. package/dist/features/provider/components/CommandPalette.js +142 -58
  47. package/dist/features/provider/useAdminShortcuts.js +20 -8
  48. package/dist/features/routes/pageRuntime.js +0 -6
  49. package/dist/features/runtime/RuntimeChrome.js +102 -87
  50. package/dist/features/studio/CamoxStudio.js +30 -50
  51. package/dist/features/studio/components/UserButton.js +4 -4
  52. package/dist/features/vite/runtimeDev.js +4 -1
  53. package/dist/features/vite/vite.d.ts +3 -2
  54. package/dist/features/vite/vite.js +9 -5
  55. package/dist/hooks/use-file-upload.js +0 -2
  56. package/dist/studio.css +1 -1
  57. package/package.json +5 -7
  58. package/dist/features/preview/components/DraftSwitchDialog.js +0 -66
  59. package/dist/lib/telemetry-client.js +0 -66
  60. package/dist/lib/telemetry.js +0 -26
@@ -1,14 +1,17 @@
1
1
  import { isFileMarker, isItemMarker, resolveFileMarker } from "../../../lib/normalized-data.js";
2
+ import { lexicalStateToPlainText } from "../../../core/lib/lexicalState.js";
2
3
  import { previewStore } from "../previewStore.js";
3
4
  import { SidebarLexicalEditor } from "../../../core/components/lexical/SidebarLexicalEditor.js";
4
5
  import { RepeatableItemsList } from "./RepeatableItemsList.js";
5
6
  import { c } from "react/compiler-runtime";
6
7
  import * as React from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
- import { FileIcon, ImageIcon, Images, Link2 } from "lucide-react";
9
+ import { Code, FileIcon, ImageIcon, Images, Link2, List, ListFilter, ToggleLeft, Type } from "lucide-react";
9
10
  import { Label } from "@camox/ui/label";
11
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@camox/ui/select";
10
12
  import { useForm } from "@tanstack/react-form";
11
13
  import { Input } from "@camox/ui/input";
14
+ import { Switch } from "@camox/ui/switch";
12
15
 
13
16
  //#region src/features/preview/components/ItemFieldsEditor.tsx
14
17
  const formatFieldName = (fieldName) => {
@@ -23,6 +26,8 @@ const getSchemaFieldsInOrder = (schema) => {
23
26
  name: fieldName,
24
27
  fieldType: prop.fieldType,
25
28
  label: prop.title,
29
+ enumLabels: prop.enumLabels,
30
+ enumValues: prop.enum,
26
31
  minItems: prop.minItems,
27
32
  maxItems: prop.maxItems
28
33
  };
@@ -30,9 +35,9 @@ const getSchemaFieldsInOrder = (schema) => {
30
35
  };
31
36
  const DrillRow = (t0) => {
32
37
  const $ = c(28);
33
- if ($[0] !== "44742e36c00267829eb7bcad0f4d0df91633b9d7bdc99a829f13e3d1db5d9c2b") {
38
+ if ($[0] !== "b2eb497558ebaf4700b0ba067f5c7a528445a839255d88cef77056524cd2971c") {
34
39
  for (let $i = 0; $i < 28; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
35
- $[0] = "44742e36c00267829eb7bcad0f4d0df91633b9d7bdc99a829f13e3d1db5d9c2b";
40
+ $[0] = "b2eb497558ebaf4700b0ba067f5c7a528445a839255d88cef77056524cd2971c";
36
41
  }
37
42
  const { label, preview, Icon, onClick, hover, postToIframe } = t0;
38
43
  let t1;
@@ -134,105 +139,118 @@ const DrillRow = (t0) => {
134
139
  return t7;
135
140
  };
136
141
  const ItemFieldsEditor = (t0) => {
137
- const $ = c(42);
138
- if ($[0] !== "44742e36c00267829eb7bcad0f4d0df91633b9d7bdc99a829f13e3d1db5d9c2b") {
139
- for (let $i = 0; $i < 42; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
140
- $[0] = "44742e36c00267829eb7bcad0f4d0df91633b9d7bdc99a829f13e3d1db5d9c2b";
142
+ const $ = c(46);
143
+ if ($[0] !== "b2eb497558ebaf4700b0ba067f5c7a528445a839255d88cef77056524cd2971c") {
144
+ for (let $i = 0; $i < 46; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
145
+ $[0] = "b2eb497558ebaf4700b0ba067f5c7a528445a839255d88cef77056524cd2971c";
141
146
  }
142
- const { schema, data, blockId, itemId, onFieldChange, postToIframe, filesMap, itemsMap, fieldIdPrefix } = t0;
147
+ const { selectedFieldName, schema, data, blockId, itemId, onFieldChange, postToIframe, filesMap, itemsMap, fieldIdPrefix } = t0;
143
148
  let t1;
144
- if ($[1] !== schema) {
145
- t1 = getSchemaFieldsInOrder(schema);
149
+ if ($[1] !== schema || $[2] !== selectedFieldName) {
150
+ let t2;
151
+ if ($[4] !== selectedFieldName) {
152
+ t2 = (field) => !selectedFieldName || field.name === selectedFieldName;
153
+ $[4] = selectedFieldName;
154
+ $[5] = t2;
155
+ } else t2 = $[5];
156
+ t1 = getSchemaFieldsInOrder(schema).filter(t2);
146
157
  $[1] = schema;
147
- $[2] = t1;
148
- } else t1 = $[2];
158
+ $[2] = selectedFieldName;
159
+ $[3] = t1;
160
+ } else t1 = $[3];
149
161
  const fields = t1;
162
+ const pendingSaveRef = React.useRef(null);
150
163
  const timerRef = React.useRef(null);
151
164
  const focusedFieldIdRef = React.useRef(null);
152
165
  let t2;
153
- if ($[3] !== blockId || $[4] !== itemId) {
166
+ if ($[6] !== blockId || $[7] !== itemId) {
154
167
  t2 = (fieldName) => {
155
168
  if (itemId != null) return `${blockId}__${itemId}__${fieldName}`;
156
169
  return `${blockId}__${fieldName}`;
157
170
  };
158
- $[3] = blockId;
159
- $[4] = itemId;
160
- $[5] = t2;
161
- } else t2 = $[5];
171
+ $[6] = blockId;
172
+ $[7] = itemId;
173
+ $[8] = t2;
174
+ } else t2 = $[8];
162
175
  const getFieldId = t2;
163
176
  let t3;
164
- if ($[6] !== fieldIdPrefix) {
177
+ if ($[9] !== fieldIdPrefix) {
165
178
  t3 = (fieldName_0) => `${fieldIdPrefix}-${fieldName_0}`;
166
- $[6] = fieldIdPrefix;
167
- $[7] = t3;
168
- } else t3 = $[7];
179
+ $[9] = fieldIdPrefix;
180
+ $[10] = t3;
181
+ } else t3 = $[10];
169
182
  const getFieldElementId = t3;
170
183
  let t4;
171
- if ($[8] !== fields) {
184
+ if ($[11] !== fields) {
172
185
  t4 = fields.filter(_temp).map(_temp2);
173
- $[8] = fields;
174
- $[9] = t4;
175
- } else t4 = $[9];
186
+ $[11] = fields;
187
+ $[12] = t4;
188
+ } else t4 = $[12];
176
189
  const scalarFields = t4;
177
190
  let values;
178
- if ($[10] !== data || $[11] !== scalarFields) {
191
+ if ($[13] !== data || $[14] !== scalarFields) {
179
192
  values = {};
180
193
  for (const fieldName_1 of scalarFields) values[fieldName_1] = data[fieldName_1] ?? "";
181
- $[10] = data;
182
- $[11] = scalarFields;
183
- $[12] = values;
184
- } else values = $[12];
194
+ $[13] = data;
195
+ $[14] = scalarFields;
196
+ $[15] = values;
197
+ } else values = $[15];
185
198
  const defaultValues = values;
186
199
  let t5;
187
- if ($[13] !== defaultValues) {
200
+ if ($[16] !== defaultValues) {
188
201
  t5 = { defaultValues };
189
- $[13] = defaultValues;
190
- $[14] = t5;
191
- } else t5 = $[14];
202
+ $[16] = defaultValues;
203
+ $[17] = t5;
204
+ } else t5 = $[17];
192
205
  const form = useForm(t5);
193
206
  let t6;
194
207
  let t7;
195
- if ($[15] !== defaultValues || $[16] !== form) {
208
+ if ($[18] !== defaultValues || $[19] !== form) {
196
209
  t6 = () => {
197
210
  form.update({ defaultValues });
198
211
  };
199
212
  t7 = [defaultValues, form];
200
- $[15] = defaultValues;
201
- $[16] = form;
202
- $[17] = t6;
203
- $[18] = t7;
213
+ $[18] = defaultValues;
214
+ $[19] = form;
215
+ $[20] = t6;
216
+ $[21] = t7;
204
217
  } else {
205
- t6 = $[17];
206
- t7 = $[18];
218
+ t6 = $[20];
219
+ t7 = $[21];
207
220
  }
208
221
  React.useEffect(t6, t7);
209
222
  let t8;
210
223
  let t9;
211
- if ($[19] !== postToIframe) {
224
+ if ($[22] !== postToIframe) {
212
225
  t8 = () => () => {
213
226
  if (timerRef.current) clearTimeout(timerRef.current);
227
+ pendingSaveRef.current?.();
228
+ pendingSaveRef.current = null;
214
229
  if (focusedFieldIdRef.current) postToIframe({
215
230
  type: "CAMOX_FOCUS_FIELD_END",
216
231
  fieldId: focusedFieldIdRef.current
217
232
  });
218
233
  };
219
234
  t9 = [postToIframe];
220
- $[19] = postToIframe;
221
- $[20] = t8;
222
- $[21] = t9;
235
+ $[22] = postToIframe;
236
+ $[23] = t8;
237
+ $[24] = t9;
223
238
  } else {
224
- t8 = $[20];
225
- t9 = $[21];
239
+ t8 = $[23];
240
+ t9 = $[24];
226
241
  }
227
242
  React.useEffect(t8, t9);
228
243
  let t10;
229
244
  let t11;
230
- if ($[22] !== blockId || $[23] !== data || $[24] !== fields || $[25] !== filesMap || $[26] !== form || $[27] !== getFieldElementId || $[28] !== getFieldId || $[29] !== itemId || $[30] !== itemsMap || $[31] !== onFieldChange || $[32] !== postToIframe || $[33] !== schema) {
245
+ if ($[25] !== blockId || $[26] !== data || $[27] !== fields || $[28] !== filesMap || $[29] !== form || $[30] !== getFieldElementId || $[31] !== getFieldId || $[32] !== itemId || $[33] !== itemsMap || $[34] !== onFieldChange || $[35] !== postToIframe || $[36] !== schema || $[37] !== selectedFieldName) {
231
246
  const handleScalarChange = (fieldName_2, value, fieldApi) => {
232
247
  fieldApi.handleChange(value);
233
248
  if (timerRef.current) clearTimeout(timerRef.current);
249
+ pendingSaveRef.current = () => onFieldChange(fieldName_2, value);
234
250
  timerRef.current = window.setTimeout(() => {
235
- onFieldChange(fieldName_2, value);
251
+ pendingSaveRef.current?.();
252
+ pendingSaveRef.current = null;
253
+ timerRef.current = null;
236
254
  }, 500);
237
255
  };
238
256
  const handleFieldFocus = (fieldName_3, fieldType) => {
@@ -263,12 +281,9 @@ const ItemFieldsEditor = (t0) => {
263
281
  type: "CAMOX_FOCUS_FIELD_END",
264
282
  fieldId: fieldId_0
265
283
  });
266
- requestAnimationFrame(() => {
267
- if (!focusedFieldIdRef.current) previewStore.send({ type: "selectParent" });
268
- });
269
284
  };
270
285
  let t12;
271
- if ($[36] !== blockId || $[37] !== itemId) {
286
+ if ($[40] !== blockId || $[41] !== itemId) {
272
287
  t12 = (fieldName_5, fieldType_0) => {
273
288
  if (itemId != null) previewStore.send({
274
289
  type: "selectItemField",
@@ -284,174 +299,230 @@ const ItemFieldsEditor = (t0) => {
284
299
  fieldType: fieldType_0
285
300
  });
286
301
  };
287
- $[36] = blockId;
288
- $[37] = itemId;
289
- $[38] = t12;
290
- } else t12 = $[38];
302
+ $[40] = blockId;
303
+ $[41] = itemId;
304
+ $[42] = t12;
305
+ } else t12 = $[42];
291
306
  const drillIntoField = t12;
292
307
  t10 = "space-y-4 px-2 py-4";
293
- t11 = fields.map((field) => {
294
- const label = field.label ?? formatFieldName(field.name);
295
- const fieldId_1 = getFieldId(field.name);
296
- if (field.fieldType === "String") return /* @__PURE__ */ jsx(form.Field, {
297
- name: field.name,
298
- children: (fieldApi_0) => /* @__PURE__ */ jsxs("div", {
299
- className: "space-y-2",
300
- onMouseEnter: () => postToIframe({
301
- type: "CAMOX_HOVER_FIELD",
302
- fieldId: fieldId_1
303
- }),
304
- onMouseLeave: () => postToIframe({
305
- type: "CAMOX_HOVER_FIELD_END",
306
- fieldId: fieldId_1
307
- }),
308
+ t11 = fields.map((field_0) => {
309
+ const label = field_0.label ?? formatFieldName(field_0.name);
310
+ const fieldId_1 = getFieldId(field_0.name);
311
+ const renderField = () => {
312
+ if (!selectedFieldName && [
313
+ "String",
314
+ "Embed",
315
+ "Repeater",
316
+ "Enum",
317
+ "Boolean"
318
+ ].includes(field_0.fieldType)) {
319
+ const value_0 = data[field_0.name];
320
+ return /* @__PURE__ */ jsx(DrillRow, {
321
+ label,
322
+ preview: field_0.fieldType === "String" ? lexicalStateToPlainText(value_0 ?? "") || "Empty text" : field_0.fieldType === "Repeater" ? `${Array.isArray(value_0) ? value_0.length : 0} items` : field_0.fieldType === "Boolean" ? value_0 ? "On" : "Off" : typeof value_0 === "string" && value_0 ? value_0 : "Empty",
323
+ Icon: field_0.fieldType === "String" ? Type : field_0.fieldType === "Repeater" ? List : field_0.fieldType === "Embed" ? Code : field_0.fieldType === "Boolean" ? ToggleLeft : ListFilter,
324
+ onClick: () => drillIntoField(field_0.name, field_0.fieldType),
325
+ hover: field_0.fieldType === "Repeater" ? {
326
+ variant: "repeater",
327
+ blockId,
328
+ fieldName: field_0.name
329
+ } : {
330
+ variant: "field",
331
+ fieldId: fieldId_1
332
+ },
333
+ postToIframe
334
+ }, field_0.name);
335
+ }
336
+ if (field_0.fieldType === "Boolean") return /* @__PURE__ */ jsxs("div", {
337
+ className: "flex items-center justify-between",
308
338
  children: [/* @__PURE__ */ jsx(Label, {
309
- htmlFor: getFieldElementId(field.name),
339
+ htmlFor: getFieldElementId(field_0.name),
310
340
  children: label
311
- }), /* @__PURE__ */ jsx(SidebarLexicalEditor, {
312
- id: getFieldElementId(field.name),
313
- value: fieldApi_0.state.value,
314
- onChange: (value_0) => handleScalarChange(field.name, value_0, fieldApi_0),
315
- onFocus: () => handleFieldFocus(field.name, field.fieldType),
316
- onBlur: () => handleFieldBlur(field.name)
341
+ }), /* @__PURE__ */ jsx(Switch, {
342
+ id: getFieldElementId(field_0.name),
343
+ checked: Boolean(data[field_0.name]),
344
+ onCheckedChange: (value_1) => onFieldChange(field_0.name, value_1)
317
345
  })]
318
- })
319
- }, field.name);
320
- if (field.fieldType === "Embed") return /* @__PURE__ */ jsx(form.Field, {
321
- name: field.name,
322
- children: (fieldApi_1) => /* @__PURE__ */ jsxs("div", {
346
+ }, field_0.name);
347
+ if (field_0.fieldType === "Enum") return /* @__PURE__ */ jsxs("div", {
323
348
  className: "space-y-2",
324
- onMouseEnter: () => postToIframe({
325
- type: "CAMOX_HOVER_FIELD",
326
- fieldId: fieldId_1
327
- }),
328
- onMouseLeave: () => postToIframe({
329
- type: "CAMOX_HOVER_FIELD_END",
330
- fieldId: fieldId_1
331
- }),
332
349
  children: [/* @__PURE__ */ jsx(Label, {
333
- htmlFor: getFieldElementId(field.name),
350
+ htmlFor: getFieldElementId(field_0.name),
334
351
  children: label
335
- }), /* @__PURE__ */ jsx(Input, {
336
- id: getFieldElementId(field.name),
337
- type: "url",
338
- value: fieldApi_1.state.value,
339
- onChange: (e) => handleScalarChange(field.name, e.target.value, fieldApi_1),
340
- onFocus: () => handleFieldFocus(field.name, field.fieldType),
341
- onBlur: () => handleFieldBlur(field.name)
342
- })]
343
- })
344
- }, field.name);
345
- if (field.fieldType === "Link") {
346
- const linkValue = data[field.name];
347
- return /* @__PURE__ */ jsx(DrillRow, {
348
- label,
349
- preview: linkValue?.text || linkValue?.href || "Empty link",
350
- Icon: Link2,
351
- onClick: () => drillIntoField(field.name, "Link"),
352
- hover: {
353
- variant: "field",
354
- fieldId: fieldId_1
355
- },
356
- postToIframe
357
- }, field.name);
358
- }
359
- if (field.fieldType === "ImageList" || field.fieldType === "FileList") {
360
- const value_1 = data[field.name];
361
- const count = Array.isArray(value_1) ? value_1.length : 0;
362
- const isImage = field.fieldType === "ImageList";
363
- const noun = isImage ? "image" : "file";
364
- let preview_0;
365
- if (count === 0) preview_0 = isImage ? "No images" : "No files";
366
- else if (count === 1) preview_0 = `1 ${noun}`;
367
- else preview_0 = `${count} ${noun}s`;
368
- return /* @__PURE__ */ jsx(DrillRow, {
369
- label,
370
- preview: preview_0,
371
- Icon: isImage ? Images : FileIcon,
372
- onClick: () => drillIntoField(field.name, isImage ? "Image" : "File"),
373
- hover: {
374
- variant: "repeater",
375
- blockId,
376
- fieldName: field.name
377
- },
378
- postToIframe
379
- }, field.name);
380
- }
381
- if (field.fieldType === "Image") {
382
- const rawImage = data[field.name];
383
- return /* @__PURE__ */ jsx(DrillRow, {
384
- label,
385
- preview: (isFileMarker(rawImage) ? resolveFileMarker(rawImage, filesMap) : rawImage)?.filename || "No image",
386
- Icon: ImageIcon,
387
- onClick: () => drillIntoField(field.name, "Image"),
388
- hover: {
389
- variant: "field",
390
- fieldId: fieldId_1
391
- },
392
- postToIframe
393
- }, field.name);
394
- }
395
- if (field.fieldType === "File") {
396
- const rawFile = data[field.name];
397
- return /* @__PURE__ */ jsx(DrillRow, {
398
- label,
399
- preview: (isFileMarker(rawFile) ? resolveFileMarker(rawFile, filesMap) : rawFile)?.filename || "No file",
400
- Icon: FileIcon,
401
- onClick: () => drillIntoField(field.name, "File"),
402
- hover: {
403
- variant: "field",
404
- fieldId: fieldId_1
405
- },
406
- postToIframe
407
- }, field.name);
408
- }
409
- if (field.fieldType === "Repeater") {
410
- const items = (data[field.name] ?? []).map((item) => {
411
- if (isItemMarker(item)) return itemsMap.get(item._itemId) ?? null;
412
- return item;
413
- }).filter(Boolean);
414
- const fieldSchema = schema?.properties?.[field.name];
415
- return /* @__PURE__ */ jsxs("div", {
416
- className: "space-y-2",
417
- children: [/* @__PURE__ */ jsx(Label, { children: label }), /* @__PURE__ */ jsx(RepeatableItemsList, {
418
- items,
419
- blockId,
420
- fieldName: field.name,
421
- schema: fieldSchema
352
+ }), /* @__PURE__ */ jsxs(Select, {
353
+ value: typeof data[field_0.name] === "string" ? data[field_0.name] : "",
354
+ onValueChange: (value_2) => onFieldChange(field_0.name, value_2),
355
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
356
+ id: getFieldElementId(field_0.name),
357
+ children: /* @__PURE__ */ jsx(SelectValue, {})
358
+ }), /* @__PURE__ */ jsx(SelectContent, { children: field_0.enumValues?.map((value_3) => /* @__PURE__ */ jsx(SelectItem, {
359
+ value: value_3,
360
+ children: field_0.enumLabels?.[value_3] ?? value_3
361
+ }, value_3)) })]
422
362
  })]
423
- }, field.name);
424
- }
425
- return null;
363
+ }, field_0.name);
364
+ if (field_0.fieldType === "String") return /* @__PURE__ */ jsx(form.Field, {
365
+ name: field_0.name,
366
+ children: (fieldApi_0) => /* @__PURE__ */ jsxs("div", {
367
+ className: "space-y-2",
368
+ onMouseEnter: () => postToIframe({
369
+ type: "CAMOX_HOVER_FIELD",
370
+ fieldId: fieldId_1
371
+ }),
372
+ onMouseLeave: () => postToIframe({
373
+ type: "CAMOX_HOVER_FIELD_END",
374
+ fieldId: fieldId_1
375
+ }),
376
+ children: [/* @__PURE__ */ jsx(Label, {
377
+ htmlFor: getFieldElementId(field_0.name),
378
+ children: label
379
+ }), /* @__PURE__ */ jsx(SidebarLexicalEditor, {
380
+ id: getFieldElementId(field_0.name),
381
+ value: fieldApi_0.state.value,
382
+ onChange: (value_4) => handleScalarChange(field_0.name, value_4, fieldApi_0),
383
+ onFocus: () => handleFieldFocus(field_0.name, field_0.fieldType),
384
+ onBlur: () => handleFieldBlur(field_0.name)
385
+ })]
386
+ })
387
+ }, field_0.name);
388
+ if (field_0.fieldType === "Embed") return /* @__PURE__ */ jsx(form.Field, {
389
+ name: field_0.name,
390
+ children: (fieldApi_1) => /* @__PURE__ */ jsxs("div", {
391
+ className: "space-y-2",
392
+ onMouseEnter: () => postToIframe({
393
+ type: "CAMOX_HOVER_FIELD",
394
+ fieldId: fieldId_1
395
+ }),
396
+ onMouseLeave: () => postToIframe({
397
+ type: "CAMOX_HOVER_FIELD_END",
398
+ fieldId: fieldId_1
399
+ }),
400
+ children: [/* @__PURE__ */ jsx(Label, {
401
+ htmlFor: getFieldElementId(field_0.name),
402
+ children: label
403
+ }), /* @__PURE__ */ jsx(Input, {
404
+ id: getFieldElementId(field_0.name),
405
+ type: "url",
406
+ value: fieldApi_1.state.value,
407
+ onChange: (e) => handleScalarChange(field_0.name, e.target.value, fieldApi_1),
408
+ onFocus: () => handleFieldFocus(field_0.name, field_0.fieldType),
409
+ onBlur: () => handleFieldBlur(field_0.name)
410
+ })]
411
+ })
412
+ }, field_0.name);
413
+ if (field_0.fieldType === "Link") {
414
+ const linkValue = data[field_0.name];
415
+ return /* @__PURE__ */ jsx(DrillRow, {
416
+ label,
417
+ preview: linkValue?.text || linkValue?.href || "Empty link",
418
+ Icon: Link2,
419
+ onClick: () => drillIntoField(field_0.name, "Link"),
420
+ hover: {
421
+ variant: "field",
422
+ fieldId: fieldId_1
423
+ },
424
+ postToIframe
425
+ }, field_0.name);
426
+ }
427
+ if (field_0.fieldType === "ImageList" || field_0.fieldType === "FileList") {
428
+ const value_5 = data[field_0.name];
429
+ const count = Array.isArray(value_5) ? value_5.length : 0;
430
+ const isImage = field_0.fieldType === "ImageList";
431
+ const noun = isImage ? "image" : "file";
432
+ let preview_1;
433
+ if (count === 0) preview_1 = isImage ? "No images" : "No files";
434
+ else if (count === 1) preview_1 = `1 ${noun}`;
435
+ else preview_1 = `${count} ${noun}s`;
436
+ return /* @__PURE__ */ jsx(DrillRow, {
437
+ label,
438
+ preview: preview_1,
439
+ Icon: isImage ? Images : FileIcon,
440
+ onClick: () => drillIntoField(field_0.name, isImage ? "Image" : "File"),
441
+ hover: {
442
+ variant: "repeater",
443
+ blockId,
444
+ fieldName: field_0.name
445
+ },
446
+ postToIframe
447
+ }, field_0.name);
448
+ }
449
+ if (field_0.fieldType === "Image") {
450
+ const rawImage = data[field_0.name];
451
+ return /* @__PURE__ */ jsx(DrillRow, {
452
+ label,
453
+ preview: (isFileMarker(rawImage) ? resolveFileMarker(rawImage, filesMap) : rawImage)?.filename || "No image",
454
+ Icon: ImageIcon,
455
+ onClick: () => drillIntoField(field_0.name, "Image"),
456
+ hover: {
457
+ variant: "field",
458
+ fieldId: fieldId_1
459
+ },
460
+ postToIframe
461
+ }, field_0.name);
462
+ }
463
+ if (field_0.fieldType === "File") {
464
+ const rawFile = data[field_0.name];
465
+ return /* @__PURE__ */ jsx(DrillRow, {
466
+ label,
467
+ preview: (isFileMarker(rawFile) ? resolveFileMarker(rawFile, filesMap) : rawFile)?.filename || "No file",
468
+ Icon: FileIcon,
469
+ onClick: () => drillIntoField(field_0.name, "File"),
470
+ hover: {
471
+ variant: "field",
472
+ fieldId: fieldId_1
473
+ },
474
+ postToIframe
475
+ }, field_0.name);
476
+ }
477
+ if (field_0.fieldType === "Repeater") {
478
+ const items = (data[field_0.name] ?? []).map((item) => {
479
+ if (isItemMarker(item)) return itemsMap.get(item._itemId) ?? null;
480
+ return item;
481
+ }).filter(Boolean);
482
+ const fieldSchema = schema?.properties?.[field_0.name];
483
+ return /* @__PURE__ */ jsxs("div", {
484
+ className: "space-y-2",
485
+ children: [/* @__PURE__ */ jsx(Label, { children: label }), /* @__PURE__ */ jsx(RepeatableItemsList, {
486
+ items,
487
+ blockId,
488
+ fieldName: field_0.name,
489
+ schema: fieldSchema
490
+ })]
491
+ }, field_0.name);
492
+ }
493
+ return null;
494
+ };
495
+ return renderField();
426
496
  });
427
- $[22] = blockId;
428
- $[23] = data;
429
- $[24] = fields;
430
- $[25] = filesMap;
431
- $[26] = form;
432
- $[27] = getFieldElementId;
433
- $[28] = getFieldId;
434
- $[29] = itemId;
435
- $[30] = itemsMap;
436
- $[31] = onFieldChange;
437
- $[32] = postToIframe;
438
- $[33] = schema;
439
- $[34] = t10;
440
- $[35] = t11;
497
+ $[25] = blockId;
498
+ $[26] = data;
499
+ $[27] = fields;
500
+ $[28] = filesMap;
501
+ $[29] = form;
502
+ $[30] = getFieldElementId;
503
+ $[31] = getFieldId;
504
+ $[32] = itemId;
505
+ $[33] = itemsMap;
506
+ $[34] = onFieldChange;
507
+ $[35] = postToIframe;
508
+ $[36] = schema;
509
+ $[37] = selectedFieldName;
510
+ $[38] = t10;
511
+ $[39] = t11;
441
512
  } else {
442
- t10 = $[34];
443
- t11 = $[35];
513
+ t10 = $[38];
514
+ t11 = $[39];
444
515
  }
445
516
  let t12;
446
- if ($[39] !== t10 || $[40] !== t11) {
517
+ if ($[43] !== t10 || $[44] !== t11) {
447
518
  t12 = /* @__PURE__ */ jsx("form", {
448
519
  className: t10,
449
520
  children: t11
450
521
  });
451
- $[39] = t10;
452
- $[40] = t11;
453
- $[41] = t12;
454
- } else t12 = $[41];
522
+ $[43] = t10;
523
+ $[44] = t11;
524
+ $[45] = t12;
525
+ } else t12 = $[45];
455
526
  return t12;
456
527
  };
457
528
  function _temp(f) {
@@ -8,9 +8,9 @@ import { useSelector } from "@xstate/store-react";
8
8
  //#region src/features/preview/components/LeftSidebar.tsx
9
9
  const LeftSidebar = (t0) => {
10
10
  const $ = c(13);
11
- if ($[0] !== "c0b8051f9d03df681e369c0b2954359f21e672e526188e45d0de7a395154e9cc") {
11
+ if ($[0] !== "37ec3b3a552e4e78e19e0a065e3326f676f367215b0ebda4b733ddd4a69ab079") {
12
12
  for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
13
- $[0] = "c0b8051f9d03df681e369c0b2954359f21e672e526188e45d0de7a395154e9cc";
13
+ $[0] = "37ec3b3a552e4e78e19e0a065e3326f676f367215b0ebda4b733ddd4a69ab079";
14
14
  }
15
15
  const { page, derivedLayout } = t0;
16
16
  const isAddBlockSidebarOpen = useSelector(previewStore, _temp);
@@ -37,28 +37,28 @@ const LeftSidebar = (t0) => {
37
37
  $[6] = t2;
38
38
  $[7] = t3;
39
39
  } else t3 = $[7];
40
- let t4;
41
- if ($[8] !== isAddBlockSidebarOpen) {
42
- t4 = isAddBlockSidebarOpen && /* @__PURE__ */ jsx("div", {
43
- className: "absolute inset-0 z-20 cursor-not-allowed",
44
- style: { background: "rgba(0, 0, 0, 0.5)" },
40
+ const t4 = `absolute inset-0 z-20 bg-black/50 transition-opacity duration-200 motion-reduce:transition-none ${isAddBlockSidebarOpen ? "cursor-not-allowed opacity-100" : "pointer-events-none opacity-0"}`;
41
+ let t5;
42
+ if ($[8] !== t4) {
43
+ t5 = /* @__PURE__ */ jsx("div", {
44
+ className: t4,
45
45
  "aria-hidden": "true"
46
46
  });
47
- $[8] = isAddBlockSidebarOpen;
48
- $[9] = t4;
49
- } else t4 = $[9];
50
- let t5;
51
- if ($[10] !== t3 || $[11] !== t4) {
52
- t5 = /* @__PURE__ */ jsxs("aside", {
47
+ $[8] = t4;
48
+ $[9] = t5;
49
+ } else t5 = $[9];
50
+ let t6;
51
+ if ($[10] !== t3 || $[11] !== t5) {
52
+ t6 = /* @__PURE__ */ jsxs("aside", {
53
53
  className: "relative flex shrink-0 flex-col border-r-2",
54
54
  style: t1,
55
- children: [t3, t4]
55
+ children: [t3, t5]
56
56
  });
57
57
  $[10] = t3;
58
- $[11] = t4;
59
- $[12] = t5;
60
- } else t5 = $[12];
61
- return t5;
58
+ $[11] = t5;
59
+ $[12] = t6;
60
+ } else t6 = $[12];
61
+ return t6;
62
62
  };
63
63
  function _temp(state) {
64
64
  return state.context.isAddBlockSidebarOpen;
@@ -26,9 +26,9 @@ const normalizeLinkValue = (value) => {
26
26
  };
27
27
  const LinkFieldEditor = (t0) => {
28
28
  const $ = c(74);
29
- if ($[0] !== "d6e76ca161ece5e3c3ab2fca39477fdbca4669ce2a59cab1e307374e6d56bc57") {
29
+ if ($[0] !== "cdb2f56fb4805e0de235a068b1342c61e1eade64737868f8170208f1ecf497ab") {
30
30
  for (let $i = 0; $i < 74; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
31
- $[0] = "d6e76ca161ece5e3c3ab2fca39477fdbca4669ce2a59cab1e307374e6d56bc57";
31
+ $[0] = "cdb2f56fb4805e0de235a068b1342c61e1eade64737868f8170208f1ecf497ab";
32
32
  }
33
33
  const { fieldName, linkValue: rawLinkValue, onSave } = t0;
34
34
  let t1;
@@ -173,8 +173,7 @@ const LinkFieldEditor = (t0) => {
173
173
  value: textField.value,
174
174
  onChange: t16,
175
175
  onFocus: textField.onFocus,
176
- onBlur: textField.onBlur,
177
- autoFocus: true
176
+ onBlur: textField.onBlur
178
177
  });
179
178
  $[33] = t15;
180
179
  $[34] = t16;