camox 0.52.3 → 0.54.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 (59) hide show
  1. package/dist/core/editing/createEditableBlock.js +1 -1
  2. package/dist/features/canvas/CamoxCanvas.js +103 -83
  3. package/dist/features/canvas/CanvasPageFrame.js +1 -1
  4. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -1
  5. package/dist/features/canvas/canvasCamera.js +3 -3
  6. package/dist/features/canvas/sidebar/CanvasInspector.js +4 -159
  7. package/dist/features/canvas/sidebar/CanvasNavigator.js +41 -85
  8. package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -32
  9. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +4 -3
  10. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +14 -6
  11. package/dist/features/canvas/sidebar/CanvasViewHeader.js +50 -0
  12. package/dist/features/canvas/sidebar/DerivedPageInspector.js +30 -18
  13. package/dist/features/canvas/sidebar/LayoutPageOverview.js +28 -11
  14. package/dist/features/canvas/sidebar/LayoutPageSeo.js +356 -0
  15. package/dist/features/canvas/sidebar/PageInspector.js +118 -80
  16. package/dist/features/canvas/sidebar/PageOverview.js +6 -1
  17. package/dist/features/canvas/sidebar/SingletonPageInspector.js +22 -14
  18. package/dist/features/canvas/useCanvasCamera.js +36 -39
  19. package/dist/features/og/documentFonts.js +49 -0
  20. package/dist/features/og/imageResponse.d.ts +14 -5
  21. package/dist/features/og/imageResponse.js +20 -21
  22. package/dist/features/og/pageImage.js +7 -4
  23. package/dist/features/preview/CamoxPreview.js +1 -1
  24. package/dist/features/preview/components/BlockActionsPopover.js +2 -2
  25. package/dist/features/preview/components/BlockThumbnail.js +1 -1
  26. package/dist/features/preview/components/CanvasPreview.js +1 -1
  27. package/dist/features/preview/components/CreatePageModal.js +1 -1
  28. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  29. package/dist/features/preview/components/ItemFieldsEditor.js +1 -1
  30. package/dist/features/preview/components/LinkFieldEditor.js +1 -1
  31. package/dist/features/preview/components/OverlayTracker.js +1 -1
  32. package/dist/features/preview/components/PageInfo.js +345 -228
  33. package/dist/features/preview/components/PagePicker.js +1 -1
  34. package/dist/features/preview/components/PageTree.js +1 -1
  35. package/dist/features/preview/components/PreviewPanel.js +1 -1
  36. package/dist/features/preview/components/PreviewToolbar.js +2 -2
  37. package/dist/features/preview/components/RepeatableItemsList.js +1 -1
  38. package/dist/features/preview/components/SelectionEditor.js +668 -652
  39. package/dist/features/preview/components/SidebarStack.js +582 -0
  40. package/dist/features/preview/components/StudioEditingFallback.js +2 -2
  41. package/dist/features/renderer/RendererFrames.js +34 -27
  42. package/dist/features/runtime/RuntimeChrome.js +1 -1
  43. package/dist/features/runtime/runtime.d.ts +5 -0
  44. package/dist/features/runtime/runtime.js +99 -30
  45. package/dist/features/studio/components/ChatSidebar.js +76 -86
  46. package/dist/features/studio/components/Navbar.js +1 -1
  47. package/dist/features/studio/components/Squareling.js +114 -0
  48. package/dist/features/studio/components/ThreadMessages.js +128 -126
  49. package/dist/features/studio/components/UserButton.js +1 -1
  50. package/dist/features/vite/bundlerLogs.js +1 -0
  51. package/dist/features/vite/runtimeDev.js +11 -0
  52. package/dist/features/vite/vite.js +3 -1
  53. package/dist/lib/studio-reads.js +18 -0
  54. package/dist/package.js +1 -1
  55. package/dist/studio.css +1 -1
  56. package/package.json +5 -5
  57. package/skills/camox/references/layout-definitions.md +11 -16
  58. package/dist/features/og/defaultFonts.js +0 -31
  59. package/dist/features/og/geist-variable-ttf-base64.js +0 -21
@@ -0,0 +1,582 @@
1
+ import { cn } from "../../../lib/utils.js";
2
+ import { useEditingFrame } from "../editingFrame.js";
3
+ import { selectionHoverMessage } from "../overlayMessages.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import * as Tooltip$1 from "@camox/ui/tooltip";
8
+ import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
9
+
10
+ //#region src/features/preview/components/SidebarStack.tsx
11
+ /** How much narrower, on each side, the header right behind the front is than the front's. */
12
+ const FIRST_STEP_INSET = 9;
13
+ /**
14
+ * How much each step back shades a card, relative to the step in front of it. The selection
15
+ * path collapses its middle, so the stack stays short and its steps can stay even.
16
+ */
17
+ const STEP_FALLOFF = .85;
18
+ /** How much each step back narrows a header, relative to the step in front of it. */
19
+ const INSET_FALLOFF = .75;
20
+ /** How much each step back tilts a header, relative to the step in front of it. */
21
+ const TILT_FALLOFF = .65;
22
+ /** How far the header right behind the front leans back, in degrees. */
23
+ const FIRST_STEP_TILT = 4;
24
+ /**
25
+ * How far the card right behind the front shades, in percent of black, or of white in dark mode,
26
+ * where the background is too dark to darken.
27
+ */
28
+ const FIRST_STEP_SHADE = 1.2;
29
+ /** How much more cards lighten in dark mode than they darken in light mode, to show as much. */
30
+ const DARK_SHADE_STRENGTH = 2.5;
31
+ /** Keeps a sidebar's cards off its sides, so their edges show. */
32
+ const SIDEBAR_GUTTER = "px-2";
33
+ /**
34
+ * The color of a card's edges: the border's, solid. Dark mode's border is translucent, so it's
35
+ * laid over the Canvas behind the sidebars, to look the same over the card as beside it.
36
+ */
37
+ const CARD_EDGE_COLOR = "border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
38
+ /** The front card's sides and bottom, under its header. */
39
+ const CARD_BODY_EDGES = `rounded-b-lg border border-t-0 ${CARD_EDGE_COLOR}`;
40
+ /** The bottom card's top and sides, as it meets the top of a sidebar. */
41
+ const BOTTOM_CARD_EDGES = `rounded-t-lg border border-b-0 ${CARD_EDGE_COLOR}`;
42
+ /** The front card's top and sides, over the cards behind it. */
43
+ const FRONT_CARD_EDGES = `border border-b-0 ${CARD_EDGE_COLOR}`;
44
+ /**
45
+ * How much the second card behind the front fades its name, which shows depth on dark
46
+ * backgrounds too. The card right behind the front doesn't fade.
47
+ */
48
+ const FIRST_STEP_FADE = .05;
49
+ /** How far away the eye is from the stack, in px: the less, the stronger the depth. */
50
+ const PERSPECTIVE = 900;
51
+ /** Sums the steps of a falloff series, `distance` views behind the front. */
52
+ function stepSeries(first, distance, falloff = STEP_FALLOFF) {
53
+ return first * (1 - falloff ** distance) / (1 - falloff);
54
+ }
55
+ /** A header's inset on each side, `distance` views behind the front. */
56
+ function stackInset(distance) {
57
+ return stepSeries(FIRST_STEP_INSET, distance, INSET_FALLOFF);
58
+ }
59
+ /** Cards settle into place, without bouncing. */
60
+ const EASE = "cubic-bezier(0.2, 0, 0, 1)";
61
+ const DURATION = 260;
62
+ /** Cards are pulled away a little faster than they're laid. */
63
+ const LEAVE_EASING = "cubic-bezier(0.4, 0, 1, 1)";
64
+ const LEAVE_DURATION = 180;
65
+ /** Cards swapped at their place cross quickly. */
66
+ const SWAP_DURATION = 150;
67
+ /** How long after each other cards laid at once land, front-most last. */
68
+ const STAGGER = 25;
69
+ const HEADER_TRANSITION = [...[
70
+ "transform",
71
+ "margin",
72
+ "height",
73
+ "padding"
74
+ ].map((p) => `${p} ${DURATION}ms ${EASE}`), ...[
75
+ "background-color",
76
+ "box-shadow",
77
+ "color"
78
+ ].map((p) => `${p} ${DURATION}ms ease-out`)].join(", ");
79
+ /** How far below the front a card is laid from, or pulled away to, in px. */
80
+ const PULL = 24;
81
+ const PLACED = {
82
+ transform: "none",
83
+ opacity: 1
84
+ };
85
+ const PULLED = {
86
+ transform: `translateY(${PULL}px)`,
87
+ opacity: 0
88
+ };
89
+ const BEHIND = {
90
+ transform: "translateY(-2px) scale(0.995)",
91
+ opacity: .8
92
+ };
93
+ const COMING = {
94
+ front: [
95
+ PULLED,
96
+ {
97
+ opacity: 1,
98
+ offset: .4
99
+ },
100
+ PLACED
101
+ ],
102
+ back: [BEHIND, PLACED],
103
+ same: [{ opacity: 0 }, { opacity: 1 }]
104
+ };
105
+ const GOING = {
106
+ front: [
107
+ PLACED,
108
+ {
109
+ opacity: 1,
110
+ offset: .3
111
+ },
112
+ PULLED
113
+ ],
114
+ back: [PLACED, {
115
+ ...BEHIND,
116
+ opacity: 0
117
+ }],
118
+ same: [{ opacity: 1 }, { opacity: 0 }]
119
+ };
120
+ const GOING_TIMING = {
121
+ front: {
122
+ duration: LEAVE_DURATION,
123
+ easing: LEAVE_EASING
124
+ },
125
+ back: {
126
+ duration: DURATION,
127
+ easing: EASE
128
+ },
129
+ same: {
130
+ duration: SWAP_DURATION,
131
+ easing: "ease-out"
132
+ }
133
+ };
134
+ function motionFor(depth, front) {
135
+ if (depth > front) return "front";
136
+ if (depth < front) return "back";
137
+ return "same";
138
+ }
139
+ function prefersMotion() {
140
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
141
+ }
142
+ const SelectionViewsContext = React.createContext(null);
143
+ const StackMotionContext = React.createContext(null);
144
+ /**
145
+ * Wraps a stack whose selection views render apart from the views under them, so the views
146
+ * under them know how many are laid over them. Its cards move as the stack changes.
147
+ */
148
+ function SidebarStack(t0) {
149
+ const $ = c(13);
150
+ const { children } = t0;
151
+ const [count, setCount] = React.useState(0);
152
+ let t1;
153
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
154
+ t1 = {
155
+ ready: false,
156
+ front: null,
157
+ behind: null,
158
+ inFront: null
159
+ };
160
+ $[0] = t1;
161
+ } else t1 = $[0];
162
+ const motion = React.useRef(t1);
163
+ let t2;
164
+ let t3;
165
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
166
+ t2 = () => {
167
+ const current = motion.current;
168
+ current.ready = true;
169
+ return () => {
170
+ current.ready = false;
171
+ };
172
+ };
173
+ t3 = [];
174
+ $[1] = t2;
175
+ $[2] = t3;
176
+ } else {
177
+ t2 = $[1];
178
+ t3 = $[2];
179
+ }
180
+ React.useLayoutEffect(t2, t3);
181
+ let t4;
182
+ if ($[3] !== count) {
183
+ t4 = {
184
+ count,
185
+ setCount
186
+ };
187
+ $[3] = count;
188
+ $[4] = t4;
189
+ } else t4 = $[4];
190
+ let t5;
191
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
192
+ t5 = cn("relative isolate flex min-h-0 flex-1 flex-col", SIDEBAR_GUTTER);
193
+ $[5] = t5;
194
+ } else t5 = $[5];
195
+ let t6;
196
+ let t7;
197
+ if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
198
+ t6 = /* @__PURE__ */ jsx("div", {
199
+ ref: (node) => {
200
+ motion.current.behind = node;
201
+ },
202
+ "aria-hidden": true,
203
+ className: "pointer-events-none absolute inset-0 -z-10 overflow-hidden"
204
+ });
205
+ t7 = /* @__PURE__ */ jsx("div", {
206
+ ref: (node_0) => {
207
+ motion.current.inFront = node_0;
208
+ },
209
+ "aria-hidden": true,
210
+ className: "pointer-events-none absolute inset-0 z-10 overflow-hidden"
211
+ });
212
+ $[6] = t6;
213
+ $[7] = t7;
214
+ } else {
215
+ t6 = $[6];
216
+ t7 = $[7];
217
+ }
218
+ let t8;
219
+ if ($[8] !== children) {
220
+ t8 = /* @__PURE__ */ jsx(StackMotionContext, {
221
+ value: motion,
222
+ children: /* @__PURE__ */ jsxs("div", {
223
+ className: t5,
224
+ children: [
225
+ children,
226
+ t6,
227
+ t7
228
+ ]
229
+ })
230
+ });
231
+ $[8] = children;
232
+ $[9] = t8;
233
+ } else t8 = $[9];
234
+ let t9;
235
+ if ($[10] !== t4 || $[11] !== t8) {
236
+ t9 = /* @__PURE__ */ jsx(SelectionViewsContext, {
237
+ value: t4,
238
+ children: t8
239
+ });
240
+ $[10] = t4;
241
+ $[11] = t8;
242
+ $[12] = t9;
243
+ } else t9 = $[12];
244
+ return t9;
245
+ }
246
+ /** A still copy of a card, where it was, so it can move away once the card is gone. */
247
+ function copyCard(card, layer) {
248
+ const layerRect = layer.getBoundingClientRect();
249
+ const rect = card.getBoundingClientRect();
250
+ const copy = card.cloneNode(true);
251
+ copy.setAttribute("aria-hidden", "true");
252
+ copy.setAttribute("inert", "");
253
+ Object.assign(copy.style, {
254
+ position: "absolute",
255
+ margin: "0",
256
+ left: `${rect.left - layerRect.left}px`,
257
+ top: `${rect.top - layerRect.top}px`,
258
+ width: `${rect.width}px`,
259
+ height: `${rect.height}px`
260
+ });
261
+ const scrolled = [];
262
+ const walk = (node, path) => {
263
+ if (node.scrollTop > 0) scrolled.push([path, node.scrollTop]);
264
+ Array.from(node.children).forEach((child, i) => walk(child, [...path, i]));
265
+ };
266
+ walk(card, []);
267
+ const restoreScroll = () => {
268
+ for (const [path, top] of scrolled) {
269
+ let node = copy;
270
+ for (const i of path) node = node?.children[i];
271
+ if (node) node.scrollTop = top;
272
+ }
273
+ };
274
+ return {
275
+ copy,
276
+ restoreScroll
277
+ };
278
+ }
279
+ /**
280
+ * Moves a card of the stack, `depth` views from its back, as it comes and goes: into place
281
+ * from where the front was, then away relative to the new front.
282
+ */
283
+ function useStackCard(ref, depth, isView) {
284
+ const stack = React.useContext(StackMotionContext);
285
+ React.useLayoutEffect(() => {
286
+ const card = ref.current;
287
+ const motion = stack?.current;
288
+ if (!card || !motion || depth == null) return;
289
+ const previousFront = motion.front;
290
+ if (isView) motion.front = depth;
291
+ if (motion.ready && previousFront != null && prefersMotion()) {
292
+ const how = motionFor(depth, previousFront);
293
+ card.animate(COMING[how], {
294
+ duration: how === "same" ? SWAP_DURATION : DURATION,
295
+ easing: how === "same" ? "ease-out" : EASE,
296
+ delay: how === "front" ? (depth - previousFront - 1) * STAGGER : 0,
297
+ fill: "backwards"
298
+ });
299
+ }
300
+ return () => {
301
+ const { behind, inFront } = motion;
302
+ if (!motion.ready || !behind || !inFront || !prefersMotion()) return;
303
+ const { copy, restoreScroll } = copyCard(card, inFront);
304
+ queueMicrotask(() => {
305
+ if (card.isConnected) return;
306
+ const how = motionFor(depth, motion.front ?? depth);
307
+ (how === "front" ? inFront : behind).append(copy);
308
+ restoreScroll();
309
+ copy.animate(GOING[how], {
310
+ ...GOING_TIMING[how],
311
+ fill: "forwards"
312
+ }).finished.then(() => copy.remove(), () => copy.remove());
313
+ });
314
+ };
315
+ }, []);
316
+ }
317
+ /** How many of the selection's views are laid over the page's, in this stack. */
318
+ function useSelectionViewCount() {
319
+ return React.useContext(SelectionViewsContext)?.count ?? 0;
320
+ }
321
+ /** Tells the stack how many views the selection lays over the page's, while it renders. */
322
+ function SelectionViewCount(t0) {
323
+ const $ = c(4);
324
+ const { count } = t0;
325
+ const setCount = React.useContext(SelectionViewsContext)?.setCount;
326
+ let t1;
327
+ let t2;
328
+ if ($[0] !== count || $[1] !== setCount) {
329
+ t1 = () => {
330
+ if (!setCount) return;
331
+ setCount(count);
332
+ return () => setCount(0);
333
+ };
334
+ t2 = [setCount, count];
335
+ $[0] = count;
336
+ $[1] = setCount;
337
+ $[2] = t1;
338
+ $[3] = t2;
339
+ } else {
340
+ t1 = $[2];
341
+ t2 = $[3];
342
+ }
343
+ React.useLayoutEffect(t1, t2);
344
+ return null;
345
+ }
346
+ /**
347
+ * A view's content, under its header, `depth` views from the back of the stack. Key it by the
348
+ * view, so it comes and goes with the view.
349
+ */
350
+ function SidebarStackView(t0) {
351
+ const $ = c(6);
352
+ const { depth, className, children } = t0;
353
+ const ref = React.useRef(null);
354
+ useStackCard(ref, depth, true);
355
+ const t1 = React.useContext(StackMotionContext) != null && "rounded-b-lg border border-t-0 border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
356
+ let t2;
357
+ if ($[0] !== className || $[1] !== t1) {
358
+ t2 = cn("bg-background min-h-0 flex-1 origin-top", t1, className);
359
+ $[0] = className;
360
+ $[1] = t1;
361
+ $[2] = t2;
362
+ } else t2 = $[2];
363
+ let t3;
364
+ if ($[3] !== children || $[4] !== t2) {
365
+ t3 = /* @__PURE__ */ jsx("div", {
366
+ ref,
367
+ className: t2,
368
+ children
369
+ });
370
+ $[3] = children;
371
+ $[4] = t2;
372
+ $[5] = t3;
373
+ } else t3 = $[5];
374
+ return t3;
375
+ }
376
+ function SidebarStackHeader(t0) {
377
+ const $ = c(55);
378
+ const { depth, distance: t1, first: t2, onSelect, hoverTarget, tooltip, popover, children } = t0;
379
+ const distance = t1 === void 0 ? 0 : t1;
380
+ const first = t2 === void 0 ? false : t2;
381
+ const covered = distance > 0;
382
+ const { send } = useEditingFrame();
383
+ const [hovered, setHovered] = React.useState(false);
384
+ let t3;
385
+ if ($[0] !== covered || $[1] !== hoverTarget || $[2] !== hovered) {
386
+ t3 = covered && hovered && hoverTarget !== void 0 ? JSON.stringify(hoverTarget) : null;
387
+ $[0] = covered;
388
+ $[1] = hoverTarget;
389
+ $[2] = hovered;
390
+ $[3] = t3;
391
+ } else t3 = $[3];
392
+ const hoverKey = t3;
393
+ let t4;
394
+ let t5;
395
+ if ($[4] !== hoverKey || $[5] !== send) {
396
+ t4 = () => {
397
+ if (hoverKey == null) return;
398
+ const target = JSON.parse(hoverKey);
399
+ send(selectionHoverMessage(target, true));
400
+ return () => send(selectionHoverMessage(target, false));
401
+ };
402
+ t5 = [hoverKey, send];
403
+ $[4] = hoverKey;
404
+ $[5] = send;
405
+ $[6] = t4;
406
+ $[7] = t5;
407
+ } else {
408
+ t4 = $[6];
409
+ t5 = $[7];
410
+ }
411
+ React.useEffect(t4, t5);
412
+ const ref = React.useRef(null);
413
+ useStackCard(ref, depth, false);
414
+ const [popoverOpen, setPopoverOpen] = React.useState(false);
415
+ const liftable = covered && (onSelect != null || popover != null);
416
+ const inStack = React.useContext(StackMotionContext) != null;
417
+ const flat = first && !covered && !inStack;
418
+ let t6;
419
+ if ($[8] !== covered || $[9] !== distance) {
420
+ t6 = covered ? stepSeries(FIRST_STEP_TILT, distance, TILT_FALLOFF) : 0;
421
+ $[8] = covered;
422
+ $[9] = distance;
423
+ $[10] = t6;
424
+ } else t6 = $[10];
425
+ const tilt = t6;
426
+ let t7;
427
+ if ($[11] !== distance) {
428
+ t7 = stepSeries(FIRST_STEP_SHADE, distance);
429
+ $[11] = distance;
430
+ $[12] = t7;
431
+ } else t7 = $[12];
432
+ const shade = t7;
433
+ let t8;
434
+ if ($[13] !== children || $[14] !== liftable || $[15] !== onSelect) {
435
+ t8 = liftable ? /* @__PURE__ */ jsx("button", {
436
+ type: "button",
437
+ className: "hover:text-foreground data-popup-open:text-foreground flex h-full w-full min-w-0 cursor-pointer items-center justify-center rounded-[inherit] px-3 text-center text-(--ancestor-foreground) transition-colors focus-visible:outline-none",
438
+ onMouseEnter: () => setHovered(true),
439
+ onMouseLeave: () => setHovered(false),
440
+ onClick: () => {
441
+ setHovered(false);
442
+ onSelect?.();
443
+ },
444
+ children: /* @__PURE__ */ jsx("span", {
445
+ className: "truncate opacity-(--fade) transition-opacity",
446
+ children
447
+ })
448
+ }) : null;
449
+ $[13] = children;
450
+ $[14] = liftable;
451
+ $[15] = onSelect;
452
+ $[16] = t8;
453
+ } else t8 = $[16];
454
+ const button = t8;
455
+ const t9 = !first && "-mt-1";
456
+ let t10;
457
+ if ($[17] !== t9) {
458
+ t10 = cn("relative shrink-0 origin-top", t9);
459
+ $[17] = t9;
460
+ $[18] = t10;
461
+ } else t10 = $[18];
462
+ const t11 = !flat && !first && "rounded-t-sm";
463
+ const t12 = covered ? "h-[38px] pb-1" : "h-11 px-3";
464
+ const t13 = first && !flat && "rounded-t-lg border border-b-0 border-border dark:border-[color-mix(in_srgb,var(--color-muted),white_10%)]";
465
+ const t14 = covered && !first && `border ${CARD_EDGE_COLOR} shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.08)] dark:shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.4)]`;
466
+ const t15 = !covered && !first && (inStack ? `${FRONT_CARD_EDGES} shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.4)]` : `border-t ${CARD_EDGE_COLOR} shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.4)]`);
467
+ const t16 = liftable && "hover:[--fade:1] hover:[--lift:var(--hover-lift)] hover:[--shade:var(--hover-shade)] hover:[--tilt:var(--hover-tilt)]";
468
+ const t17 = liftable && "has-focus-visible:[--fade:1] has-focus-visible:[--lift:var(--hover-lift)] has-focus-visible:[--shade:var(--hover-shade)] has-focus-visible:[--tilt:var(--hover-tilt)]";
469
+ const t18 = liftable && "has-data-popup-open:[--fade:1] has-data-popup-open:[--lift:var(--hover-lift)] has-data-popup-open:[--shade:var(--hover-shade)] has-data-popup-open:[--tilt:var(--hover-tilt)]";
470
+ let t19;
471
+ if ($[19] !== t11 || $[20] !== t12 || $[21] !== t13 || $[22] !== t14 || $[23] !== t15 || $[24] !== t16 || $[25] !== t17 || $[26] !== t18) {
472
+ t19 = cn("relative flex min-w-0 items-center justify-center text-center text-sm", t11, "[--ancestor-foreground:color-mix(in_oklab,var(--color-muted-foreground),var(--color-foreground)_40%)]", "[--fade:var(--rest-fade)] [--lift:0px] [--shade:var(--rest-shade)] [--tilt:var(--rest-tilt)]", "[--shade-color:black] [--shade-strength:1] dark:[--shade-color:white] dark:[--shade-strength:var(--dark-shade-strength)]", "origin-bottom [backface-visibility:hidden] motion-reduce:transition-none!", t12, t13, t14, t15, t16, t17, t18);
473
+ $[19] = t11;
474
+ $[20] = t12;
475
+ $[21] = t13;
476
+ $[22] = t14;
477
+ $[23] = t15;
478
+ $[24] = t16;
479
+ $[25] = t17;
480
+ $[26] = t18;
481
+ $[27] = t19;
482
+ } else t19 = $[27];
483
+ const t20 = `${tilt}deg`;
484
+ const t21 = `${tilt / 2}deg`;
485
+ const t22 = `${shade}%`;
486
+ const t23 = Math.max(0, distance - 1);
487
+ let t24;
488
+ if ($[28] !== t23) {
489
+ t24 = stepSeries(FIRST_STEP_SHADE, t23);
490
+ $[28] = t23;
491
+ $[29] = t24;
492
+ } else t24 = $[29];
493
+ const t25 = `${t24}%`;
494
+ const t26 = `${first ? 0 : -1.5}px`;
495
+ const t27 = covered ? 1 - stepSeries(FIRST_STEP_FADE, distance - 1) : 1;
496
+ let t28;
497
+ if ($[30] !== covered || $[31] !== distance) {
498
+ t28 = covered ? stackInset(distance) : void 0;
499
+ $[30] = covered;
500
+ $[31] = distance;
501
+ $[32] = t28;
502
+ } else t28 = $[32];
503
+ let t29;
504
+ if ($[33] !== t20 || $[34] !== t21 || $[35] !== t22 || $[36] !== t25 || $[37] !== t26 || $[38] !== t27 || $[39] !== t28) {
505
+ t29 = {
506
+ "--rest-tilt": t20,
507
+ "--hover-tilt": t21,
508
+ "--rest-shade": t22,
509
+ "--dark-shade-strength": DARK_SHADE_STRENGTH,
510
+ "--hover-shade": t25,
511
+ "--hover-lift": t26,
512
+ "--rest-fade": t27,
513
+ marginInline: t28,
514
+ transform: `perspective(${PERSPECTIVE}px) translateY(var(--lift)) rotateX(var(--tilt))`,
515
+ backgroundColor: "color-mix(in oklab, var(--color-background), var(--shade-color) calc(var(--shade) * var(--shade-strength)))",
516
+ transition: HEADER_TRANSITION
517
+ };
518
+ $[33] = t20;
519
+ $[34] = t21;
520
+ $[35] = t22;
521
+ $[36] = t25;
522
+ $[37] = t26;
523
+ $[38] = t27;
524
+ $[39] = t28;
525
+ $[40] = t29;
526
+ } else t29 = $[40];
527
+ const t30 = t29;
528
+ let t31;
529
+ if ($[41] !== button || $[42] !== children || $[43] !== covered || $[44] !== popover || $[45] !== popoverOpen || $[46] !== tooltip) {
530
+ t31 = button && popover ? /* @__PURE__ */ jsxs(Popover, {
531
+ open: popoverOpen,
532
+ onOpenChange: setPopoverOpen,
533
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: button }), /* @__PURE__ */ jsx(PopoverContent, {
534
+ side: "bottom",
535
+ sideOffset: 8,
536
+ className: "w-48 gap-0 p-1",
537
+ onClick: () => setPopoverOpen(false),
538
+ children: popover
539
+ })]
540
+ }) : button && tooltip ? /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, { render: button }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, {
541
+ side: "bottom",
542
+ children: tooltip
543
+ })] }) : button ?? (covered ? /* @__PURE__ */ jsx("span", {
544
+ className: "truncate px-3 text-(--ancestor-foreground) opacity-(--fade)",
545
+ children
546
+ }) : children);
547
+ $[41] = button;
548
+ $[42] = children;
549
+ $[43] = covered;
550
+ $[44] = popover;
551
+ $[45] = popoverOpen;
552
+ $[46] = tooltip;
553
+ $[47] = t31;
554
+ } else t31 = $[47];
555
+ let t32;
556
+ if ($[48] !== t19 || $[49] !== t30 || $[50] !== t31) {
557
+ t32 = /* @__PURE__ */ jsx("div", {
558
+ className: t19,
559
+ style: t30,
560
+ children: t31
561
+ });
562
+ $[48] = t19;
563
+ $[49] = t30;
564
+ $[50] = t31;
565
+ $[51] = t32;
566
+ } else t32 = $[51];
567
+ let t33;
568
+ if ($[52] !== t10 || $[53] !== t32) {
569
+ t33 = /* @__PURE__ */ jsx("div", {
570
+ ref,
571
+ className: t10,
572
+ children: t32
573
+ });
574
+ $[52] = t10;
575
+ $[53] = t32;
576
+ $[54] = t33;
577
+ } else t33 = $[54];
578
+ return t33;
579
+ }
580
+
581
+ //#endregion
582
+ export { BOTTOM_CARD_EDGES, CARD_BODY_EDGES, SIDEBAR_GUTTER, SelectionViewCount, SidebarStack, SidebarStackHeader, SidebarStackView, useSelectionViewCount };
@@ -1,6 +1,6 @@
1
1
  import { CanvasLoadingScreen } from "../../canvas/CanvasLoadingScreen.js";
2
- import { CanvasSidebarSkeleton } from "../../canvas/sidebar/CanvasSidebarSkeleton.js";
3
2
  import { previewStore, selectIsCanvasShown } from "../previewStore.js";
3
+ import { CanvasSidebarSkeleton } from "../../canvas/sidebar/CanvasSidebarSkeleton.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import { useSelector } from "@xstate/store-react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -36,7 +36,7 @@ function StudioEditingFallback(t0) {
36
36
  let t4;
37
37
  if ($[5] !== t1 || $[6] !== t3) {
38
38
  t4 = /* @__PURE__ */ jsxs("div", {
39
- className: "flex h-full min-h-0 flex-1",
39
+ className: "relative flex h-full min-h-0 flex-1",
40
40
  children: [t1, t3]
41
41
  });
42
42
  $[5] = t1;
@@ -102,7 +102,7 @@ function _temp() {}
102
102
  * the studio keeps the Canvas position and selection, and tells the new renderer.
103
103
  */
104
104
  function RendererFramesProvider(t0) {
105
- const $ = c(27);
105
+ const $ = c(28);
106
106
  const { runtimeBasePath, children } = t0;
107
107
  const queryClient = useQueryClient();
108
108
  const studioCache = useStudioCache();
@@ -166,32 +166,39 @@ function RendererFramesProvider(t0) {
166
166
  const revisions = React.use(RevisionsContext);
167
167
  let t6;
168
168
  let t7;
169
- if ($[12] !== draftScope || $[13] !== revisions) {
169
+ if ($[12] !== documentUrl || $[13] !== draftScope || $[14] !== revisions) {
170
170
  t6 = () => revisions?.subscribe((t8) => {
171
171
  const { draftId } = t8;
172
- if (draftId === draftScope.current()) setLoads(_temp2);
172
+ if (draftId !== draftScope.current()) return;
173
+ setSource(documentUrl());
174
+ setLoads(_temp2);
173
175
  });
174
- t7 = [revisions, draftScope];
175
- $[12] = draftScope;
176
- $[13] = revisions;
177
- $[14] = t6;
178
- $[15] = t7;
176
+ t7 = [
177
+ revisions,
178
+ draftScope,
179
+ documentUrl
180
+ ];
181
+ $[12] = documentUrl;
182
+ $[13] = draftScope;
183
+ $[14] = revisions;
184
+ $[15] = t6;
185
+ $[16] = t7;
179
186
  } else {
180
- t6 = $[14];
181
- t7 = $[15];
187
+ t6 = $[15];
188
+ t7 = $[16];
182
189
  }
183
190
  React.useEffect(t6, t7);
184
191
  let t8;
185
- if ($[16] !== host) {
192
+ if ($[17] !== host) {
186
193
  t8 = (frame) => {
187
194
  if (frame && host) frame[STUDIO_HANDLE_KEY] = host.handle;
188
195
  };
189
- $[16] = host;
190
- $[17] = t8;
191
- } else t8 = $[17];
196
+ $[17] = host;
197
+ $[18] = t8;
198
+ } else t8 = $[18];
192
199
  const connect = t8;
193
200
  let t9;
194
- if ($[18] !== connect || $[19] !== host || $[20] !== loads || $[21] !== source) {
201
+ if ($[19] !== connect || $[20] !== host || $[21] !== loads || $[22] !== source) {
195
202
  t9 = host && /* @__PURE__ */ jsx("iframe", {
196
203
  ref: connect,
197
204
  src: source,
@@ -199,23 +206,23 @@ function RendererFramesProvider(t0) {
199
206
  title: "Website renderer",
200
207
  "data-camox-renderer": true
201
208
  }, `${source}#${loads}`);
202
- $[18] = connect;
203
- $[19] = host;
204
- $[20] = loads;
205
- $[21] = source;
206
- $[22] = t9;
207
- } else t9 = $[22];
209
+ $[19] = connect;
210
+ $[20] = host;
211
+ $[21] = loads;
212
+ $[22] = source;
213
+ $[23] = t9;
214
+ } else t9 = $[23];
208
215
  let t10;
209
- if ($[23] !== children || $[24] !== host || $[25] !== t9) {
216
+ if ($[24] !== children || $[25] !== host || $[26] !== t9) {
210
217
  t10 = /* @__PURE__ */ jsxs(RendererHostContext, {
211
218
  value: host,
212
219
  children: [children, t9]
213
220
  });
214
- $[23] = children;
215
- $[24] = host;
216
- $[25] = t9;
217
- $[26] = t10;
218
- } else t10 = $[26];
221
+ $[24] = children;
222
+ $[25] = host;
223
+ $[26] = t9;
224
+ $[27] = t10;
225
+ } else t10 = $[27];
219
226
  return t10;
220
227
  }
221
228
  function _temp2(count) {
@@ -112,7 +112,7 @@ function RuntimeChrome(t0) {
112
112
  let t17;
113
113
  if ($[22] !== t14 || $[23] !== t16) {
114
114
  t17 = /* @__PURE__ */ jsxs("div", {
115
- className: "flex min-h-0 flex-1",
115
+ className: "relative flex min-h-0 flex-1",
116
116
  children: [t14, t16]
117
117
  });
118
118
  $[22] = t14;