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.
Files changed (117) hide show
  1. package/dist/core/createApp.d.ts +19 -6
  2. package/dist/core/createApp.js +7 -2
  3. package/dist/core/createBlock.js +54 -43
  4. package/dist/core/createCollection.d.ts +25 -7
  5. package/dist/core/createCollection.js +28 -9
  6. package/dist/core/createLayout.d.ts +98 -71
  7. package/dist/core/createLayout.js +10 -16
  8. package/dist/core/derivedRoutes.js +1 -1
  9. package/dist/core/editing/BlockEditingRuntime.d.ts +3 -2
  10. package/dist/core/editing/CompleteBlockEditingRuntime.js +2 -1
  11. package/dist/core/editing/createEditableBlock.d.ts +59 -19
  12. package/dist/core/editing/createEditableBlock.js +162 -151
  13. package/dist/core/editing/useLatestRecord.js +7 -7
  14. package/dist/core/layoutContext.d.ts +55 -0
  15. package/dist/core/layoutContext.js +66 -0
  16. package/dist/core/lib/contentType.d.ts +91 -4
  17. package/dist/core/lib/contentType.js +84 -7
  18. package/dist/core/lib/recordScope.js +19 -17
  19. package/dist/core/lib/reference.d.ts +6 -2
  20. package/dist/core/recordItem.js +55 -2
  21. package/dist/core/requestContext.d.ts +18 -0
  22. package/dist/core/structuredData.d.ts +126 -0
  23. package/dist/core/structuredData.js +40 -0
  24. package/dist/features/canvas/canvasCamera.js +1 -1
  25. package/dist/features/canvas/sidebar/CanvasInspector.js +1 -1
  26. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +1 -1
  27. package/dist/features/content/ContentAssets.js +84 -88
  28. package/dist/features/content/ContentCollection.js +13 -7
  29. package/dist/features/content/collection-form.js +6 -2
  30. package/dist/features/content/components/MissingFromLocale.js +1 -1
  31. package/dist/features/og/pageImage.js +89 -0
  32. package/dist/features/page/CuratedPageContent.js +45 -32
  33. package/dist/features/page/DerivedPageContent.js +49 -22
  34. package/dist/features/page/SharedLayoutContent.js +26 -22
  35. package/dist/features/preview/CamoxPreview.js +41 -27
  36. package/dist/features/preview/EditablePageExperience.js +17 -9
  37. package/dist/features/preview/components/AddBlockSheet.js +1 -0
  38. package/dist/features/preview/components/BlockActionsPopover.js +19 -41
  39. package/dist/features/preview/components/FieldToolbar.js +1 -1
  40. package/dist/features/preview/components/MobilePreviewDrawer.js +6 -9
  41. package/dist/features/preview/components/PageInfo.js +244 -264
  42. package/dist/features/preview/components/PageTree.js +63 -53
  43. package/dist/features/preview/components/PreviewPanel.js +10 -64
  44. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  45. package/dist/features/preview/components/RecordCard.js +50 -34
  46. package/dist/features/preview/components/RecordCombobox.js +12 -5
  47. package/dist/features/preview/components/ReferenceFieldEditor.js +4 -2
  48. package/dist/features/preview/components/ReferenceListFieldEditor.js +24 -19
  49. package/dist/features/preview/components/RepeatableItemsList.js +62 -46
  50. package/dist/features/preview/components/SelectionEditor.js +3 -2
  51. package/dist/features/preview/components/useFieldWriter.js +2 -4
  52. package/dist/features/preview/components/useRecordView.js +2 -2
  53. package/dist/features/preview/entityName.js +11 -0
  54. package/dist/features/preview/pageRecord.js +17 -18
  55. package/dist/features/preview/previewConstants.js +2 -8
  56. package/dist/features/preview/usePreviewViewportActions.js +1 -1
  57. package/dist/features/provider/AuthenticatedCamoxProvider.js +1 -1
  58. package/dist/features/provider/components/CommandPalette.js +2 -5
  59. package/dist/features/provider/signInShortcut.js +1 -2
  60. package/dist/features/provider/useAdminShortcuts.js +47 -53
  61. package/dist/features/routes/pageRuntime.d.ts +17 -2
  62. package/dist/features/routes/pageRuntime.js +61 -57
  63. package/dist/features/runtime/RuntimeChrome.js +1 -1
  64. package/dist/features/runtime/breadcrumbs.js +68 -0
  65. package/dist/features/runtime/livePages.js +3 -2
  66. package/dist/features/runtime/pageGraph.js +92 -0
  67. package/dist/features/runtime/projectLogo.js +110 -0
  68. package/dist/features/runtime/publicCache.js +83 -0
  69. package/dist/features/runtime/runtime.d.ts +24 -9
  70. package/dist/features/runtime/runtime.js +447 -130
  71. package/dist/features/runtime/runtimeRoutes.d.ts +1 -0
  72. package/dist/features/runtime/runtimeRoutes.js +1 -0
  73. package/dist/features/runtime/structuredData.js +213 -0
  74. package/dist/features/runtime/worker.d.ts +5 -1
  75. package/dist/features/runtime/worker.js +20 -3
  76. package/dist/features/settings/AnalyticsSettings.js +622 -0
  77. package/dist/features/settings/CamoxSettings.js +95 -0
  78. package/dist/features/settings/FaviconSettings.js +254 -0
  79. package/dist/features/settings/ProjectNameSettings.js +145 -0
  80. package/dist/features/settings/SettingsPart.js +73 -0
  81. package/dist/features/settings/SocialProfilesSettings.js +245 -0
  82. package/dist/features/settings/useProjectMutation.js +61 -0
  83. package/dist/features/studio/components/ChatSidebar.js +5 -5
  84. package/dist/features/studio/components/DraftsControl.js +136 -131
  85. package/dist/features/studio/components/LocalePicker.js +178 -174
  86. package/dist/features/studio/components/Navbar.js +107 -66
  87. package/dist/features/studio/components/ProjectMenu.js +85 -110
  88. package/dist/features/studio/components/ReviewDraftSheet.js +1046 -990
  89. package/dist/features/studio/components/ThreadMessages.js +2 -2
  90. package/dist/features/studio/components/UserButton.js +1 -1
  91. package/dist/features/studio/routes.js +3 -1
  92. package/dist/features/studio/showInCanvas.js +129 -0
  93. package/dist/features/vite/blockBoilerplate.js +3 -2
  94. package/dist/features/vite/definitionsSync.js +4 -5
  95. package/dist/features/vite/layoutGeneration.js +3 -2
  96. package/dist/features/vite/runtimeDev.js +32 -17
  97. package/dist/features/vite/staticAssetHeaders.js +52 -0
  98. package/dist/features/vite/vite.d.ts +1 -1
  99. package/dist/features/vite/vite.js +17 -4
  100. package/dist/lib/api-client-server.d.ts +1 -1
  101. package/dist/lib/api-client.d.ts +2 -1
  102. package/dist/lib/draft-scope.d.ts +1 -0
  103. package/dist/lib/locale-path.d.ts +3 -11
  104. package/dist/lib/locale-path.js +3 -27
  105. package/dist/lib/queries.d.ts +4 -0
  106. package/dist/lib/queries.js +8 -1
  107. package/dist/lib/shortcuts.js +29 -0
  108. package/dist/lib/studio-reads.d.ts +1 -0
  109. package/dist/lib/studio-reads.js +3 -1
  110. package/dist/lib/utils.js +1 -104
  111. package/dist/package.js +1 -1
  112. package/dist/studio.css +1 -1
  113. package/package.json +6 -4
  114. package/skills/camox/references/block-definitions.md +105 -25
  115. package/skills/camox/references/layout-definitions.md +53 -17
  116. package/skills/camox/references/routed-layouts.md +17 -14
  117. package/dist/features/studio/components/FaviconDialog.js +0 -318
@@ -1,318 +0,0 @@
1
- import { getApiUrl } from "../../../lib/api-client.js";
2
- import { reads, useStudioCache } from "../../../lib/studio-reads.js";
3
- import { projectMutations } from "../../../lib/queries.js";
4
- import { buildDefaultFaviconUrl, buildFaviconUrl } from "../../routes/pageRuntime.js";
5
- import { c } from "react/compiler-runtime";
6
- import * as React from "react";
7
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { useMutation } from "@tanstack/react-query";
9
- import { Button } from "@camox/ui/button";
10
- import { Trash2, TriangleAlert } from "lucide-react";
11
- import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@camox/ui/dialog";
12
- import { toast } from "@camox/ui/toaster";
13
- import { Spinner } from "@camox/ui/spinner";
14
- import { Alert, AlertDescription } from "@camox/ui/alert";
15
- import { FaviconDropZone, validateFaviconFile } from "@camox/ui/favicon-drop-zone";
16
-
17
- //#region src/features/studio/components/FaviconDialog.tsx
18
- /** Points the studio tab's own icon at the saved favicon, so the change shows without a reload. */
19
- function refreshDocumentFavicon(href) {
20
- for (const link of document.querySelectorAll("link[rel~=\"icon\"]")) link.href = href;
21
- }
22
- function FaviconDialog(t0) {
23
- const $ = c(9);
24
- const { project, open, onOpenChange } = t0;
25
- let t1;
26
- if ($[0] !== onOpenChange) {
27
- t1 = () => onOpenChange(false);
28
- $[0] = onOpenChange;
29
- $[1] = t1;
30
- } else t1 = $[1];
31
- let t2;
32
- if ($[2] !== project || $[3] !== t1) {
33
- t2 = /* @__PURE__ */ jsx(DialogContent, {
34
- className: "gap-5 sm:max-w-md",
35
- children: /* @__PURE__ */ jsx(FaviconForm, {
36
- project,
37
- onSaved: t1
38
- })
39
- });
40
- $[2] = project;
41
- $[3] = t1;
42
- $[4] = t2;
43
- } else t2 = $[4];
44
- let t3;
45
- if ($[5] !== onOpenChange || $[6] !== open || $[7] !== t2) {
46
- t3 = /* @__PURE__ */ jsx(Dialog, {
47
- open,
48
- onOpenChange,
49
- children: t2
50
- });
51
- $[5] = onOpenChange;
52
- $[6] = open;
53
- $[7] = t2;
54
- $[8] = t3;
55
- } else t3 = $[8];
56
- return t3;
57
- }
58
- function FaviconForm(t0) {
59
- const $ = c(56);
60
- const { project, onSaved } = t0;
61
- const studioCache = useStudioCache();
62
- const [pending, setPending] = React.useState(null);
63
- const [hasCurrent, setHasCurrent] = React.useState(false);
64
- let t1;
65
- if ($[0] !== project) {
66
- t1 = buildFaviconUrl(getApiUrl(), project, { withDefault: false });
67
- $[0] = project;
68
- $[1] = t1;
69
- } else t1 = $[1];
70
- const currentUrl = t1;
71
- let t2;
72
- let t3;
73
- if ($[2] !== currentUrl) {
74
- t2 = () => {
75
- const probe = new Image();
76
- probe.onload = () => setHasCurrent(true);
77
- probe.onerror = () => setHasCurrent(false);
78
- probe.src = currentUrl;
79
- return () => {
80
- probe.onload = null;
81
- probe.onerror = null;
82
- };
83
- };
84
- t3 = [currentUrl];
85
- $[2] = currentUrl;
86
- $[3] = t2;
87
- $[4] = t3;
88
- } else {
89
- t2 = $[3];
90
- t3 = $[4];
91
- }
92
- React.useEffect(t2, t3);
93
- const pendingFile = pending?.type === "upload" ? pending.file : null;
94
- let t4;
95
- if ($[5] !== pendingFile) {
96
- t4 = pendingFile ? URL.createObjectURL(pendingFile) : null;
97
- $[5] = pendingFile;
98
- $[6] = t4;
99
- } else t4 = $[6];
100
- const pendingUrl = t4;
101
- let t5;
102
- let t6;
103
- if ($[7] !== pendingUrl) {
104
- t5 = () => {
105
- if (!pendingUrl) return;
106
- return () => URL.revokeObjectURL(pendingUrl);
107
- };
108
- t6 = [pendingUrl];
109
- $[7] = pendingUrl;
110
- $[8] = t5;
111
- $[9] = t6;
112
- } else {
113
- t5 = $[8];
114
- t6 = $[9];
115
- }
116
- React.useEffect(t5, t6);
117
- let t7;
118
- if ($[10] !== onSaved || $[11] !== pending?.type || $[12] !== project || $[13] !== studioCache) {
119
- t7 = async () => {
120
- await studioCache.invalidate(reads.project({ projectUuid: project.uuid }));
121
- const updated = studioCache.get(reads.project({ projectUuid: project.uuid }));
122
- refreshDocumentFavicon(buildFaviconUrl(getApiUrl(), updated ?? project));
123
- toast.success(pending?.type === "remove" ? "Favicon removed" : "Favicon updated");
124
- onSaved();
125
- };
126
- $[10] = onSaved;
127
- $[11] = pending?.type;
128
- $[12] = project;
129
- $[13] = studioCache;
130
- $[14] = t7;
131
- } else t7 = $[14];
132
- const onSuccess = t7;
133
- const onError = _temp;
134
- let t8;
135
- if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
136
- t8 = projectMutations.uploadFavicon();
137
- $[15] = t8;
138
- } else t8 = $[15];
139
- let t9;
140
- if ($[16] !== onSuccess) {
141
- t9 = {
142
- ...t8,
143
- onSuccess,
144
- onError
145
- };
146
- $[16] = onSuccess;
147
- $[17] = t9;
148
- } else t9 = $[17];
149
- const upload = useMutation(t9);
150
- let t10;
151
- if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
152
- t10 = projectMutations.deleteFavicon();
153
- $[18] = t10;
154
- } else t10 = $[18];
155
- let t11;
156
- if ($[19] !== onSuccess) {
157
- t11 = {
158
- ...t10,
159
- onSuccess,
160
- onError
161
- };
162
- $[19] = onSuccess;
163
- $[20] = t11;
164
- } else t11 = $[20];
165
- const remove = useMutation(t11);
166
- const isSaving = upload.isPending || remove.isPending;
167
- let t12;
168
- if ($[21] === Symbol.for("react.memo_cache_sentinel")) {
169
- t12 = (file) => {
170
- const error_0 = validateFaviconFile(file);
171
- if (error_0) {
172
- toast.error(error_0);
173
- return;
174
- }
175
- setPending({
176
- type: "upload",
177
- file
178
- });
179
- };
180
- $[21] = t12;
181
- } else t12 = $[21];
182
- const choose = t12;
183
- let t13;
184
- if ($[22] !== pending || $[23] !== project || $[24] !== remove || $[25] !== upload) {
185
- t13 = () => {
186
- if (pending?.type === "upload") {
187
- upload.mutate({
188
- projectId: project.id,
189
- file: pending.file
190
- });
191
- return;
192
- }
193
- if (pending?.type === "remove") remove.mutate({ projectId: project.id });
194
- };
195
- $[22] = pending;
196
- $[23] = project;
197
- $[24] = remove;
198
- $[25] = upload;
199
- $[26] = t13;
200
- } else t13 = $[26];
201
- const save = t13;
202
- const showsFavicon = pending ? pending.type === "upload" : hasCurrent;
203
- let t14;
204
- if ($[27] !== currentUrl || $[28] !== pendingUrl || $[29] !== showsFavicon) {
205
- t14 = pendingUrl ?? (showsFavicon ? currentUrl : buildDefaultFaviconUrl(getApiUrl()));
206
- $[27] = currentUrl;
207
- $[28] = pendingUrl;
208
- $[29] = showsFavicon;
209
- $[30] = t14;
210
- } else t14 = $[30];
211
- const previewUrl = t14;
212
- const prompt = pendingFile ? pendingFile.name : showsFavicon ? "Drop a new favicon, or click to browse" : "Drop your favicon here, or click to browse";
213
- let t15;
214
- if ($[31] === Symbol.for("react.memo_cache_sentinel")) {
215
- t15 = /* @__PURE__ */ jsxs(DialogHeader, { children: [/* @__PURE__ */ jsx(DialogTitle, { children: "Favicon" }), /* @__PURE__ */ jsx(DialogDescription, { children: "The icon shown in browser tabs and bookmarks." })] });
216
- $[31] = t15;
217
- } else t15 = $[31];
218
- let t16;
219
- if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
220
- t16 = /* @__PURE__ */ jsxs(Alert, {
221
- variant: "warning",
222
- children: [/* @__PURE__ */ jsx(TriangleAlert, {}), /* @__PURE__ */ jsx(AlertDescription, { children: "Applies to the whole site, including Live and every draft." })]
223
- });
224
- $[32] = t16;
225
- } else t16 = $[32];
226
- let t17;
227
- if ($[33] !== isSaving || $[34] !== previewUrl || $[35] !== prompt) {
228
- t17 = /* @__PURE__ */ jsx(FaviconDropZone, {
229
- previewUrl,
230
- prompt,
231
- disabled: isSaving,
232
- onFileSelected: choose
233
- });
234
- $[33] = isSaving;
235
- $[34] = previewUrl;
236
- $[35] = prompt;
237
- $[36] = t17;
238
- } else t17 = $[36];
239
- let t18;
240
- if ($[37] !== hasCurrent || $[38] !== isSaving || $[39] !== showsFavicon) {
241
- t18 = showsFavicon && /* @__PURE__ */ jsxs(Button, {
242
- type: "button",
243
- variant: "ghost",
244
- className: "sm:mr-auto",
245
- disabled: isSaving,
246
- onClick: () => setPending(hasCurrent ? { type: "remove" } : null),
247
- children: [/* @__PURE__ */ jsx(Trash2, {}), "Remove favicon"]
248
- });
249
- $[37] = hasCurrent;
250
- $[38] = isSaving;
251
- $[39] = showsFavicon;
252
- $[40] = t18;
253
- } else t18 = $[40];
254
- let t19;
255
- if ($[41] !== isSaving) {
256
- t19 = /* @__PURE__ */ jsx(DialogClose, {
257
- render: /* @__PURE__ */ jsx(Button, {
258
- type: "button",
259
- variant: "outline",
260
- disabled: isSaving
261
- }),
262
- children: "Cancel"
263
- });
264
- $[41] = isSaving;
265
- $[42] = t19;
266
- } else t19 = $[42];
267
- const t20 = !pending || isSaving;
268
- let t21;
269
- if ($[43] !== isSaving) {
270
- t21 = isSaving && /* @__PURE__ */ jsx(Spinner, {});
271
- $[43] = isSaving;
272
- $[44] = t21;
273
- } else t21 = $[44];
274
- let t22;
275
- if ($[45] !== save || $[46] !== t20 || $[47] !== t21) {
276
- t22 = /* @__PURE__ */ jsxs(Button, {
277
- type: "button",
278
- onClick: save,
279
- disabled: t20,
280
- children: [t21, "Save"]
281
- });
282
- $[45] = save;
283
- $[46] = t20;
284
- $[47] = t21;
285
- $[48] = t22;
286
- } else t22 = $[48];
287
- let t23;
288
- if ($[49] !== t18 || $[50] !== t19 || $[51] !== t22) {
289
- t23 = /* @__PURE__ */ jsxs(DialogFooter, { children: [
290
- t18,
291
- t19,
292
- t22
293
- ] });
294
- $[49] = t18;
295
- $[50] = t19;
296
- $[51] = t22;
297
- $[52] = t23;
298
- } else t23 = $[52];
299
- let t24;
300
- if ($[53] !== t17 || $[54] !== t23) {
301
- t24 = /* @__PURE__ */ jsxs(Fragment, { children: [
302
- t15,
303
- t16,
304
- t17,
305
- t23
306
- ] });
307
- $[53] = t17;
308
- $[54] = t23;
309
- $[55] = t24;
310
- } else t24 = $[55];
311
- return t24;
312
- }
313
- function _temp(error) {
314
- toast.error(error.message || "Could not save the favicon");
315
- }
316
-
317
- //#endregion
318
- export { FaviconDialog };