camox 0.71.0 → 0.74.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) 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 +41 -185
  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/useIsEditable.js +2 -2
  10. package/dist/core/lib/artifactData.js +8 -3
  11. package/dist/core/lib/contentType.d.ts +23 -38
  12. package/dist/core/lib/contentType.js +34 -62
  13. package/dist/core/lib/iconTypes.d.ts +0 -3
  14. package/dist/core/lib/icons.js +63 -51
  15. package/dist/core/lib/recordScope.js +1 -1
  16. package/dist/features/canvas/CanvasOverlays.js +94 -176
  17. package/dist/features/canvas/CanvasPageFrame.js +62 -68
  18. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
  19. package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
  20. package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
  21. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
  22. package/dist/features/canvas/useCanvasCamera.js +1 -1
  23. package/dist/features/canvas/useCanvasFrame.js +1 -1
  24. package/dist/features/content/ContentCollection.js +2 -2
  25. package/dist/features/content/collection-form.js +6 -7
  26. package/dist/features/page/CuratedPageContent.js +15 -24
  27. package/dist/features/page/UnplacedBlockContent.js +1 -6
  28. package/dist/features/preview/CamoxPreview.js +30 -33
  29. package/dist/features/preview/EditablePageContent.js +131 -151
  30. package/dist/features/preview/components/BlockActionsPopover.js +43 -152
  31. package/dist/features/preview/components/CanvasPreview.js +2 -2
  32. package/dist/features/preview/components/Frame.js +3 -3
  33. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  34. package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
  35. package/dist/features/preview/components/Overlays.js +18 -84
  36. package/dist/features/preview/components/PageInfo.js +121 -98
  37. package/dist/features/preview/components/PageTree.js +57 -103
  38. package/dist/features/preview/components/PreviewPanel.js +8 -11
  39. package/dist/features/preview/components/RecordCombobox.js +65 -78
  40. package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
  41. package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
  42. package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
  43. package/dist/features/preview/components/SelectionEditor.js +6 -5
  44. package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
  45. package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
  46. package/dist/features/preview/overlayMessages.js +1 -4
  47. package/dist/features/preview/previewStore.js +3 -23
  48. package/dist/features/renderer/RendererApp.js +17 -141
  49. package/dist/features/renderer/definitionAnswers.js +1 -8
  50. package/dist/features/renderer/rendererHost.js +1 -31
  51. package/dist/features/renderer/studioConnection.js +1 -25
  52. package/dist/features/routes/pageRuntime.js +15 -4
  53. package/dist/features/runtime/ClaimCard.js +192 -0
  54. package/dist/features/runtime/pageApp.js +5 -4
  55. package/dist/features/runtime/runtime.js +29 -8
  56. package/dist/features/runtime/worker.js +2 -2
  57. package/dist/features/runtime/workerRequest.d.ts +6 -0
  58. package/dist/features/runtime/workerRequest.js +13 -1
  59. package/dist/features/runtime/workerRuntime.d.ts +2 -2
  60. package/dist/features/runtime/workerRuntime.js +2 -2
  61. package/dist/features/studio/components/AgentSidebar.js +7 -7
  62. package/dist/features/studio/components/ChatWidget.js +142 -106
  63. package/dist/features/studio/components/ContentFindings.js +127 -230
  64. package/dist/features/studio/components/DeleteDraftDialog.js +112 -0
  65. package/dist/features/studio/components/DraftBar.js +98 -53
  66. package/dist/features/studio/components/DraftsControl.js +203 -190
  67. package/dist/features/studio/components/ReviewDraftDialog.js +670 -0
  68. package/dist/features/studio/components/{Patrol.js → Specialists.js} +291 -330
  69. package/dist/features/studio/components/Squareling.js +5 -5
  70. package/dist/features/studio/components/ThreadComposer.js +106 -127
  71. package/dist/features/studio/components/ThreadMessages.js +137 -45
  72. package/dist/features/studio/findingSentence.js +14 -12
  73. package/dist/features/studio/fixMessage.js +23 -0
  74. package/dist/features/studio/reportSentence.js +1 -1
  75. package/dist/features/studio/{patrollerBio.js → specialistBio.js} +8 -5
  76. package/dist/features/studio/studioStore.js +29 -15
  77. package/dist/features/studio/workingSentence.js +1 -1
  78. package/dist/features/vite/blockBoilerplate.js +1 -1
  79. package/dist/features/vite/definitionsSync.js +1 -8
  80. package/dist/lib/api-client.js +5 -1
  81. package/dist/lib/queries.js +5 -6
  82. package/dist/lib/studio-definitions.js +0 -2
  83. package/dist/lib/studio-reads.d.ts +1 -1
  84. package/dist/lib/studio-reads.js +5 -10
  85. package/dist/lib/use-thread.js +196 -138
  86. package/dist/package.js +1 -1
  87. package/dist/studio-overlays.css +0 -29
  88. package/dist/studio.css +1 -1
  89. package/package.json +4 -4
  90. package/skills/camox/SKILL.md +1 -1
  91. package/skills/camox/references/artifacts.md +4 -4
  92. package/skills/camox/references/block-definitions.md +21 -25
  93. package/skills/camox/references/dom-integrations.md +1 -1
  94. package/skills/camox/references/layout-definitions.md +3 -12
  95. package/skills/camox/references/routed-layouts.md +2 -2
  96. package/skills/camox-expand/SKILL.md +5 -5
  97. package/skills/camoxify/SKILL.md +4 -4
  98. package/dist/features/canvas/canvasInsertionSeams.js +0 -44
  99. package/dist/features/preview/components/AddBlockSheet.js +0 -314
  100. package/dist/features/preview/components/BlockPeek.js +0 -66
  101. package/dist/features/preview/components/BlockThumbnail.js +0 -281
  102. package/dist/features/preview/components/blockGridNavigation.js +0 -15
  103. package/dist/features/preview/referencePickerFocus.js +0 -29
  104. package/dist/features/studio/components/ReviewDraftSheet.js +0 -1587
@@ -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,6 +1,6 @@
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";
@@ -15,10 +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
20
  import { ARTIFACT_FIELD_ATTRIBUTE, ARTIFACT_ITEM_ATTRIBUTE } from "@camox/api-contract/drafts";
21
- import { generateKeyBetween } from "fractional-indexing";
22
21
  import { jsx } from "react/jsx-runtime";
23
22
 
24
23
  //#region src/core/createBlock.tsx
@@ -38,98 +37,12 @@ function resolveLinkHref(link, pages, pathname) {
38
37
  if (!link.href || link.href.startsWith("#")) return `${pathname}${link.href ?? ""}`;
39
38
  return link.href;
40
39
  }
41
- function collectDefaults(properties) {
42
- const defaults = {};
43
- for (const [key, property] of Object.entries(properties)) if ("default" in property) defaults[key] = property.default;
44
- return defaults;
45
- }
46
- function buildInitialItems(properties, parentTempId, content, items, counter) {
47
- for (const [fieldName, property] of Object.entries(properties)) {
48
- if (property.type !== "array" || !property.items?.properties) continue;
49
- if (property.fieldType === "ImageList" || property.fieldType === "FileList") continue;
50
- const markers = [];
51
- const defaultCount = Number(property.defaultItems ?? property.minItems ?? 0);
52
- let previousPosition = null;
53
- for (let index = 0; index < defaultCount; index += 1) {
54
- const tempId = `seed_${++counter.value}`;
55
- const itemContent = {};
56
- for (const [key, itemProperty] of Object.entries(property.items.properties)) {
57
- if (itemProperty.type === "array" && itemProperty.items?.properties) continue;
58
- if ("default" in itemProperty) itemContent[key] = itemProperty.default;
59
- }
60
- const position = generateKeyBetween(previousPosition, null);
61
- previousPosition = position;
62
- items.push({
63
- tempId,
64
- parentTempId,
65
- fieldName,
66
- content: { ...itemContent },
67
- ...property.defaultItemSettings && { settings: { ...property.defaultItemSettings } },
68
- position
69
- });
70
- buildInitialItems(property.items?.properties ?? {}, tempId, {}, items, counter);
71
- markers.push({ _itemId: tempId });
72
- }
73
- content[fieldName] = markers;
74
- }
75
- }
76
- function buildPeekItems(properties, blockId, parentItemId, content, items, counter) {
77
- for (const [fieldName, property] of Object.entries(properties)) {
78
- if (property.type !== "array" || !property.items?.properties) continue;
79
- if (property.fieldType === "ImageList" || property.fieldType === "FileList") continue;
80
- const defaultCount = Number(property.defaultItems ?? property.minItems ?? 0);
81
- const markers = [];
82
- let previousPosition = null;
83
- for (let index = 0; index < defaultCount; index += 1) {
84
- const id = `peek_${++counter.value}`;
85
- const itemContent = {};
86
- for (const [key, itemProperty] of Object.entries(property.items.properties)) {
87
- if (itemProperty.type === "array" && itemProperty.items?.properties) continue;
88
- if ("default" in itemProperty) itemContent[key] = itemProperty.default;
89
- }
90
- const position = generateKeyBetween(previousPosition, null);
91
- previousPosition = position;
92
- items.push({
93
- id,
94
- blockId,
95
- parentItemId,
96
- fieldName,
97
- content: itemContent,
98
- settings: property.defaultItemSettings ? { ...property.defaultItemSettings } : null,
99
- summary: "",
100
- title: "",
101
- position,
102
- createdAt: 0,
103
- updatedAt: 0,
104
- projectId: null,
105
- sharedContentType: null,
106
- references: {}
107
- });
108
- markers.push({ _itemId: id });
109
- const nestedContent = {};
110
- buildPeekItems(property.items.properties, blockId, id, nestedContent, items, counter);
111
- const item = items.find((candidate) => candidate.id === id);
112
- if (item) item.content = {
113
- ...item.content,
114
- ...nestedContent
115
- };
116
- }
117
- content[fieldName] = markers;
118
- }
119
- }
120
40
  function createViewBlock(options) {
121
41
  const fields = resolveBlockFields(options);
122
42
  const typeboxSchema = Type.Object(fields.content);
123
43
  const settingsTypeboxSchema = fields.settings ? Type.Object(fields.settings) : null;
124
- const contentDefaults = collectDefaults(typeboxSchema.properties);
125
- const settingsDefaults = settingsTypeboxSchema ? collectDefaults(settingsTypeboxSchema.properties) : {};
126
- const repeatableDefaults = {};
127
- const repeatableSettingsDefaults = {};
128
- for (const [key, property] of Object.entries(typeboxSchema.properties)) {
129
- if (property.fieldType !== "Repeater") continue;
130
- repeatableDefaults[key] = collectDefaults(property.items?.properties ?? {});
131
- repeatableSettingsDefaults[key] = { ...property.defaultItemSettings };
132
- }
44
+ const emptyContent = emptyFieldValues(typeboxSchema);
45
+ const emptySettings = emptyFieldValues(settingsTypeboxSchema);
133
46
  const Context = React.createContext(null);
134
47
  const RepeaterContext = React.createContext(null);
135
48
  function useValue(name) {
@@ -301,8 +214,7 @@ function createViewBlock(options) {
301
214
  $[2] = t0;
302
215
  } else t0 = $[2];
303
216
  const resolved = t0;
304
- const fallback = item ? repeatableDefaults[item.arrayFieldName]?.[String(name)] : contentDefaults[String(name)];
305
- return resolved ?? fallback;
217
+ return resolved?.url ? resolved : null;
306
218
  }
307
219
  const Image = ({ name, children }) => {
308
220
  const editingRuntime = useBlockEditingRuntime();
@@ -310,7 +222,8 @@ function createViewBlock(options) {
310
222
  name,
311
223
  children
312
224
  });
313
- const value = useAsset(name);
225
+ const title = useFieldSchema(name)?.title;
226
+ const value = useAsset(name) ?? placeholderImage(title);
314
227
  return renderImagePlaceholder(value, children({
315
228
  src: transformImageUrl(value.url, {
316
229
  width: getDefaultImageWidth(),
@@ -329,6 +242,7 @@ function createViewBlock(options) {
329
242
  children
330
243
  });
331
244
  const value = useAsset(name);
245
+ if (!value) return null;
332
246
  return children({
333
247
  href: value.url,
334
248
  download: value.filename
@@ -513,12 +427,10 @@ function createViewBlock(options) {
513
427
  const { filesMap } = useNormalizedData();
514
428
  if (!block) throw new Error("ImageList/FileList must be used within a Block Component");
515
429
  const fieldName = String(name);
516
- const schema = parent ? typeboxSchema.properties[parent.arrayFieldName]?.items?.properties?.[fieldName] : (block.sourceSchema ?? typeboxSchema.properties)[fieldName];
517
- const fieldType = schema?.fieldType;
430
+ const fieldType = (parent ? typeboxSchema.properties[parent.arrayFieldName]?.items?.properties?.[fieldName] : (block.sourceSchema ?? typeboxSchema.properties)[fieldName])?.fieldType;
518
431
  if (fieldType !== "ImageList" && fieldType !== "FileList") throw new Error(`"${fieldName}" is not an imageList or fileList field`);
519
432
  const source = parent ? parent.itemContent[fieldName] : block.content[fieldName];
520
- let values = Array.isArray(source) ? source : [];
521
- 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 : [];
522
434
  const Single = fieldType === "ImageList" ? Image : File;
523
435
  return values.map((value) => resolveAssetValue(value, filesMap)).filter(Boolean).map((value, index) => /* @__PURE__ */ jsx(RepeaterContext.Provider, {
524
436
  value: {
@@ -572,15 +484,18 @@ function createViewBlock(options) {
572
484
  const fieldName = String(name);
573
485
  const source = parent ? parent.itemContent[fieldName] : block.content[fieldName];
574
486
  if (!Array.isArray(source)) throw new Error(`Field "${fieldName}" is not an array`);
575
- 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);
576
491
  return source.map((item) => isItemMarker(item) ? itemsMap.get(item._itemId) ?? null : item).filter(Boolean).map((item, index) => {
577
492
  const databaseItem = item.content !== void 0 && item.id != null;
578
493
  const itemContent = {
579
- ...repeatableDefaults[fieldName],
494
+ ...emptyItem,
580
495
  ...databaseItem ? item.content : item
581
496
  };
582
497
  const itemSettings = {
583
- ...repeatableSettingsDefaults[fieldName],
498
+ ...emptyItemSettings,
584
499
  ...databaseItem ? item.settings : null
585
500
  };
586
501
  const itemId = databaseItem ? item.id : void 0;
@@ -648,7 +563,7 @@ function createViewBlock(options) {
648
563
  return t1;
649
564
  };
650
565
  const Component = (props) => {
651
- const $ = c(23);
566
+ const $ = c(22);
652
567
  const editingRuntime = useBlockEditingRuntime();
653
568
  if (editingRuntime) {
654
569
  let t0;
@@ -660,12 +575,12 @@ function createViewBlock(options) {
660
575
  } else t0 = $[2];
661
576
  return t0;
662
577
  }
663
- const { blockData, mode } = props;
578
+ const { blockData } = props;
664
579
  let mergedContent;
665
580
  let normalizedContent;
666
581
  if ($[3] !== blockData.content) {
667
582
  mergedContent = {
668
- ...contentDefaults,
583
+ ...emptyContent,
669
584
  ...blockData.content
670
585
  };
671
586
  normalizedContent = { ...mergedContent };
@@ -681,7 +596,7 @@ function createViewBlock(options) {
681
596
  let t0;
682
597
  if ($[6] !== blockData.settings) {
683
598
  t0 = {
684
- ...settingsDefaults,
599
+ ...emptySettings,
685
600
  ...blockData.settings
686
601
  };
687
602
  $[6] = blockData.settings;
@@ -697,51 +612,49 @@ function createViewBlock(options) {
697
612
  $[8] = t1;
698
613
  } else t1 = $[8];
699
614
  let t2;
700
- if ($[9] !== blockData._id || $[10] !== mergedContent || $[11] !== mode || $[12] !== settings) {
615
+ if ($[9] !== blockData._id || $[10] !== mergedContent || $[11] !== settings) {
701
616
  t2 = {
702
617
  blockId: blockData._id,
703
618
  content: mergedContent,
704
- settings,
705
- mode
619
+ settings
706
620
  };
707
621
  $[9] = blockData._id;
708
622
  $[10] = mergedContent;
709
- $[11] = mode;
710
- $[12] = settings;
711
- $[13] = t2;
712
- } else t2 = $[13];
623
+ $[11] = settings;
624
+ $[12] = t2;
625
+ } else t2 = $[12];
713
626
  let t3;
714
- if ($[14] !== normalizedContent || $[15] !== settings) {
627
+ if ($[13] !== normalizedContent || $[14] !== settings) {
715
628
  t3 = /* @__PURE__ */ jsx(ToReact, {
716
629
  content: normalizedContent,
717
630
  settings
718
631
  });
719
- $[14] = normalizedContent;
720
- $[15] = settings;
721
- $[16] = t3;
722
- } else t3 = $[16];
632
+ $[13] = normalizedContent;
633
+ $[14] = settings;
634
+ $[15] = t3;
635
+ } else t3 = $[15];
723
636
  let t4;
724
- if ($[17] !== t2 || $[18] !== t3) {
637
+ if ($[16] !== t2 || $[17] !== t3) {
725
638
  t4 = /* @__PURE__ */ jsx(Context.Provider, {
726
639
  value: t2,
727
640
  children: t3
728
641
  });
729
- $[17] = t2;
730
- $[18] = t3;
731
- $[19] = t4;
732
- } else t4 = $[19];
642
+ $[16] = t2;
643
+ $[17] = t3;
644
+ $[18] = t4;
645
+ } else t4 = $[18];
733
646
  let t5;
734
- if ($[20] !== blockData._id || $[21] !== t4) {
647
+ if ($[19] !== blockData._id || $[20] !== t4) {
735
648
  t5 = /* @__PURE__ */ jsx("div", {
736
649
  className: "group visual-editing-block",
737
650
  "data-camox-viewport-block": blockData._id,
738
651
  style: t1,
739
652
  children: t4
740
653
  });
741
- $[20] = blockData._id;
742
- $[21] = t4;
743
- $[22] = t5;
744
- } else t5 = $[22];
654
+ $[19] = blockData._id;
655
+ $[20] = t4;
656
+ $[21] = t5;
657
+ } else t5 = $[21];
745
658
  return t5;
746
659
  };
747
660
  const contentSchema = {
@@ -759,27 +672,6 @@ function createViewBlock(options) {
759
672
  properties: settingsTypeboxSchema.properties,
760
673
  required: Object.keys(fields.settings ?? {})
761
674
  } : void 0;
762
- const getInitialBundle = () => {
763
- const content = { ...contentDefaults };
764
- const repeatableItems = [];
765
- buildInitialItems(typeboxSchema.properties, null, content, repeatableItems, { value: 0 });
766
- const storageContent = {};
767
- for (const [key, property] of Object.entries(typeboxSchema.properties)) {
768
- if ([
769
- "Image",
770
- "File",
771
- "ImageList",
772
- "FileList",
773
- "Repeater"
774
- ].includes(property.fieldType)) continue;
775
- if ("default" in property) storageContent[key] = property.default;
776
- }
777
- return {
778
- content: storageContent,
779
- settings: { ...settingsDefaults },
780
- repeatableItems
781
- };
782
- };
783
675
  return {
784
676
  Detached,
785
677
  Icon,
@@ -803,43 +695,7 @@ function createViewBlock(options) {
803
695
  contentSchema,
804
696
  settingsSchema,
805
697
  layoutOnly: options.layoutOnly ?? false,
806
- synced: options.synced ?? false,
807
- getInitialBundle,
808
- getInitialContent: () => {
809
- const content = { ...contentDefaults };
810
- for (const [key, property] of Object.entries(typeboxSchema.properties)) if ([
811
- "Image",
812
- "File",
813
- "ImageList",
814
- "FileList",
815
- "Repeater"
816
- ].includes(property.fieldType)) delete content[key];
817
- return content;
818
- },
819
- getInitialSettings: () => ({ ...settingsDefaults }),
820
- getPeekBundle: () => {
821
- const content = { ...contentDefaults };
822
- const repeatableItems = [];
823
- buildPeekItems(typeboxSchema.properties, "peek", null, content, repeatableItems, { value: 0 });
824
- return {
825
- block: {
826
- id: "peek",
827
- pageId: null,
828
- layoutId: null,
829
- type: options.id,
830
- content,
831
- settings: settingsDefaults,
832
- slot: null,
833
- summary: "",
834
- title: "",
835
- position: "",
836
- createdAt: 0,
837
- updatedAt: 0
838
- },
839
- repeatableItems,
840
- files: []
841
- };
842
- }
698
+ synced: options.synced ?? false
843
699
  }
844
700
  };
845
701
  }