camox 0.41.0 → 0.41.1

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 (27) hide show
  1. package/dist/core/createApp.d.ts +2 -2
  2. package/dist/core/createBlock.js +11 -25
  3. package/dist/core/createLayout.d.ts +1 -1
  4. package/dist/core/editing/BlockEditingRuntime.js +4 -4
  5. package/dist/core/editing/CompleteBlockEditingRuntime.js +5 -5
  6. package/dist/core/editing/createEditableBlock.js +169 -306
  7. package/dist/core/hooks/useIsEditable.js +4 -7
  8. package/dist/core/hooks/useRequireDraftSource.js +7 -11
  9. package/dist/features/preview/CamoxPreview.js +59 -80
  10. package/dist/features/preview/DerivedPreview.js +6 -9
  11. package/dist/features/preview/components/BlockActionsPopover.js +8 -8
  12. package/dist/features/preview/components/DerivedLayoutSidebar.js +4 -7
  13. package/dist/features/preview/components/LinkFieldEditor.js +3 -4
  14. package/dist/features/preview/components/MobilePreviewDrawer.js +3 -3
  15. package/dist/features/preview/components/Overlays.js +6 -9
  16. package/dist/features/preview/components/PageEditorSidebar.js +194 -203
  17. package/dist/features/preview/components/PageTree.js +162 -228
  18. package/dist/features/preview/components/PreviewPanel.js +39 -41
  19. package/dist/features/preview/components/PreviewToolbar.js +15 -18
  20. package/dist/features/preview/components/PreviewToolbarSpacer.js +43 -0
  21. package/dist/features/preview/components/PublicationRow.js +11 -17
  22. package/dist/features/preview/previewStore.js +18 -29
  23. package/dist/features/provider/useAdminShortcuts.js +5 -4
  24. package/dist/features/runtime/RuntimeChrome.js +98 -86
  25. package/dist/features/studio/components/UserButton.js +4 -4
  26. package/package.json +4 -4
  27. package/dist/features/preview/components/DraftSwitchDialog.js +0 -66
@@ -98,7 +98,6 @@ const PageEditorSidebar = () => {
98
98
  const requireDraft = useRequireDraftSource();
99
99
  const selection = useSelector(previewStore, (state) => state.context.selection);
100
100
  const iframeElement = useSelector(previewStore, (state_0) => state_0.context.iframeElement);
101
- const isReadOnly = useSelector(previewStore, (state_1) => state_1.context.previewSource) !== "draft";
102
101
  const postToIframe = React.useCallback((message) => {
103
102
  if (!iframeElement?.contentWindow) return;
104
103
  iframeElement.contentWindow.postMessage(message, "*");
@@ -359,213 +358,205 @@ const PageEditorSidebar = () => {
359
358
  })
360
359
  })
361
360
  })
362
- }), /* @__PURE__ */ jsxs("div", {
361
+ }), /* @__PURE__ */ jsx("div", {
363
362
  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, {
363
+ children: /* @__PURE__ */ jsx("div", { children: isItemLoading ? /* @__PURE__ */ jsx("div", {
364
+ className: "flex h-full items-center justify-center py-12",
365
+ children: /* @__PURE__ */ jsx(Spinner, {})
366
+ }) : /* @__PURE__ */ jsxs(Fragment, { children: [
367
+ currentItemId == null && !fieldHasOwnView && settingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
368
+ className: "border-border space-y-4 border-b px-2 py-4",
369
+ children: [/* @__PURE__ */ jsx(Label, {
370
+ className: "text-muted-foreground",
371
+ children: "Settings"
372
+ }), settingsFields.map((field) => {
373
+ const label = field.label ?? formatFieldName(field.name);
374
+ const settingsValues = block.settings ?? {};
375
+ if (field.fieldType === "Enum") {
376
+ const value_3 = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? "";
377
+ return /* @__PURE__ */ jsxs("div", {
378
+ className: "space-y-2",
379
+ children: [/* @__PURE__ */ jsx(Label, {
380
+ htmlFor: `setting-${field.name}`,
381
+ children: label
382
+ }), /* @__PURE__ */ jsxs(Select, {
383
+ value: value_3,
384
+ onValueChange: (newValue) => {
385
+ if (!requireDraft()) return;
386
+ sessionDirtyRef.current = true;
387
+ updateSettings.mutate({
388
+ id: block.id,
389
+ settings: { [field.name]: newValue }
390
+ });
391
+ },
392
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
418
393
  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;
432
- })]
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
+ children: /* @__PURE__ */ jsx(SelectValue, {})
395
+ }), /* @__PURE__ */ jsx(SelectContent, { children: field.enumValues?.map((enumValue) => /* @__PURE__ */ jsx(SelectItem, {
396
+ value: enumValue,
397
+ children: field.enumLabels?.[enumValue] ?? enumValue
398
+ }, enumValue)) })]
399
+ })]
400
+ }, field.name);
401
+ }
402
+ if (field.fieldType === "Boolean") {
403
+ const checked = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? false;
404
+ return /* @__PURE__ */ jsxs("div", {
405
+ className: "flex items-center justify-between",
406
+ children: [/* @__PURE__ */ jsx(Label, {
407
+ htmlFor: `setting-${field.name}`,
408
+ children: label
409
+ }), /* @__PURE__ */ jsx(Switch, {
410
+ id: `setting-${field.name}`,
411
+ checked,
412
+ onCheckedChange: (newValue_0) => {
413
+ if (!requireDraft()) return;
414
+ sessionDirtyRef.current = true;
415
+ updateSettings.mutate({
416
+ id: block.id,
417
+ settings: { [field.name]: newValue_0 }
418
+ });
419
+ }
420
+ })]
421
+ }, field.name);
422
+ }
423
+ return null;
424
+ })]
425
+ }),
426
+ currentItemId != null && !fieldHasOwnView && itemSettingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
427
+ className: "border-border space-y-4 border-b px-2 py-4",
428
+ children: [/* @__PURE__ */ jsx(Label, {
429
+ className: "text-muted-foreground",
430
+ children: "Settings"
431
+ }), itemSettingsFields.map((field_0) => {
432
+ const label_0 = field_0.label ?? formatFieldName(field_0.name);
433
+ const itemSettingsValues = currentItem?.settings ?? {};
434
+ const itemSettingsSchemaProps = itemArraySchema?.itemSettingsSchema?.properties;
435
+ if (field_0.fieldType === "Enum") {
436
+ const value_4 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? "";
437
+ return /* @__PURE__ */ jsxs("div", {
438
+ className: "space-y-2",
439
+ children: [/* @__PURE__ */ jsx(Label, {
440
+ htmlFor: `item-setting-${field_0.name}`,
441
+ children: label_0
442
+ }), /* @__PURE__ */ jsxs(Select, {
443
+ value: value_4,
444
+ onValueChange: (newValue_1) => {
445
+ if (!requireDraft()) return;
446
+ sessionDirtyRef.current = true;
447
+ updateRepeatableSettings.mutate({
448
+ id: currentItemId,
449
+ settings: { [field_0.name]: newValue_1 }
450
+ });
451
+ },
452
+ children: [/* @__PURE__ */ jsx(SelectTrigger, {
478
453
  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
454
+ children: /* @__PURE__ */ jsx(SelectValue, {})
455
+ }), /* @__PURE__ */ jsx(SelectContent, { children: field_0.enumValues?.map((enumValue_0) => /* @__PURE__ */ jsx(SelectItem, {
456
+ value: enumValue_0,
457
+ children: field_0.enumLabels?.[enumValue_0] ?? enumValue_0
458
+ }, enumValue_0)) })]
459
+ })]
460
+ }, field_0.name);
461
+ }
462
+ if (field_0.fieldType === "Boolean") {
463
+ const checked_0 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? false;
464
+ return /* @__PURE__ */ jsxs("div", {
465
+ className: "flex items-center justify-between",
466
+ children: [/* @__PURE__ */ jsx(Label, {
467
+ htmlFor: `item-setting-${field_0.name}`,
468
+ children: label_0
469
+ }), /* @__PURE__ */ jsx(Switch, {
470
+ id: `item-setting-${field_0.name}`,
471
+ checked: checked_0,
472
+ onCheckedChange: (newValue_2) => {
473
+ if (!requireDraft()) return;
474
+ sessionDirtyRef.current = true;
475
+ updateRepeatableSettings.mutate({
476
+ id: currentItemId,
477
+ settings: { [field_0.name]: newValue_2 }
478
+ });
479
+ }
480
+ })]
481
+ }, field_0.name);
482
+ }
483
+ return null;
484
+ })]
485
+ }),
486
+ isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
487
+ fieldName: assetFieldName,
488
+ assetType,
489
+ currentData,
490
+ onFieldChange: activeFieldChangeHandler
491
+ }),
492
+ isViewingAsset && assetFieldName && !isMultipleAsset && /* @__PURE__ */ jsx(SingleAssetFieldEditor, {
493
+ fieldName: assetFieldName,
494
+ assetType,
495
+ currentData,
496
+ onFieldChange: activeFieldChangeHandler
497
+ }),
498
+ !isViewingAsset && isViewingLink && linkFieldName && /* @__PURE__ */ jsx("div", {
499
+ className: "px-2 py-4",
500
+ children: /* @__PURE__ */ jsx(LinkFieldEditor, {
501
+ fieldName: linkFieldName,
502
+ linkValue: currentData[linkFieldName] ?? {
503
+ type: "external",
504
+ text: "",
505
+ href: "",
506
+ newTab: false
507
+ },
508
+ onSave: (fieldName_1, value_5) => {
509
+ activeFieldChangeHandler(fieldName_1, value_5);
510
+ }
511
+ })
512
+ }),
513
+ !isViewingAsset && !isViewingLink && (currentItemId == null || currentItem) && /* @__PURE__ */ jsx(ItemFieldsEditor, {
514
+ schema: currentSchema,
515
+ data: currentData,
516
+ blockId: block.id,
517
+ itemId: currentItemId ?? void 0,
518
+ onFieldChange: activeFieldChangeHandler,
519
+ postToIframe,
520
+ filesMap,
521
+ itemsMap,
522
+ fieldIdPrefix
523
+ }, currentItemId ?? `block-${block.id}`),
524
+ !isViewingAsset && !isViewingLink && currentItemId != null && currentItem && /* @__PURE__ */ jsxs("div", {
525
+ className: "border-border flex items-center gap-1 border-t px-2 py-4",
526
+ children: [
527
+ canAddSibling && /* @__PURE__ */ jsxs(Button, {
528
+ type: "button",
529
+ variant: "ghost",
530
+ size: "sm",
531
+ className: "text-muted-foreground justify-start",
532
+ onClick: () => {
533
+ if (!requireDraft()) return;
534
+ addSibling({ afterPosition: currentItem.position });
515
535
  },
516
- onSave: (fieldName_1, value_5) => {
517
- activeFieldChangeHandler(fieldName_1, value_5);
518
- }
536
+ children: [/* @__PURE__ */ jsx(CirclePlus, { className: "h-4 w-4" }), "Add item"]
537
+ }),
538
+ canRemoveCurrent && /* @__PURE__ */ jsxs(Button, {
539
+ type: "button",
540
+ variant: "ghost",
541
+ size: "sm",
542
+ className: "text-muted-foreground justify-start",
543
+ onClick: () => {
544
+ if (!requireDraft()) return;
545
+ removeCurrent(currentItemId, { onSuccess: () => previewStore.send({ type: "selectParent" }) });
546
+ },
547
+ children: [/* @__PURE__ */ jsx(CircleMinus, { className: "h-4 w-4" }), "Remove item"]
548
+ }),
549
+ /* @__PURE__ */ jsxs(Button, {
550
+ type: "button",
551
+ variant: "ghost",
552
+ size: "sm",
553
+ className: "text-muted-foreground justify-start",
554
+ onClick: () => previewStore.send({ type: "selectParent" }),
555
+ children: [/* @__PURE__ */ jsx(CornerLeftUp, { className: "h-4 w-4" }), "Select parent"]
519
556
  })
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
- ]
566
- })
567
- ] })
568
- })]
557
+ ]
558
+ })
559
+ ] }) })
569
560
  })] });
570
561
  };
571
562