camox 0.69.0 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/createApp.d.ts +4 -103
- package/dist/core/createApp.js +3 -24
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +55 -192
- package/dist/core/createLayout.d.ts +6 -77
- package/dist/core/createLayout.js +12 -50
- package/dist/core/editing/createEditableBlock.d.ts +9 -75
- package/dist/core/editing/createEditableBlock.js +258 -640
- package/dist/core/hooks/useArtifactHost.js +56 -46
- package/dist/core/hooks/useIsEditable.js +2 -2
- package/dist/core/lib/artifact.d.ts +4 -0
- package/dist/core/lib/artifactData.js +8 -3
- package/dist/core/lib/artifactHost.js +40 -0
- package/dist/core/lib/artifactRuntime.js +20 -1
- package/dist/core/lib/contentType.d.ts +23 -38
- package/dist/core/lib/contentType.js +34 -62
- package/dist/core/lib/iconTypes.d.ts +0 -3
- package/dist/core/lib/icons.js +63 -51
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CanvasOverlays.js +94 -176
- package/dist/features/canvas/CanvasPageFrame.js +62 -68
- package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
- package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
- package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
- package/dist/features/canvas/useCanvasCamera.js +1 -1
- package/dist/features/canvas/useCanvasFrame.js +1 -1
- package/dist/features/content/ContentCollection.js +2 -2
- package/dist/features/content/collection-form.js +6 -7
- package/dist/features/page/CuratedPageContent.js +15 -24
- package/dist/features/page/UnplacedBlockContent.js +1 -6
- package/dist/features/preview/CamoxPreview.js +30 -33
- package/dist/features/preview/EditablePageContent.js +131 -151
- package/dist/features/preview/components/BlockActionsPopover.js +43 -152
- package/dist/features/preview/components/CanvasPreview.js +2 -2
- package/dist/features/preview/components/Frame.js +3 -3
- package/dist/features/preview/components/IconFieldEditor.js +1 -1
- package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
- package/dist/features/preview/components/Overlays.js +18 -84
- package/dist/features/preview/components/PageTree.js +57 -103
- package/dist/features/preview/components/PreviewPanel.js +8 -11
- package/dist/features/preview/components/RecordCombobox.js +65 -78
- package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
- package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
- package/dist/features/preview/components/SelectionEditor.js +5 -4
- package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
- package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
- package/dist/features/preview/overlayMessages.js +1 -4
- package/dist/features/preview/previewStore.js +3 -23
- package/dist/features/renderer/RendererApp.js +17 -141
- package/dist/features/renderer/definitionAnswers.js +1 -8
- package/dist/features/renderer/rendererHost.js +1 -31
- package/dist/features/renderer/studioConnection.js +1 -25
- package/dist/features/runtime/pageApp.js +8 -4
- package/dist/features/runtime/runtime.js +3 -3
- package/dist/features/studio/agentRunToast.js +71 -0
- package/dist/features/studio/components/ChatWidget.js +2 -0
- package/dist/features/studio/components/DraftBar.js +2 -3
- package/dist/features/studio/components/DraftsControl.js +150 -176
- package/dist/features/studio/components/ReviewDraftSheet.js +344 -548
- package/dist/features/studio/components/ThreadMessages.js +89 -22
- package/dist/features/studio/draftLabel.js +1 -1
- package/dist/features/studio/studioStore.js +5 -17
- package/dist/features/studio/viewSwitch.js +2 -4
- package/dist/features/vite/blockBoilerplate.js +1 -1
- package/dist/features/vite/definitionsSync.js +1 -8
- package/dist/lib/queries.js +0 -1
- package/dist/lib/studio-definitions.js +0 -2
- package/dist/lib/studio-reads.js +0 -5
- package/dist/lib/use-thread.js +196 -138
- package/dist/package.js +1 -1
- package/dist/studio-overlays.css +0 -29
- package/dist/studio.css +1 -1
- package/package.json +6 -4
- package/skills/camox/SKILL.md +1 -1
- package/skills/camox/references/artifacts.md +89 -5
- package/skills/camox/references/block-definitions.md +21 -25
- package/skills/camox/references/dom-integrations.md +1 -1
- package/skills/camox/references/layout-definitions.md +3 -12
- package/skills/camox/references/routed-layouts.md +2 -2
- package/skills/camox-expand/SKILL.md +5 -5
- package/skills/camoxify/SKILL.md +4 -4
- package/dist/features/canvas/canvasInsertionSeams.js +0 -44
- package/dist/features/preview/components/AddBlockSheet.js +0 -314
- package/dist/features/preview/components/BlockPeek.js +0 -66
- package/dist/features/preview/components/BlockThumbnail.js +0 -281
- package/dist/features/preview/components/blockGridNavigation.js +0 -15
- package/dist/features/preview/referencePickerFocus.js +0 -29
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,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 {
|
|
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
|
|
124
|
-
const
|
|
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
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
...
|
|
494
|
+
...emptyItem,
|
|
573
495
|
...databaseItem ? item.content : item
|
|
574
496
|
};
|
|
575
497
|
const itemSettings = {
|
|
576
|
-
...
|
|
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(
|
|
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
|
|
578
|
+
const { blockData } = props;
|
|
657
579
|
let mergedContent;
|
|
658
580
|
let normalizedContent;
|
|
659
581
|
if ($[3] !== blockData.content) {
|
|
660
582
|
mergedContent = {
|
|
661
|
-
...
|
|
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
|
-
...
|
|
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] !==
|
|
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] =
|
|
703
|
-
$[12] =
|
|
704
|
-
|
|
705
|
-
} else t2 = $[13];
|
|
623
|
+
$[11] = settings;
|
|
624
|
+
$[12] = t2;
|
|
625
|
+
} else t2 = $[12];
|
|
706
626
|
let t3;
|
|
707
|
-
if ($[
|
|
627
|
+
if ($[13] !== normalizedContent || $[14] !== settings) {
|
|
708
628
|
t3 = /* @__PURE__ */ jsx(ToReact, {
|
|
709
629
|
content: normalizedContent,
|
|
710
630
|
settings
|
|
711
631
|
});
|
|
712
|
-
$[
|
|
713
|
-
$[
|
|
714
|
-
$[
|
|
715
|
-
} else t3 = $[
|
|
632
|
+
$[13] = normalizedContent;
|
|
633
|
+
$[14] = settings;
|
|
634
|
+
$[15] = t3;
|
|
635
|
+
} else t3 = $[15];
|
|
716
636
|
let t4;
|
|
717
|
-
if ($[
|
|
637
|
+
if ($[16] !== t2 || $[17] !== t3) {
|
|
718
638
|
t4 = /* @__PURE__ */ jsx(Context.Provider, {
|
|
719
639
|
value: t2,
|
|
720
640
|
children: t3
|
|
721
641
|
});
|
|
722
|
-
$[
|
|
723
|
-
$[
|
|
724
|
-
$[
|
|
725
|
-
} else t4 = $[
|
|
642
|
+
$[16] = t2;
|
|
643
|
+
$[17] = t3;
|
|
644
|
+
$[18] = t4;
|
|
645
|
+
} else t4 = $[18];
|
|
726
646
|
let t5;
|
|
727
|
-
if ($[
|
|
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
|
-
$[
|
|
735
|
-
$[
|
|
736
|
-
$[
|
|
737
|
-
} else t5 = $[
|
|
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
|
}
|