camox 0.43.0 → 0.44.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 (63) hide show
  1. package/bin/camox.mjs +9 -1
  2. package/dist/core/components/lexical/InlineStylesPlugin.js +22 -6
  3. package/dist/core/components/lexical/SelectionBroadcaster.js +4 -4
  4. package/dist/core/components/lexical/SidebarLexicalEditor.js +15 -15
  5. package/dist/core/createApp.d.ts +28 -2
  6. package/dist/core/createBlock.js +24 -10
  7. package/dist/core/editing/createEditableBlock.d.ts +135 -1
  8. package/dist/core/editing/createEditableBlock.js +209 -74
  9. package/dist/core/lib/contentType.d.ts +5 -0
  10. package/dist/core/lib/contentType.js +11 -0
  11. package/dist/core/lib/fieldTypes.js +1 -0
  12. package/dist/core/lib/iconTypes.d.ts +13 -0
  13. package/dist/core/lib/icons.d.ts +6 -0
  14. package/dist/core/lib/icons.js +130 -0
  15. package/dist/core/lib/lexicalState.js +6 -6
  16. package/dist/core/lib/modifierFormats.js +1 -1
  17. package/dist/core/lib/textStyles.d.ts +1 -1
  18. package/dist/core/lib/textStyles.js +3 -3
  19. package/dist/features/content/components/AssetCard.js +104 -68
  20. package/dist/features/preview/CamoxPreview.js +120 -95
  21. package/dist/features/preview/commentsEnabled.js +2 -2
  22. package/dist/features/preview/components/AssetLightbox.js +17 -6
  23. package/dist/features/preview/components/AttachedComments.js +224 -87
  24. package/dist/features/preview/components/CommentTargetQuote.js +22 -21
  25. package/dist/features/preview/components/DerivedLayoutDialog.js +36 -21
  26. package/dist/features/preview/components/FieldOverlayStyles.js +29 -9
  27. package/dist/features/preview/components/FieldToolbar.js +8 -8
  28. package/dist/features/preview/components/IconFieldEditor.js +231 -0
  29. package/dist/features/preview/components/ItemFieldsEditor.js +21 -14
  30. package/dist/features/preview/components/OverlayTracker.js +1 -1
  31. package/dist/features/preview/components/PagePicker.js +44 -44
  32. package/dist/features/preview/components/PreviewPanel.js +1 -1
  33. package/dist/features/preview/components/PreviewToolbar.js +224 -225
  34. package/dist/features/preview/components/SendFeedbackDialog.js +83 -0
  35. package/dist/features/preview/overlayHighlights.js +54 -0
  36. package/dist/features/preview/previewCommentsStore.js +54 -34
  37. package/dist/features/preview/previewSelection.js +28 -23
  38. package/dist/features/preview/usePageComments.js +39 -0
  39. package/dist/features/provider/CoreCamoxProvider.js +37 -5
  40. package/dist/features/provider/LocalhostPreviewProvider.js +81 -45
  41. package/dist/features/provider/components/CommandPalette.js +35 -84
  42. package/dist/features/runtime/pageApp.js +32 -28
  43. package/dist/features/runtime/pageServer.js +4 -1
  44. package/dist/features/runtime/runtime.d.ts +2 -0
  45. package/dist/features/runtime/runtime.js +25 -0
  46. package/dist/features/studio/components/EnvironmentMenu.js +75 -63
  47. package/dist/features/vite/auth.js +1 -50
  48. package/dist/features/vite/iconGeneration.js +16 -0
  49. package/dist/features/vite/vite.d.ts +4 -2
  50. package/dist/features/vite/vite.js +19 -2
  51. package/dist/lib/auth.js +39 -16
  52. package/dist/lib/preview-handoff.js +13 -0
  53. package/dist/lib/queries.js +12 -1
  54. package/dist/lib/use-project-room.js +5 -2
  55. package/dist/studio-overlays.css +19 -15
  56. package/dist/studio.css +1 -1
  57. package/package.json +5 -4
  58. package/skills/camox/SKILL.md +6 -0
  59. package/skills/camox/references/block-definitions.md +27 -0
  60. package/skills/camox/references/cli-common.md +14 -0
  61. package/skills/camox/references/cli-content.md +11 -0
  62. package/skills/camox/references/field-styling.md +4 -4
  63. package/skills/camoxify/SKILL.md +14 -0
@@ -2,7 +2,7 @@ import { formatShortcut } from "../../../lib/utils.js";
2
2
  import { areCommentsEnabled } from "../commentsEnabled.js";
3
3
  import { previewStore, selectIsCommentMode, selectIsEditMode } from "../previewStore.js";
4
4
  import { EDIT_MODE_SHORTCUT } from "../previewConstants.js";
5
- import { previewCommentsStore } from "../previewCommentsStore.js";
5
+ import { usePageComments } from "../usePageComments.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { useSelector } from "@xstate/store-react";
@@ -17,73 +17,72 @@ import { Toggle } from "@camox/ui/toggle";
17
17
 
18
18
  //#region src/features/preview/components/PreviewToolbar.tsx
19
19
  const PreviewToolbar = (t0) => {
20
- const $ = c(77);
21
- if ($[0] !== "19095e3108d685099398c545dfc96ef948a6769b13376550d2ac5eaeccd94797") {
22
- for (let $i = 0; $i < 77; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
23
- $[0] = "19095e3108d685099398c545dfc96ef948a6769b13376550d2ac5eaeccd94797";
20
+ const $ = c(75);
21
+ if ($[0] !== "bc3d0cc36dd18cfaa2c723a679367d11408a341dd85e473695399613e686075a") {
22
+ for (let $i = 0; $i < 75; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
23
+ $[0] = "bc3d0cc36dd18cfaa2c723a679367d11408a341dd85e473695399613e686075a";
24
24
  }
25
- const { onEditModeChange, pageId, pageStatus, hasLiveVersion } = t0;
25
+ const { onEditModeChange, onCommentModeChange, pageId, pageStatus, hasLiveVersion } = t0;
26
26
  const isEditMode = useSelector(previewStore, selectIsEditMode);
27
27
  const isCommentMode = useSelector(previewStore, selectIsCommentMode);
28
28
  const isToolbarHidden = useSelector(previewStore, _temp);
29
29
  const peekedBlock = useSelector(previewStore, _temp2);
30
30
  const viewportMode = useSelector(previewStore, _temp3);
31
- let t1;
32
- if ($[1] !== pageId) {
33
- t1 = (state_2) => state_2.context.comments.filter((comment) => comment.pageId === pageId).length;
34
- $[1] = pageId;
35
- $[2] = t1;
36
- } else t1 = $[2];
37
- const commentCount = useSelector(previewCommentsStore, t1);
31
+ const { data: comments } = usePageComments(pageStatus ? pageId : void 0);
32
+ const commentCount = comments?.length ?? 0;
38
33
  if (isToolbarHidden || peekedBlock) return null;
39
- let t2;
40
- if ($[3] !== onEditModeChange) {
41
- t2 = (checked) => {
34
+ let t1;
35
+ if ($[1] !== onEditModeChange) {
36
+ t1 = (checked) => {
42
37
  if (onEditModeChange) {
43
38
  onEditModeChange(checked);
44
39
  return;
45
40
  }
46
41
  previewStore.send({ type: checked ? "enterEditMode" : "exitEditMode" });
47
42
  };
48
- $[3] = onEditModeChange;
49
- $[4] = t2;
50
- } else t2 = $[4];
51
- let t3;
52
- if ($[5] !== isEditMode || $[6] !== t2) {
53
- t3 = /* @__PURE__ */ jsx(Switch, {
43
+ $[1] = onEditModeChange;
44
+ $[2] = t1;
45
+ } else t1 = $[2];
46
+ let t2;
47
+ if ($[3] !== isEditMode || $[4] !== t1) {
48
+ t2 = /* @__PURE__ */ jsx(Switch, {
54
49
  id: "edit-mode",
55
50
  checked: isEditMode,
56
- onCheckedChange: t2
51
+ onCheckedChange: t1
57
52
  });
58
- $[5] = isEditMode;
59
- $[6] = t2;
60
- $[7] = t3;
61
- } else t3 = $[7];
62
- let t4;
63
- if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
64
- t4 = /* @__PURE__ */ jsxs(Label, {
53
+ $[3] = isEditMode;
54
+ $[4] = t1;
55
+ $[5] = t2;
56
+ } else t2 = $[5];
57
+ let t3;
58
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
59
+ t3 = /* @__PURE__ */ jsxs(Label, {
65
60
  htmlFor: "edit-mode",
66
61
  className: "flex items-center gap-2",
67
62
  children: ["Edit mode ", formatShortcut(EDIT_MODE_SHORTCUT)]
68
63
  });
64
+ $[6] = t3;
65
+ } else t3 = $[6];
66
+ let t4;
67
+ if ($[7] !== t2) {
68
+ t4 = /* @__PURE__ */ jsxs("div", {
69
+ className: "flex shrink-0 items-center gap-2 px-2",
70
+ children: [t2, t3]
71
+ });
72
+ $[7] = t2;
69
73
  $[8] = t4;
70
74
  } else t4 = $[8];
71
75
  let t5;
72
- if ($[9] !== t3) {
73
- t5 = /* @__PURE__ */ jsxs("div", {
74
- className: "flex shrink-0 items-center gap-2 px-2",
75
- children: [t3, t4]
76
- });
77
- $[9] = t3;
78
- $[10] = t5;
79
- } else t5 = $[10];
80
- let t6;
81
- if ($[11] !== commentCount || $[12] !== isCommentMode || $[13] !== isEditMode || $[14] !== pageStatus) {
82
- t6 = areCommentsEnabled() && pageStatus && /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsxs(Tooltip$1.TooltipTrigger, {
76
+ if ($[9] !== commentCount || $[10] !== isCommentMode || $[11] !== isEditMode || $[12] !== onCommentModeChange) {
77
+ t5 = areCommentsEnabled() && /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsxs(Tooltip$1.TooltipTrigger, {
83
78
  render: /* @__PURE__ */ jsx(Toggle, {
84
79
  pressed: isCommentMode,
85
80
  "data-state": isCommentMode ? "on" : "off",
86
81
  onPressedChange: (enabled) => {
82
+ if (onCommentModeChange) {
83
+ onCommentModeChange(enabled);
84
+ return;
85
+ }
87
86
  if (enabled && !isEditMode) previewStore.send({ type: "enterEditMode" });
88
87
  previewStore.send({
89
88
  type: "setCommentMode",
@@ -104,197 +103,197 @@ const PreviewToolbar = (t0) => {
104
103
  ]
105
104
  })
106
105
  ]
107
- }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Leave feedback for agents or teammates" })] });
108
- $[11] = commentCount;
109
- $[12] = isCommentMode;
110
- $[13] = isEditMode;
111
- $[14] = pageStatus;
112
- $[15] = t6;
113
- } else t6 = $[15];
114
- const t7 = viewportMode === "full" ? "on" : "off";
115
- const t8 = viewportMode === "full";
116
- let t9;
117
- if ($[16] !== viewportMode) {
118
- t9 = () => {
106
+ }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Leave feedback for agents" })] });
107
+ $[9] = commentCount;
108
+ $[10] = isCommentMode;
109
+ $[11] = isEditMode;
110
+ $[12] = onCommentModeChange;
111
+ $[13] = t5;
112
+ } else t5 = $[13];
113
+ const t6 = viewportMode === "full" ? "on" : "off";
114
+ const t7 = viewportMode === "full";
115
+ let t8;
116
+ if ($[14] !== viewportMode) {
117
+ t8 = () => {
119
118
  if (viewportMode === "full") return;
120
119
  previewStore.send({
121
120
  type: "setViewportMode",
122
121
  mode: "full"
123
122
  });
124
123
  };
125
- $[16] = viewportMode;
126
- $[17] = t9;
127
- } else t9 = $[17];
128
- let t10;
129
- if ($[18] !== t7 || $[19] !== t8 || $[20] !== t9) {
130
- t10 = /* @__PURE__ */ jsx(Toggle, {
131
- "data-state": t7,
132
- pressed: t8,
133
- onPressedChange: t9,
124
+ $[14] = viewportMode;
125
+ $[15] = t8;
126
+ } else t8 = $[15];
127
+ let t9;
128
+ if ($[16] !== t6 || $[17] !== t7 || $[18] !== t8) {
129
+ t9 = /* @__PURE__ */ jsx(Toggle, {
130
+ "data-state": t6,
131
+ pressed: t7,
132
+ onPressedChange: t8,
134
133
  variant: "outline"
135
134
  });
136
- $[18] = t7;
137
- $[19] = t8;
138
- $[20] = t9;
139
- $[21] = t10;
140
- } else t10 = $[21];
135
+ $[16] = t6;
136
+ $[17] = t7;
137
+ $[18] = t8;
138
+ $[19] = t9;
139
+ } else t9 = $[19];
140
+ let t10;
141
+ if ($[20] === Symbol.for("react.memo_cache_sentinel")) {
142
+ t10 = /* @__PURE__ */ jsx(Monitor, {});
143
+ $[20] = t10;
144
+ } else t10 = $[20];
141
145
  let t11;
142
- if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
143
- t11 = /* @__PURE__ */ jsx(Monitor, {});
146
+ if ($[21] !== t9) {
147
+ t11 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
148
+ render: t9,
149
+ children: t10
150
+ });
151
+ $[21] = t9;
144
152
  $[22] = t11;
145
153
  } else t11 = $[22];
146
154
  let t12;
147
- if ($[23] !== t10) {
148
- t12 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
149
- render: t10,
150
- children: t11
151
- });
152
- $[23] = t10;
153
- $[24] = t12;
154
- } else t12 = $[24];
155
+ if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
156
+ t12 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Full view" });
157
+ $[23] = t12;
158
+ } else t12 = $[23];
155
159
  let t13;
156
- if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
157
- t13 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Full view" });
160
+ if ($[24] !== t11) {
161
+ t13 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t11, t12] });
162
+ $[24] = t11;
158
163
  $[25] = t13;
159
164
  } else t13 = $[25];
160
- let t14;
161
- if ($[26] !== t12) {
162
- t14 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t12, t13] });
163
- $[26] = t12;
164
- $[27] = t14;
165
- } else t14 = $[27];
166
- const t15 = viewportMode === "tablet" ? "on" : "off";
167
- const t16 = viewportMode === "tablet";
168
- let t17;
169
- if ($[28] !== viewportMode) {
170
- t17 = () => {
165
+ const t14 = viewportMode === "tablet" ? "on" : "off";
166
+ const t15 = viewportMode === "tablet";
167
+ let t16;
168
+ if ($[26] !== viewportMode) {
169
+ t16 = () => {
171
170
  if (viewportMode === "tablet") return;
172
171
  previewStore.send({
173
172
  type: "setViewportMode",
174
173
  mode: "tablet"
175
174
  });
176
175
  };
177
- $[28] = viewportMode;
178
- $[29] = t17;
179
- } else t17 = $[29];
180
- let t18;
181
- if ($[30] !== t15 || $[31] !== t16 || $[32] !== t17) {
182
- t18 = /* @__PURE__ */ jsx(Toggle, {
183
- "data-state": t15,
184
- pressed: t16,
185
- onPressedChange: t17,
176
+ $[26] = viewportMode;
177
+ $[27] = t16;
178
+ } else t16 = $[27];
179
+ let t17;
180
+ if ($[28] !== t14 || $[29] !== t15 || $[30] !== t16) {
181
+ t17 = /* @__PURE__ */ jsx(Toggle, {
182
+ "data-state": t14,
183
+ pressed: t15,
184
+ onPressedChange: t16,
186
185
  variant: "outline"
187
186
  });
188
- $[30] = t15;
189
- $[31] = t16;
190
- $[32] = t17;
191
- $[33] = t18;
192
- } else t18 = $[33];
187
+ $[28] = t14;
188
+ $[29] = t15;
189
+ $[30] = t16;
190
+ $[31] = t17;
191
+ } else t17 = $[31];
192
+ let t18;
193
+ if ($[32] === Symbol.for("react.memo_cache_sentinel")) {
194
+ t18 = /* @__PURE__ */ jsx(Tablet, {});
195
+ $[32] = t18;
196
+ } else t18 = $[32];
193
197
  let t19;
194
- if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
195
- t19 = /* @__PURE__ */ jsx(Tablet, {});
198
+ if ($[33] !== t17) {
199
+ t19 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
200
+ render: t17,
201
+ children: t18
202
+ });
203
+ $[33] = t17;
196
204
  $[34] = t19;
197
205
  } else t19 = $[34];
198
206
  let t20;
199
- if ($[35] !== t18) {
200
- t20 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
201
- render: t18,
202
- children: t19
203
- });
204
- $[35] = t18;
205
- $[36] = t20;
206
- } else t20 = $[36];
207
+ if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
208
+ t20 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Tablet view" });
209
+ $[35] = t20;
210
+ } else t20 = $[35];
207
211
  let t21;
208
- if ($[37] === Symbol.for("react.memo_cache_sentinel")) {
209
- t21 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Tablet view" });
212
+ if ($[36] !== t19) {
213
+ t21 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t19, t20] });
214
+ $[36] = t19;
210
215
  $[37] = t21;
211
216
  } else t21 = $[37];
212
- let t22;
213
- if ($[38] !== t20) {
214
- t22 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t20, t21] });
215
- $[38] = t20;
216
- $[39] = t22;
217
- } else t22 = $[39];
218
- const t23 = viewportMode === "mobile" ? "on" : "off";
219
- const t24 = viewportMode === "mobile";
220
- let t25;
221
- if ($[40] !== viewportMode) {
222
- t25 = () => {
217
+ const t22 = viewportMode === "mobile" ? "on" : "off";
218
+ const t23 = viewportMode === "mobile";
219
+ let t24;
220
+ if ($[38] !== viewportMode) {
221
+ t24 = () => {
223
222
  if (viewportMode === "mobile") return;
224
223
  previewStore.send({
225
224
  type: "setViewportMode",
226
225
  mode: "mobile"
227
226
  });
228
227
  };
229
- $[40] = viewportMode;
230
- $[41] = t25;
231
- } else t25 = $[41];
232
- let t26;
233
- if ($[42] !== t23 || $[43] !== t24 || $[44] !== t25) {
234
- t26 = /* @__PURE__ */ jsx(Toggle, {
235
- "data-state": t23,
236
- pressed: t24,
237
- onPressedChange: t25,
228
+ $[38] = viewportMode;
229
+ $[39] = t24;
230
+ } else t24 = $[39];
231
+ let t25;
232
+ if ($[40] !== t22 || $[41] !== t23 || $[42] !== t24) {
233
+ t25 = /* @__PURE__ */ jsx(Toggle, {
234
+ "data-state": t22,
235
+ pressed: t23,
236
+ onPressedChange: t24,
238
237
  variant: "outline"
239
238
  });
240
- $[42] = t23;
241
- $[43] = t24;
242
- $[44] = t25;
243
- $[45] = t26;
244
- } else t26 = $[45];
239
+ $[40] = t22;
240
+ $[41] = t23;
241
+ $[42] = t24;
242
+ $[43] = t25;
243
+ } else t25 = $[43];
244
+ let t26;
245
+ if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
246
+ t26 = /* @__PURE__ */ jsx(Smartphone, {});
247
+ $[44] = t26;
248
+ } else t26 = $[44];
245
249
  let t27;
246
- if ($[46] === Symbol.for("react.memo_cache_sentinel")) {
247
- t27 = /* @__PURE__ */ jsx(Smartphone, {});
250
+ if ($[45] !== t25) {
251
+ t27 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
252
+ render: t25,
253
+ children: t26
254
+ });
255
+ $[45] = t25;
248
256
  $[46] = t27;
249
257
  } else t27 = $[46];
250
258
  let t28;
251
- if ($[47] !== t26) {
252
- t28 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
253
- render: t26,
254
- children: t27
255
- });
256
- $[47] = t26;
257
- $[48] = t28;
258
- } else t28 = $[48];
259
+ if ($[47] === Symbol.for("react.memo_cache_sentinel")) {
260
+ t28 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Mobile view" });
261
+ $[47] = t28;
262
+ } else t28 = $[47];
259
263
  let t29;
260
- if ($[49] === Symbol.for("react.memo_cache_sentinel")) {
261
- t29 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Mobile view" });
264
+ if ($[48] !== t27) {
265
+ t29 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t27, t28] });
266
+ $[48] = t27;
262
267
  $[49] = t29;
263
268
  } else t29 = $[49];
264
269
  let t30;
265
- if ($[50] !== t28) {
266
- t30 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t28, t29] });
267
- $[50] = t28;
268
- $[51] = t30;
269
- } else t30 = $[51];
270
- let t31;
271
- if ($[52] !== t14 || $[53] !== t22 || $[54] !== t30) {
272
- t31 = /* @__PURE__ */ jsxs(ButtonGroup, { children: [
273
- t14,
274
- t22,
275
- t30
270
+ if ($[50] !== t13 || $[51] !== t21 || $[52] !== t29) {
271
+ t30 = /* @__PURE__ */ jsxs(ButtonGroup, { children: [
272
+ t13,
273
+ t21,
274
+ t29
276
275
  ] });
277
- $[52] = t14;
278
- $[53] = t22;
279
- $[54] = t30;
280
- $[55] = t31;
281
- } else t31 = $[55];
282
- let t32;
283
- if ($[56] !== hasLiveVersion || $[57] !== pageStatus) {
284
- t32 = pageStatus && /* @__PURE__ */ jsx(Button, {
276
+ $[50] = t13;
277
+ $[51] = t21;
278
+ $[52] = t29;
279
+ $[53] = t30;
280
+ } else t30 = $[53];
281
+ let t31;
282
+ if ($[54] !== hasLiveVersion || $[55] !== pageStatus) {
283
+ t31 = pageStatus && /* @__PURE__ */ jsx(Button, {
285
284
  type: "button",
286
285
  variant: "outline",
287
286
  disabled: pageStatus === "published" || !hasLiveVersion,
288
287
  onClick: _temp4,
289
288
  children: "View live page"
290
289
  });
291
- $[56] = hasLiveVersion;
292
- $[57] = pageStatus;
293
- $[58] = t32;
294
- } else t32 = $[58];
295
- let t33;
296
- if ($[59] !== isEditMode) {
297
- t33 = /* @__PURE__ */ jsx(Button, {
290
+ $[54] = hasLiveVersion;
291
+ $[55] = pageStatus;
292
+ $[56] = t31;
293
+ } else t31 = $[56];
294
+ let t32;
295
+ if ($[57] !== isEditMode) {
296
+ t32 = /* @__PURE__ */ jsx(Button, {
298
297
  type: "button",
299
298
  variant: "ghost",
300
299
  size: "icon",
@@ -303,70 +302,70 @@ const PreviewToolbar = (t0) => {
303
302
  "aria-label": "Hide toolbar",
304
303
  className: "text-muted-foreground"
305
304
  });
306
- $[59] = isEditMode;
307
- $[60] = t33;
308
- } else t33 = $[60];
305
+ $[57] = isEditMode;
306
+ $[58] = t32;
307
+ } else t32 = $[58];
308
+ let t33;
309
+ if ($[59] === Symbol.for("react.memo_cache_sentinel")) {
310
+ t33 = /* @__PURE__ */ jsx(X, {});
311
+ $[59] = t33;
312
+ } else t33 = $[59];
309
313
  let t34;
310
- if ($[61] === Symbol.for("react.memo_cache_sentinel")) {
311
- t34 = /* @__PURE__ */ jsx(X, {});
314
+ if ($[60] !== t32) {
315
+ t34 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
316
+ render: t32,
317
+ children: t33
318
+ });
319
+ $[60] = t32;
312
320
  $[61] = t34;
313
321
  } else t34 = $[61];
314
322
  let t35;
315
- if ($[62] !== t33) {
316
- t35 = /* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
317
- render: t33,
318
- children: t34
319
- });
320
- $[62] = t33;
321
- $[63] = t35;
322
- } else t35 = $[63];
323
+ if ($[62] === Symbol.for("react.memo_cache_sentinel")) {
324
+ t35 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Hide toolbar" });
325
+ $[62] = t35;
326
+ } else t35 = $[62];
323
327
  let t36;
324
- if ($[64] === Symbol.for("react.memo_cache_sentinel")) {
325
- t36 = /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, { children: "Hide toolbar" });
328
+ if ($[63] !== t34) {
329
+ t36 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t34, t35] });
330
+ $[63] = t34;
326
331
  $[64] = t36;
327
332
  } else t36 = $[64];
328
333
  let t37;
329
- if ($[65] !== t35) {
330
- t37 = /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [t35, t36] });
331
- $[65] = t35;
332
- $[66] = t37;
333
- } else t37 = $[66];
334
- let t38;
335
- if ($[67] !== t32 || $[68] !== t37) {
336
- t38 = /* @__PURE__ */ jsxs("div", {
334
+ if ($[65] !== t31 || $[66] !== t36) {
335
+ t37 = /* @__PURE__ */ jsxs("div", {
337
336
  className: "flex items-center gap-2",
338
- children: [t32, t37]
337
+ children: [t31, t36]
339
338
  });
340
- $[67] = t32;
341
- $[68] = t37;
342
- $[69] = t38;
343
- } else t38 = $[69];
344
- let t39;
345
- if ($[70] !== t31 || $[71] !== t38 || $[72] !== t6) {
346
- t39 = /* @__PURE__ */ jsxs("div", {
339
+ $[65] = t31;
340
+ $[66] = t36;
341
+ $[67] = t37;
342
+ } else t37 = $[67];
343
+ let t38;
344
+ if ($[68] !== t30 || $[69] !== t37 || $[70] !== t5) {
345
+ t38 = /* @__PURE__ */ jsxs("div", {
347
346
  className: "flex shrink-0 items-center gap-6 self-stretch",
348
347
  children: [
349
- t6,
350
- t31,
351
- t38
348
+ t5,
349
+ t30,
350
+ t37
352
351
  ]
353
352
  });
354
- $[70] = t31;
353
+ $[68] = t30;
354
+ $[69] = t37;
355
+ $[70] = t5;
355
356
  $[71] = t38;
356
- $[72] = t6;
357
- $[73] = t39;
358
- } else t39 = $[73];
359
- let t40;
360
- if ($[74] !== t39 || $[75] !== t5) {
361
- t40 = /* @__PURE__ */ jsxs(FloatingToolbar, {
357
+ } else t38 = $[71];
358
+ let t39;
359
+ if ($[72] !== t38 || $[73] !== t4) {
360
+ t39 = /* @__PURE__ */ jsxs(FloatingToolbar, {
362
361
  className: "bottom-2 w-max justify-between gap-6 transition-none",
363
- children: [t5, t39]
362
+ children: [t4, t38]
364
363
  });
364
+ $[72] = t38;
365
+ $[73] = t4;
365
366
  $[74] = t39;
366
- $[75] = t5;
367
- $[76] = t40;
368
- } else t40 = $[76];
369
- return t40;
367
+ } else t39 = $[74];
368
+ return t39;
370
369
  };
371
370
  function _temp(state) {
372
371
  return state.context.isToolbarHidden;
@@ -0,0 +1,83 @@
1
+ import * as React from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Button } from "@camox/ui/button";
4
+ import { Copy, Info } from "lucide-react";
5
+ import { Alert, AlertDescription } from "@camox/ui/alert";
6
+ import { toast } from "@camox/ui/toaster";
7
+ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@camox/ui/dialog";
8
+ import { Label } from "@camox/ui/label";
9
+ import { Textarea } from "@camox/ui/textarea";
10
+
11
+ //#region src/features/preview/components/SendFeedbackDialog.tsx
12
+ function feedbackPrompt(pageId, context) {
13
+ const request = `Address unresolved Camox feedback for page ID ${pageId}. Load the camox skill and follow its feedback workflow: read the page's comments with the CLI, make the requested changes, and resolve each addressed comment.`;
14
+ const additionalContext = context.trim();
15
+ return additionalContext ? `${request}\n\nAdditional context:\n${additionalContext}` : request;
16
+ }
17
+ function SendFeedbackDialog({ pageId, disabled }) {
18
+ const contextId = React.useId();
19
+ const [open, setOpen] = React.useState(false);
20
+ const [context, setContext] = React.useState("");
21
+ const [copying, setCopying] = React.useState(false);
22
+ const copyPrompt = async () => {
23
+ if (copying) return;
24
+ setCopying(true);
25
+ try {
26
+ await navigator.clipboard.writeText(feedbackPrompt(pageId, context));
27
+ toast.success("Prompt copied. Paste it into your coding agent.");
28
+ setOpen(false);
29
+ } catch {
30
+ toast.error("Could not copy the prompt. Please try again.");
31
+ } finally {
32
+ setCopying(false);
33
+ }
34
+ };
35
+ return /* @__PURE__ */ jsxs(Dialog, {
36
+ open,
37
+ onOpenChange: setOpen,
38
+ children: [/* @__PURE__ */ jsx(DialogTrigger, {
39
+ disabled,
40
+ render: /* @__PURE__ */ jsx(Button, {
41
+ type: "button",
42
+ className: "w-full"
43
+ }),
44
+ children: "Send feedback to agent..."
45
+ }), /* @__PURE__ */ jsxs(DialogContent, {
46
+ className: "sm:max-w-lg",
47
+ "aria-describedby": `${contextId}-description`,
48
+ children: [
49
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Send feedback to agent" }) }),
50
+ /* @__PURE__ */ jsxs(Alert, { children: [/* @__PURE__ */ jsx(Info, {}), /* @__PURE__ */ jsx(AlertDescription, {
51
+ id: `${contextId}-description`,
52
+ children: "Copy the prompt and paste it into your own coding agent outside of Camox Studio to address your feedback. It will resolve the comments on its own."
53
+ })] }),
54
+ /* @__PURE__ */ jsxs("div", {
55
+ className: "space-y-2",
56
+ children: [/* @__PURE__ */ jsxs(Label, {
57
+ htmlFor: contextId,
58
+ children: ["Additional context ", /* @__PURE__ */ jsx("span", {
59
+ className: "text-muted-foreground font-normal",
60
+ children: "(optional)"
61
+ })]
62
+ }), /* @__PURE__ */ jsx(Textarea, {
63
+ id: contextId,
64
+ value: context,
65
+ onChange: (event) => setContext(event.target.value),
66
+ placeholder: "Add an overall note or extra instructions for your agent…",
67
+ rows: 2,
68
+ className: "min-h-16"
69
+ })]
70
+ }),
71
+ /* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs(Button, {
72
+ type: "button",
73
+ onClick: copyPrompt,
74
+ disabled: copying,
75
+ children: [/* @__PURE__ */ jsx(Copy, {}), copying ? "Copying…" : "Copy agent prompt"]
76
+ }) })
77
+ ]
78
+ })]
79
+ });
80
+ }
81
+
82
+ //#endregion
83
+ export { SendFeedbackDialog };