camox 0.71.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 +41 -185
- 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/useIsEditable.js +2 -2
- package/dist/core/lib/artifactData.js +8 -3
- 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 +1 -1
- package/dist/features/runtime/runtime.js +3 -3
- package/dist/features/studio/components/ThreadMessages.js +89 -22
- 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 +4 -4
- package/skills/camox/SKILL.md +1 -1
- package/skills/camox/references/artifacts.md +4 -4
- 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
package/dist/core/createApp.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
921
|
+
/** All of a website's definitions taken together. */
|
|
1021
922
|
export type DefinitionSet = Awaited<ReturnType<CamoxApp["getDefinitionSet"]>>;
|
|
1022
923
|
//#endregion
|
|
1023
924
|
export {};
|
package/dist/core/createApp.js
CHANGED
|
@@ -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
|
-
/**
|
|
75
|
-
const
|
|
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:
|
|
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,
|
|
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,
|
|
9
|
+
export type { BlockComponentProps, ContentFieldBuilder, InlineStyle, InlineTextStyles, SettingBuilder, TextLinkStyleData, TextStyleData };
|
package/dist/core/createBlock.js
CHANGED
|
@@ -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
|
|
125
|
-
const
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
...
|
|
494
|
+
...emptyItem,
|
|
580
495
|
...databaseItem ? item.content : item
|
|
581
496
|
};
|
|
582
497
|
const itemSettings = {
|
|
583
|
-
...
|
|
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(
|
|
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
|
|
578
|
+
const { blockData } = props;
|
|
664
579
|
let mergedContent;
|
|
665
580
|
let normalizedContent;
|
|
666
581
|
if ($[3] !== blockData.content) {
|
|
667
582
|
mergedContent = {
|
|
668
|
-
...
|
|
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
|
-
...
|
|
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] !==
|
|
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] =
|
|
710
|
-
$[12] =
|
|
711
|
-
|
|
712
|
-
} else t2 = $[13];
|
|
623
|
+
$[11] = settings;
|
|
624
|
+
$[12] = t2;
|
|
625
|
+
} else t2 = $[12];
|
|
713
626
|
let t3;
|
|
714
|
-
if ($[
|
|
627
|
+
if ($[13] !== normalizedContent || $[14] !== settings) {
|
|
715
628
|
t3 = /* @__PURE__ */ jsx(ToReact, {
|
|
716
629
|
content: normalizedContent,
|
|
717
630
|
settings
|
|
718
631
|
});
|
|
719
|
-
$[
|
|
720
|
-
$[
|
|
721
|
-
$[
|
|
722
|
-
} else t3 = $[
|
|
632
|
+
$[13] = normalizedContent;
|
|
633
|
+
$[14] = settings;
|
|
634
|
+
$[15] = t3;
|
|
635
|
+
} else t3 = $[15];
|
|
723
636
|
let t4;
|
|
724
|
-
if ($[
|
|
637
|
+
if ($[16] !== t2 || $[17] !== t3) {
|
|
725
638
|
t4 = /* @__PURE__ */ jsx(Context.Provider, {
|
|
726
639
|
value: t2,
|
|
727
640
|
children: t3
|
|
728
641
|
});
|
|
729
|
-
$[
|
|
730
|
-
$[
|
|
731
|
-
$[
|
|
732
|
-
} else t4 = $[
|
|
642
|
+
$[16] = t2;
|
|
643
|
+
$[17] = t3;
|
|
644
|
+
$[18] = t4;
|
|
645
|
+
} else t4 = $[18];
|
|
733
646
|
let t5;
|
|
734
|
-
if ($[
|
|
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
|
-
$[
|
|
742
|
-
$[
|
|
743
|
-
$[
|
|
744
|
-
} else t5 = $[
|
|
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
|
}
|