camox 0.47.0 → 0.51.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 +19 -6
- package/dist/core/createApp.js +7 -2
- package/dist/core/createBlock.js +54 -43
- package/dist/core/createCollection.d.ts +25 -7
- package/dist/core/createCollection.js +28 -9
- package/dist/core/createLayout.d.ts +98 -71
- package/dist/core/createLayout.js +10 -16
- package/dist/core/derivedRoutes.js +1 -1
- package/dist/core/editing/BlockEditingRuntime.d.ts +3 -2
- package/dist/core/editing/CompleteBlockEditingRuntime.js +2 -1
- package/dist/core/editing/createEditableBlock.d.ts +59 -19
- package/dist/core/editing/createEditableBlock.js +162 -151
- package/dist/core/editing/useLatestRecord.js +7 -7
- package/dist/core/layoutContext.d.ts +55 -0
- package/dist/core/layoutContext.js +66 -0
- package/dist/core/lib/contentType.d.ts +91 -4
- package/dist/core/lib/contentType.js +84 -7
- package/dist/core/lib/recordScope.js +19 -17
- package/dist/core/lib/reference.d.ts +6 -2
- package/dist/core/recordItem.js +55 -2
- package/dist/core/requestContext.d.ts +18 -0
- package/dist/core/structuredData.d.ts +126 -0
- package/dist/core/structuredData.js +40 -0
- package/dist/features/canvas/canvasCamera.js +1 -1
- package/dist/features/canvas/sidebar/CanvasInspector.js +1 -1
- package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +1 -1
- package/dist/features/content/ContentAssets.js +84 -88
- package/dist/features/content/ContentCollection.js +13 -7
- package/dist/features/content/collection-form.js +6 -2
- package/dist/features/content/components/MissingFromLocale.js +1 -1
- package/dist/features/og/pageImage.js +89 -0
- package/dist/features/page/CuratedPageContent.js +45 -32
- package/dist/features/page/DerivedPageContent.js +49 -22
- package/dist/features/page/SharedLayoutContent.js +26 -22
- package/dist/features/preview/CamoxPreview.js +41 -27
- package/dist/features/preview/EditablePageExperience.js +17 -9
- package/dist/features/preview/components/AddBlockSheet.js +1 -0
- package/dist/features/preview/components/BlockActionsPopover.js +19 -41
- package/dist/features/preview/components/FieldToolbar.js +1 -1
- package/dist/features/preview/components/MobilePreviewDrawer.js +6 -9
- package/dist/features/preview/components/PageInfo.js +244 -264
- package/dist/features/preview/components/PageTree.js +63 -53
- package/dist/features/preview/components/PreviewPanel.js +10 -64
- package/dist/features/preview/components/PreviewToolbar.js +1 -1
- package/dist/features/preview/components/RecordCard.js +50 -34
- package/dist/features/preview/components/RecordCombobox.js +12 -5
- package/dist/features/preview/components/ReferenceFieldEditor.js +4 -2
- package/dist/features/preview/components/ReferenceListFieldEditor.js +24 -19
- package/dist/features/preview/components/RepeatableItemsList.js +62 -46
- package/dist/features/preview/components/SelectionEditor.js +3 -2
- package/dist/features/preview/components/useFieldWriter.js +2 -4
- package/dist/features/preview/components/useRecordView.js +2 -2
- package/dist/features/preview/entityName.js +11 -0
- package/dist/features/preview/pageRecord.js +17 -18
- package/dist/features/preview/previewConstants.js +2 -8
- package/dist/features/preview/usePreviewViewportActions.js +1 -1
- package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
- package/dist/features/provider/components/CommandPalette.js +2 -5
- package/dist/features/provider/signInShortcut.js +1 -2
- package/dist/features/provider/useAdminShortcuts.js +47 -53
- package/dist/features/routes/pageRuntime.d.ts +17 -2
- package/dist/features/routes/pageRuntime.js +61 -57
- package/dist/features/runtime/RuntimeChrome.js +1 -1
- package/dist/features/runtime/breadcrumbs.js +68 -0
- package/dist/features/runtime/livePages.js +3 -2
- package/dist/features/runtime/pageGraph.js +92 -0
- package/dist/features/runtime/projectLogo.js +110 -0
- package/dist/features/runtime/publicCache.js +83 -0
- package/dist/features/runtime/runtime.d.ts +24 -9
- package/dist/features/runtime/runtime.js +447 -130
- package/dist/features/runtime/runtimeRoutes.d.ts +1 -0
- package/dist/features/runtime/runtimeRoutes.js +1 -0
- package/dist/features/runtime/structuredData.js +213 -0
- package/dist/features/runtime/worker.d.ts +5 -1
- package/dist/features/runtime/worker.js +20 -3
- package/dist/features/settings/AnalyticsSettings.js +622 -0
- package/dist/features/settings/CamoxSettings.js +95 -0
- package/dist/features/settings/FaviconSettings.js +254 -0
- package/dist/features/settings/ProjectNameSettings.js +145 -0
- package/dist/features/settings/SettingsPart.js +73 -0
- package/dist/features/settings/SocialProfilesSettings.js +245 -0
- package/dist/features/settings/useProjectMutation.js +61 -0
- package/dist/features/studio/components/ChatSidebar.js +5 -5
- package/dist/features/studio/components/DraftsControl.js +136 -131
- package/dist/features/studio/components/LocalePicker.js +178 -174
- package/dist/features/studio/components/Navbar.js +107 -66
- package/dist/features/studio/components/ProjectMenu.js +85 -110
- package/dist/features/studio/components/ReviewDraftSheet.js +1046 -990
- package/dist/features/studio/components/ThreadMessages.js +2 -2
- package/dist/features/studio/components/UserButton.js +1 -1
- package/dist/features/studio/routes.js +3 -1
- package/dist/features/studio/showInCanvas.js +129 -0
- package/dist/features/vite/blockBoilerplate.js +3 -2
- package/dist/features/vite/definitionsSync.js +4 -5
- package/dist/features/vite/layoutGeneration.js +3 -2
- package/dist/features/vite/runtimeDev.js +32 -17
- package/dist/features/vite/staticAssetHeaders.js +52 -0
- package/dist/features/vite/vite.d.ts +1 -1
- package/dist/features/vite/vite.js +17 -4
- package/dist/lib/api-client-server.d.ts +1 -1
- package/dist/lib/api-client.d.ts +2 -1
- package/dist/lib/draft-scope.d.ts +1 -0
- package/dist/lib/locale-path.d.ts +3 -11
- package/dist/lib/locale-path.js +3 -27
- package/dist/lib/queries.d.ts +4 -0
- package/dist/lib/queries.js +8 -1
- package/dist/lib/shortcuts.js +29 -0
- package/dist/lib/studio-reads.d.ts +1 -0
- package/dist/lib/studio-reads.js +3 -1
- package/dist/lib/utils.js +1 -104
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +6 -4
- package/skills/camox/references/block-definitions.md +105 -25
- package/skills/camox/references/layout-definitions.md +53 -17
- package/skills/camox/references/routed-layouts.md +17 -14
- package/dist/features/studio/components/FaviconDialog.js +0 -318
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useProjectUuid } from "../../lib/auth.js";
|
|
2
2
|
import { reads, useReadQuery } from "../../lib/studio-reads.js";
|
|
3
|
-
import { checkIfInputFocused } from "../../lib/utils.js";
|
|
4
3
|
import { UploadDropZone } from "./components/UploadDropZone.js";
|
|
5
4
|
import { UploadProgressDrawer } from "./components/UploadProgressDrawer.js";
|
|
6
5
|
import { useFileUpload } from "../../hooks/use-file-upload.js";
|
|
@@ -10,12 +9,13 @@ import { AssetCard } from "./components/AssetCard.js";
|
|
|
10
9
|
import { useMarqueeSelection } from "../../hooks/use-marquee-selection.js";
|
|
11
10
|
import { AssetCardSkeleton } from "./components/AssetCardSkeleton.js";
|
|
12
11
|
import { c } from "react/compiler-runtime";
|
|
13
|
-
import {
|
|
12
|
+
import { useRef, useState } from "react";
|
|
14
13
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
15
14
|
import { useMutation } from "@tanstack/react-query";
|
|
16
15
|
import { Button } from "@camox/ui/button";
|
|
17
16
|
import { PanelContent } from "@camox/ui/panel";
|
|
18
17
|
import { ImageIcon, UploadIcon } from "lucide-react";
|
|
18
|
+
import { useHotkey } from "@tanstack/react-hotkeys";
|
|
19
19
|
import { FloatingToolbar } from "@camox/ui/floating-toolbar";
|
|
20
20
|
|
|
21
21
|
//#region src/features/content/ContentAssets.tsx
|
|
@@ -74,31 +74,27 @@ const ContentAssets = () => {
|
|
|
74
74
|
$[10] = t8;
|
|
75
75
|
} else t8 = $[10];
|
|
76
76
|
const { selectionRect, didDragRef, handlers } = useMarqueeSelection(containerRef, t8);
|
|
77
|
-
let t10;
|
|
78
77
|
let t9;
|
|
79
|
-
if ($[11]
|
|
80
|
-
t9 = () =>
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
|
|
79
|
+
t9 = () => setSelectedIds(_temp);
|
|
80
|
+
$[11] = t9;
|
|
81
|
+
} else t9 = $[11];
|
|
82
|
+
const t10 = lightboxFileId === null;
|
|
83
|
+
let t11;
|
|
84
|
+
if ($[12] !== t10) {
|
|
85
|
+
t11 = {
|
|
86
|
+
enabled: t10,
|
|
87
|
+
ignoreInputs: true,
|
|
88
|
+
preventDefault: false,
|
|
89
|
+
stopPropagation: false
|
|
89
90
|
};
|
|
90
|
-
t10 = [lightboxFileId];
|
|
91
|
-
$[11] = lightboxFileId;
|
|
92
91
|
$[12] = t10;
|
|
93
|
-
$[13] =
|
|
94
|
-
} else
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
useEffect(t9, t10);
|
|
99
|
-
let t11;
|
|
92
|
+
$[13] = t11;
|
|
93
|
+
} else t11 = $[13];
|
|
94
|
+
useHotkey("Escape", t9, t11);
|
|
95
|
+
let t12;
|
|
100
96
|
if ($[14] !== didDragRef) {
|
|
101
|
-
|
|
97
|
+
t12 = () => {
|
|
102
98
|
if (didDragRef.current) {
|
|
103
99
|
didDragRef.current = false;
|
|
104
100
|
return;
|
|
@@ -106,20 +102,20 @@ const ContentAssets = () => {
|
|
|
106
102
|
setSelectedIds(/* @__PURE__ */ new Set());
|
|
107
103
|
};
|
|
108
104
|
$[14] = didDragRef;
|
|
109
|
-
$[15] =
|
|
110
|
-
} else
|
|
111
|
-
let
|
|
105
|
+
$[15] = t12;
|
|
106
|
+
} else t12 = $[15];
|
|
107
|
+
let t13;
|
|
112
108
|
if ($[16] !== files) {
|
|
113
|
-
|
|
109
|
+
t13 = files === void 0 && /* @__PURE__ */ jsx("div", {
|
|
114
110
|
className: "grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-4",
|
|
115
111
|
children: Array.from({ length: 12 }, _temp2)
|
|
116
112
|
});
|
|
117
113
|
$[16] = files;
|
|
118
|
-
$[17] =
|
|
119
|
-
} else
|
|
120
|
-
let
|
|
114
|
+
$[17] = t13;
|
|
115
|
+
} else t13 = $[17];
|
|
116
|
+
let t14;
|
|
121
117
|
if ($[18] !== files?.length || $[19] !== uploadFiles) {
|
|
122
|
-
|
|
118
|
+
t14 = files?.length === 0 && /* @__PURE__ */ jsx("div", {
|
|
123
119
|
className: "flex h-full items-center justify-center",
|
|
124
120
|
children: /* @__PURE__ */ jsxs("div", {
|
|
125
121
|
className: "flex max-w-sm flex-col items-center gap-2 text-center",
|
|
@@ -150,9 +146,9 @@ const ContentAssets = () => {
|
|
|
150
146
|
type: "file",
|
|
151
147
|
className: "sr-only",
|
|
152
148
|
multiple: true,
|
|
153
|
-
onChange: (
|
|
154
|
-
if (
|
|
155
|
-
|
|
149
|
+
onChange: (event) => {
|
|
150
|
+
if (event.target.files) uploadFiles(event.target.files);
|
|
151
|
+
event.target.value = "";
|
|
156
152
|
}
|
|
157
153
|
})
|
|
158
154
|
]
|
|
@@ -162,11 +158,11 @@ const ContentAssets = () => {
|
|
|
162
158
|
});
|
|
163
159
|
$[18] = files?.length;
|
|
164
160
|
$[19] = uploadFiles;
|
|
165
|
-
$[20] =
|
|
166
|
-
} else
|
|
167
|
-
let
|
|
161
|
+
$[20] = t14;
|
|
162
|
+
} else t14 = $[20];
|
|
163
|
+
let t15;
|
|
168
164
|
if ($[21] !== files || $[22] !== selectedIds) {
|
|
169
|
-
|
|
165
|
+
t15 = files && files.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
170
166
|
className: "grid grid-cols-[repeat(auto-fill,minmax(220px,1fr))] gap-4",
|
|
171
167
|
children: files.map((file) => /* @__PURE__ */ jsx(AssetCard, {
|
|
172
168
|
file,
|
|
@@ -184,11 +180,11 @@ const ContentAssets = () => {
|
|
|
184
180
|
});
|
|
185
181
|
$[21] = files;
|
|
186
182
|
$[22] = selectedIds;
|
|
187
|
-
$[23] =
|
|
188
|
-
} else
|
|
189
|
-
let
|
|
183
|
+
$[23] = t15;
|
|
184
|
+
} else t15 = $[23];
|
|
185
|
+
let t16;
|
|
190
186
|
if ($[24] !== selectionRect) {
|
|
191
|
-
|
|
187
|
+
t16 = selectionRect && /* @__PURE__ */ jsx("div", {
|
|
192
188
|
className: "border-primary bg-primary/10 pointer-events-none absolute z-50 border",
|
|
193
189
|
style: {
|
|
194
190
|
left: selectionRect.left,
|
|
@@ -198,61 +194,61 @@ const ContentAssets = () => {
|
|
|
198
194
|
}
|
|
199
195
|
});
|
|
200
196
|
$[24] = selectionRect;
|
|
201
|
-
$[25] =
|
|
202
|
-
} else
|
|
203
|
-
let
|
|
204
|
-
if ($[26] !== handlers.onPointerDown || $[27] !== handlers.onPointerMove || $[28] !== handlers.onPointerUp || $[29] !==
|
|
205
|
-
|
|
197
|
+
$[25] = t16;
|
|
198
|
+
} else t16 = $[25];
|
|
199
|
+
let t17;
|
|
200
|
+
if ($[26] !== handlers.onPointerDown || $[27] !== handlers.onPointerMove || $[28] !== handlers.onPointerUp || $[29] !== t12 || $[30] !== t13 || $[31] !== t14 || $[32] !== t15 || $[33] !== t16) {
|
|
201
|
+
t17 = /* @__PURE__ */ jsxs(PanelContent, {
|
|
206
202
|
ref: containerRef,
|
|
207
203
|
className: "relative p-4 select-none",
|
|
208
|
-
onClick:
|
|
204
|
+
onClick: t12,
|
|
209
205
|
onPointerDown: handlers.onPointerDown,
|
|
210
206
|
onPointerMove: handlers.onPointerMove,
|
|
211
207
|
onPointerUp: handlers.onPointerUp,
|
|
212
208
|
children: [
|
|
213
|
-
t12,
|
|
214
209
|
t13,
|
|
215
210
|
t14,
|
|
216
|
-
t15
|
|
211
|
+
t15,
|
|
212
|
+
t16
|
|
217
213
|
]
|
|
218
214
|
});
|
|
219
215
|
$[26] = handlers.onPointerDown;
|
|
220
216
|
$[27] = handlers.onPointerMove;
|
|
221
217
|
$[28] = handlers.onPointerUp;
|
|
222
|
-
$[29] =
|
|
223
|
-
$[30] =
|
|
224
|
-
$[31] =
|
|
225
|
-
$[32] =
|
|
226
|
-
$[33] =
|
|
227
|
-
$[34] =
|
|
228
|
-
} else
|
|
229
|
-
let
|
|
230
|
-
if ($[35] !==
|
|
231
|
-
|
|
218
|
+
$[29] = t12;
|
|
219
|
+
$[30] = t13;
|
|
220
|
+
$[31] = t14;
|
|
221
|
+
$[32] = t15;
|
|
222
|
+
$[33] = t16;
|
|
223
|
+
$[34] = t17;
|
|
224
|
+
} else t17 = $[34];
|
|
225
|
+
let t18;
|
|
226
|
+
if ($[35] !== t17 || $[36] !== uploadFiles) {
|
|
227
|
+
t18 = /* @__PURE__ */ jsx("div", {
|
|
232
228
|
className: "flex min-h-0 min-w-0 flex-1 flex-col",
|
|
233
229
|
children: /* @__PURE__ */ jsx(UploadDropZone, {
|
|
234
230
|
onDrop: uploadFiles,
|
|
235
231
|
className: "flex min-h-0 flex-1 flex-col",
|
|
236
|
-
children:
|
|
232
|
+
children: t17
|
|
237
233
|
})
|
|
238
234
|
});
|
|
239
|
-
$[35] =
|
|
235
|
+
$[35] = t17;
|
|
240
236
|
$[36] = uploadFiles;
|
|
241
|
-
$[37] =
|
|
242
|
-
} else
|
|
243
|
-
let
|
|
237
|
+
$[37] = t18;
|
|
238
|
+
} else t18 = $[37];
|
|
239
|
+
let t19;
|
|
244
240
|
if ($[38] !== clearAll || $[39] !== uploads) {
|
|
245
|
-
|
|
241
|
+
t19 = /* @__PURE__ */ jsx(UploadProgressDrawer, {
|
|
246
242
|
uploads,
|
|
247
243
|
onClose: clearAll
|
|
248
244
|
});
|
|
249
245
|
$[38] = clearAll;
|
|
250
246
|
$[39] = uploads;
|
|
251
|
-
$[40] =
|
|
252
|
-
} else
|
|
253
|
-
let
|
|
247
|
+
$[40] = t19;
|
|
248
|
+
} else t19 = $[40];
|
|
249
|
+
let t20;
|
|
254
250
|
if ($[41] !== deleteFiles || $[42] !== selectedIds) {
|
|
255
|
-
|
|
251
|
+
t20 = selectedIds.size > 0 && /* @__PURE__ */ jsxs(FloatingToolbar, {
|
|
256
252
|
className: "bottom-4 min-w-xs justify-between gap-4 pl-3",
|
|
257
253
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
258
254
|
className: "text-muted-foreground",
|
|
@@ -274,11 +270,11 @@ const ContentAssets = () => {
|
|
|
274
270
|
});
|
|
275
271
|
$[41] = deleteFiles;
|
|
276
272
|
$[42] = selectedIds;
|
|
277
|
-
$[43] =
|
|
278
|
-
} else
|
|
279
|
-
let
|
|
273
|
+
$[43] = t20;
|
|
274
|
+
} else t20 = $[43];
|
|
275
|
+
let t21;
|
|
280
276
|
if ($[44] !== lightboxFileId) {
|
|
281
|
-
|
|
277
|
+
t21 = lightboxFileId && /* @__PURE__ */ jsx(AssetLightbox, {
|
|
282
278
|
open: true,
|
|
283
279
|
onOpenChange: (open) => {
|
|
284
280
|
if (!open) setLightboxFileId(null);
|
|
@@ -286,23 +282,23 @@ const ContentAssets = () => {
|
|
|
286
282
|
fileId: lightboxFileId
|
|
287
283
|
});
|
|
288
284
|
$[44] = lightboxFileId;
|
|
289
|
-
$[45] =
|
|
290
|
-
} else
|
|
291
|
-
let
|
|
292
|
-
if ($[46] !==
|
|
293
|
-
|
|
294
|
-
t17,
|
|
285
|
+
$[45] = t21;
|
|
286
|
+
} else t21 = $[45];
|
|
287
|
+
let t22;
|
|
288
|
+
if ($[46] !== t18 || $[47] !== t19 || $[48] !== t20 || $[49] !== t21) {
|
|
289
|
+
t22 = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
295
290
|
t18,
|
|
296
291
|
t19,
|
|
297
|
-
t20
|
|
292
|
+
t20,
|
|
293
|
+
t21
|
|
298
294
|
] });
|
|
299
|
-
$[46] =
|
|
300
|
-
$[47] =
|
|
301
|
-
$[48] =
|
|
302
|
-
$[49] =
|
|
303
|
-
$[50] =
|
|
304
|
-
} else
|
|
305
|
-
return
|
|
295
|
+
$[46] = t18;
|
|
296
|
+
$[47] = t19;
|
|
297
|
+
$[48] = t20;
|
|
298
|
+
$[49] = t21;
|
|
299
|
+
$[50] = t22;
|
|
300
|
+
} else t22 = $[50];
|
|
301
|
+
return t22;
|
|
306
302
|
};
|
|
307
303
|
function _temp(prev) {
|
|
308
304
|
return prev.size === 0 ? prev : /* @__PURE__ */ new Set();
|
|
@@ -177,9 +177,15 @@ const ContentCollection = (t0) => {
|
|
|
177
177
|
itemId: record.id
|
|
178
178
|
}),
|
|
179
179
|
className: "focus-visible:bg-accent flex min-w-0 flex-1 items-center gap-2 px-4 py-3 text-sm",
|
|
180
|
-
children: [/* @__PURE__ */
|
|
181
|
-
className: "
|
|
182
|
-
children:
|
|
180
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
181
|
+
className: "flex min-w-0 flex-col items-start text-left",
|
|
182
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
183
|
+
className: "max-w-full truncate",
|
|
184
|
+
children: record.title || "Untitled item"
|
|
185
|
+
}), record.description && /* @__PURE__ */ jsx("span", {
|
|
186
|
+
className: "text-muted-foreground max-w-full truncate text-xs",
|
|
187
|
+
children: record.description
|
|
188
|
+
})]
|
|
183
189
|
}), record.duplicatePageValue && /* @__PURE__ */ jsx("span", {
|
|
184
190
|
className: "text-destructive shrink-0 text-xs",
|
|
185
191
|
title: "Another item's page has the same URL. Change one of them before publishing.",
|
|
@@ -189,7 +195,7 @@ const ContentCollection = (t0) => {
|
|
|
189
195
|
projectUuid,
|
|
190
196
|
collectionId: collection.collectionId,
|
|
191
197
|
id: record.id,
|
|
192
|
-
label: record.
|
|
198
|
+
label: record.title,
|
|
193
199
|
compact: true
|
|
194
200
|
})]
|
|
195
201
|
}, record.id)), /* @__PURE__ */ jsx("li", {
|
|
@@ -244,9 +250,9 @@ const ContentCollection = (t0) => {
|
|
|
244
250
|
return t14;
|
|
245
251
|
};
|
|
246
252
|
const fieldLabel = (name, schema) => schema.title ?? name.replace(/([A-Z])/g, " $1").replace(/^./, (letter) => letter.toUpperCase());
|
|
247
|
-
function CollectionItemForm({ contentSchema,
|
|
253
|
+
function CollectionItemForm({ contentSchema, toTitle, projectUuid, collectionId, record, initialContent, onSaved }) {
|
|
248
254
|
const studioCache = useStudioCache();
|
|
249
|
-
const fields = collectionFormFields(contentSchema,
|
|
255
|
+
const fields = collectionFormFields(contentSchema, toTitle);
|
|
250
256
|
const [savedRecord, setSavedRecord] = useState(record);
|
|
251
257
|
const [error, setError] = useState(null);
|
|
252
258
|
const create = useMutation(collectionMutations.create());
|
|
@@ -502,7 +508,7 @@ const ContentCollectionItemEditor = (t0) => {
|
|
|
502
508
|
if ($[20] !== collectionId || $[21] !== definition || $[22] !== initialContent || $[23] !== itemId || $[24] !== onSaved || $[25] !== projectUuid || $[26] !== recordQuery) {
|
|
503
509
|
t9 = definition && (!itemId || recordQuery.data) && /* @__PURE__ */ jsx(CollectionItemForm, {
|
|
504
510
|
contentSchema: definition.contentSchema,
|
|
505
|
-
|
|
511
|
+
toTitle: definition.toTitle,
|
|
506
512
|
projectUuid,
|
|
507
513
|
collectionId,
|
|
508
514
|
record: itemId ? recordQuery.data : void 0,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { isLexicalState, lexicalStateToPlainText } from "../../core/lib/lexicalState.js";
|
|
2
|
+
import { titleField } from "../../core/recordItem.js";
|
|
2
3
|
|
|
3
4
|
//#region src/features/content/collection-form.ts
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
/** The form's fields, the one the record's title starts with first. */
|
|
6
|
+
function collectionFormFields(contentSchema, toTitle) {
|
|
7
|
+
const schema = contentSchema;
|
|
8
|
+
const first = titleField(toTitle);
|
|
9
|
+
return Object.entries(schema.properties).sort(([a], [b]) => Number(b === first) - Number(a === first));
|
|
6
10
|
}
|
|
7
11
|
function collectionFormDefaults(fields, content = {}) {
|
|
8
12
|
return Object.fromEntries(fields.map(([name, schema]) => {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/features/og/pageImage.tsx
|
|
5
|
+
/** The size every page image renders at, which the page head states. */
|
|
6
|
+
const PAGE_IMAGE_SIZE = {
|
|
7
|
+
width: 1200,
|
|
8
|
+
height: 630
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A page's image, chosen in order: the editor's custom image, else `/og` for the page, which
|
|
12
|
+
* renders its layout's `toImage` or Camox's default image. `/og` names the page by its path,
|
|
13
|
+
* with its locale's prefix.
|
|
14
|
+
*/
|
|
15
|
+
function pageImageUrl({ origin, path, customImageUrl }) {
|
|
16
|
+
return customImageUrl || `${origin}/og?${new URLSearchParams({ path }).toString()}`;
|
|
17
|
+
}
|
|
18
|
+
/** Camox's default image, for a page whose layout has no `toImage`: its title and project. */
|
|
19
|
+
function DefaultPageImage(t0) {
|
|
20
|
+
const $ = c(9);
|
|
21
|
+
const { page, project } = t0;
|
|
22
|
+
let t1;
|
|
23
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
24
|
+
t1 = {
|
|
25
|
+
display: "flex",
|
|
26
|
+
flexDirection: "column",
|
|
27
|
+
justifyContent: "center",
|
|
28
|
+
width: "100%",
|
|
29
|
+
height: "100%",
|
|
30
|
+
backgroundColor: "#09090b",
|
|
31
|
+
padding: "60px 80px"
|
|
32
|
+
};
|
|
33
|
+
$[0] = t1;
|
|
34
|
+
} else t1 = $[0];
|
|
35
|
+
let t2;
|
|
36
|
+
if ($[1] !== project.name) {
|
|
37
|
+
t2 = project.name && /* @__PURE__ */ jsx("div", {
|
|
38
|
+
style: {
|
|
39
|
+
fontSize: 24,
|
|
40
|
+
color: "#a1a1aa",
|
|
41
|
+
marginBottom: 24,
|
|
42
|
+
textTransform: "uppercase",
|
|
43
|
+
letterSpacing: "0.1em"
|
|
44
|
+
},
|
|
45
|
+
children: project.name
|
|
46
|
+
});
|
|
47
|
+
$[1] = project.name;
|
|
48
|
+
$[2] = t2;
|
|
49
|
+
} else t2 = $[2];
|
|
50
|
+
let t3;
|
|
51
|
+
if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
|
|
52
|
+
t3 = {
|
|
53
|
+
fontSize: 64,
|
|
54
|
+
fontWeight: 700,
|
|
55
|
+
color: "#fafafa",
|
|
56
|
+
lineHeight: 1.2
|
|
57
|
+
};
|
|
58
|
+
$[3] = t3;
|
|
59
|
+
} else t3 = $[3];
|
|
60
|
+
let t4;
|
|
61
|
+
if ($[4] !== page.title) {
|
|
62
|
+
t4 = /* @__PURE__ */ jsx("div", {
|
|
63
|
+
style: t3,
|
|
64
|
+
children: page.title
|
|
65
|
+
});
|
|
66
|
+
$[4] = page.title;
|
|
67
|
+
$[5] = t4;
|
|
68
|
+
} else t4 = $[5];
|
|
69
|
+
let t5;
|
|
70
|
+
if ($[6] !== t2 || $[7] !== t4) {
|
|
71
|
+
t5 = /* @__PURE__ */ jsxs("div", {
|
|
72
|
+
style: t1,
|
|
73
|
+
children: [t2, t4]
|
|
74
|
+
});
|
|
75
|
+
$[6] = t2;
|
|
76
|
+
$[7] = t4;
|
|
77
|
+
$[8] = t5;
|
|
78
|
+
} else t5 = $[8];
|
|
79
|
+
return t5;
|
|
80
|
+
}
|
|
81
|
+
/** Renders a page image as a PNG response. Server only. */
|
|
82
|
+
async function renderPageImage(element) {
|
|
83
|
+
if (import.meta.env?.SSR === false) throw new Error("OG images can only be rendered on the server.");
|
|
84
|
+
const { ImageResponse } = await import("camox/_internal/imageResponse");
|
|
85
|
+
return new ImageResponse(element, PAGE_IMAGE_SIZE);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { DefaultPageImage, PAGE_IMAGE_SIZE, pageImageUrl, renderPageImage };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { useProjectUuid } from "../../lib/auth.js";
|
|
2
|
+
import { useViewLocale } from "../../lib/view-locale-context.js";
|
|
2
3
|
import { useCamoxApp } from "../provider/components/CamoxAppContext.js";
|
|
3
4
|
import { NormalizedDataProvider, usePageBlocks } from "../../lib/normalized-data.js";
|
|
4
5
|
import { reads, useRead } from "../../lib/studio-reads.js";
|
|
5
6
|
import { BlockErrorBoundary } from "../preview/components/BlockErrorBoundary.js";
|
|
7
|
+
import { curatedLayoutContext } from "../../core/layoutContext.js";
|
|
6
8
|
import { useLocalePath } from "../../lib/view-locale.js";
|
|
7
9
|
import { SharedLayoutContent } from "./SharedLayoutContent.js";
|
|
8
10
|
import { c } from "react/compiler-runtime";
|
|
@@ -84,7 +86,7 @@ function PageBlock(t0) {
|
|
|
84
86
|
}
|
|
85
87
|
/** A curated page as visitors see it, without editing. */
|
|
86
88
|
function CuratedPageContent() {
|
|
87
|
-
const $ = c(
|
|
89
|
+
const $ = c(23);
|
|
88
90
|
const pathname = useLocalePath();
|
|
89
91
|
const projectUuid = useProjectUuid();
|
|
90
92
|
const camoxApp = useCamoxApp();
|
|
@@ -108,49 +110,60 @@ function CuratedPageContent() {
|
|
|
108
110
|
$[5] = t1;
|
|
109
111
|
} else t1 = $[5];
|
|
110
112
|
const layout = t1;
|
|
113
|
+
const { locale } = useViewLocale();
|
|
111
114
|
let t2;
|
|
112
|
-
if ($[6] !==
|
|
113
|
-
t2 =
|
|
114
|
-
$[6] =
|
|
115
|
-
$[7] =
|
|
116
|
-
|
|
117
|
-
|
|
115
|
+
if ($[6] !== locale || $[7] !== pageData) {
|
|
116
|
+
t2 = curatedLayoutContext(pageData, locale);
|
|
117
|
+
$[6] = locale;
|
|
118
|
+
$[7] = pageData;
|
|
119
|
+
$[8] = t2;
|
|
120
|
+
} else t2 = $[8];
|
|
121
|
+
const context = t2;
|
|
122
|
+
let t3;
|
|
123
|
+
if ($[9] !== pageBlocks) {
|
|
124
|
+
t3 = pageBlocks.map(_temp);
|
|
125
|
+
$[9] = pageBlocks;
|
|
126
|
+
$[10] = t3;
|
|
127
|
+
} else t3 = $[10];
|
|
128
|
+
const pageBlocksContent = t3;
|
|
118
129
|
if (!layout) {
|
|
119
|
-
let
|
|
120
|
-
if ($[
|
|
121
|
-
|
|
130
|
+
let t4;
|
|
131
|
+
if ($[11] !== pageBlocksContent) {
|
|
132
|
+
t4 = /* @__PURE__ */ jsx("main", {
|
|
122
133
|
className: "flex min-h-screen flex-col",
|
|
123
134
|
children: pageBlocksContent
|
|
124
135
|
});
|
|
125
|
-
$[
|
|
126
|
-
$[
|
|
127
|
-
} else
|
|
128
|
-
return
|
|
136
|
+
$[11] = pageBlocksContent;
|
|
137
|
+
$[12] = t4;
|
|
138
|
+
} else t4 = $[12];
|
|
139
|
+
return t4;
|
|
129
140
|
}
|
|
130
|
-
let t3;
|
|
131
|
-
if ($[10] !== afterBlocks || $[11] !== beforeBlocks) {
|
|
132
|
-
t3 = [...beforeBlocks, ...afterBlocks];
|
|
133
|
-
$[10] = afterBlocks;
|
|
134
|
-
$[11] = beforeBlocks;
|
|
135
|
-
$[12] = t3;
|
|
136
|
-
} else t3 = $[12];
|
|
137
141
|
let t4;
|
|
138
|
-
if ($[13] !==
|
|
139
|
-
t4 =
|
|
142
|
+
if ($[13] !== afterBlocks || $[14] !== beforeBlocks) {
|
|
143
|
+
t4 = [...beforeBlocks, ...afterBlocks];
|
|
144
|
+
$[13] = afterBlocks;
|
|
145
|
+
$[14] = beforeBlocks;
|
|
146
|
+
$[15] = t4;
|
|
147
|
+
} else t4 = $[15];
|
|
148
|
+
let t5;
|
|
149
|
+
if ($[16] !== context || $[17] !== layout || $[18] !== layoutFiles || $[19] !== layoutItems || $[20] !== pageBlocksContent || $[21] !== t4) {
|
|
150
|
+
t5 = /* @__PURE__ */ jsx(SharedLayoutContent, {
|
|
140
151
|
layout,
|
|
141
|
-
|
|
152
|
+
context,
|
|
153
|
+
blocks: t4,
|
|
142
154
|
files: layoutFiles,
|
|
143
155
|
repeatableItems: layoutItems,
|
|
144
156
|
children: pageBlocksContent
|
|
145
157
|
});
|
|
146
|
-
$[
|
|
147
|
-
$[
|
|
148
|
-
$[
|
|
149
|
-
$[
|
|
150
|
-
$[
|
|
151
|
-
$[
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
$[16] = context;
|
|
159
|
+
$[17] = layout;
|
|
160
|
+
$[18] = layoutFiles;
|
|
161
|
+
$[19] = layoutItems;
|
|
162
|
+
$[20] = pageBlocksContent;
|
|
163
|
+
$[21] = t4;
|
|
164
|
+
$[22] = t5;
|
|
165
|
+
} else t5 = $[22];
|
|
166
|
+
return t5;
|
|
154
167
|
}
|
|
155
168
|
function _temp(block) {
|
|
156
169
|
return /* @__PURE__ */ jsx(BlockErrorBoundary, {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { useViewLocale } from "../../lib/view-locale-context.js";
|
|
1
2
|
import { usePageBlocks } from "../../lib/normalized-data.js";
|
|
3
|
+
import { asCollectionItem, recordPageValues } from "../../core/recordItem.js";
|
|
4
|
+
import { buildLayoutContext } from "../../core/layoutContext.js";
|
|
2
5
|
import { SharedLayoutContent } from "./SharedLayoutContent.js";
|
|
3
6
|
import { c } from "react/compiler-runtime";
|
|
4
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -6,7 +9,7 @@ import { jsx } from "react/jsx-runtime";
|
|
|
6
9
|
//#region src/features/page/DerivedPageContent.tsx
|
|
7
10
|
const EMPTY_PAGE = { blockIds: [] };
|
|
8
11
|
function DerivedPageContent(t0) {
|
|
9
|
-
const $ = c(
|
|
12
|
+
const $ = c(18);
|
|
10
13
|
const { camoxApp, derived } = t0;
|
|
11
14
|
let t1;
|
|
12
15
|
if ($[0] !== derived.layout) {
|
|
@@ -18,38 +21,62 @@ function DerivedPageContent(t0) {
|
|
|
18
21
|
$[1] = t1;
|
|
19
22
|
} else t1 = $[1];
|
|
20
23
|
const { beforeBlocks, afterBlocks, layoutFiles, layoutItems } = usePageBlocks(t1);
|
|
24
|
+
const { locale } = useViewLocale();
|
|
25
|
+
let layout;
|
|
26
|
+
let result;
|
|
21
27
|
let t2;
|
|
22
|
-
if ($[2] !== camoxApp || $[3] !== derived
|
|
23
|
-
|
|
28
|
+
if ($[2] !== camoxApp || $[3] !== derived || $[4] !== locale) {
|
|
29
|
+
layout = camoxApp.getLayoutById(derived.layoutId);
|
|
30
|
+
if (!layout) throw new Error(`Unknown derived layout: ${derived.layoutId}`);
|
|
31
|
+
const { page, result: t3 } = derived;
|
|
32
|
+
result = t3;
|
|
33
|
+
const record = asCollectionItem(result);
|
|
34
|
+
const collection = record && camoxApp.getCollectionById(record.collectionId);
|
|
35
|
+
t2 = buildLayoutContext(layout._internal, {
|
|
36
|
+
path: page?.path ?? "",
|
|
37
|
+
locale: locale.tag,
|
|
38
|
+
projectName: page?.projectName ?? "",
|
|
39
|
+
data: result?.data,
|
|
40
|
+
params: page?.params,
|
|
41
|
+
record: record && collection ? recordPageValues(collection, record) : void 0
|
|
42
|
+
});
|
|
24
43
|
$[2] = camoxApp;
|
|
25
|
-
$[3] = derived
|
|
26
|
-
$[4] =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
44
|
+
$[3] = derived;
|
|
45
|
+
$[4] = locale;
|
|
46
|
+
$[5] = layout;
|
|
47
|
+
$[6] = result;
|
|
48
|
+
$[7] = t2;
|
|
49
|
+
} else {
|
|
50
|
+
layout = $[5];
|
|
51
|
+
result = $[6];
|
|
52
|
+
t2 = $[7];
|
|
53
|
+
}
|
|
54
|
+
const context = t2;
|
|
30
55
|
let t3;
|
|
31
|
-
if ($[
|
|
56
|
+
if ($[8] !== afterBlocks || $[9] !== beforeBlocks) {
|
|
32
57
|
t3 = [...beforeBlocks, ...afterBlocks];
|
|
33
|
-
$[
|
|
34
|
-
$[
|
|
35
|
-
$[
|
|
36
|
-
} else t3 = $[
|
|
58
|
+
$[8] = afterBlocks;
|
|
59
|
+
$[9] = beforeBlocks;
|
|
60
|
+
$[10] = t3;
|
|
61
|
+
} else t3 = $[10];
|
|
37
62
|
let t4;
|
|
38
|
-
if ($[
|
|
63
|
+
if ($[11] !== context || $[12] !== layout || $[13] !== layoutFiles || $[14] !== layoutItems || $[15] !== result || $[16] !== t3) {
|
|
39
64
|
t4 = /* @__PURE__ */ jsx(SharedLayoutContent, {
|
|
40
65
|
layout,
|
|
41
|
-
|
|
66
|
+
context,
|
|
67
|
+
result,
|
|
42
68
|
blocks: t3,
|
|
43
69
|
files: layoutFiles,
|
|
44
70
|
repeatableItems: layoutItems
|
|
45
71
|
});
|
|
46
|
-
$[
|
|
47
|
-
$[
|
|
48
|
-
$[
|
|
49
|
-
$[
|
|
50
|
-
$[
|
|
51
|
-
$[
|
|
52
|
-
|
|
72
|
+
$[11] = context;
|
|
73
|
+
$[12] = layout;
|
|
74
|
+
$[13] = layoutFiles;
|
|
75
|
+
$[14] = layoutItems;
|
|
76
|
+
$[15] = result;
|
|
77
|
+
$[16] = t3;
|
|
78
|
+
$[17] = t4;
|
|
79
|
+
} else t4 = $[17];
|
|
53
80
|
return t4;
|
|
54
81
|
}
|
|
55
82
|
|