camox 0.69.0 → 0.72.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 (89) hide show
  1. package/dist/core/createApp.d.ts +4 -103
  2. package/dist/core/createApp.js +3 -24
  3. package/dist/core/createBlock.d.ts +2 -2
  4. package/dist/core/createBlock.js +55 -192
  5. package/dist/core/createLayout.d.ts +6 -77
  6. package/dist/core/createLayout.js +12 -50
  7. package/dist/core/editing/createEditableBlock.d.ts +9 -75
  8. package/dist/core/editing/createEditableBlock.js +258 -640
  9. package/dist/core/hooks/useArtifactHost.js +56 -46
  10. package/dist/core/hooks/useIsEditable.js +2 -2
  11. package/dist/core/lib/artifact.d.ts +4 -0
  12. package/dist/core/lib/artifactData.js +8 -3
  13. package/dist/core/lib/artifactHost.js +40 -0
  14. package/dist/core/lib/artifactRuntime.js +20 -1
  15. package/dist/core/lib/contentType.d.ts +23 -38
  16. package/dist/core/lib/contentType.js +34 -62
  17. package/dist/core/lib/iconTypes.d.ts +0 -3
  18. package/dist/core/lib/icons.js +63 -51
  19. package/dist/core/lib/recordScope.js +1 -1
  20. package/dist/features/canvas/CanvasOverlays.js +94 -176
  21. package/dist/features/canvas/CanvasPageFrame.js +62 -68
  22. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
  23. package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
  24. package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
  25. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
  26. package/dist/features/canvas/useCanvasCamera.js +1 -1
  27. package/dist/features/canvas/useCanvasFrame.js +1 -1
  28. package/dist/features/content/ContentCollection.js +2 -2
  29. package/dist/features/content/collection-form.js +6 -7
  30. package/dist/features/page/CuratedPageContent.js +15 -24
  31. package/dist/features/page/UnplacedBlockContent.js +1 -6
  32. package/dist/features/preview/CamoxPreview.js +30 -33
  33. package/dist/features/preview/EditablePageContent.js +131 -151
  34. package/dist/features/preview/components/BlockActionsPopover.js +43 -152
  35. package/dist/features/preview/components/CanvasPreview.js +2 -2
  36. package/dist/features/preview/components/Frame.js +3 -3
  37. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  38. package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
  39. package/dist/features/preview/components/Overlays.js +18 -84
  40. package/dist/features/preview/components/PageTree.js +57 -103
  41. package/dist/features/preview/components/PreviewPanel.js +8 -11
  42. package/dist/features/preview/components/RecordCombobox.js +65 -78
  43. package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
  44. package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
  45. package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
  46. package/dist/features/preview/components/SelectionEditor.js +5 -4
  47. package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
  48. package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
  49. package/dist/features/preview/overlayMessages.js +1 -4
  50. package/dist/features/preview/previewStore.js +3 -23
  51. package/dist/features/renderer/RendererApp.js +17 -141
  52. package/dist/features/renderer/definitionAnswers.js +1 -8
  53. package/dist/features/renderer/rendererHost.js +1 -31
  54. package/dist/features/renderer/studioConnection.js +1 -25
  55. package/dist/features/runtime/pageApp.js +8 -4
  56. package/dist/features/runtime/runtime.js +3 -3
  57. package/dist/features/studio/agentRunToast.js +71 -0
  58. package/dist/features/studio/components/ChatWidget.js +2 -0
  59. package/dist/features/studio/components/DraftBar.js +2 -3
  60. package/dist/features/studio/components/DraftsControl.js +150 -176
  61. package/dist/features/studio/components/ReviewDraftSheet.js +344 -548
  62. package/dist/features/studio/components/ThreadMessages.js +89 -22
  63. package/dist/features/studio/draftLabel.js +1 -1
  64. package/dist/features/studio/studioStore.js +5 -17
  65. package/dist/features/studio/viewSwitch.js +2 -4
  66. package/dist/features/vite/blockBoilerplate.js +1 -1
  67. package/dist/features/vite/definitionsSync.js +1 -8
  68. package/dist/lib/queries.js +0 -1
  69. package/dist/lib/studio-definitions.js +0 -2
  70. package/dist/lib/studio-reads.js +0 -5
  71. package/dist/lib/use-thread.js +196 -138
  72. package/dist/package.js +1 -1
  73. package/dist/studio-overlays.css +0 -29
  74. package/dist/studio.css +1 -1
  75. package/package.json +6 -4
  76. package/skills/camox/SKILL.md +1 -1
  77. package/skills/camox/references/artifacts.md +89 -5
  78. package/skills/camox/references/block-definitions.md +21 -25
  79. package/skills/camox/references/dom-integrations.md +1 -1
  80. package/skills/camox/references/layout-definitions.md +3 -12
  81. package/skills/camox/references/routed-layouts.md +2 -2
  82. package/skills/camox-expand/SKILL.md +5 -5
  83. package/skills/camoxify/SKILL.md +4 -4
  84. package/dist/features/canvas/canvasInsertionSeams.js +0 -44
  85. package/dist/features/preview/components/AddBlockSheet.js +0 -314
  86. package/dist/features/preview/components/BlockPeek.js +0 -66
  87. package/dist/features/preview/components/BlockThumbnail.js +0 -281
  88. package/dist/features/preview/components/blockGridNavigation.js +0 -15
  89. package/dist/features/preview/referencePickerFocus.js +0 -29
@@ -10,11 +10,11 @@ import { BlockActionsPopover } from "./BlockActionsPopover.js";
10
10
  import { usePreviewedPage } from "../CamoxPreview.js";
11
11
  import { c } from "react/compiler-runtime";
12
12
  import * as React from "react";
13
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
14
  import { useSelector } from "@xstate/store-react";
15
15
  import { Button } from "@camox/ui/button";
16
16
  import { Label } from "@camox/ui/label";
17
- import { ChevronsUpDown, Ellipsis, GripVertical, LayoutTemplate, Plus } from "lucide-react";
17
+ import { ChevronsUpDown, Ellipsis, GripVertical, LayoutTemplate } from "lucide-react";
18
18
  import { Tooltip, TooltipContent, TooltipTrigger } from "@camox/ui/tooltip";
19
19
  import { DndContext, DragOverlay, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors } from "@dnd-kit/core";
20
20
  import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
@@ -375,98 +375,76 @@ const SortableBlock = (t0) => {
375
375
  return t17;
376
376
  };
377
377
  const LayoutBlockItem = (t0) => {
378
- const $ = c(23);
379
- const { block, layoutName, withActions: t1 } = t0;
380
- const withActions = t1 === void 0 ? true : t1;
378
+ const $ = c(17);
379
+ const { block, layoutName } = t0;
381
380
  const blockDef = useBlockDefinition(block.type);
382
381
  const ctx = useBlockTreeItem(block);
383
382
  const displayText = blockDef?.title ?? block.type;
384
- let t2;
383
+ let t1;
385
384
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
386
- t2 = /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(LayoutTemplate, { className: "h-4 w-4" }) });
387
- $[0] = t2;
388
- } else t2 = $[0];
389
- let t3;
385
+ t1 = /* @__PURE__ */ jsx(TooltipTrigger, { children: /* @__PURE__ */ jsx(LayoutTemplate, { className: "h-4 w-4" }) });
386
+ $[0] = t1;
387
+ } else t1 = $[0];
388
+ let t2;
390
389
  if ($[1] !== layoutName) {
391
- t3 = /* @__PURE__ */ jsx("span", {
390
+ t2 = /* @__PURE__ */ jsx("span", {
392
391
  className: "font-semibold",
393
392
  children: layoutName
394
393
  });
395
394
  $[1] = layoutName;
396
- $[2] = t3;
397
- } else t3 = $[2];
398
- let t4;
395
+ $[2] = t2;
396
+ } else t2 = $[2];
397
+ let t3;
399
398
  if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
400
- t4 = /* @__PURE__ */ jsx("br", {});
401
- $[3] = t4;
402
- } else t4 = $[3];
403
- const t5 = blockDef?.synced ? "Synced: editing this block updates it across all layouts and pages" : "Changing the content may affect other pages";
404
- let t6;
405
- if ($[4] !== t3 || $[5] !== t5) {
406
- t6 = /* @__PURE__ */ jsx("div", {
399
+ t3 = /* @__PURE__ */ jsx("br", {});
400
+ $[3] = t3;
401
+ } else t3 = $[3];
402
+ const t4 = blockDef?.synced ? "Synced: editing this block updates it across all layouts and pages" : "Changing the content may affect other pages";
403
+ let t5;
404
+ if ($[4] !== t2 || $[5] !== t4) {
405
+ t5 = /* @__PURE__ */ jsx("div", {
407
406
  className: "text-muted-foreground flex size-8 shrink-0 items-center justify-center",
408
- children: /* @__PURE__ */ jsxs(Tooltip, { children: [t2, /* @__PURE__ */ jsxs(TooltipContent, { children: [
407
+ children: /* @__PURE__ */ jsxs(Tooltip, { children: [t1, /* @__PURE__ */ jsxs(TooltipContent, { children: [
409
408
  "From ",
410
- t3,
409
+ t2,
411
410
  " layout.",
412
- t4,
413
- t5
411
+ t3,
412
+ t4
414
413
  ] })] })
415
414
  });
416
- $[4] = t3;
417
- $[5] = t5;
418
- $[6] = t6;
419
- } else t6 = $[6];
420
- let t7;
415
+ $[4] = t2;
416
+ $[5] = t4;
417
+ $[6] = t5;
418
+ } else t5 = $[6];
419
+ let t6;
421
420
  if ($[7] !== ctx.toggleSelection || $[8] !== displayText) {
422
- t7 = /* @__PURE__ */ jsx(BlockTreeItemTrigger, {
421
+ t6 = /* @__PURE__ */ jsx(BlockTreeItemTrigger, {
423
422
  displayText,
424
423
  onClick: ctx.toggleSelection
425
424
  });
426
425
  $[7] = ctx.toggleSelection;
427
426
  $[8] = displayText;
428
- $[9] = t7;
429
- } else t7 = $[9];
430
- let t8;
431
- if ($[10] !== block || $[11] !== ctx.ellipsisPopoverOpen || $[12] !== ctx.setEllipsisPopoverOpen || $[13] !== withActions) {
432
- t8 = withActions && /* @__PURE__ */ jsx(BlockActionsPopover, {
433
- block,
434
- open: ctx.ellipsisPopoverOpen,
435
- onOpenChange: ctx.setEllipsisPopoverOpen,
436
- isLayoutBlock: true,
437
- layoutSlot: block.slot,
438
- children: /* @__PURE__ */ jsx(BlockTreeItemEllipsis, { open: ctx.ellipsisPopoverOpen })
439
- });
440
- $[10] = block;
441
- $[11] = ctx.ellipsisPopoverOpen;
442
- $[12] = ctx.setEllipsisPopoverOpen;
443
- $[13] = withActions;
444
- $[14] = t8;
445
- } else t8 = $[14];
446
- let t9;
447
- if ($[15] !== ctx.handleBlockMouseEnter || $[16] !== ctx.handleBlockMouseLeave || $[17] !== ctx.shouldShowActive || $[18] !== ctx.shouldShowHover || $[19] !== t6 || $[20] !== t7 || $[21] !== t8) {
448
- t9 = /* @__PURE__ */ jsxs(BlockTreeItemHeader, {
427
+ $[9] = t6;
428
+ } else t6 = $[9];
429
+ let t7;
430
+ if ($[10] !== ctx.handleBlockMouseEnter || $[11] !== ctx.handleBlockMouseLeave || $[12] !== ctx.shouldShowActive || $[13] !== ctx.shouldShowHover || $[14] !== t5 || $[15] !== t6) {
431
+ t7 = /* @__PURE__ */ jsxs(BlockTreeItemHeader, {
449
432
  className: "group",
450
433
  shouldShowHover: ctx.shouldShowHover,
451
434
  shouldShowActive: ctx.shouldShowActive,
452
435
  onMouseEnter: ctx.handleBlockMouseEnter,
453
436
  onMouseLeave: ctx.handleBlockMouseLeave,
454
- children: [
455
- t6,
456
- t7,
457
- t8
458
- ]
437
+ children: [t5, t6]
459
438
  });
460
- $[15] = ctx.handleBlockMouseEnter;
461
- $[16] = ctx.handleBlockMouseLeave;
462
- $[17] = ctx.shouldShowActive;
463
- $[18] = ctx.shouldShowHover;
464
- $[19] = t6;
465
- $[20] = t7;
466
- $[21] = t8;
467
- $[22] = t9;
468
- } else t9 = $[22];
469
- return t9;
439
+ $[10] = ctx.handleBlockMouseEnter;
440
+ $[11] = ctx.handleBlockMouseLeave;
441
+ $[12] = ctx.shouldShowActive;
442
+ $[13] = ctx.shouldShowHover;
443
+ $[14] = t5;
444
+ $[15] = t6;
445
+ $[16] = t7;
446
+ } else t7 = $[16];
447
+ return t7;
470
448
  };
471
449
  /** A sidebar field labelled "Blocks", holding a page's blocks and what acts on them. */
472
450
  const BlocksGroup = (t0) => {
@@ -577,7 +555,7 @@ const CollapsedPageTree = (t0) => {
577
555
  };
578
556
  /** A page's blocks. When `collapsible`, they start collapsed behind a toggle showing their count. */
579
557
  const PageTree = (t0) => {
580
- const $ = c(48);
558
+ const $ = c(45);
581
559
  const { collapsible: t1 } = t0;
582
560
  const collapsible = t1 === void 0 ? false : t1;
583
561
  const page = usePreviewedPage();
@@ -784,40 +762,19 @@ const PageTree = (t0) => {
784
762
  $[41] = t17;
785
763
  } else t17 = $[41];
786
764
  const list = t17;
787
- let t18;
788
- if ($[42] === Symbol.for("react.memo_cache_sentinel")) {
789
- t18 = /* @__PURE__ */ jsxs(Button, {
790
- variant: "secondary",
791
- onClick: _temp4,
792
- children: [/* @__PURE__ */ jsx(Plus, {}), "Add block"]
793
- });
794
- $[42] = t18;
795
- } else t18 = $[42];
796
- const addBlockButton = t18;
797
- if (!collapsible) {
798
- let t19;
799
- if ($[43] !== list) {
800
- t19 = /* @__PURE__ */ jsxs(Fragment, { children: [list, addBlockButton] });
801
- $[43] = list;
802
- $[44] = t19;
803
- } else t19 = $[44];
804
- return t19;
805
- }
765
+ if (!collapsible) return list;
806
766
  const blockCount = layoutBeforeBlocks.length + pageBlocks.length + layoutAfterBlocks.length;
807
- let t19;
808
- if ($[45] !== blockCount || $[46] !== list) {
809
- t19 = /* @__PURE__ */ jsx(BlocksGroup, { children: /* @__PURE__ */ jsxs("div", {
810
- className: "flex flex-col gap-1",
811
- children: [/* @__PURE__ */ jsx(CollapsedPageTree, {
812
- blockCount,
813
- children: list
814
- }), addBlockButton]
767
+ let t18;
768
+ if ($[42] !== blockCount || $[43] !== list) {
769
+ t18 = /* @__PURE__ */ jsx(BlocksGroup, { children: /* @__PURE__ */ jsx(CollapsedPageTree, {
770
+ blockCount,
771
+ children: list
815
772
  }) });
816
- $[45] = blockCount;
817
- $[46] = list;
818
- $[47] = t19;
819
- } else t19 = $[47];
820
- return t19;
773
+ $[42] = blockCount;
774
+ $[43] = list;
775
+ $[44] = t18;
776
+ } else t18 = $[44];
777
+ return t18;
821
778
  };
822
779
  function _temp(value) {
823
780
  return !value;
@@ -828,9 +785,6 @@ function _temp2(block_2) {
828
785
  function _temp3(block_3) {
829
786
  return /* @__PURE__ */ jsx(SortableBlock, { block: block_3 }, block_3.id);
830
787
  }
831
- function _temp4() {
832
- previewStore.send({ type: "openAddBlockSheet" });
833
- }
834
788
 
835
789
  //#endregion
836
790
  export { BlocksGroup, CollapsedPageTree, LayoutBlockItem, PageTree };
@@ -6,13 +6,13 @@ import { useEditingFrameClaim, useEditingOwner } from "../editingFrame.js";
6
6
  import { EditableSurfaceContext } from "../../../core/hooks/useIsEditable.js";
7
7
  import { CanvasWorkspaceContext } from "../../canvas/canvasZoom.js";
8
8
  import { PreviewEditingOwnerContext } from "../previewSelection.js";
9
- import { Frame, useFrame } from "./Frame.js";
10
9
  import { previewPageIframeProps, usePreviewPageFrame } from "../previewPageFrame.js";
11
10
  import { adoptCanvasDocument, pauseCanvasDocument } from "../../canvas/canvasFrameDocument.js";
12
11
  import { forwardCanvasWheel, useCanvasFrameInput } from "../../canvas/useCanvasFrameInput.js";
13
12
  import { useActionShortcuts } from "../../provider/useAdminShortcuts.js";
14
13
  import { guardStrayCaret } from "../strayCaretGuard.js";
15
14
  import { useBlockActionsShortcuts } from "./BlockActionsPopover.js";
15
+ import { Frame, useFrame } from "./Frame.js";
16
16
  import { FieldOverlayStyles } from "./FieldOverlayStyles.js";
17
17
  import { MobilePreviewDrawer } from "./MobilePreviewDrawer.js";
18
18
  import { Overlays } from "./Overlays.js";
@@ -114,7 +114,7 @@ function CuratedBlockShortcuts() {
114
114
  * when used, pauses with the camera, and draws its editing overlays.
115
115
  */
116
116
  function PreviewPageCanvasEffects(t0) {
117
- const $ = c(31);
117
+ const $ = c(30);
118
118
  const { owner } = t0;
119
119
  const { window: frameWindow, iframeElement } = useFrame();
120
120
  const { frame, slot, inCanvas } = usePreviewPageFrame();
@@ -261,25 +261,22 @@ function PreviewPageCanvasEffects(t0) {
261
261
  t12 = $[25];
262
262
  t13 = $[26];
263
263
  }
264
- const t14 = owner?.kind === "page";
265
- let t15;
266
- if ($[27] !== iframeElement || $[28] !== owner || $[29] !== t14) {
267
- t15 = /* @__PURE__ */ jsxs(Fragment, { children: [
264
+ let t14;
265
+ if ($[27] !== iframeElement || $[28] !== owner) {
266
+ t14 = /* @__PURE__ */ jsxs(Fragment, { children: [
268
267
  t11,
269
268
  t12,
270
269
  t13,
271
270
  /* @__PURE__ */ jsx(Overlays, {
272
271
  frame: iframeElement,
273
- owner,
274
- canAddBlocks: t14
272
+ owner
275
273
  })
276
274
  ] });
277
275
  $[27] = iframeElement;
278
276
  $[28] = owner;
279
277
  $[29] = t14;
280
- $[30] = t15;
281
- } else t15 = $[30];
282
- return t15;
278
+ } else t14 = $[29];
279
+ return t14;
283
280
  }
284
281
  function _temp(event) {
285
282
  if (event.target?.closest?.("a")) event.preventDefault();
@@ -12,82 +12,71 @@ import { Combobox } from "@base-ui/react/combobox";
12
12
  * current search text so it can prefill a new record.
13
13
  */
14
14
  function RecordCombobox(t0) {
15
- const $ = c(25);
16
- const { records, collectionTitle, onSelect, emptyMessage: emptyMessageOverride, footerAction, disabled, open: controlledOpen, onOpenChange } = t0;
17
- const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
18
- const open = controlledOpen ?? uncontrolledOpen;
15
+ const $ = c(21);
16
+ const { records, collectionTitle, onSelect, emptyMessage: emptyMessageOverride, footerAction, disabled } = t0;
17
+ const [open, setOpen] = React.useState(false);
18
+ const [search, setSearch] = React.useState("");
19
+ const emptyMessage = records.length > 0 ? "No items found." : emptyMessageOverride ?? `${collectionTitle} has no items yet.`;
19
20
  let t1;
20
- if ($[0] !== onOpenChange) {
21
- t1 = (next) => {
22
- setUncontrolledOpen(next);
23
- onOpenChange?.(next);
21
+ if ($[0] !== onSelect) {
22
+ t1 = (record_2) => {
23
+ if (record_2) onSelect(record_2);
24
24
  };
25
- $[0] = onOpenChange;
25
+ $[0] = onSelect;
26
26
  $[1] = t1;
27
27
  } else t1 = $[1];
28
- const setOpen = t1;
29
- const [search, setSearch] = React.useState("");
30
- const emptyMessage = records.length > 0 ? "No items found." : emptyMessageOverride ?? `${collectionTitle} has no items yet.`;
31
28
  let t2;
32
- if ($[2] !== onSelect) {
33
- t2 = (record_2) => {
34
- if (record_2) onSelect(record_2);
35
- };
36
- $[2] = onSelect;
37
- $[3] = t2;
38
- } else t2 = $[3];
39
- let t3;
40
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
41
- t3 = /* @__PURE__ */ jsx(Button, {
29
+ if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
30
+ t2 = /* @__PURE__ */ jsx(Button, {
42
31
  type: "button",
43
32
  variant: "outline",
44
33
  className: "w-full justify-between"
45
34
  });
46
- $[4] = t3;
47
- } else t3 = $[4];
48
- let t4;
49
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
50
- t4 = /* @__PURE__ */ jsxs(Combobox.Trigger, {
51
- render: t3,
35
+ $[2] = t2;
36
+ } else t2 = $[2];
37
+ let t3;
38
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
39
+ t3 = /* @__PURE__ */ jsxs(Combobox.Trigger, {
40
+ render: t2,
52
41
  children: ["Select item", /* @__PURE__ */ jsx(ChevronsUpDown, {
53
42
  "aria-hidden": true,
54
43
  className: "text-muted-foreground size-4"
55
44
  })]
56
45
  });
57
- $[5] = t4;
58
- } else t4 = $[5];
59
- let t5;
60
- if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
61
- t5 = /* @__PURE__ */ jsx(Combobox.Input, {
46
+ $[3] = t3;
47
+ } else t3 = $[3];
48
+ let t4;
49
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
50
+ t4 = /* @__PURE__ */ jsx(Combobox.Input, {
62
51
  render: /* @__PURE__ */ jsx(Input, { className: "mb-1" }),
63
52
  "aria-label": "Search items",
64
53
  placeholder: "Search items…"
65
54
  });
66
- $[6] = t5;
67
- } else t5 = $[6];
68
- let t6;
69
- if ($[7] !== emptyMessage) {
70
- t6 = /* @__PURE__ */ jsx(Combobox.Empty, {
55
+ $[4] = t4;
56
+ } else t4 = $[4];
57
+ let t5;
58
+ if ($[5] !== emptyMessage) {
59
+ t5 = /* @__PURE__ */ jsx(Combobox.Empty, {
71
60
  className: "text-muted-foreground text-sm",
72
61
  children: /* @__PURE__ */ jsx("div", {
73
62
  className: "p-2",
74
63
  children: emptyMessage
75
64
  })
76
65
  });
77
- $[7] = emptyMessage;
78
- $[8] = t6;
79
- } else t6 = $[8];
80
- let t7;
81
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
82
- t7 = /* @__PURE__ */ jsx(Combobox.List, {
66
+ $[5] = emptyMessage;
67
+ $[6] = t5;
68
+ } else t5 = $[6];
69
+ let t6;
70
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
71
+ t6 = /* @__PURE__ */ jsx(Combobox.List, {
83
72
  className: "max-h-64 min-h-0 overflow-y-auto",
84
73
  children: _temp4
85
74
  });
86
- $[9] = t7;
87
- } else t7 = $[9];
88
- let t8;
89
- if ($[10] !== footerAction || $[11] !== search || $[12] !== setOpen) {
90
- t8 = footerAction && /* @__PURE__ */ jsx("div", {
75
+ $[7] = t6;
76
+ } else t6 = $[7];
77
+ let t7;
78
+ if ($[8] !== footerAction || $[9] !== search) {
79
+ t7 = footerAction && /* @__PURE__ */ jsx("div", {
91
80
  className: "mt-1 shrink-0 border-t pt-1",
92
81
  children: /* @__PURE__ */ jsxs("button", {
93
82
  type: "button",
@@ -102,34 +91,33 @@ function RecordCombobox(t0) {
102
91
  }), /* @__PURE__ */ jsx("span", { children: footerAction.label })]
103
92
  })
104
93
  });
105
- $[10] = footerAction;
106
- $[11] = search;
107
- $[12] = setOpen;
108
- $[13] = t8;
109
- } else t8 = $[13];
110
- let t9;
111
- if ($[14] !== t6 || $[15] !== t8) {
112
- t9 = /* @__PURE__ */ jsx(Combobox.Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, {
94
+ $[8] = footerAction;
95
+ $[9] = search;
96
+ $[10] = t7;
97
+ } else t7 = $[10];
98
+ let t8;
99
+ if ($[11] !== t5 || $[12] !== t7) {
100
+ t8 = /* @__PURE__ */ jsx(Combobox.Portal, { children: /* @__PURE__ */ jsx(Combobox.Positioner, {
113
101
  sideOffset: 4,
114
102
  align: "start",
115
103
  className: "isolate z-50",
116
104
  children: /* @__PURE__ */ jsxs(Combobox.Popup, {
117
105
  className: "bg-popover text-popover-foreground ring-foreground/10 flex max-h-(--available-height) w-(--anchor-width) min-w-48 flex-col rounded-md p-1 shadow-md ring-1",
118
106
  children: [
107
+ t4,
119
108
  t5,
120
109
  t6,
121
- t7,
122
- t8
110
+ t7
123
111
  ]
124
112
  })
125
113
  }) });
126
- $[14] = t6;
127
- $[15] = t8;
128
- $[16] = t9;
129
- } else t9 = $[16];
130
- let t10;
131
- if ($[17] !== disabled || $[18] !== open || $[19] !== records || $[20] !== search || $[21] !== setOpen || $[22] !== t2 || $[23] !== t9) {
132
- t10 = /* @__PURE__ */ jsxs(Combobox.Root, {
114
+ $[11] = t5;
115
+ $[12] = t7;
116
+ $[13] = t8;
117
+ } else t8 = $[13];
118
+ let t9;
119
+ if ($[14] !== disabled || $[15] !== open || $[16] !== records || $[17] !== search || $[18] !== t1 || $[19] !== t8) {
120
+ t9 = /* @__PURE__ */ jsxs(Combobox.Root, {
133
121
  items: records,
134
122
  value: null,
135
123
  open,
@@ -139,20 +127,19 @@ function RecordCombobox(t0) {
139
127
  itemToStringLabel: _temp,
140
128
  itemToStringValue: _temp2,
141
129
  isItemEqualToValue: _temp3,
142
- onValueChange: t2,
130
+ onValueChange: t1,
143
131
  disabled,
144
- children: [t4, t9]
132
+ children: [t3, t8]
145
133
  });
146
- $[17] = disabled;
147
- $[18] = open;
148
- $[19] = records;
149
- $[20] = search;
150
- $[21] = setOpen;
151
- $[22] = t2;
152
- $[23] = t9;
153
- $[24] = t10;
154
- } else t10 = $[24];
155
- return t10;
134
+ $[14] = disabled;
135
+ $[15] = open;
136
+ $[16] = records;
137
+ $[17] = search;
138
+ $[18] = t1;
139
+ $[19] = t8;
140
+ $[20] = t9;
141
+ } else t9 = $[20];
142
+ return t9;
156
143
  }
157
144
  function _temp4(record_3) {
158
145
  return /* @__PURE__ */ jsx(Combobox.Item, {
@@ -3,7 +3,6 @@ import { reads, useReadQuery } from "../../../lib/studio-reads.js";
3
3
  import { titleField } from "../../../core/recordItem.js";
4
4
  import { useCollectionItemSheet } from "../../content/CollectionItemSheetContext.js";
5
5
  import { useCollectionDefinition } from "../../../lib/studio-definitions.js";
6
- import { referencePickerFocus, useReferencePickerFocusRequested } from "../referencePickerFocus.js";
7
6
  import { DrillRow } from "./DrillRow.js";
8
7
  import { RecordCard } from "./RecordCard.js";
9
8
  import { RecordCombobox } from "./RecordCombobox.js";
@@ -18,7 +17,7 @@ function referenceHint({ linked, required }) {
18
17
  return !linked && required ? "Required" : null;
19
18
  }
20
19
  /** This view owns the reference only. Record content is edited elsewhere. */
21
- function ReferenceFieldEditor({ collectionId, fieldId, value, required = false, record = null, onChange, onOpenRecord, drill, allowCreate = true }) {
20
+ function ReferenceFieldEditor({ collectionId, value, required = false, record = null, onChange, onOpenRecord, drill, allowCreate = true }) {
22
21
  const projectUuid = useProjectUuid();
23
22
  const collection = useCollectionDefinition(collectionId);
24
23
  const collectionTitle = collection?.title ?? collectionId;
@@ -33,9 +32,6 @@ function ReferenceFieldEditor({ collectionId, fieldId, value, required = false,
33
32
  const selected = records.data?.find((option) => option.id === value);
34
33
  const hydrated = record?.id === selectedId ? record : null;
35
34
  const selectedLabel = selected?.title ?? hydrated?.title ?? "Unavailable item";
36
- const [pickerOpen, setPickerOpen] = React.useState(false);
37
- const focusRequested = useReferencePickerFocusRequested(drill ? void 0 : fieldId);
38
- const pickerReady = !selectedId && records.isSuccess && !saving;
39
35
  const save = async (id) => {
40
36
  setSaving(true);
41
37
  setError(null);
@@ -51,18 +47,6 @@ function ReferenceFieldEditor({ collectionId, fieldId, value, required = false,
51
47
  const change = (id) => {
52
48
  save(id).catch(() => {});
53
49
  };
54
- React.useEffect(() => {
55
- if (!focusRequested || !fieldId || !pickerReady) return;
56
- referencePickerFocus.send({
57
- type: "consume",
58
- fieldId
59
- });
60
- setPickerOpen(true);
61
- }, [
62
- focusRequested,
63
- fieldId,
64
- pickerReady
65
- ]);
66
50
  const hint = referenceHint({
67
51
  linked: selectedId !== null,
68
52
  required
@@ -108,8 +92,6 @@ function ReferenceFieldEditor({ collectionId, fieldId, value, required = false,
108
92
  collectionTitle,
109
93
  onSelect: (option) => change(option.id),
110
94
  disabled: saving || records.isPending || records.isError,
111
- open: pickerOpen,
112
- onOpenChange: setPickerOpen,
113
95
  footerAction: allowCreate ? {
114
96
  label: "Create item",
115
97
  onSelect: (search) => sheet.open({
@@ -5,7 +5,6 @@ import { referenceListIds } from "../../../core/lib/reference.js";
5
5
  import { titleField } from "../../../core/recordItem.js";
6
6
  import { useCollectionItemSheet } from "../../content/CollectionItemSheetContext.js";
7
7
  import { useCollectionDefinition } from "../../../lib/studio-definitions.js";
8
- import { referencePickerFocus, useReferencePickerFocusRequested } from "../referencePickerFocus.js";
9
8
  import { DrillRow } from "./DrillRow.js";
10
9
  import { RecordCard } from "./RecordCard.js";
11
10
  import { RecordCombobox } from "./RecordCombobox.js";
@@ -253,7 +252,7 @@ function SortableRecordCard(t0) {
253
252
  * Manages which records a reference list links, and their order. Every change writes the
254
253
  * whole id array; records themselves are edited in their own view, never unlinked by deletion.
255
254
  */
256
- function ReferenceListFieldEditor({ collectionId, fieldId, value, maxItems, query, records: hydratedRecords = [], onChange, onOpenRecord, recordHover, drill, allowCreate = true }) {
255
+ function ReferenceListFieldEditor({ collectionId, value, maxItems, query, records: hydratedRecords = [], onChange, onOpenRecord, recordHover, drill, allowCreate = true }) {
257
256
  const projectUuid = useProjectUuid();
258
257
  const collection = useCollectionDefinition(collectionId);
259
258
  const collectionTitle = collection?.title ?? collectionId;
@@ -267,22 +266,7 @@ function ReferenceListFieldEditor({ collectionId, fieldId, value, maxItems, quer
267
266
  const ids = pendingIds ?? storedIds;
268
267
  const [saving, setSaving] = React.useState(false);
269
268
  const [error, setError] = React.useState(null);
270
- const [pickerOpen, setPickerOpen] = React.useState(false);
271
- const focusRequested = useReferencePickerFocusRequested(drill ? void 0 : fieldId);
272
269
  const canAdd = maxItems === void 0 || ids.length < maxItems;
273
- const pickerReady = canAdd && records.isSuccess && !saving;
274
- React.useEffect(() => {
275
- if (!focusRequested || !fieldId || !pickerReady) return;
276
- referencePickerFocus.send({
277
- type: "consume",
278
- fieldId
279
- });
280
- setPickerOpen(true);
281
- }, [
282
- focusRequested,
283
- fieldId,
284
- pickerReady
285
- ]);
286
270
  const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
287
271
  if (drill && query) {
288
272
  const count = hydratedRecords.length;
@@ -399,8 +383,6 @@ function ReferenceListFieldEditor({ collectionId, fieldId, value, maxItems, quer
399
383
  emptyMessage: records.data?.length ? `Every ${collectionTitle} item is already linked.` : void 0,
400
384
  onSelect: (option) => change([...ids, option.id]),
401
385
  disabled: saving || records.isPending || records.isError,
402
- open: pickerOpen,
403
- onOpenChange: setPickerOpen,
404
386
  footerAction: allowCreate ? {
405
387
  label: "Create item",
406
388
  onSelect: (search) => sheet.open({
@@ -12,8 +12,8 @@ import { Trash2 } from "lucide-react";
12
12
  * mode it shows this placeholder, whose only action is delete. Its content stays stored and
13
13
  * comes back if the definition does.
14
14
  */
15
- function RemovedBlockPlaceholder({ blockId, type, mode }) {
16
- const isEditable = useIsEditable(mode);
15
+ function RemovedBlockPlaceholder({ blockId, type }) {
16
+ const isEditable = useIsEditable();
17
17
  const applyEdit = useApplyContentEdit();
18
18
  const notify = useStudioNotice();
19
19
  const [deleting, setDeleting] = React.useState(false);
@@ -22,6 +22,7 @@ import { useFieldWriter } from "./useFieldWriter.js";
22
22
  import { useRecordView } from "./useRecordView.js";
23
23
  import { c } from "react/compiler-runtime";
24
24
  import * as React from "react";
25
+ import { emptyFieldValue } from "@camox/api-contract";
25
26
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
26
27
  import { useSelector } from "@xstate/store-react";
27
28
  import { useMutation } from "@tanstack/react-query";
@@ -817,7 +818,7 @@ const SelectionEditorContent = (t0) => {
817
818
  const label = field.label ?? formatFieldName(field.name);
818
819
  const settingsValues = block.settings ?? {};
819
820
  if (field.fieldType === "Enum") {
820
- const value_2 = settingsValues[field.name] ?? (blockDef.settingsSchema?.properties?.[field.name])?.default ?? "";
821
+ const value_2 = String(settingsValues[field.name] ?? emptyFieldValue(blockDef.settingsSchema?.properties?.[field.name]));
821
822
  return /* @__PURE__ */ jsxs("div", {
822
823
  className: "space-y-2",
823
824
  children: [/* @__PURE__ */ jsx(Label, {
@@ -842,7 +843,7 @@ const SelectionEditorContent = (t0) => {
842
843
  }, field.name);
843
844
  }
844
845
  if (field.fieldType === "Boolean") {
845
- const checked = settingsValues[field.name] ?? (blockDef.settingsSchema?.properties?.[field.name])?.default ?? false;
846
+ const checked = settingsValues[field.name] === true;
846
847
  return /* @__PURE__ */ jsxs("div", {
847
848
  className: "flex items-center justify-between",
848
849
  children: [/* @__PURE__ */ jsx(Label, {
@@ -871,7 +872,7 @@ const SelectionEditorContent = (t0) => {
871
872
  const itemSettingsValues = currentItem?.settings ?? {};
872
873
  const itemSettingsSchemaProps = itemArraySchema?.itemSettingsSchema?.properties;
873
874
  if (field_0.fieldType === "Enum") {
874
- const value_3 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? "";
875
+ const value_3 = String(itemSettingsValues[field_0.name] ?? emptyFieldValue(itemSettingsSchemaProps?.[field_0.name]));
875
876
  return /* @__PURE__ */ jsxs("div", {
876
877
  className: "space-y-2",
877
878
  children: [/* @__PURE__ */ jsx(Label, {
@@ -896,7 +897,7 @@ const SelectionEditorContent = (t0) => {
896
897
  }, field_0.name);
897
898
  }
898
899
  if (field_0.fieldType === "Boolean") {
899
- const checked_0 = itemSettingsValues[field_0.name] ?? itemSettingsSchemaProps?.[field_0.name]?.default ?? false;
900
+ const checked_0 = itemSettingsValues[field_0.name] === true;
900
901
  return /* @__PURE__ */ jsxs("div", {
901
902
  className: "flex items-center justify-between",
902
903
  children: [/* @__PURE__ */ jsx(Label, {