camox 0.52.3 → 0.53.1

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