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.
- package/dist/core/createApp.d.ts +4 -103
- package/dist/core/createApp.js +3 -24
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +55 -192
- package/dist/core/createLayout.d.ts +6 -77
- package/dist/core/createLayout.js +12 -50
- package/dist/core/editing/createEditableBlock.d.ts +9 -75
- package/dist/core/editing/createEditableBlock.js +258 -640
- package/dist/core/hooks/useArtifactHost.js +56 -46
- package/dist/core/hooks/useIsEditable.js +2 -2
- package/dist/core/lib/artifact.d.ts +4 -0
- package/dist/core/lib/artifactData.js +8 -3
- package/dist/core/lib/artifactHost.js +40 -0
- package/dist/core/lib/artifactRuntime.js +20 -1
- package/dist/core/lib/contentType.d.ts +23 -38
- package/dist/core/lib/contentType.js +34 -62
- package/dist/core/lib/iconTypes.d.ts +0 -3
- package/dist/core/lib/icons.js +63 -51
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CanvasOverlays.js +94 -176
- package/dist/features/canvas/CanvasPageFrame.js +62 -68
- package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
- package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
- package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
- package/dist/features/canvas/useCanvasCamera.js +1 -1
- package/dist/features/canvas/useCanvasFrame.js +1 -1
- package/dist/features/content/ContentCollection.js +2 -2
- package/dist/features/content/collection-form.js +6 -7
- package/dist/features/page/CuratedPageContent.js +15 -24
- package/dist/features/page/UnplacedBlockContent.js +1 -6
- package/dist/features/preview/CamoxPreview.js +30 -33
- package/dist/features/preview/EditablePageContent.js +131 -151
- package/dist/features/preview/components/BlockActionsPopover.js +43 -152
- package/dist/features/preview/components/CanvasPreview.js +2 -2
- package/dist/features/preview/components/Frame.js +3 -3
- package/dist/features/preview/components/IconFieldEditor.js +1 -1
- package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
- package/dist/features/preview/components/Overlays.js +18 -84
- package/dist/features/preview/components/PageTree.js +57 -103
- package/dist/features/preview/components/PreviewPanel.js +8 -11
- package/dist/features/preview/components/RecordCombobox.js +65 -78
- package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
- package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
- package/dist/features/preview/components/SelectionEditor.js +5 -4
- package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
- package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
- package/dist/features/preview/overlayMessages.js +1 -4
- package/dist/features/preview/previewStore.js +3 -23
- package/dist/features/renderer/RendererApp.js +17 -141
- package/dist/features/renderer/definitionAnswers.js +1 -8
- package/dist/features/renderer/rendererHost.js +1 -31
- package/dist/features/renderer/studioConnection.js +1 -25
- package/dist/features/runtime/pageApp.js +8 -4
- package/dist/features/runtime/runtime.js +3 -3
- package/dist/features/studio/agentRunToast.js +71 -0
- package/dist/features/studio/components/ChatWidget.js +2 -0
- package/dist/features/studio/components/DraftBar.js +2 -3
- package/dist/features/studio/components/DraftsControl.js +150 -176
- package/dist/features/studio/components/ReviewDraftSheet.js +344 -548
- package/dist/features/studio/components/ThreadMessages.js +89 -22
- package/dist/features/studio/draftLabel.js +1 -1
- package/dist/features/studio/studioStore.js +5 -17
- package/dist/features/studio/viewSwitch.js +2 -4
- package/dist/features/vite/blockBoilerplate.js +1 -1
- package/dist/features/vite/definitionsSync.js +1 -8
- package/dist/lib/queries.js +0 -1
- package/dist/lib/studio-definitions.js +0 -2
- package/dist/lib/studio-reads.js +0 -5
- package/dist/lib/use-thread.js +196 -138
- package/dist/package.js +1 -1
- package/dist/studio-overlays.css +0 -29
- package/dist/studio.css +1 -1
- package/package.json +6 -4
- package/skills/camox/SKILL.md +1 -1
- package/skills/camox/references/artifacts.md +89 -5
- package/skills/camox/references/block-definitions.md +21 -25
- package/skills/camox/references/dom-integrations.md +1 -1
- package/skills/camox/references/layout-definitions.md +3 -12
- package/skills/camox/references/routed-layouts.md +2 -2
- package/skills/camox-expand/SKILL.md +5 -5
- package/skills/camoxify/SKILL.md +4 -4
- package/dist/features/canvas/canvasInsertionSeams.js +0 -44
- package/dist/features/preview/components/AddBlockSheet.js +0 -314
- package/dist/features/preview/components/BlockPeek.js +0 -66
- package/dist/features/preview/components/BlockThumbnail.js +0 -281
- package/dist/features/preview/components/blockGridNavigation.js +0 -15
- 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 {
|
|
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
|
|
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(
|
|
379
|
-
const { block, layoutName
|
|
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
|
|
383
|
+
let t1;
|
|
385
384
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
386
|
-
|
|
387
|
-
$[0] =
|
|
388
|
-
} else
|
|
389
|
-
let
|
|
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
|
-
|
|
390
|
+
t2 = /* @__PURE__ */ jsx("span", {
|
|
392
391
|
className: "font-semibold",
|
|
393
392
|
children: layoutName
|
|
394
393
|
});
|
|
395
394
|
$[1] = layoutName;
|
|
396
|
-
$[2] =
|
|
397
|
-
} else
|
|
398
|
-
let
|
|
395
|
+
$[2] = t2;
|
|
396
|
+
} else t2 = $[2];
|
|
397
|
+
let t3;
|
|
399
398
|
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
400
|
-
|
|
401
|
-
$[3] =
|
|
402
|
-
} else
|
|
403
|
-
const
|
|
404
|
-
let
|
|
405
|
-
if ($[4] !==
|
|
406
|
-
|
|
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: [
|
|
407
|
+
children: /* @__PURE__ */ jsxs(Tooltip, { children: [t1, /* @__PURE__ */ jsxs(TooltipContent, { children: [
|
|
409
408
|
"From ",
|
|
410
|
-
|
|
409
|
+
t2,
|
|
411
410
|
" layout.",
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
t3,
|
|
412
|
+
t4
|
|
414
413
|
] })] })
|
|
415
414
|
});
|
|
416
|
-
$[4] =
|
|
417
|
-
$[5] =
|
|
418
|
-
$[6] =
|
|
419
|
-
} else
|
|
420
|
-
let
|
|
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
|
-
|
|
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] =
|
|
429
|
-
} else
|
|
430
|
-
let
|
|
431
|
-
if ($[10] !==
|
|
432
|
-
|
|
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
|
-
$[
|
|
461
|
-
$[
|
|
462
|
-
$[
|
|
463
|
-
$[
|
|
464
|
-
$[
|
|
465
|
-
$[
|
|
466
|
-
$[
|
|
467
|
-
|
|
468
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
808
|
-
if ($[
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
children:
|
|
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
|
-
$[
|
|
817
|
-
$[
|
|
818
|
-
$[
|
|
819
|
-
} else
|
|
820
|
-
return
|
|
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(
|
|
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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
281
|
-
|
|
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(
|
|
16
|
-
const { records, collectionTitle, onSelect, emptyMessage: emptyMessageOverride, footerAction, disabled
|
|
17
|
-
const [
|
|
18
|
-
const
|
|
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] !==
|
|
21
|
-
t1 = (
|
|
22
|
-
|
|
23
|
-
onOpenChange?.(next);
|
|
21
|
+
if ($[0] !== onSelect) {
|
|
22
|
+
t1 = (record_2) => {
|
|
23
|
+
if (record_2) onSelect(record_2);
|
|
24
24
|
};
|
|
25
|
-
$[0] =
|
|
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]
|
|
33
|
-
t2 = (
|
|
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
|
-
$[
|
|
47
|
-
} else
|
|
48
|
-
let
|
|
49
|
-
if ($[
|
|
50
|
-
|
|
51
|
-
render:
|
|
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
|
-
$[
|
|
58
|
-
} else
|
|
59
|
-
let
|
|
60
|
-
if ($[
|
|
61
|
-
|
|
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
|
-
$[
|
|
67
|
-
} else
|
|
68
|
-
let
|
|
69
|
-
if ($[
|
|
70
|
-
|
|
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
|
-
$[
|
|
78
|
-
$[
|
|
79
|
-
} else
|
|
80
|
-
let
|
|
81
|
-
if ($[
|
|
82
|
-
|
|
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
|
-
$[
|
|
87
|
-
} else
|
|
88
|
-
let
|
|
89
|
-
if ($[
|
|
90
|
-
|
|
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
|
-
$[
|
|
106
|
-
$[
|
|
107
|
-
$[
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
$[
|
|
127
|
-
$[
|
|
128
|
-
$[
|
|
129
|
-
} else
|
|
130
|
-
let
|
|
131
|
-
if ($[
|
|
132
|
-
|
|
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:
|
|
130
|
+
onValueChange: t1,
|
|
143
131
|
disabled,
|
|
144
|
-
children: [
|
|
132
|
+
children: [t3, t8]
|
|
145
133
|
});
|
|
146
|
-
$[
|
|
147
|
-
$[
|
|
148
|
-
$[
|
|
149
|
-
$[
|
|
150
|
-
$[
|
|
151
|
-
$[
|
|
152
|
-
$[
|
|
153
|
-
|
|
154
|
-
|
|
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,
|
|
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,
|
|
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
|
|
16
|
-
const isEditable = useIsEditable(
|
|
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])
|
|
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]
|
|
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]
|
|
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]
|
|
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, {
|