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
@@ -2,11 +2,13 @@ import { isFileMarker } from "../../../lib/normalized-data.js";
2
2
  import { blockMutations, blockQueries, fileQueries, repeatableItemMutations } from "../../../lib/queries.js";
3
3
  import { cn } from "../../../lib/utils.js";
4
4
  import { useCamoxApp } from "../../provider/components/CamoxAppContext.js";
5
- import { trackClientEvent } from "../../../lib/telemetry-client.js";
5
+ import { areCommentsEnabled } from "../commentsEnabled.js";
6
6
  import { previewStore, selectionBlockId, selectionField, selectionItemId } from "../previewStore.js";
7
7
  import { useRequireDraftSource } from "../../../core/hooks/useRequireDraftSource.js";
8
8
  import { fieldTypesDictionary } from "../../../core/lib/fieldTypes.js";
9
9
  import { SingleAssetFieldEditor } from "./AssetFieldEditor.js";
10
+ import { SidebarSection, SidebarSectionContent, SidebarSectionHeader } from "./SidebarSection.js";
11
+ import { AttachedComments } from "./AttachedComments.js";
10
12
  import { useRepeatableItemActions } from "./useRepeatableItemActions.js";
11
13
  import { ItemFieldsEditor, formatFieldName } from "./ItemFieldsEditor.js";
12
14
  import { LinkFieldEditor } from "./LinkFieldEditor.js";
@@ -16,10 +18,11 @@ import * as React from "react";
16
18
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
19
  import { useSelector } from "@xstate/store-react";
18
20
  import { Button } from "@camox/ui/button";
19
- import { CircleMinus, CirclePlus, CornerLeftUp } from "lucide-react";
21
+ import { CirclePlus, Trash2 } from "lucide-react";
20
22
  import { Spinner } from "@camox/ui/spinner";
21
23
  import { Label } from "@camox/ui/label";
22
24
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@camox/ui/select";
25
+ import { ButtonGroup } from "@camox/ui/button-group";
23
26
  import { Switch } from "@camox/ui/switch";
24
27
 
25
28
  //#region src/features/preview/components/PageEditorSidebar.tsx
@@ -89,7 +92,7 @@ const buildAncestorChain = (itemId, itemsMap) => {
89
92
  }
90
93
  return chain;
91
94
  };
92
- const PageEditorSidebar = () => {
95
+ const PageEditorSidebar = ({ pageId }) => {
93
96
  const camoxApp = useCamoxApp();
94
97
  const updateContent = useMutation(blockMutations.updateContent());
95
98
  const updateSettings = useMutation(blockMutations.updateSettings());
@@ -98,14 +101,13 @@ const PageEditorSidebar = () => {
98
101
  const requireDraft = useRequireDraftSource();
99
102
  const selection = useSelector(previewStore, (state) => state.context.selection);
100
103
  const iframeElement = useSelector(previewStore, (state_0) => state_0.context.iframeElement);
101
- const isReadOnly = useSelector(previewStore, (state_1) => state_1.context.previewSource) !== "draft";
102
104
  const postToIframe = React.useCallback((message) => {
103
105
  if (!iframeElement?.contentWindow) return;
104
106
  iframeElement.contentWindow.postMessage(message, "*");
105
107
  }, [iframeElement]);
106
108
  const blockId = selectionBlockId(selection);
107
109
  const currentItemId = selectionItemId(selection);
108
- const fieldInfo = selectionField(selection);
110
+ const selectedField = selectionField(selection);
109
111
  const { data: blockBundle } = useQuery({
110
112
  ...blockQueries.get(blockId),
111
113
  enabled: blockId != null
@@ -197,11 +199,15 @@ const PageEditorSidebar = () => {
197
199
  for (const [key, value_0] of Object.entries(rawCurrentData)) resolved_0[key] = resolveValue(value_0);
198
200
  return resolved_0;
199
201
  }, [rawCurrentData, filesMap]);
202
+ const fieldInfo = selectedField ? {
203
+ ...selectedField,
204
+ fieldType: currentSchema?.properties?.[selectedField.fieldName]?.fieldType ?? selectedField.fieldType
205
+ } : null;
200
206
  const isViewingLink = fieldInfo?.fieldType === "Link";
201
207
  const linkFieldName = isViewingLink ? fieldInfo.fieldName : null;
202
- const isViewingImage = fieldInfo?.fieldType === "Image";
208
+ const isViewingImage = fieldInfo?.fieldType === "Image" || fieldInfo?.fieldType === "ImageList";
203
209
  const imageFieldName = isViewingImage ? fieldInfo.fieldName : null;
204
- const isViewingFile = fieldInfo?.fieldType === "File";
210
+ const isViewingFile = fieldInfo?.fieldType === "File" || fieldInfo?.fieldType === "FileList";
205
211
  const fileFieldName = isViewingFile ? fieldInfo.fieldName : null;
206
212
  const isViewingAsset = isViewingImage || isViewingFile;
207
213
  const assetFieldName = imageFieldName ?? fileFieldName;
@@ -215,34 +221,10 @@ const PageEditorSidebar = () => {
215
221
  assetFieldName,
216
222
  currentSchema
217
223
  ]);
218
- const sessionDirtyRef = React.useRef(false);
219
- const trackedBlockIdRef = React.useRef(null);
220
- React.useEffect(() => {
221
- if (!block) {
222
- trackedBlockIdRef.current = null;
223
- return;
224
- }
225
- if (trackedBlockIdRef.current === block.id) return;
226
- trackedBlockIdRef.current = block.id;
227
- sessionDirtyRef.current = false;
228
- trackClientEvent("page_editor_sidebar_opened", { blockType: block.type });
229
- }, [block]);
230
- React.useEffect(() => {
231
- if (!block) return;
232
- return () => {
233
- if (!sessionDirtyRef.current) return;
234
- trackClientEvent("block_edited", {
235
- via: "page-editor-sidebar",
236
- blockType: block.type
237
- });
238
- sessionDirtyRef.current = false;
239
- };
240
- }, [block]);
241
224
  const fieldIdPrefix = React.useId();
242
225
  const handleBlockFieldChange = React.useCallback((fieldName, value_1) => {
243
226
  if (!block) return;
244
227
  if (!requireDraft()) return;
245
- sessionDirtyRef.current = true;
246
228
  updateContent.mutate({
247
229
  id: block.id,
248
230
  content: { [fieldName]: value_1 }
@@ -255,7 +237,6 @@ const PageEditorSidebar = () => {
255
237
  const handleItemFieldChange = React.useCallback((fieldName_0, value_2) => {
256
238
  if (currentItemId == null) return;
257
239
  if (!requireDraft()) return;
258
- sessionDirtyRef.current = true;
259
240
  updateRepeatableContent.mutate({
260
241
  id: currentItemId,
261
242
  content: { [fieldName_0]: value_2 }
@@ -288,16 +269,35 @@ const PageEditorSidebar = () => {
288
269
  blockId: block.id
289
270
  })
290
271
  },
291
- ...ancestorChain.map((ancestor) => ({
292
- key: `item-${ancestor.id}`,
272
+ ...ancestorChain.flatMap((ancestor) => [{
273
+ key: `repeater-${ancestor.id}`,
293
274
  label: getArraySchemaForItem(blockDef._internal.contentSchema, ancestor.id, itemsMap)?.title ?? formatFieldName(ancestor.fieldName),
275
+ isCurrent: false,
276
+ onClick: () => previewStore.send({
277
+ type: "setSelection",
278
+ selection: ancestor.parentItemId == null ? {
279
+ type: "block-field",
280
+ blockId: block.id,
281
+ fieldName: ancestor.fieldName,
282
+ fieldType: "Repeater"
283
+ } : {
284
+ type: "item-field",
285
+ blockId: block.id,
286
+ itemId: ancestor.parentItemId,
287
+ fieldName: ancestor.fieldName,
288
+ fieldType: "Repeater"
289
+ }
290
+ })
291
+ }, {
292
+ key: `item-${ancestor.id}`,
293
+ label: ancestor.summary || "Item",
294
294
  isCurrent: ancestor.id === currentItemId && !fieldHasOwnView && ancestor.id === ancestorChain[ancestorChain.length - 1]?.id,
295
295
  onClick: () => previewStore.send({
296
296
  type: "selectItem",
297
297
  blockId: block.id,
298
298
  itemId: ancestor.id
299
299
  })
300
- })),
300
+ }]),
301
301
  ...fieldHasOwnView && fieldInfo ? [{
302
302
  key: `field-${fieldInfo.fieldName}`,
303
303
  label: currentSchema?.properties?.[fieldInfo.fieldName]?.title ?? formatFieldName(fieldInfo.fieldName),
@@ -305,8 +305,8 @@ const PageEditorSidebar = () => {
305
305
  onClick: void 0
306
306
  }] : []
307
307
  ];
308
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
309
- className: "border-border flex flex-col gap-1.5 border-b px-2 py-4",
308
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SidebarSection, {
309
+ divider: "bottom",
310
310
  children: /* @__PURE__ */ jsx("nav", {
311
311
  "aria-label": "Selection path",
312
312
  className: "text-muted-foreground text-sm",
@@ -359,213 +359,203 @@ const PageEditorSidebar = () => {
359
359
  })
360
360
  })
361
361
  })
362
- }), /* @__PURE__ */ jsxs("div", {
363
- className: "relative flex-1 overflow-auto",
364
- children: [isReadOnly && /* @__PURE__ */ jsx("button", {
365
- type: "button",
366
- "aria-label": "Switch to draft to edit",
367
- className: "absolute inset-0 z-10 h-full w-full cursor-not-allowed",
368
- onClick: () => previewStore.send({ type: "requestDraftSwitch" })
369
- }), /* @__PURE__ */ jsx("div", {
370
- className: cn(isReadOnly && "pointer-events-none opacity-50"),
371
- children: isItemLoading ? /* @__PURE__ */ jsx("div", {
372
- className: "flex h-full items-center justify-center py-12",
373
- children: /* @__PURE__ */ jsx(Spinner, {})
374
- }) : /* @__PURE__ */ jsxs(Fragment, { children: [
375
- currentItemId == null && !fieldHasOwnView && settingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
376
- className: "border-border space-y-4 border-b px-2 py-4",
377
- children: [/* @__PURE__ */ jsx(Label, {
378
- className: "text-muted-foreground",
379
- children: "Settings"
380
- }), settingsFields.map((field) => {
381
- const label = field.label ?? formatFieldName(field.name);
382
- const settingsValues = block.settings ?? {};
383
- if (field.fieldType === "Enum") {
384
- const value_3 = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? "";
385
- return /* @__PURE__ */ jsxs("div", {
386
- className: "space-y-2",
387
- children: [/* @__PURE__ */ jsx(Label, {
388
- htmlFor: `setting-${field.name}`,
389
- children: label
390
- }), /* @__PURE__ */ jsxs(Select, {
391
- value: value_3,
392
- onValueChange: (newValue) => {
393
- if (!requireDraft()) return;
394
- sessionDirtyRef.current = true;
395
- updateSettings.mutate({
396
- id: block.id,
397
- settings: { [field.name]: newValue }
398
- });
399
- },
400
- children: [/* @__PURE__ */ jsx(SelectTrigger, {
401
- id: `setting-${field.name}`,
402
- children: /* @__PURE__ */ jsx(SelectValue, {})
403
- }), /* @__PURE__ */ jsx(SelectContent, { children: field.enumValues?.map((enumValue) => /* @__PURE__ */ jsx(SelectItem, {
404
- value: enumValue,
405
- children: field.enumLabels?.[enumValue] ?? enumValue
406
- }, enumValue)) })]
407
- })]
408
- }, field.name);
409
- }
410
- if (field.fieldType === "Boolean") {
411
- const checked = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? false;
412
- return /* @__PURE__ */ jsxs("div", {
413
- className: "flex items-center justify-between",
414
- children: [/* @__PURE__ */ jsx(Label, {
415
- htmlFor: `setting-${field.name}`,
416
- children: label
417
- }), /* @__PURE__ */ jsx(Switch, {
418
- id: `setting-${field.name}`,
419
- checked,
420
- onCheckedChange: (newValue_0) => {
421
- if (!requireDraft()) return;
422
- sessionDirtyRef.current = true;
423
- updateSettings.mutate({
424
- id: block.id,
425
- settings: { [field.name]: newValue_0 }
426
- });
427
- }
428
- })]
429
- }, field.name);
430
- }
431
- return null;
362
+ }), /* @__PURE__ */ jsx("div", {
363
+ className: "relative min-w-0 flex-1 overflow-x-hidden overflow-y-auto",
364
+ children: /* @__PURE__ */ jsx("div", { children: isItemLoading ? /* @__PURE__ */ jsx("div", {
365
+ className: "flex h-full items-center justify-center py-12",
366
+ children: /* @__PURE__ */ jsx(Spinner, {})
367
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
368
+ !fieldHasOwnView && currentItemId != null && currentItem && /* @__PURE__ */ jsxs(SidebarSection, {
369
+ divider: "bottom",
370
+ "aria-label": "List actions",
371
+ children: [/* @__PURE__ */ jsx(SidebarSectionHeader, { children: "List actions" }), /* @__PURE__ */ jsx(SidebarSectionContent, { children: /* @__PURE__ */ jsxs(ButtonGroup, {
372
+ "aria-label": "List actions",
373
+ children: [/* @__PURE__ */ jsxs(Button, {
374
+ type: "button",
375
+ variant: "outline",
376
+ size: "sm",
377
+ disabled: !canAddSibling,
378
+ onClick: () => {
379
+ if (!canAddSibling || !requireDraft()) return;
380
+ addSibling({ afterPosition: currentItem.position });
381
+ },
382
+ children: [/* @__PURE__ */ jsx(CirclePlus, { className: "text-muted-foreground h-4 w-4" }), "Add sibling"]
383
+ }), /* @__PURE__ */ jsxs(Button, {
384
+ type: "button",
385
+ variant: "outline",
386
+ size: "sm",
387
+ disabled: !canRemoveCurrent,
388
+ onClick: () => {
389
+ if (!canRemoveCurrent || !requireDraft()) return;
390
+ removeCurrent(currentItemId, { onSuccess: () => previewStore.send({ type: "selectParent" }) });
391
+ },
392
+ children: [/* @__PURE__ */ jsx(Trash2, { className: "text-muted-foreground h-4 w-4" }), "Delete"]
432
393
  })]
433
- }),
434
- currentItemId != null && !fieldHasOwnView && itemSettingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
435
- className: "border-border space-y-4 border-b px-2 py-4",
436
- children: [/* @__PURE__ */ jsx(Label, {
437
- className: "text-muted-foreground",
438
- children: "Settings"
439
- }), itemSettingsFields.map((field_0) => {
440
- const label_0 = field_0.label ?? formatFieldName(field_0.name);
441
- const itemSettingsValues = currentItem?.settings ?? {};
442
- const itemSettingsSchemaProps = itemArraySchema?.itemSettingsSchema?.properties;
443
- if (field_0.fieldType === "Enum") {
444
- const value_4 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? "";
445
- return /* @__PURE__ */ jsxs("div", {
446
- className: "space-y-2",
447
- children: [/* @__PURE__ */ jsx(Label, {
448
- htmlFor: `item-setting-${field_0.name}`,
449
- children: label_0
450
- }), /* @__PURE__ */ jsxs(Select, {
451
- value: value_4,
452
- onValueChange: (newValue_1) => {
453
- if (!requireDraft()) return;
454
- sessionDirtyRef.current = true;
455
- updateRepeatableSettings.mutate({
456
- id: currentItemId,
457
- settings: { [field_0.name]: newValue_1 }
458
- });
459
- },
460
- children: [/* @__PURE__ */ jsx(SelectTrigger, {
461
- id: `item-setting-${field_0.name}`,
462
- children: /* @__PURE__ */ jsx(SelectValue, {})
463
- }), /* @__PURE__ */ jsx(SelectContent, { children: field_0.enumValues?.map((enumValue_0) => /* @__PURE__ */ jsx(SelectItem, {
464
- value: enumValue_0,
465
- children: field_0.enumLabels?.[enumValue_0] ?? enumValue_0
466
- }, enumValue_0)) })]
467
- })]
468
- }, field_0.name);
469
- }
470
- if (field_0.fieldType === "Boolean") {
471
- const checked_0 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? false;
472
- return /* @__PURE__ */ jsxs("div", {
473
- className: "flex items-center justify-between",
474
- children: [/* @__PURE__ */ jsx(Label, {
475
- htmlFor: `item-setting-${field_0.name}`,
476
- children: label_0
477
- }), /* @__PURE__ */ jsx(Switch, {
394
+ }) })]
395
+ }),
396
+ currentItemId == null && !fieldHasOwnView && settingsFields.length > 0 && /* @__PURE__ */ jsxs(SidebarSection, {
397
+ divider: "bottom",
398
+ "aria-label": "Block settings",
399
+ children: [/* @__PURE__ */ jsx(SidebarSectionHeader, { children: "Settings" }), /* @__PURE__ */ jsx(SidebarSectionContent, { children: settingsFields.map((field) => {
400
+ const label = field.label ?? formatFieldName(field.name);
401
+ const settingsValues = block.settings ?? {};
402
+ if (field.fieldType === "Enum") {
403
+ const value_3 = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? "";
404
+ return /* @__PURE__ */ jsxs("div", {
405
+ className: "space-y-2",
406
+ children: [/* @__PURE__ */ jsx(Label, {
407
+ htmlFor: `setting-${field.name}`,
408
+ children: label
409
+ }), /* @__PURE__ */ jsxs(Select, {
410
+ value: value_3,
411
+ onValueChange: (newValue) => {
412
+ if (!requireDraft()) return;
413
+ updateSettings.mutate({
414
+ id: block.id,
415
+ settings: { [field.name]: newValue }
416
+ });
417
+ },
418
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
419
+ id: `setting-${field.name}`,
420
+ children: /* @__PURE__ */ jsx(SelectValue, {})
421
+ }), /* @__PURE__ */ jsx(SelectContent, { children: field.enumValues?.map((enumValue) => /* @__PURE__ */ jsx(SelectItem, {
422
+ value: enumValue,
423
+ children: field.enumLabels?.[enumValue] ?? enumValue
424
+ }, enumValue)) })]
425
+ })]
426
+ }, field.name);
427
+ }
428
+ if (field.fieldType === "Boolean") {
429
+ const checked = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? false;
430
+ return /* @__PURE__ */ jsxs("div", {
431
+ className: "flex items-center justify-between",
432
+ children: [/* @__PURE__ */ jsx(Label, {
433
+ htmlFor: `setting-${field.name}`,
434
+ children: label
435
+ }), /* @__PURE__ */ jsx(Switch, {
436
+ id: `setting-${field.name}`,
437
+ checked,
438
+ onCheckedChange: (newValue_0) => {
439
+ if (!requireDraft()) return;
440
+ updateSettings.mutate({
441
+ id: block.id,
442
+ settings: { [field.name]: newValue_0 }
443
+ });
444
+ }
445
+ })]
446
+ }, field.name);
447
+ }
448
+ return null;
449
+ }) })]
450
+ }),
451
+ currentItemId != null && !fieldHasOwnView && itemSettingsFields.length > 0 && /* @__PURE__ */ jsxs(SidebarSection, {
452
+ divider: "bottom",
453
+ "aria-label": "Item settings",
454
+ children: [/* @__PURE__ */ jsx(SidebarSectionHeader, { children: "Settings" }), /* @__PURE__ */ jsx(SidebarSectionContent, { children: itemSettingsFields.map((field_0) => {
455
+ const label_0 = field_0.label ?? formatFieldName(field_0.name);
456
+ const itemSettingsValues = currentItem?.settings ?? {};
457
+ const itemSettingsSchemaProps = itemArraySchema?.itemSettingsSchema?.properties;
458
+ if (field_0.fieldType === "Enum") {
459
+ const value_4 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? "";
460
+ return /* @__PURE__ */ jsxs("div", {
461
+ className: "space-y-2",
462
+ children: [/* @__PURE__ */ jsx(Label, {
463
+ htmlFor: `item-setting-${field_0.name}`,
464
+ children: label_0
465
+ }), /* @__PURE__ */ jsxs(Select, {
466
+ value: value_4,
467
+ onValueChange: (newValue_1) => {
468
+ if (!requireDraft()) return;
469
+ updateRepeatableSettings.mutate({
470
+ id: currentItemId,
471
+ settings: { [field_0.name]: newValue_1 }
472
+ });
473
+ },
474
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
478
475
  id: `item-setting-${field_0.name}`,
479
- checked: checked_0,
480
- onCheckedChange: (newValue_2) => {
481
- if (!requireDraft()) return;
482
- sessionDirtyRef.current = true;
483
- updateRepeatableSettings.mutate({
484
- id: currentItemId,
485
- settings: { [field_0.name]: newValue_2 }
486
- });
487
- }
488
- })]
489
- }, field_0.name);
490
- }
491
- return null;
492
- })]
493
- }),
494
- isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
495
- fieldName: assetFieldName,
496
- assetType,
497
- currentData,
498
- onFieldChange: activeFieldChangeHandler
499
- }),
500
- isViewingAsset && assetFieldName && !isMultipleAsset && /* @__PURE__ */ jsx(SingleAssetFieldEditor, {
501
- fieldName: assetFieldName,
502
- assetType,
503
- currentData,
504
- onFieldChange: activeFieldChangeHandler
505
- }),
506
- !isViewingAsset && isViewingLink && linkFieldName && /* @__PURE__ */ jsx("div", {
507
- className: "px-2 py-4",
508
- children: /* @__PURE__ */ jsx(LinkFieldEditor, {
509
- fieldName: linkFieldName,
510
- linkValue: currentData[linkFieldName] ?? {
511
- type: "external",
512
- text: "",
513
- href: "",
514
- newTab: false
515
- },
516
- onSave: (fieldName_1, value_5) => {
517
- activeFieldChangeHandler(fieldName_1, value_5);
518
- }
519
- })
520
- }),
521
- !isViewingAsset && !isViewingLink && (currentItemId == null || currentItem) && /* @__PURE__ */ jsx(ItemFieldsEditor, {
522
- schema: currentSchema,
523
- data: currentData,
524
- blockId: block.id,
525
- itemId: currentItemId ?? void 0,
526
- onFieldChange: activeFieldChangeHandler,
527
- postToIframe,
528
- filesMap,
529
- itemsMap,
530
- fieldIdPrefix
531
- }, currentItemId ?? `block-${block.id}`),
532
- !isViewingAsset && !isViewingLink && currentItemId != null && currentItem && /* @__PURE__ */ jsxs("div", {
533
- className: "border-border flex items-center gap-1 border-t px-2 py-4",
534
- children: [
535
- canAddSibling && /* @__PURE__ */ jsxs(Button, {
536
- type: "button",
537
- variant: "ghost",
538
- size: "sm",
539
- className: "text-muted-foreground justify-start",
540
- onClick: () => {
541
- if (!requireDraft()) return;
542
- addSibling({ afterPosition: currentItem.position });
543
- },
544
- children: [/* @__PURE__ */ jsx(CirclePlus, { className: "h-4 w-4" }), "Add item"]
545
- }),
546
- canRemoveCurrent && /* @__PURE__ */ jsxs(Button, {
547
- type: "button",
548
- variant: "ghost",
549
- size: "sm",
550
- className: "text-muted-foreground justify-start",
551
- onClick: () => {
552
- if (!requireDraft()) return;
553
- removeCurrent(currentItemId, { onSuccess: () => previewStore.send({ type: "selectParent" }) });
554
- },
555
- children: [/* @__PURE__ */ jsx(CircleMinus, { className: "h-4 w-4" }), "Remove item"]
556
- }),
557
- /* @__PURE__ */ jsxs(Button, {
558
- type: "button",
559
- variant: "ghost",
560
- size: "sm",
561
- className: "text-muted-foreground justify-start",
562
- onClick: () => previewStore.send({ type: "selectParent" }),
563
- children: [/* @__PURE__ */ jsx(CornerLeftUp, { className: "h-4 w-4" }), "Select parent"]
564
- })
565
- ]
476
+ children: /* @__PURE__ */ jsx(SelectValue, {})
477
+ }), /* @__PURE__ */ jsx(SelectContent, { children: field_0.enumValues?.map((enumValue_0) => /* @__PURE__ */ jsx(SelectItem, {
478
+ value: enumValue_0,
479
+ children: field_0.enumLabels?.[enumValue_0] ?? enumValue_0
480
+ }, enumValue_0)) })]
481
+ })]
482
+ }, field_0.name);
483
+ }
484
+ if (field_0.fieldType === "Boolean") {
485
+ const checked_0 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? false;
486
+ return /* @__PURE__ */ jsxs("div", {
487
+ className: "flex items-center justify-between",
488
+ children: [/* @__PURE__ */ jsx(Label, {
489
+ htmlFor: `item-setting-${field_0.name}`,
490
+ children: label_0
491
+ }), /* @__PURE__ */ jsx(Switch, {
492
+ id: `item-setting-${field_0.name}`,
493
+ checked: checked_0,
494
+ onCheckedChange: (newValue_2) => {
495
+ if (!requireDraft()) return;
496
+ updateRepeatableSettings.mutate({
497
+ id: currentItemId,
498
+ settings: { [field_0.name]: newValue_2 }
499
+ });
500
+ }
501
+ })]
502
+ }, field_0.name);
503
+ }
504
+ return null;
505
+ }) })]
506
+ }),
507
+ isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
508
+ fieldName: assetFieldName,
509
+ assetType,
510
+ currentData,
511
+ onFieldChange: activeFieldChangeHandler
512
+ }),
513
+ isViewingAsset && assetFieldName && !isMultipleAsset && /* @__PURE__ */ jsx(SingleAssetFieldEditor, {
514
+ fieldName: assetFieldName,
515
+ assetType,
516
+ currentData,
517
+ onFieldChange: activeFieldChangeHandler
518
+ }),
519
+ !isViewingAsset && isViewingLink && linkFieldName && /* @__PURE__ */ jsx("div", {
520
+ className: "px-2 py-4",
521
+ children: /* @__PURE__ */ jsx(LinkFieldEditor, {
522
+ fieldName: linkFieldName,
523
+ linkValue: currentData[linkFieldName] ?? {
524
+ type: "external",
525
+ text: "",
526
+ href: "",
527
+ newTab: false
528
+ },
529
+ onSave: (fieldName_1, value_5) => {
530
+ activeFieldChangeHandler(fieldName_1, value_5);
531
+ }
566
532
  })
567
- ] })
568
- })]
533
+ }),
534
+ !isViewingAsset && !isViewingLink && (currentItemId == null || currentItem) && /* @__PURE__ */ jsx(ItemFieldsEditor, {
535
+ selectedFieldName: fieldInfo?.fieldName,
536
+ schema: currentSchema,
537
+ data: currentData,
538
+ blockId: block.id,
539
+ itemId: currentItemId ?? void 0,
540
+ onFieldChange: activeFieldChangeHandler,
541
+ postToIframe,
542
+ filesMap,
543
+ itemsMap,
544
+ fieldIdPrefix
545
+ }, `${block.id}-${currentItemId ?? "block"}-${fieldInfo?.fieldName ?? "fields"}`),
546
+ areCommentsEnabled() && !fieldHasOwnView && (currentItemId == null || currentItem) && /* @__PURE__ */ jsx(AttachedComments, {
547
+ pageId,
548
+ blockId: block.id,
549
+ itemId: currentItemId ?? void 0
550
+ }),
551
+ areCommentsEnabled() && fieldHasOwnView && fieldInfo && /* @__PURE__ */ jsx(AttachedComments, {
552
+ pageId,
553
+ blockId: block.id,
554
+ itemId: currentItemId ?? void 0,
555
+ fieldName: fieldInfo.fieldName,
556
+ fieldType: fieldInfo.fieldType
557
+ })
558
+ ] }) })
569
559
  })] });
570
560
  };
571
561