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
@@ -8,7 +8,7 @@ import { Collection } from "./createCollection.js";
8
8
  import { IconValue } from "./lib/iconTypes.js";
9
9
  import { ArtifactSource, EmbedURL, FileValue, ImageValue, LinkValue } from "./lib/contentType.js";
10
10
  import { LayoutItemProps } from "./editing/BlockEditingRuntime.js";
11
- import { BlockComponentProps, PeekItem, RepeatableItemSeed } from "./editing/createEditableBlock.js";
11
+ import { BlockComponentProps } from "./editing/createEditableBlock.js";
12
12
  import { Block } from "./createBlock.js";
13
13
  //#region src/core/createApp.d.ts
14
14
  interface CreateAppOptions {
@@ -413,7 +413,7 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
413
413
  }) => React.ReactNode;
414
414
  useSetting: <K extends string>(name: K) => unknown;
415
415
  _internal: {
416
- Component: ({ blockData, mode, isFirstBlock, showAddBlockTop, showAddBlockBottom, addBlockAfterPosition }: BlockComponentProps<{
416
+ Component: ({ blockData }: BlockComponentProps<{
417
417
  [x: string]: unknown;
418
418
  }>) => import("react").JSX.Element;
419
419
  LayoutItem: ({ collectionId, collection, properties, record, children, fallback }: LayoutItemProps) => string | number | bigint | boolean | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | Iterable<import("react").ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
@@ -437,37 +437,6 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
437
437
  } | undefined;
438
438
  layoutOnly: boolean;
439
439
  synced: boolean;
440
- getInitialBundle: () => {
441
- content: Record<string, unknown>;
442
- settings: {
443
- [x: string]: unknown;
444
- };
445
- repeatableItems: RepeatableItemSeed[];
446
- };
447
- getInitialContent: () => {
448
- [x: string]: unknown;
449
- };
450
- getInitialSettings: () => {
451
- [x: string]: unknown;
452
- };
453
- getPeekBundle: () => {
454
- block: {
455
- id: string;
456
- pageId: null;
457
- layoutId: null;
458
- type: string;
459
- content: Record<string, unknown>;
460
- settings: Record<string, unknown>;
461
- slot: null;
462
- summary: string;
463
- title: string;
464
- position: string;
465
- createdAt: number;
466
- updatedAt: number;
467
- };
468
- repeatableItems: PeekItem[];
469
- files: never[];
470
- };
471
440
  };
472
441
  }[];
473
442
  /** A loaded block. Call `loadBlock` first for a block that may be lazy. */
@@ -855,7 +824,7 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
855
824
  }) => React.ReactNode;
856
825
  useSetting: <K extends string>(name: K) => unknown;
857
826
  _internal: {
858
- Component: ({ blockData, mode, isFirstBlock, showAddBlockTop, showAddBlockBottom, addBlockAfterPosition }: BlockComponentProps<{
827
+ Component: ({ blockData }: BlockComponentProps<{
859
828
  [x: string]: unknown;
860
829
  }>) => import("react").JSX.Element;
861
830
  LayoutItem: ({ collectionId, collection, properties, record, children, fallback }: LayoutItemProps) => string | number | bigint | boolean | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | Iterable<import("react").ReactNode> | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | import("react").ReactPortal | null | undefined> | null | undefined;
@@ -879,37 +848,6 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
879
848
  } | undefined;
880
849
  layoutOnly: boolean;
881
850
  synced: boolean;
882
- getInitialBundle: () => {
883
- content: Record<string, unknown>;
884
- settings: {
885
- [x: string]: unknown;
886
- };
887
- repeatableItems: RepeatableItemSeed[];
888
- };
889
- getInitialContent: () => {
890
- [x: string]: unknown;
891
- };
892
- getInitialSettings: () => {
893
- [x: string]: unknown;
894
- };
895
- getPeekBundle: () => {
896
- block: {
897
- id: string;
898
- pageId: null;
899
- layoutId: null;
900
- type: string;
901
- content: Record<string, unknown>;
902
- settings: Record<string, unknown>;
903
- slot: null;
904
- summary: string;
905
- title: string;
906
- position: string;
907
- createdAt: number;
908
- updatedAt: number;
909
- };
910
- repeatableItems: PeekItem[];
911
- files: never[];
912
- };
913
851
  };
914
852
  } | undefined;
915
853
  loadBlock: (id: string) => Promise<Block | undefined>;
@@ -945,12 +883,6 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
945
883
  properties: Record<string, import("@sinclair/typebox").TSchema>;
946
884
  required: string[];
947
885
  } | undefined;
948
- defaultContent: {
949
- [x: string]: unknown;
950
- };
951
- defaultSettings: {
952
- [x: string]: unknown;
953
- };
954
886
  layoutOnly: true | undefined;
955
887
  synced: boolean;
956
888
  }[];
@@ -961,27 +893,9 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
961
893
  description: string;
962
894
  blocks: ({
963
895
  type: string;
964
- content: Record<string, unknown>;
965
- settings: Record<string, unknown>;
966
- repeatableItems: {
967
- tempId: string;
968
- parentTempId: string | null;
969
- fieldName: string;
970
- content: Record<string, unknown>;
971
- position: string;
972
- }[];
973
896
  slot: "before";
974
897
  } | {
975
898
  type: string;
976
- content: Record<string, unknown>;
977
- settings: Record<string, unknown>;
978
- repeatableItems: {
979
- tempId: string;
980
- parentTempId: string | null;
981
- fieldName: string;
982
- content: Record<string, unknown>;
983
- position: string;
984
- }[];
985
899
  slot: "after";
986
900
  })[];
987
901
  recordPages?: {
@@ -1000,24 +914,11 @@ export declare function createApp({ blocks, lazyBlocks, layouts, collections, do
1000
914
  }[];
1001
915
  homepage: {
1002
916
  layoutId: string;
1003
- blocks: {
1004
- type: string;
1005
- content: Record<string, unknown>;
1006
- settings: Record<string, unknown>;
1007
- repeatableItems: {
1008
- tempId: string;
1009
- parentTempId: string | null;
1010
- fieldName: string;
1011
- content: Record<string, unknown>;
1012
- position: string;
1013
- }[];
1014
- }[];
1015
- hasInitialBlocks: boolean;
1016
917
  } | null;
1017
918
  }>;
1018
919
  };
1019
920
  export type CamoxApp = ReturnType<typeof createApp>;
1020
- /** All of a website's definitions taken together, with the content they declare. */
921
+ /** All of a website's definitions taken together. */
1021
922
  export type DefinitionSet = Awaited<ReturnType<CamoxApp["getDefinitionSet"]>>;
1022
923
  //#endregion
1023
924
  export {};
@@ -65,28 +65,9 @@ function createApp({ blocks, lazyBlocks = {}, layouts = [], collections = [], do
65
65
  }
66
66
  layoutsMap.set(id, layout);
67
67
  }
68
- const layoutsWithInitialBlocks = layouts.filter((l) => l._internal.loadInitialBlockBundles);
69
- if (layoutsWithInitialBlocks.length > 1) {
70
- const ids = layoutsWithInitialBlocks.map((l) => `"${l._internal.id}"`).join(", ");
71
- throw new Error(`[camox] Only one layout can define blocks.initial, but found ${layoutsWithInitialBlocks.length}: ${ids}`);
72
- }
73
68
  const fontLinks = artifactFontLinks(document);
74
- /** Loads the initial blocks' modules: only syncing needs them, never a page. */
75
- const getHomepage = async () => {
76
- const layout = layoutsWithInitialBlocks[0];
77
- if (layout) return {
78
- layoutId: layout._internal.id,
79
- blocks: await layout._internal.loadInitialBlockBundles(),
80
- hasInitialBlocks: true
81
- };
82
- const fallback = layouts.find((layout) => layout._internal.kind === "curated");
83
- if (!fallback) return null;
84
- return {
85
- layoutId: fallback._internal.id,
86
- blocks: [],
87
- hasInitialBlocks: false
88
- };
89
- };
69
+ /** The homepage the API creates when the website has none: the first curated layout's. */
70
+ const homepageLayout = layouts.find((layout) => layout._internal.kind === "curated");
90
71
  return {
91
72
  /** The document's font links as HTML, for artifacts to load before their source. */
92
73
  getArtifactFontLinks() {
@@ -148,8 +129,6 @@ function createApp({ blocks, lazyBlocks = {}, layouts = [], collections = [], do
148
129
  description: _internal.description,
149
130
  contentSchema: _internal.contentSchema,
150
131
  settingsSchema: _internal.settingsSchema,
151
- defaultContent: _internal.getInitialContent(),
152
- defaultSettings: _internal.getInitialSettings(),
153
132
  layoutOnly: _internal.layoutOnly || void 0,
154
133
  synced: _internal.synced
155
134
  })),
@@ -163,7 +142,7 @@ function createApp({ blocks, lazyBlocks = {}, layouts = [], collections = [], do
163
142
  ..._internal.toStructuredData && { toStructuredData: _internal.toStructuredData },
164
143
  contentSchema: JSON.parse(JSON.stringify(_internal.contentSchema))
165
144
  })),
166
- homepage: await getHomepage()
145
+ homepage: homepageLayout ? { layoutId: homepageLayout._internal.id } : null
167
146
  };
168
147
  }
169
148
  };
@@ -1,9 +1,9 @@
1
1
  import { InlineStyle, InlineTextStyles, TextLinkStyleData, TextStyleData } from "./lib/textStyles.js";
2
2
  import "./lib/lexicalReact.js";
3
3
  import { ContentFieldBuilder, SettingBuilder } from "./lib/contentType.js";
4
- import { BlockComponentProps, PeekItem, RepeatableItemSeed, createEditableBlock } from "./editing/createEditableBlock.js";
4
+ import { BlockComponentProps, createEditableBlock } from "./editing/createEditableBlock.js";
5
5
  //#region src/core/createBlock.d.ts
6
6
  export declare const createBlock: typeof createEditableBlock;
7
7
  export type Block = ReturnType<typeof createBlock>;
8
8
  //#endregion
9
- export type { BlockComponentProps, ContentFieldBuilder, InlineStyle, InlineTextStyles, PeekItem, RepeatableItemSeed, SettingBuilder, TextLinkStyleData, TextStyleData };
9
+ export type { BlockComponentProps, ContentFieldBuilder, InlineStyle, InlineTextStyles, SettingBuilder, TextLinkStyleData, TextStyleData };
@@ -1,13 +1,13 @@
1
1
  import { artifactFrameProps, artifactStandInProps, isArtifactSource, isArtifactSourceReference } from "./lib/artifact.js";
2
2
  import { artifactData } from "./lib/artifactData.js";
3
- import { resolveBlockFields, resolveToMarkdown, resolveToStructuredData, resolveToTitle } from "./lib/contentType.js";
3
+ import { placeholderImage, resolveBlockFields, resolveToMarkdown, resolveToStructuredData, resolveToTitle } from "./lib/contentType.js";
4
4
  import { useLocation, useNavigate } from "../features/navigation/navigation.js";
5
5
  import { useOptionalCamoxApp } from "../features/provider/components/CamoxAppContext.js";
6
6
  import { useProjectUuid } from "../lib/auth.js";
7
7
  import { isItemMarker, queryResultIds, resolveAssetValue, useNormalizedData } from "../lib/normalized-data.js";
8
8
  import { useLinkPages } from "../lib/link-pages.js";
9
9
  import { useBlockEditingRuntime } from "./editing/BlockEditingRuntime.js";
10
- import { ArtifactStudioContext, ArtifactsRunContext, useArtifactHost, useInitialArtifactData } from "./hooks/useArtifactHost.js";
10
+ import { ArtifactCaptureContext, ArtifactStudioContext, ArtifactsRunContext, useArtifactHost, useInitialArtifactData } from "./hooks/useArtifactHost.js";
11
11
  import { IconSvg } from "./lib/icons.js";
12
12
  import { renderImagePlaceholder } from "./lib/imagePlaceholder.js";
13
13
  import { buildImageSrcSet, getDefaultImageSizes, getDefaultImageWidth, transformImageUrl } from "./lib/imageTransform.js";
@@ -15,9 +15,9 @@ import { markdownToReactNodes } from "./lib/lexicalReact.js";
15
15
  import { resolveReference, resolveReferenceList } from "./lib/reference.js";
16
16
  import { c } from "react/compiler-runtime";
17
17
  import * as React from "react";
18
- import { isQueryBacked } from "@camox/api-contract";
18
+ import { emptyFieldValues, isQueryBacked } from "@camox/api-contract";
19
19
  import { Type } from "@sinclair/typebox";
20
- import { generateKeyBetween } from "fractional-indexing";
20
+ import { ARTIFACT_FIELD_ATTRIBUTE, ARTIFACT_ITEM_ATTRIBUTE } from "@camox/api-contract/drafts";
21
21
  import { jsx } from "react/jsx-runtime";
22
22
 
23
23
  //#region src/core/createBlock.tsx
@@ -37,98 +37,12 @@ function resolveLinkHref(link, pages, pathname) {
37
37
  if (!link.href || link.href.startsWith("#")) return `${pathname}${link.href ?? ""}`;
38
38
  return link.href;
39
39
  }
40
- function collectDefaults(properties) {
41
- const defaults = {};
42
- for (const [key, property] of Object.entries(properties)) if ("default" in property) defaults[key] = property.default;
43
- return defaults;
44
- }
45
- function buildInitialItems(properties, parentTempId, content, items, counter) {
46
- for (const [fieldName, property] of Object.entries(properties)) {
47
- if (property.type !== "array" || !property.items?.properties) continue;
48
- if (property.fieldType === "ImageList" || property.fieldType === "FileList") continue;
49
- const markers = [];
50
- const defaultCount = Number(property.defaultItems ?? property.minItems ?? 0);
51
- let previousPosition = null;
52
- for (let index = 0; index < defaultCount; index += 1) {
53
- const tempId = `seed_${++counter.value}`;
54
- const itemContent = {};
55
- for (const [key, itemProperty] of Object.entries(property.items.properties)) {
56
- if (itemProperty.type === "array" && itemProperty.items?.properties) continue;
57
- if ("default" in itemProperty) itemContent[key] = itemProperty.default;
58
- }
59
- const position = generateKeyBetween(previousPosition, null);
60
- previousPosition = position;
61
- items.push({
62
- tempId,
63
- parentTempId,
64
- fieldName,
65
- content: { ...itemContent },
66
- ...property.defaultItemSettings && { settings: { ...property.defaultItemSettings } },
67
- position
68
- });
69
- buildInitialItems(property.items?.properties ?? {}, tempId, {}, items, counter);
70
- markers.push({ _itemId: tempId });
71
- }
72
- content[fieldName] = markers;
73
- }
74
- }
75
- function buildPeekItems(properties, blockId, parentItemId, content, items, counter) {
76
- for (const [fieldName, property] of Object.entries(properties)) {
77
- if (property.type !== "array" || !property.items?.properties) continue;
78
- if (property.fieldType === "ImageList" || property.fieldType === "FileList") continue;
79
- const defaultCount = Number(property.defaultItems ?? property.minItems ?? 0);
80
- const markers = [];
81
- let previousPosition = null;
82
- for (let index = 0; index < defaultCount; index += 1) {
83
- const id = `peek_${++counter.value}`;
84
- const itemContent = {};
85
- for (const [key, itemProperty] of Object.entries(property.items.properties)) {
86
- if (itemProperty.type === "array" && itemProperty.items?.properties) continue;
87
- if ("default" in itemProperty) itemContent[key] = itemProperty.default;
88
- }
89
- const position = generateKeyBetween(previousPosition, null);
90
- previousPosition = position;
91
- items.push({
92
- id,
93
- blockId,
94
- parentItemId,
95
- fieldName,
96
- content: itemContent,
97
- settings: property.defaultItemSettings ? { ...property.defaultItemSettings } : null,
98
- summary: "",
99
- title: "",
100
- position,
101
- createdAt: 0,
102
- updatedAt: 0,
103
- projectId: null,
104
- sharedContentType: null,
105
- references: {}
106
- });
107
- markers.push({ _itemId: id });
108
- const nestedContent = {};
109
- buildPeekItems(property.items.properties, blockId, id, nestedContent, items, counter);
110
- const item = items.find((candidate) => candidate.id === id);
111
- if (item) item.content = {
112
- ...item.content,
113
- ...nestedContent
114
- };
115
- }
116
- content[fieldName] = markers;
117
- }
118
- }
119
40
  function createViewBlock(options) {
120
41
  const fields = resolveBlockFields(options);
121
42
  const typeboxSchema = Type.Object(fields.content);
122
43
  const settingsTypeboxSchema = fields.settings ? Type.Object(fields.settings) : null;
123
- const contentDefaults = collectDefaults(typeboxSchema.properties);
124
- const settingsDefaults = settingsTypeboxSchema ? collectDefaults(settingsTypeboxSchema.properties) : {};
125
- const repeatableDefaults = {};
126
- const repeatableSettingsDefaults = {};
127
- for (const [key, property] of Object.entries(typeboxSchema.properties)) {
128
- if (property.fieldType !== "Repeater") continue;
129
- repeatableDefaults[key] = collectDefaults(property.items?.properties ?? {});
130
- repeatableSettingsDefaults[key] = { ...property.defaultItemSettings };
131
- }
44
+ const emptyContent = emptyFieldValues(typeboxSchema);
45
+ const emptySettings = emptyFieldValues(settingsTypeboxSchema);
132
46
  const Context = React.createContext(null);
133
47
  const RepeaterContext = React.createContext(null);
134
48
  function useValue(name) {
@@ -184,12 +98,18 @@ function createViewBlock(options) {
184
98
  });
185
99
  const value = useValue(name);
186
100
  const data = useArtifactData(name);
187
- const hostProps = useArtifactHost({
188
- studio: React.use(ArtifactStudioContext),
189
- data,
190
- size: useFieldSchema(name)?.size,
191
- navigate: useNavigate()
192
- });
101
+ const item = React.use(RepeaterContext);
102
+ const hostProps = {
103
+ ...useArtifactHost({
104
+ studio: React.use(ArtifactStudioContext),
105
+ data,
106
+ size: useFieldSchema(name)?.size,
107
+ navigate: useNavigate(),
108
+ capture: React.use(ArtifactCaptureContext)
109
+ }),
110
+ [ARTIFACT_FIELD_ATTRIBUTE]: name,
111
+ ...item?.itemId ? { [ARTIFACT_ITEM_ATTRIBUTE]: item.itemId } : {}
112
+ };
193
113
  const initialData = useInitialArtifactData(isArtifactSourceReference(value) ? value.artifactUrl : value, data);
194
114
  const fontLinks = useOptionalCamoxApp()?.getArtifactFontLinks();
195
115
  const runs = React.use(ArtifactsRunContext);
@@ -294,8 +214,7 @@ function createViewBlock(options) {
294
214
  $[2] = t0;
295
215
  } else t0 = $[2];
296
216
  const resolved = t0;
297
- const fallback = item ? repeatableDefaults[item.arrayFieldName]?.[String(name)] : contentDefaults[String(name)];
298
- return resolved ?? fallback;
217
+ return resolved?.url ? resolved : null;
299
218
  }
300
219
  const Image = ({ name, children }) => {
301
220
  const editingRuntime = useBlockEditingRuntime();
@@ -303,7 +222,8 @@ function createViewBlock(options) {
303
222
  name,
304
223
  children
305
224
  });
306
- const value = useAsset(name);
225
+ const title = useFieldSchema(name)?.title;
226
+ const value = useAsset(name) ?? placeholderImage(title);
307
227
  return renderImagePlaceholder(value, children({
308
228
  src: transformImageUrl(value.url, {
309
229
  width: getDefaultImageWidth(),
@@ -322,6 +242,7 @@ function createViewBlock(options) {
322
242
  children
323
243
  });
324
244
  const value = useAsset(name);
245
+ if (!value) return null;
325
246
  return children({
326
247
  href: value.url,
327
248
  download: value.filename
@@ -506,12 +427,10 @@ function createViewBlock(options) {
506
427
  const { filesMap } = useNormalizedData();
507
428
  if (!block) throw new Error("ImageList/FileList must be used within a Block Component");
508
429
  const fieldName = String(name);
509
- const schema = parent ? typeboxSchema.properties[parent.arrayFieldName]?.items?.properties?.[fieldName] : (block.sourceSchema ?? typeboxSchema.properties)[fieldName];
510
- const fieldType = schema?.fieldType;
430
+ const fieldType = (parent ? typeboxSchema.properties[parent.arrayFieldName]?.items?.properties?.[fieldName] : (block.sourceSchema ?? typeboxSchema.properties)[fieldName])?.fieldType;
511
431
  if (fieldType !== "ImageList" && fieldType !== "FileList") throw new Error(`"${fieldName}" is not an imageList or fileList field`);
512
432
  const source = parent ? parent.itemContent[fieldName] : block.content[fieldName];
513
- let values = Array.isArray(source) ? source : [];
514
- if (values.length === 0 && schema.defaultItems > 0 && schema.items?.default) values = Array.from({ length: schema.defaultItems }, () => schema.items.default);
433
+ const values = Array.isArray(source) ? source : [];
515
434
  const Single = fieldType === "ImageList" ? Image : File;
516
435
  return values.map((value) => resolveAssetValue(value, filesMap)).filter(Boolean).map((value, index) => /* @__PURE__ */ jsx(RepeaterContext.Provider, {
517
436
  value: {
@@ -565,15 +484,18 @@ function createViewBlock(options) {
565
484
  const fieldName = String(name);
566
485
  const source = parent ? parent.itemContent[fieldName] : block.content[fieldName];
567
486
  if (!Array.isArray(source)) throw new Error(`Field "${fieldName}" is not an array`);
568
- const itemSchema = (parent ? parent.itemSchema?.[fieldName] : typeboxSchema.properties[fieldName])?.items?.properties;
487
+ const fieldSchema = parent ? parent.itemSchema?.[fieldName] : typeboxSchema.properties[fieldName];
488
+ const itemSchema = fieldSchema?.items?.properties;
489
+ const emptyItem = emptyFieldValues(fieldSchema?.items);
490
+ const emptyItemSettings = emptyFieldValues(fieldSchema?.itemSettingsSchema);
569
491
  return source.map((item) => isItemMarker(item) ? itemsMap.get(item._itemId) ?? null : item).filter(Boolean).map((item, index) => {
570
492
  const databaseItem = item.content !== void 0 && item.id != null;
571
493
  const itemContent = {
572
- ...repeatableDefaults[fieldName],
494
+ ...emptyItem,
573
495
  ...databaseItem ? item.content : item
574
496
  };
575
497
  const itemSettings = {
576
- ...repeatableSettingsDefaults[fieldName],
498
+ ...emptyItemSettings,
577
499
  ...databaseItem ? item.settings : null
578
500
  };
579
501
  const itemId = databaseItem ? item.id : void 0;
@@ -641,7 +563,7 @@ function createViewBlock(options) {
641
563
  return t1;
642
564
  };
643
565
  const Component = (props) => {
644
- const $ = c(23);
566
+ const $ = c(22);
645
567
  const editingRuntime = useBlockEditingRuntime();
646
568
  if (editingRuntime) {
647
569
  let t0;
@@ -653,12 +575,12 @@ function createViewBlock(options) {
653
575
  } else t0 = $[2];
654
576
  return t0;
655
577
  }
656
- const { blockData, mode } = props;
578
+ const { blockData } = props;
657
579
  let mergedContent;
658
580
  let normalizedContent;
659
581
  if ($[3] !== blockData.content) {
660
582
  mergedContent = {
661
- ...contentDefaults,
583
+ ...emptyContent,
662
584
  ...blockData.content
663
585
  };
664
586
  normalizedContent = { ...mergedContent };
@@ -674,7 +596,7 @@ function createViewBlock(options) {
674
596
  let t0;
675
597
  if ($[6] !== blockData.settings) {
676
598
  t0 = {
677
- ...settingsDefaults,
599
+ ...emptySettings,
678
600
  ...blockData.settings
679
601
  };
680
602
  $[6] = blockData.settings;
@@ -690,51 +612,49 @@ function createViewBlock(options) {
690
612
  $[8] = t1;
691
613
  } else t1 = $[8];
692
614
  let t2;
693
- if ($[9] !== blockData._id || $[10] !== mergedContent || $[11] !== mode || $[12] !== settings) {
615
+ if ($[9] !== blockData._id || $[10] !== mergedContent || $[11] !== settings) {
694
616
  t2 = {
695
617
  blockId: blockData._id,
696
618
  content: mergedContent,
697
- settings,
698
- mode
619
+ settings
699
620
  };
700
621
  $[9] = blockData._id;
701
622
  $[10] = mergedContent;
702
- $[11] = mode;
703
- $[12] = settings;
704
- $[13] = t2;
705
- } else t2 = $[13];
623
+ $[11] = settings;
624
+ $[12] = t2;
625
+ } else t2 = $[12];
706
626
  let t3;
707
- if ($[14] !== normalizedContent || $[15] !== settings) {
627
+ if ($[13] !== normalizedContent || $[14] !== settings) {
708
628
  t3 = /* @__PURE__ */ jsx(ToReact, {
709
629
  content: normalizedContent,
710
630
  settings
711
631
  });
712
- $[14] = normalizedContent;
713
- $[15] = settings;
714
- $[16] = t3;
715
- } else t3 = $[16];
632
+ $[13] = normalizedContent;
633
+ $[14] = settings;
634
+ $[15] = t3;
635
+ } else t3 = $[15];
716
636
  let t4;
717
- if ($[17] !== t2 || $[18] !== t3) {
637
+ if ($[16] !== t2 || $[17] !== t3) {
718
638
  t4 = /* @__PURE__ */ jsx(Context.Provider, {
719
639
  value: t2,
720
640
  children: t3
721
641
  });
722
- $[17] = t2;
723
- $[18] = t3;
724
- $[19] = t4;
725
- } else t4 = $[19];
642
+ $[16] = t2;
643
+ $[17] = t3;
644
+ $[18] = t4;
645
+ } else t4 = $[18];
726
646
  let t5;
727
- if ($[20] !== blockData._id || $[21] !== t4) {
647
+ if ($[19] !== blockData._id || $[20] !== t4) {
728
648
  t5 = /* @__PURE__ */ jsx("div", {
729
649
  className: "group visual-editing-block",
730
650
  "data-camox-viewport-block": blockData._id,
731
651
  style: t1,
732
652
  children: t4
733
653
  });
734
- $[20] = blockData._id;
735
- $[21] = t4;
736
- $[22] = t5;
737
- } else t5 = $[22];
654
+ $[19] = blockData._id;
655
+ $[20] = t4;
656
+ $[21] = t5;
657
+ } else t5 = $[21];
738
658
  return t5;
739
659
  };
740
660
  const contentSchema = {
@@ -752,27 +672,6 @@ function createViewBlock(options) {
752
672
  properties: settingsTypeboxSchema.properties,
753
673
  required: Object.keys(fields.settings ?? {})
754
674
  } : void 0;
755
- const getInitialBundle = () => {
756
- const content = { ...contentDefaults };
757
- const repeatableItems = [];
758
- buildInitialItems(typeboxSchema.properties, null, content, repeatableItems, { value: 0 });
759
- const storageContent = {};
760
- for (const [key, property] of Object.entries(typeboxSchema.properties)) {
761
- if ([
762
- "Image",
763
- "File",
764
- "ImageList",
765
- "FileList",
766
- "Repeater"
767
- ].includes(property.fieldType)) continue;
768
- if ("default" in property) storageContent[key] = property.default;
769
- }
770
- return {
771
- content: storageContent,
772
- settings: { ...settingsDefaults },
773
- repeatableItems
774
- };
775
- };
776
675
  return {
777
676
  Detached,
778
677
  Icon,
@@ -796,43 +695,7 @@ function createViewBlock(options) {
796
695
  contentSchema,
797
696
  settingsSchema,
798
697
  layoutOnly: options.layoutOnly ?? false,
799
- synced: options.synced ?? false,
800
- getInitialBundle,
801
- getInitialContent: () => {
802
- const content = { ...contentDefaults };
803
- for (const [key, property] of Object.entries(typeboxSchema.properties)) if ([
804
- "Image",
805
- "File",
806
- "ImageList",
807
- "FileList",
808
- "Repeater"
809
- ].includes(property.fieldType)) delete content[key];
810
- return content;
811
- },
812
- getInitialSettings: () => ({ ...settingsDefaults }),
813
- getPeekBundle: () => {
814
- const content = { ...contentDefaults };
815
- const repeatableItems = [];
816
- buildPeekItems(typeboxSchema.properties, "peek", null, content, repeatableItems, { value: 0 });
817
- return {
818
- block: {
819
- id: "peek",
820
- pageId: null,
821
- layoutId: null,
822
- type: options.id,
823
- content,
824
- settings: settingsDefaults,
825
- slot: null,
826
- summary: "",
827
- title: "",
828
- position: "",
829
- createdAt: 0,
830
- updatedAt: 0
831
- },
832
- repeatableItems,
833
- files: []
834
- };
835
- }
698
+ synced: options.synced ?? false
836
699
  }
837
700
  };
838
701
  }