camox 0.32.0 → 0.33.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 (58) hide show
  1. package/dist/core/createBlock.d.ts +1 -1
  2. package/dist/core/createBlock.js +88 -108
  3. package/dist/core/hooks/useIsEditable.js +6 -10
  4. package/dist/core/lib/fieldTypes.js +10 -219
  5. package/dist/features/agent-chat/components/AgentChatSidebar.js +172 -0
  6. package/dist/features/agent-chat/components/AgentChatThread.js +9 -9
  7. package/dist/features/preview/CamoxPreview.js +137 -729
  8. package/dist/features/preview/components/{AddBlockSheet.js → AddBlockSidebar.js} +121 -131
  9. package/dist/features/preview/components/AssetFieldEditor.js +107 -82
  10. package/dist/features/preview/components/AssetLightbox.js +4 -4
  11. package/dist/features/preview/components/AssetPickerModal.js +277 -0
  12. package/dist/features/preview/components/BlockActionsPopover.js +18 -24
  13. package/dist/features/preview/components/CreatePageModal.js +6 -6
  14. package/dist/features/preview/components/FieldToolbar.js +64 -127
  15. package/dist/features/preview/components/ItemFieldsEditor.js +98 -125
  16. package/dist/features/preview/components/LeftSidebar.js +64 -0
  17. package/dist/features/preview/components/LinkFieldEditor.js +1 -1
  18. package/dist/features/preview/components/MultipleAssetFieldEditor.js +94 -56
  19. package/dist/features/preview/components/OverlayTracker.js +15 -15
  20. package/dist/features/preview/components/Overlays.js +12 -12
  21. package/dist/features/preview/components/PageEditorSidebar.js +563 -0
  22. package/dist/features/preview/components/PageInfoSidebar.js +1453 -0
  23. package/dist/features/preview/components/PageNavigatorSidebar.js +590 -0
  24. package/dist/features/preview/components/PagePicker.js +3 -3
  25. package/dist/features/preview/components/PageStatusBadge.js +1 -1
  26. package/dist/features/preview/components/PageTree.js +204 -564
  27. package/dist/features/preview/components/PreviewPanel.js +123 -158
  28. package/dist/features/preview/components/PreviewToolbar.js +260 -256
  29. package/dist/features/preview/components/PublishDialog.js +2 -2
  30. package/dist/features/preview/components/RepeatableItemsList.js +2 -2
  31. package/dist/features/preview/components/RightSidebar.js +109 -0
  32. package/dist/features/preview/components/UnlinkAssetButton.js +2 -2
  33. package/dist/features/preview/components/useRepeatableItemActions.js +3 -138
  34. package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
  35. package/dist/features/preview/previewQueryFns.js +23 -0
  36. package/dist/features/preview/previewStore.js +46 -63
  37. package/dist/features/provider/CamoxProvider.js +255 -70
  38. package/dist/features/provider/useAdminShortcuts.js +5 -48
  39. package/dist/features/routes/pageRoute.js +1 -1
  40. package/dist/features/studio/CamoxStudio.js +6 -5
  41. package/dist/features/studio/components/EnvironmentMenu.js +2 -2
  42. package/dist/features/studio/components/Navbar.js +53 -71
  43. package/dist/features/studio/components/ProjectMenu.js +1 -1
  44. package/dist/features/studio/components/UserButton.js +1 -1
  45. package/dist/features/studio/routes.js +7 -0
  46. package/dist/features/studio/useTheme.js +67 -33
  47. package/dist/features/vite/routeGeneration.js +68 -66
  48. package/dist/hooks/use-file-upload.js +1 -1
  49. package/dist/lib/auth.js +23 -22
  50. package/dist/lib/utils.js +1 -1
  51. package/dist/studio-overlays.css +1 -1
  52. package/dist/studio.css +1 -1
  53. package/package.json +4 -4
  54. package/dist/features/agent-chat/components/AgentChatSheet.js +0 -207
  55. package/dist/features/preview/components/AssetPickerGrid.js +0 -236
  56. package/dist/features/preview/components/PageContentSheet.js +0 -608
  57. package/dist/features/preview/components/PageMetadataModal.js +0 -908
  58. package/dist/features/preview/components/PreviewSideSheet.js +0 -76
@@ -1,207 +0,0 @@
1
- import { previewStore } from "../../preview/previewStore.js";
2
- import { PreviewSideSheet, Sheet } from "../../preview/components/PreviewSideSheet.js";
3
- import { useProjectSlug } from "../../../lib/auth.js";
4
- import { projectQueries } from "../../../lib/queries.js";
5
- import { AgentChatThread } from "./AgentChatThread.js";
6
- import { c } from "react/compiler-runtime";
7
- import { useQuery } from "@tanstack/react-query";
8
- import { useLocation } from "@tanstack/react-router";
9
- import { useSelector } from "@xstate/store-react";
10
- import * as React from "react";
11
- import { jsx, jsxs } from "react/jsx-runtime";
12
- import { Button } from "@camox/ui/button";
13
- import { Info, Lock, Plus, X } from "lucide-react";
14
- import { Alert, AlertDescription, AlertTitle } from "@camox/ui/alert";
15
-
16
- //#region src/features/agent-chat/components/AgentChatSheet.tsx
17
- const AgentChatSheet = () => {
18
- const $ = c(25);
19
- if ($[0] !== "66d93480e99ec8c64f18df9857d7ce7ad49013bef915961bf486d380834988ee") {
20
- for (let $i = 0; $i < 25; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
21
- $[0] = "66d93480e99ec8c64f18df9857d7ce7ad49013bef915961bf486d380834988ee";
22
- }
23
- const isOpen = useSelector(previewStore, _temp);
24
- const previewSource = useSelector(previewStore, _temp2);
25
- const pageScaffoldContext = useSelector(previewStore, _temp3);
26
- const [agentChatKey, setAgentChatKey] = React.useState(0);
27
- const [composerFocusKey, setComposerFocusKey] = React.useState(0);
28
- const { pathname } = useLocation();
29
- const projectSlug = useProjectSlug();
30
- let t0;
31
- if ($[1] !== projectSlug) {
32
- t0 = projectQueries.getBySlug(projectSlug);
33
- $[1] = projectSlug;
34
- $[2] = t0;
35
- } else t0 = $[2];
36
- const { data: project } = useQuery(t0);
37
- const isLiveSource = previewSource === "live";
38
- let t1;
39
- let t2;
40
- if ($[3] !== isOpen) {
41
- t1 = () => {
42
- if (!isOpen) return;
43
- setComposerFocusKey(_temp4);
44
- };
45
- t2 = [isOpen];
46
- $[3] = isOpen;
47
- $[4] = t1;
48
- $[5] = t2;
49
- } else {
50
- t1 = $[4];
51
- t2 = $[5];
52
- }
53
- React.useEffect(t1, t2);
54
- const handleOpenChange = _temp5;
55
- let t3;
56
- if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
57
- t3 = /* @__PURE__ */ jsx(Sheet.SheetTitle, {
58
- className: "flex-1",
59
- children: "Agent Chat"
60
- });
61
- $[6] = t3;
62
- } else t3 = $[6];
63
- let t4;
64
- if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
65
- t4 = /* @__PURE__ */ jsx(Button, {
66
- type: "button",
67
- variant: "ghost",
68
- size: "icon-sm",
69
- "aria-label": "Start a new Agent Chat",
70
- onClick: () => {
71
- previewStore.send({ type: "clearAgentChatPageScaffoldContext" });
72
- setAgentChatKey(_temp6);
73
- setComposerFocusKey(_temp7);
74
- },
75
- children: /* @__PURE__ */ jsx(Plus, { className: "size-4" })
76
- });
77
- $[7] = t4;
78
- } else t4 = $[7];
79
- let t5;
80
- if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
81
- t5 = /* @__PURE__ */ jsxs("div", {
82
- className: "flex items-center gap-1",
83
- children: [
84
- t3,
85
- t4,
86
- /* @__PURE__ */ jsx(Sheet.SheetClose, {
87
- render: /* @__PURE__ */ jsx(Button, {
88
- type: "button",
89
- variant: "ghost",
90
- size: "icon-sm",
91
- "aria-label": "Close"
92
- }),
93
- children: /* @__PURE__ */ jsx(X, { className: "size-4" })
94
- })
95
- ]
96
- });
97
- $[8] = t5;
98
- } else t5 = $[8];
99
- let t6;
100
- if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
101
- t6 = /* @__PURE__ */ jsxs(Sheet.SheetHeader, {
102
- className: "gap-4 pb-0",
103
- children: [t5, /* @__PURE__ */ jsxs(Alert, { children: [
104
- /* @__PURE__ */ jsx(Info, { className: "size-4" }),
105
- /* @__PURE__ */ jsx(AlertTitle, { children: "Camox is most powerful in your coding agent" }),
106
- /* @__PURE__ */ jsx(AlertDescription, { children: "Use Claude Code or Codex to manage your site with both code and content access." })
107
- ] })]
108
- });
109
- $[9] = t6;
110
- } else t6 = $[9];
111
- let t7;
112
- if ($[10] !== isLiveSource) {
113
- t7 = isLiveSource && /* @__PURE__ */ jsx("div", {
114
- className: "p-4 pb-0",
115
- children: /* @__PURE__ */ jsxs(Alert, { children: [
116
- /* @__PURE__ */ jsx(Lock, { className: "size-4" }),
117
- /* @__PURE__ */ jsx(AlertTitle, { children: "Live Source is read-only" }),
118
- /* @__PURE__ */ jsxs(AlertDescription, {
119
- className: "space-y-3",
120
- children: [/* @__PURE__ */ jsx("p", { children: "Agent Chat can inspect live content, but edits require switching to Draft Source." }), /* @__PURE__ */ jsx(Button, {
121
- type: "button",
122
- size: "sm",
123
- onClick: _temp8,
124
- children: "Switch to draft"
125
- })]
126
- })
127
- ] })
128
- });
129
- $[10] = isLiveSource;
130
- $[11] = t7;
131
- } else t7 = $[11];
132
- let t8;
133
- if ($[12] !== agentChatKey || $[13] !== composerFocusKey || $[14] !== pageScaffoldContext || $[15] !== pathname || $[16] !== previewSource || $[17] !== project) {
134
- t8 = project ? /* @__PURE__ */ jsx(AgentChatThread, {
135
- projectId: project.id,
136
- currentPath: pathname,
137
- source: previewSource,
138
- focusKey: composerFocusKey,
139
- pageScaffoldContext: pageScaffoldContext ?? void 0
140
- }, `${agentChatKey}:${pageScaffoldContext?.id ?? 0}`) : /* @__PURE__ */ jsx("div", {
141
- className: "text-muted-foreground flex flex-1 items-center justify-center p-6 text-sm",
142
- children: "Loading project…"
143
- });
144
- $[12] = agentChatKey;
145
- $[13] = composerFocusKey;
146
- $[14] = pageScaffoldContext;
147
- $[15] = pathname;
148
- $[16] = previewSource;
149
- $[17] = project;
150
- $[18] = t8;
151
- } else t8 = $[18];
152
- let t9;
153
- if ($[19] !== t7 || $[20] !== t8) {
154
- t9 = /* @__PURE__ */ jsxs("div", {
155
- className: "flex min-h-0 flex-1 flex-col",
156
- children: [t7, t8]
157
- });
158
- $[19] = t7;
159
- $[20] = t8;
160
- $[21] = t9;
161
- } else t9 = $[21];
162
- let t10;
163
- if ($[22] !== isOpen || $[23] !== t9) {
164
- t10 = /* @__PURE__ */ jsxs(PreviewSideSheet, {
165
- open: isOpen,
166
- onOpenChange: handleOpenChange,
167
- keepMounted: true,
168
- showCloseButton: false,
169
- initialFocus: false,
170
- children: [t6, t9]
171
- });
172
- $[22] = isOpen;
173
- $[23] = t9;
174
- $[24] = t10;
175
- } else t10 = $[24];
176
- return t10;
177
- };
178
- function _temp(state) {
179
- return state.context.isAgentChatSheetOpen;
180
- }
181
- function _temp2(state_0) {
182
- return state_0.context.previewSource;
183
- }
184
- function _temp3(state_1) {
185
- return state_1.context.agentChatPageScaffoldContext;
186
- }
187
- function _temp4(key) {
188
- return key + 1;
189
- }
190
- function _temp5(open) {
191
- if (!open) previewStore.send({ type: "closeAgentChatSheet" });
192
- }
193
- function _temp6(key_0) {
194
- return key_0 + 1;
195
- }
196
- function _temp7(key_1) {
197
- return key_1 + 1;
198
- }
199
- function _temp8() {
200
- return previewStore.send({
201
- type: "setPreviewSource",
202
- source: "draft"
203
- });
204
- }
205
-
206
- //#endregion
207
- export { AgentChatSheet };
@@ -1,236 +0,0 @@
1
- import { useProjectSlug } from "../../../lib/auth.js";
2
- import { fileQueries, projectQueries } from "../../../lib/queries.js";
3
- import { AssetLightbox } from "./AssetLightbox.js";
4
- import { AssetCard } from "../../content/components/AssetCard.js";
5
- import { c } from "react/compiler-runtime";
6
- import { useQuery } from "@tanstack/react-query";
7
- import * as React from "react";
8
- import { jsx, jsxs } from "react/jsx-runtime";
9
- import { Button } from "@camox/ui/button";
10
- import { ArrowLeft } from "lucide-react";
11
- import { Skeleton } from "@camox/ui/skeleton";
12
-
13
- //#region src/features/preview/components/AssetPickerGrid.tsx
14
- const AssetPickerGrid = (t0) => {
15
- const $ = c(46);
16
- if ($[0] !== "304cb8ddef70ef73677034ff5f21cf46713e477681a8d7ac41df1f9785316fcf") {
17
- for (let $i = 0; $i < 46; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
18
- $[0] = "304cb8ddef70ef73677034ff5f21cf46713e477681a8d7ac41df1f9785316fcf";
19
- }
20
- const { assetType, mode, onSelectSingle, onSelectMultiple, onClose } = t0;
21
- const projectSlug = useProjectSlug();
22
- let t1;
23
- if ($[1] !== projectSlug) {
24
- t1 = projectQueries.getBySlug(projectSlug);
25
- $[1] = projectSlug;
26
- $[2] = t1;
27
- } else t1 = $[2];
28
- const { data: project } = useQuery(t1);
29
- let t2;
30
- if ($[3] !== project?.id) {
31
- t2 = fileQueries.list(project?.id ?? 0);
32
- $[3] = project?.id;
33
- $[4] = t2;
34
- } else t2 = $[4];
35
- const t3 = !!project;
36
- let t4;
37
- if ($[5] !== t2 || $[6] !== t3) {
38
- t4 = {
39
- ...t2,
40
- enabled: t3
41
- };
42
- $[5] = t2;
43
- $[6] = t3;
44
- $[7] = t4;
45
- } else t4 = $[7];
46
- const { data: allFiles } = useQuery(t4);
47
- let t5;
48
- if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
49
- t5 = /* @__PURE__ */ new Set();
50
- $[8] = t5;
51
- } else t5 = $[8];
52
- const [selectedIds, setSelectedIds] = React.useState(t5);
53
- const [lightboxFile, setLightboxFile] = React.useState(null);
54
- const isImage = assetType === "Image";
55
- let t6;
56
- bb0: {
57
- if (!allFiles) {
58
- t6 = void 0;
59
- break bb0;
60
- }
61
- if (!isImage) {
62
- t6 = allFiles;
63
- break bb0;
64
- }
65
- let t7;
66
- if ($[9] !== allFiles) {
67
- t7 = allFiles.filter(_temp);
68
- $[9] = allFiles;
69
- $[10] = t7;
70
- } else t7 = $[10];
71
- t6 = t7;
72
- }
73
- const files = t6;
74
- let t7;
75
- if ($[11] === Symbol.for("react.memo_cache_sentinel")) {
76
- t7 = (fileId) => {
77
- setSelectedIds((prev) => {
78
- const next = new Set(prev);
79
- if (next.has(fileId)) next.delete(fileId);
80
- else next.add(fileId);
81
- return next;
82
- });
83
- };
84
- $[11] = t7;
85
- } else t7 = $[11];
86
- const toggleSelection = t7;
87
- let t8;
88
- if ($[12] !== files || $[13] !== onSelectMultiple || $[14] !== selectedIds) {
89
- t8 = () => {
90
- if (!files) return;
91
- onSelectMultiple(files.filter((f_0) => selectedIds.has(f_0.id)));
92
- };
93
- $[12] = files;
94
- $[13] = onSelectMultiple;
95
- $[14] = selectedIds;
96
- $[15] = t8;
97
- } else t8 = $[15];
98
- const handleConfirmMultiple = t8;
99
- const title = mode === "multiple" ? `Select ${isImage ? "images" : "files"}` : `Select ${isImage ? "image" : "file"}`;
100
- let t9;
101
- if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
102
- t9 = /* @__PURE__ */ jsx(ArrowLeft, { className: "h-4 w-4" });
103
- $[16] = t9;
104
- } else t9 = $[16];
105
- let t10;
106
- if ($[17] !== onClose || $[18] !== title) {
107
- t10 = /* @__PURE__ */ jsxs(Button, {
108
- variant: "ghost",
109
- size: "sm",
110
- onClick: onClose,
111
- children: [t9, title]
112
- });
113
- $[17] = onClose;
114
- $[18] = title;
115
- $[19] = t10;
116
- } else t10 = $[19];
117
- let t11;
118
- if ($[20] !== handleConfirmMultiple || $[21] !== mode || $[22] !== selectedIds) {
119
- t11 = mode === "multiple" && /* @__PURE__ */ jsxs(Button, {
120
- variant: "default",
121
- size: "sm",
122
- className: "ml-auto",
123
- disabled: selectedIds.size === 0,
124
- onClick: handleConfirmMultiple,
125
- children: [
126
- "Add selected (",
127
- selectedIds.size,
128
- ")"
129
- ]
130
- });
131
- $[20] = handleConfirmMultiple;
132
- $[21] = mode;
133
- $[22] = selectedIds;
134
- $[23] = t11;
135
- } else t11 = $[23];
136
- let t12;
137
- if ($[24] !== t10 || $[25] !== t11) {
138
- t12 = /* @__PURE__ */ jsxs("div", {
139
- className: "sticky top-0 z-10 flex items-center gap-2 px-4 py-4",
140
- children: [t10, t11]
141
- });
142
- $[24] = t10;
143
- $[25] = t11;
144
- $[26] = t12;
145
- } else t12 = $[26];
146
- let t13;
147
- if ($[27] !== files) {
148
- t13 = files === void 0 && /* @__PURE__ */ jsx("div", {
149
- className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3",
150
- children: Array.from({ length: 6 }).map(_temp2)
151
- });
152
- $[27] = files;
153
- $[28] = t13;
154
- } else t13 = $[28];
155
- let t14;
156
- if ($[29] !== files?.length) {
157
- t14 = files?.length === 0 && /* @__PURE__ */ jsx("p", {
158
- className: "text-muted-foreground py-8 text-center text-sm",
159
- children: "No assets yet"
160
- });
161
- $[29] = files?.length;
162
- $[30] = t14;
163
- } else t14 = $[30];
164
- let t15;
165
- if ($[31] !== files || $[32] !== mode || $[33] !== onSelectSingle || $[34] !== selectedIds) {
166
- t15 = files && files.length > 0 && /* @__PURE__ */ jsx("div", {
167
- className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3",
168
- children: files.map((file) => /* @__PURE__ */ jsx(AssetCard, {
169
- file,
170
- selected: selectedIds.has(file.id),
171
- onSelect: () => {
172
- if (mode === "single") onSelectSingle(file);
173
- else toggleSelection(file.id);
174
- },
175
- onOpen: () => setLightboxFile(file)
176
- }, file.id))
177
- });
178
- $[31] = files;
179
- $[32] = mode;
180
- $[33] = onSelectSingle;
181
- $[34] = selectedIds;
182
- $[35] = t15;
183
- } else t15 = $[35];
184
- let t16;
185
- if ($[36] !== t13 || $[37] !== t14 || $[38] !== t15) {
186
- t16 = /* @__PURE__ */ jsxs("div", {
187
- className: "px-4 pb-4",
188
- children: [
189
- t13,
190
- t14,
191
- t15
192
- ]
193
- });
194
- $[36] = t13;
195
- $[37] = t14;
196
- $[38] = t15;
197
- $[39] = t16;
198
- } else t16 = $[39];
199
- let t17;
200
- if ($[40] !== lightboxFile) {
201
- t17 = lightboxFile && /* @__PURE__ */ jsx(AssetLightbox, {
202
- open: !!lightboxFile,
203
- onOpenChange: (open) => {
204
- if (!open) setLightboxFile(null);
205
- },
206
- fileId: lightboxFile.id
207
- });
208
- $[40] = lightboxFile;
209
- $[41] = t17;
210
- } else t17 = $[41];
211
- let t18;
212
- if ($[42] !== t12 || $[43] !== t16 || $[44] !== t17) {
213
- t18 = /* @__PURE__ */ jsxs("div", { children: [
214
- t12,
215
- t16,
216
- t17
217
- ] });
218
- $[42] = t12;
219
- $[43] = t16;
220
- $[44] = t17;
221
- $[45] = t18;
222
- } else t18 = $[45];
223
- return t18;
224
- };
225
- function _temp(f) {
226
- return f.mimeType?.startsWith("image/");
227
- }
228
- function _temp2(_, i) {
229
- return /* @__PURE__ */ jsxs("div", {
230
- className: "flex flex-col gap-1.5 rounded-lg p-2",
231
- children: [/* @__PURE__ */ jsx(Skeleton, { className: "aspect-4/3 w-full rounded-md" }), /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-3/4 rounded" })]
232
- }, i);
233
- }
234
-
235
- //#endregion
236
- export { AssetPickerGrid };