camox 0.45.0 → 0.47.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.
- package/dist/core/hooks/useArtifactHost.js +2 -2
- package/dist/features/canvas/CamoxCanvas.js +438 -771
- package/dist/features/canvas/CanvasPageFrame.js +1 -3
- package/dist/features/canvas/CanvasPreviewPageSlot.js +26 -6
- package/dist/features/canvas/canvasCamera.js +24 -9
- package/dist/features/canvas/canvasFrameDocument.js +4 -19
- package/dist/features/canvas/canvasItems.js +12 -102
- package/dist/features/canvas/canvasStore.js +3 -92
- package/dist/features/canvas/sidebar/CanvasNavigator.js +81 -183
- package/dist/features/canvas/sidebar/CanvasSidebar.js +22 -28
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +2 -2
- package/dist/features/canvas/useCanvasCamera.js +16 -31
- package/dist/features/canvas/useCanvasFrame.js +5 -6
- package/dist/features/preview/CamoxPreview.js +137 -120
- package/dist/features/preview/components/{AddBlockDialog.js → AddBlockSheet.js} +35 -32
- package/dist/features/preview/components/BlockActionsPopover.js +6 -6
- package/dist/features/preview/components/BlockThumbnail.js +31 -33
- package/dist/features/preview/components/Overlays.js +1 -1
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +74 -85
- package/dist/features/preview/previewStore.js +9 -9
- package/dist/features/provider/CamoxProvider.js +8 -16
- package/dist/features/provider/CoreCamoxProvider.js +10 -12
- package/dist/features/provider/signInShortcut.js +60 -0
- package/dist/features/routes/pageRuntime.js +8 -8
- package/dist/features/runtime/RuntimeChrome.js +1 -1
- package/dist/features/runtime/pageApp.js +11 -39
- package/dist/features/runtime/runtime.d.ts +2 -7
- package/dist/features/runtime/runtime.js +6 -19
- package/dist/features/studio/FollowAgentProvider.js +11 -22
- package/dist/features/studio/components/FaviconDialog.js +3 -3
- package/dist/features/studio/followAgent.js +5 -14
- package/dist/features/studio/routes.js +1 -23
- package/dist/lib/auth.js +36 -24
- package/dist/lib/studio-reads.js +0 -20
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/skills/camox-expand/SKILL.md +5 -4
- package/dist/features/canvas/CanvasBlockFrame.js +0 -353
- package/dist/features/canvas/CanvasBlockHeader.js +0 -55
- package/dist/features/canvas/CanvasShelfMarker.js +0 -255
- package/dist/features/canvas/sidebar/CatalogBlockInspector.js +0 -189
- package/dist/features/provider/LocalhostPreviewProvider.js +0 -158
|
@@ -1,224 +1,122 @@
|
|
|
1
|
-
import { cn } from "../../../lib/utils.js";
|
|
2
1
|
import { previewStore } from "../../preview/previewStore.js";
|
|
3
2
|
import { canvasPagePath } from "../canvasPages.js";
|
|
4
3
|
import { c } from "react/compiler-runtime";
|
|
5
4
|
import * as React from "react";
|
|
6
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
6
|
import { Button } from "@camox/ui/button";
|
|
8
|
-
import {
|
|
7
|
+
import { Plus } from "lucide-react";
|
|
9
8
|
import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, commandFilter } from "@camox/ui/command";
|
|
10
9
|
|
|
11
10
|
//#region src/features/canvas/sidebar/CanvasNavigator.tsx
|
|
12
|
-
/** Blocks behind a bordered toggle, collapsed until opened. */
|
|
13
|
-
function CollapsedBlocks(t0) {
|
|
14
|
-
const $ = c(14);
|
|
15
|
-
const { label, children } = t0;
|
|
16
|
-
const [expanded, setExpanded] = React.useState(false);
|
|
17
|
-
let t1;
|
|
18
|
-
let t2;
|
|
19
|
-
let t3;
|
|
20
|
-
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
21
|
-
t1 = cn("hover:bg-accent/75 flex w-full cursor-default items-center gap-2 px-3 py-2 text-left text-sm", "focus-visible:rounded-none focus-visible:ring-inset");
|
|
22
|
-
t2 = () => setExpanded(_temp);
|
|
23
|
-
t3 = /* @__PURE__ */ jsx(ChevronsUpDown, { className: "text-muted-foreground size-4 shrink-0" });
|
|
24
|
-
$[0] = t1;
|
|
25
|
-
$[1] = t2;
|
|
26
|
-
$[2] = t3;
|
|
27
|
-
} else {
|
|
28
|
-
t1 = $[0];
|
|
29
|
-
t2 = $[1];
|
|
30
|
-
t3 = $[2];
|
|
31
|
-
}
|
|
32
|
-
let t4;
|
|
33
|
-
if ($[3] !== label) {
|
|
34
|
-
t4 = /* @__PURE__ */ jsx("span", {
|
|
35
|
-
className: "truncate",
|
|
36
|
-
children: label
|
|
37
|
-
});
|
|
38
|
-
$[3] = label;
|
|
39
|
-
$[4] = t4;
|
|
40
|
-
} else t4 = $[4];
|
|
41
|
-
let t5;
|
|
42
|
-
if ($[5] !== expanded || $[6] !== t4) {
|
|
43
|
-
t5 = /* @__PURE__ */ jsxs("button", {
|
|
44
|
-
type: "button",
|
|
45
|
-
"aria-expanded": expanded,
|
|
46
|
-
className: t1,
|
|
47
|
-
onClick: t2,
|
|
48
|
-
children: [t3, t4]
|
|
49
|
-
});
|
|
50
|
-
$[5] = expanded;
|
|
51
|
-
$[6] = t4;
|
|
52
|
-
$[7] = t5;
|
|
53
|
-
} else t5 = $[7];
|
|
54
|
-
let t6;
|
|
55
|
-
if ($[8] !== children || $[9] !== expanded) {
|
|
56
|
-
t6 = expanded && /* @__PURE__ */ jsx("div", {
|
|
57
|
-
className: "border-input border-t p-1",
|
|
58
|
-
children
|
|
59
|
-
});
|
|
60
|
-
$[8] = children;
|
|
61
|
-
$[9] = expanded;
|
|
62
|
-
$[10] = t6;
|
|
63
|
-
} else t6 = $[10];
|
|
64
|
-
let t7;
|
|
65
|
-
if ($[11] !== t5 || $[12] !== t6) {
|
|
66
|
-
t7 = /* @__PURE__ */ jsxs("div", {
|
|
67
|
-
className: "border-input flex flex-col overflow-hidden rounded-lg border shadow-xs",
|
|
68
|
-
children: [t5, t6]
|
|
69
|
-
});
|
|
70
|
-
$[11] = t5;
|
|
71
|
-
$[12] = t6;
|
|
72
|
-
$[13] = t7;
|
|
73
|
-
} else t7 = $[13];
|
|
74
|
-
return t7;
|
|
75
|
-
}
|
|
76
|
-
function _temp(value) {
|
|
77
|
-
return !value;
|
|
78
|
-
}
|
|
79
|
-
function canvasItemLabel(item) {
|
|
80
|
-
return item.kind === "page" ? item.page.title : item.block._internal.title;
|
|
81
|
-
}
|
|
82
|
-
/** Search an item by its label, and a Page by its path too, never by its key. */
|
|
83
|
-
function canvasItemKeywords(item) {
|
|
84
|
-
const label = canvasItemLabel(item);
|
|
85
|
-
const path = item.kind === "page" ? canvasPagePath(item.page) : null;
|
|
86
|
-
return path ? [label, path] : [label];
|
|
87
|
-
}
|
|
88
11
|
/**
|
|
89
|
-
* The Canvas Navigator, shown while nothing is selected: every
|
|
90
|
-
* in Canvas order,
|
|
91
|
-
*
|
|
92
|
-
* finds them. Picking an item shows it: the camera goes to it.
|
|
12
|
+
* The Canvas Navigator, shown while nothing is selected: every Page of the Canvas,
|
|
13
|
+
* in Canvas order, with its path, and a search that takes focus. Picking a Page
|
|
14
|
+
* shows it: the camera goes to it.
|
|
93
15
|
*/
|
|
94
16
|
function CanvasNavigator(t0) {
|
|
95
|
-
const $ = c(
|
|
96
|
-
const {
|
|
17
|
+
const $ = c(17);
|
|
18
|
+
const { pages, selectedKey, onShowPage } = t0;
|
|
97
19
|
const [search, setSearch] = React.useState("");
|
|
98
20
|
let t1;
|
|
99
21
|
if ($[0] !== search) {
|
|
100
|
-
t1 =
|
|
101
|
-
|
|
102
|
-
$[1] = t1;
|
|
103
|
-
} else t1 = $[1];
|
|
104
|
-
const searching = t1 !== "";
|
|
105
|
-
let t2;
|
|
106
|
-
if ($[2] !== onShowItem || $[3] !== selectedKey) {
|
|
107
|
-
t2 = (item) => {
|
|
108
|
-
const selected = item.key === selectedKey;
|
|
109
|
-
const path = item.kind === "page" ? canvasPagePath(item.page) : null;
|
|
110
|
-
return /* @__PURE__ */ jsx(CommandItem, {
|
|
111
|
-
value: item.key,
|
|
112
|
-
keywords: canvasItemKeywords(item),
|
|
113
|
-
"data-checked": selected,
|
|
114
|
-
"aria-current": selected ? "true" : void 0,
|
|
115
|
-
onSelect: () => onShowItem(item.key),
|
|
116
|
-
children: item.kind === "page" ? /* @__PURE__ */ jsxs("div", {
|
|
117
|
-
className: "flex min-w-0 flex-col py-0.5",
|
|
118
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
119
|
-
className: "truncate font-medium",
|
|
120
|
-
children: canvasItemLabel(item)
|
|
121
|
-
}), path && /* @__PURE__ */ jsx("span", {
|
|
122
|
-
className: "text-muted-foreground truncate font-mono text-xs",
|
|
123
|
-
children: path
|
|
124
|
-
})]
|
|
125
|
-
}) : /* @__PURE__ */ jsx("span", {
|
|
126
|
-
className: "truncate",
|
|
127
|
-
children: canvasItemLabel(item)
|
|
128
|
-
})
|
|
129
|
-
}, item.key);
|
|
130
|
-
};
|
|
131
|
-
$[2] = onShowItem;
|
|
132
|
-
$[3] = selectedKey;
|
|
133
|
-
$[4] = t2;
|
|
134
|
-
} else t2 = $[4];
|
|
135
|
-
const renderItem = t2;
|
|
136
|
-
let t3;
|
|
137
|
-
if ($[5] !== search) {
|
|
138
|
-
t3 = /* @__PURE__ */ jsx(CommandInput, {
|
|
139
|
-
placeholder: "Search the Canvas…",
|
|
22
|
+
t1 = /* @__PURE__ */ jsx(CommandInput, {
|
|
23
|
+
placeholder: "Search pages…",
|
|
140
24
|
autoFocus: true,
|
|
141
25
|
value: search,
|
|
142
26
|
onValueChange: setSearch
|
|
143
27
|
});
|
|
144
|
-
$[
|
|
145
|
-
$[
|
|
146
|
-
} else
|
|
28
|
+
$[0] = search;
|
|
29
|
+
$[1] = t1;
|
|
30
|
+
} else t1 = $[1];
|
|
31
|
+
let t2;
|
|
32
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
33
|
+
t2 = /* @__PURE__ */ jsx(CommandEmpty, { children: "Nothing found." });
|
|
34
|
+
$[2] = t2;
|
|
35
|
+
} else t2 = $[2];
|
|
36
|
+
const t3 = `Pages (${pages.length})`;
|
|
147
37
|
let t4;
|
|
148
|
-
if ($[
|
|
149
|
-
|
|
150
|
-
$[7]
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
children:
|
|
161
|
-
className: "
|
|
162
|
-
children: /* @__PURE__ */
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
children:
|
|
168
|
-
})
|
|
169
|
-
})]
|
|
170
|
-
}, shelf.key);
|
|
171
|
-
return /* @__PURE__ */ jsx(CommandGroup, {
|
|
172
|
-
heading: searching ? heading : void 0,
|
|
173
|
-
children: searching || shelf.items.length === 0 ? shelf.items.map(renderItem) : /* @__PURE__ */ jsx("div", {
|
|
174
|
-
className: "p-1",
|
|
175
|
-
children: /* @__PURE__ */ jsx(CollapsedBlocks, {
|
|
176
|
-
label: `${shelf.items.length} ${shelf.items.length === 1 ? "block" : "blocks"}`,
|
|
177
|
-
children: shelf.items.map(renderItem)
|
|
178
|
-
})
|
|
38
|
+
if ($[3] !== onShowPage || $[4] !== pages || $[5] !== selectedKey) {
|
|
39
|
+
let t5;
|
|
40
|
+
if ($[7] !== onShowPage || $[8] !== selectedKey) {
|
|
41
|
+
t5 = (page) => {
|
|
42
|
+
const selected = page.key === selectedKey;
|
|
43
|
+
const path = canvasPagePath(page);
|
|
44
|
+
return /* @__PURE__ */ jsx(CommandItem, {
|
|
45
|
+
value: page.key,
|
|
46
|
+
keywords: path ? [page.title, path] : [page.title],
|
|
47
|
+
"data-checked": selected,
|
|
48
|
+
"aria-current": selected ? "true" : void 0,
|
|
49
|
+
onSelect: () => onShowPage(page.key),
|
|
50
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
51
|
+
className: "flex min-w-0 flex-col py-0.5",
|
|
52
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
53
|
+
className: "truncate font-medium",
|
|
54
|
+
children: page.title
|
|
55
|
+
}), path && /* @__PURE__ */ jsx("span", {
|
|
56
|
+
className: "text-muted-foreground truncate font-mono text-xs",
|
|
57
|
+
children: path
|
|
58
|
+
})]
|
|
179
59
|
})
|
|
180
|
-
},
|
|
60
|
+
}, page.key);
|
|
181
61
|
};
|
|
182
|
-
$[
|
|
183
|
-
$[
|
|
184
|
-
$[
|
|
185
|
-
} else
|
|
186
|
-
|
|
187
|
-
$[
|
|
188
|
-
$[
|
|
189
|
-
$[
|
|
190
|
-
$[
|
|
191
|
-
} else
|
|
62
|
+
$[7] = onShowPage;
|
|
63
|
+
$[8] = selectedKey;
|
|
64
|
+
$[9] = t5;
|
|
65
|
+
} else t5 = $[9];
|
|
66
|
+
t4 = pages.map(t5);
|
|
67
|
+
$[3] = onShowPage;
|
|
68
|
+
$[4] = pages;
|
|
69
|
+
$[5] = selectedKey;
|
|
70
|
+
$[6] = t4;
|
|
71
|
+
} else t4 = $[6];
|
|
72
|
+
let t5;
|
|
73
|
+
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
74
|
+
t5 = /* @__PURE__ */ jsx("div", {
|
|
75
|
+
className: "p-1",
|
|
76
|
+
children: /* @__PURE__ */ jsxs(Button, {
|
|
77
|
+
type: "button",
|
|
78
|
+
variant: "secondary",
|
|
79
|
+
className: "w-full",
|
|
80
|
+
onClick: _temp2,
|
|
81
|
+
children: [/* @__PURE__ */ jsx(Plus, {}), "Create page"]
|
|
82
|
+
})
|
|
83
|
+
});
|
|
84
|
+
$[10] = t5;
|
|
85
|
+
} else t5 = $[10];
|
|
192
86
|
let t6;
|
|
193
|
-
if ($[
|
|
87
|
+
if ($[11] !== t3 || $[12] !== t4) {
|
|
194
88
|
t6 = /* @__PURE__ */ jsxs(CommandList, {
|
|
195
89
|
className: "max-h-none flex-1",
|
|
196
|
-
children: [
|
|
90
|
+
children: [t2, /* @__PURE__ */ jsxs(CommandGroup, {
|
|
91
|
+
heading: t3,
|
|
92
|
+
children: [t4, t5]
|
|
93
|
+
})]
|
|
197
94
|
});
|
|
198
|
-
$[
|
|
199
|
-
$[
|
|
200
|
-
|
|
95
|
+
$[11] = t3;
|
|
96
|
+
$[12] = t4;
|
|
97
|
+
$[13] = t6;
|
|
98
|
+
} else t6 = $[13];
|
|
201
99
|
let t7;
|
|
202
|
-
if ($[
|
|
100
|
+
if ($[14] !== t1 || $[15] !== t6) {
|
|
203
101
|
t7 = /* @__PURE__ */ jsx("div", {
|
|
204
102
|
"data-canvas-navigator": true,
|
|
205
103
|
className: "flex min-h-0 flex-1 flex-col",
|
|
206
104
|
children: /* @__PURE__ */ jsxs(Command$1, {
|
|
207
105
|
className: "rounded-none! bg-transparent",
|
|
208
|
-
filter:
|
|
209
|
-
children: [
|
|
106
|
+
filter: _temp,
|
|
107
|
+
children: [t1, t6]
|
|
210
108
|
})
|
|
211
109
|
});
|
|
212
|
-
$[
|
|
213
|
-
$[
|
|
214
|
-
$[
|
|
215
|
-
} else t7 = $[
|
|
110
|
+
$[14] = t1;
|
|
111
|
+
$[15] = t6;
|
|
112
|
+
$[16] = t7;
|
|
113
|
+
} else t7 = $[16];
|
|
216
114
|
return t7;
|
|
217
115
|
}
|
|
218
|
-
function
|
|
116
|
+
function _temp2() {
|
|
219
117
|
return previewStore.send({ type: "openCreatePageModal" });
|
|
220
118
|
}
|
|
221
|
-
function
|
|
119
|
+
function _temp(_value, search_0, keywords) {
|
|
222
120
|
return commandFilter(keywords?.join(" ") ?? "", search_0);
|
|
223
121
|
}
|
|
224
122
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { CanvasSidebarFrame } from "./CanvasSidebarFrame.js";
|
|
2
2
|
import { CreatePageModal } from "../../preview/components/CreatePageModal.js";
|
|
3
3
|
import { CanvasNavigator } from "./CanvasNavigator.js";
|
|
4
|
-
import { CatalogBlockInspector } from "./CatalogBlockInspector.js";
|
|
5
4
|
import { PageInspector } from "./PageInspector.js";
|
|
6
5
|
import { c } from "react/compiler-runtime";
|
|
7
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -9,50 +8,45 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
9
8
|
//#region src/features/canvas/sidebar/CanvasSidebar.tsx
|
|
10
9
|
/**
|
|
11
10
|
* The sidebar beside the Canvas. Without a selection, it shows the Canvas Navigator;
|
|
12
|
-
* with one, the Canvas Inspector of the selected Page
|
|
11
|
+
* with one, the Canvas Inspector of the selected Page.
|
|
13
12
|
*/
|
|
14
13
|
function CanvasSidebar(t0) {
|
|
15
|
-
const $ = c(
|
|
16
|
-
const { page,
|
|
14
|
+
const $ = c(11);
|
|
15
|
+
const { page, navigator, onShowWholeCanvas, onRenamePage, owner: t1, pageRecord } = t0;
|
|
17
16
|
const owner = t1 === void 0 ? null : t1;
|
|
18
|
-
const t2 =
|
|
17
|
+
const t2 = page?.title ?? "Canvas navigator";
|
|
19
18
|
let t3;
|
|
20
|
-
if ($[0] !==
|
|
21
|
-
t3 =
|
|
22
|
-
block: catalog.block,
|
|
23
|
-
projectId: catalog.projectId,
|
|
24
|
-
onBack: onShowWholeCanvas
|
|
25
|
-
}) : page ? /* @__PURE__ */ jsx(PageInspector, {
|
|
19
|
+
if ($[0] !== navigator || $[1] !== onRenamePage || $[2] !== onShowWholeCanvas || $[3] !== owner || $[4] !== page || $[5] !== pageRecord) {
|
|
20
|
+
t3 = page ? /* @__PURE__ */ jsx(PageInspector, {
|
|
26
21
|
page,
|
|
27
22
|
owner,
|
|
28
23
|
pageRecord,
|
|
29
24
|
onBack: onShowWholeCanvas,
|
|
30
25
|
onRenamePage
|
|
31
26
|
}) : /* @__PURE__ */ jsx(CanvasNavigator, { ...navigator });
|
|
32
|
-
$[0] =
|
|
33
|
-
$[1] =
|
|
34
|
-
$[2] =
|
|
35
|
-
$[3] =
|
|
36
|
-
$[4] =
|
|
37
|
-
$[5] =
|
|
38
|
-
$[6] =
|
|
39
|
-
|
|
40
|
-
} else t3 = $[7];
|
|
27
|
+
$[0] = navigator;
|
|
28
|
+
$[1] = onRenamePage;
|
|
29
|
+
$[2] = onShowWholeCanvas;
|
|
30
|
+
$[3] = owner;
|
|
31
|
+
$[4] = page;
|
|
32
|
+
$[5] = pageRecord;
|
|
33
|
+
$[6] = t3;
|
|
34
|
+
} else t3 = $[6];
|
|
41
35
|
let t4;
|
|
42
|
-
if ($[
|
|
36
|
+
if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
|
|
43
37
|
t4 = /* @__PURE__ */ jsx(CreatePageModal, {});
|
|
44
|
-
$[
|
|
45
|
-
} else t4 = $[
|
|
38
|
+
$[7] = t4;
|
|
39
|
+
} else t4 = $[7];
|
|
46
40
|
let t5;
|
|
47
|
-
if ($[
|
|
41
|
+
if ($[8] !== t2 || $[9] !== t3) {
|
|
48
42
|
t5 = /* @__PURE__ */ jsxs(CanvasSidebarFrame, {
|
|
49
43
|
label: t2,
|
|
50
44
|
children: [t3, t4]
|
|
51
45
|
});
|
|
52
|
-
$[
|
|
53
|
-
$[
|
|
54
|
-
$[
|
|
55
|
-
} else t5 = $[
|
|
46
|
+
$[8] = t2;
|
|
47
|
+
$[9] = t3;
|
|
48
|
+
$[10] = t5;
|
|
49
|
+
} else t5 = $[10];
|
|
56
50
|
return t5;
|
|
57
51
|
}
|
|
58
52
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useProjectUuid } from "../../../lib/auth.js";
|
|
2
2
|
import { reads, useRead } from "../../../lib/studio-reads.js";
|
|
3
3
|
import { useLocalePath } from "../../../lib/view-locale.js";
|
|
4
|
-
import {
|
|
4
|
+
import { AddBlockSheet } from "../../preview/components/AddBlockSheet.js";
|
|
5
5
|
import { PreviewEditingOwnerContext } from "../../preview/previewSelection.js";
|
|
6
6
|
import { PageInfo } from "../../preview/components/PageInfo.js";
|
|
7
7
|
import { PageTree } from "../../preview/components/PageTree.js";
|
|
@@ -51,7 +51,7 @@ function CuratedPageInspector() {
|
|
|
51
51
|
const t3 = owner?.kind === "page" && owner.pageId === pageId;
|
|
52
52
|
let t4;
|
|
53
53
|
if ($[6] !== t3) {
|
|
54
|
-
t4 = /* @__PURE__ */ jsx(
|
|
54
|
+
t4 = /* @__PURE__ */ jsx(AddBlockSheet, { focusCreatedBlock: t3 });
|
|
55
55
|
$[6] = t3;
|
|
56
56
|
$[7] = t4;
|
|
57
57
|
} else t4 = $[7];
|
|
@@ -2,7 +2,7 @@ import { canvasStore } from "./canvasStore.js";
|
|
|
2
2
|
import { ViewportContinuityContext, captureViewportAnchor, resolveViewportAnchor } from "../preview/viewportContinuity.js";
|
|
3
3
|
import { canvasPageIframe } from "../preview/previewPageFrame.js";
|
|
4
4
|
import { canvasBlockOverlap } from "./canvasFrameDocument.js";
|
|
5
|
-
import { CANVAS_WHEEL_ZOOM_RATE,
|
|
5
|
+
import { CANVAS_WHEEL_ZOOM_RATE, ZOOM_STRETCH, canvasMaximumScale, canvasMinimumScale, canvasOverview, canvasVerticalRail, canvasWheelDelta, constrainCanvasCamera, findCanvasSnapTarget, fitCanvasPage, isCanvasCameraSnapped, isCanvasPageScale, isInCanvasSnapWindow, placeCanvasPageAnchor, snapCanvasZoom, stretchCanvasZoom, unstretchCanvasZoom, zoomCanvasAt } from "./canvasCamera.js";
|
|
6
6
|
import { revealScrollDelta } from "../preview/selectionReveal.js";
|
|
7
7
|
import { createCanvasFlight, createCanvasPan } from "./canvasFlight.js";
|
|
8
8
|
import * as React from "react";
|
|
@@ -71,13 +71,6 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
71
71
|
};
|
|
72
72
|
}, []);
|
|
73
73
|
/**
|
|
74
|
-
* Pan immediately so a world x sits at or right of a screen x; never pans
|
|
75
|
-
* otherwise, nor while a selection holds the camera.
|
|
76
|
-
*/
|
|
77
|
-
const keepInView = React.useCallback((worldX, screenX) => {
|
|
78
|
-
flightControls.current?.keepInView(worldX, screenX);
|
|
79
|
-
}, []);
|
|
80
|
-
/**
|
|
81
74
|
* Pan vertically to an element inside a Canvas frame, such as a selected block,
|
|
82
75
|
* unless enough of it already shows. A page flight or a drag in progress keeps the camera.
|
|
83
76
|
*/
|
|
@@ -240,16 +233,17 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
240
233
|
};
|
|
241
234
|
const candidate = findCanvasSnapTarget(intended, viewportSize, targets());
|
|
242
235
|
const fit = candidate && fitCanvasPage(viewportSize, candidate);
|
|
243
|
-
if (!candidate || !fit ||
|
|
244
|
-
const held =
|
|
245
|
-
|
|
246
|
-
if (Math.abs(intended.x - fit.x) > band) return intended;
|
|
236
|
+
if (!candidate || !fit || fit.scale < minimumScale) return intended;
|
|
237
|
+
const held = isCanvasCameraSnapped(base, viewportSize, candidate);
|
|
238
|
+
if (!isInCanvasSnapWindow(intended, viewportSize, candidate, held)) return intended;
|
|
247
239
|
if (selection !== candidate.key) rowRef.current?.onSnap?.();
|
|
248
240
|
select(candidate.key);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
x: fit.x
|
|
252
|
-
|
|
241
|
+
gesture.intendedX += (candidate.left + candidate.width / 2) * (intended.scale - fit.scale);
|
|
242
|
+
return constrain({
|
|
243
|
+
x: fit.x,
|
|
244
|
+
y: rescaleY(intended, fit.scale),
|
|
245
|
+
scale: fit.scale
|
|
246
|
+
});
|
|
253
247
|
};
|
|
254
248
|
const endZoom = () => {
|
|
255
249
|
ownerWindow.clearTimeout(zoomEnd);
|
|
@@ -271,6 +265,10 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
271
265
|
else delete element.dataset.canvasPan;
|
|
272
266
|
};
|
|
273
267
|
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
268
|
+
const isOverview = (view) => {
|
|
269
|
+
const overview = canvasOverview(viewportSize, contentSize);
|
|
270
|
+
return Math.abs(view.scale - overview.scale) < 1e-8 && Math.abs(view.x - overview.x) < .5 && Math.abs(view.y - overview.y) < .5;
|
|
271
|
+
};
|
|
274
272
|
const remember = () => {
|
|
275
273
|
if (restoredCamera || fittingInitialPage || !viewportSize.width || !viewportSize.height) return;
|
|
276
274
|
canvasStore.send({
|
|
@@ -278,7 +276,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
278
276
|
workspaceKey,
|
|
279
277
|
view: {
|
|
280
278
|
camera,
|
|
281
|
-
fitted:
|
|
279
|
+
fitted: isOverview(camera)
|
|
282
280
|
}
|
|
283
281
|
});
|
|
284
282
|
};
|
|
@@ -433,18 +431,6 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
433
431
|
};
|
|
434
432
|
flightControls.current = {
|
|
435
433
|
flyTo: startFlight,
|
|
436
|
-
keepInView: (worldX, screenX) => {
|
|
437
|
-
const x = screenX - worldX * camera.scale;
|
|
438
|
-
if (selection || camera.x >= x) return;
|
|
439
|
-
cancelCameraFlight();
|
|
440
|
-
restoredCamera = void 0;
|
|
441
|
-
fittingInitialPage = false;
|
|
442
|
-
gesture = void 0;
|
|
443
|
-
applyCamera({
|
|
444
|
-
...camera,
|
|
445
|
-
x
|
|
446
|
-
}, true);
|
|
447
|
-
},
|
|
448
434
|
reveal: (element, immediate) => {
|
|
449
435
|
const frame = element.ownerDocument.defaultView?.frameElement;
|
|
450
436
|
if (!frame || flight && !flight.pan || pointers.size) return;
|
|
@@ -535,7 +521,7 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
535
521
|
};
|
|
536
522
|
const nextContent = measureContent();
|
|
537
523
|
if (nextViewport.width === viewportSize.width && nextViewport.height === viewportSize.height && nextContent.width === contentSize.width && nextContent.height === contentSize.height) return;
|
|
538
|
-
const wasFitted =
|
|
524
|
+
const wasFitted = isOverview(target);
|
|
539
525
|
gesture = void 0;
|
|
540
526
|
const held = nextViewport.width !== viewportSize.width && !flight && !fittingInitialPage ? targetOf(selection) : void 0;
|
|
541
527
|
updateGeometry(nextViewport, nextContent);
|
|
@@ -793,7 +779,6 @@ function useCanvasCamera(workspaceKey, initialTarget, row) {
|
|
|
793
779
|
contentRef,
|
|
794
780
|
flyTo,
|
|
795
781
|
mirrorCamera,
|
|
796
|
-
keepInView,
|
|
797
782
|
reveal,
|
|
798
783
|
fitAll
|
|
799
784
|
};
|
|
@@ -20,7 +20,7 @@ function toError(error) {
|
|
|
20
20
|
* Unless live, the frame's document is paused. A resting frame keeps its size:
|
|
21
21
|
* its content is hidden, and must not shrink the frame and move the Canvas.
|
|
22
22
|
*/
|
|
23
|
-
function useCanvasFrame({ previewDocument, href, width, viewportHeight,
|
|
23
|
+
function useCanvasFrame({ previewDocument, href, width, viewportHeight, mode }) {
|
|
24
24
|
const iframeRef = React.useRef(null);
|
|
25
25
|
const [srcDoc, setSrcDoc] = React.useState();
|
|
26
26
|
const [mount, setMount] = React.useState(null);
|
|
@@ -44,7 +44,7 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, fit, sub
|
|
|
44
44
|
React.useLayoutEffect(() => {
|
|
45
45
|
const iframe = iframeRef.current;
|
|
46
46
|
if (!iframe || !mount) return;
|
|
47
|
-
const stop = observeCanvasDocument(iframe, mount, viewportHeight,
|
|
47
|
+
const stop = observeCanvasDocument(iframe, mount, viewportHeight, () => restingRef.current);
|
|
48
48
|
sizing.current = stop;
|
|
49
49
|
return () => {
|
|
50
50
|
stop();
|
|
@@ -53,8 +53,7 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, fit, sub
|
|
|
53
53
|
}, [
|
|
54
54
|
mount,
|
|
55
55
|
viewportHeight,
|
|
56
|
-
width
|
|
57
|
-
fit
|
|
56
|
+
width
|
|
58
57
|
]);
|
|
59
58
|
React.useEffect(() => {
|
|
60
59
|
if (!mount || live) return;
|
|
@@ -73,7 +72,7 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, fit, sub
|
|
|
73
72
|
try {
|
|
74
73
|
const loaded = iframeRef.current;
|
|
75
74
|
const root = (loaded?.contentDocument)?.querySelector("[data-camox-preview-root]");
|
|
76
|
-
if (!root) throw new Error(
|
|
75
|
+
if (!root) throw new Error("The page preview document has no content root.");
|
|
77
76
|
if (root === mount) return;
|
|
78
77
|
root.replaceChildren();
|
|
79
78
|
setMount(root);
|
|
@@ -82,7 +81,7 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, fit, sub
|
|
|
82
81
|
setFailure(toError(error));
|
|
83
82
|
}
|
|
84
83
|
},
|
|
85
|
-
onError: () => setFailure(/* @__PURE__ */ new Error(
|
|
84
|
+
onError: () => setFailure(/* @__PURE__ */ new Error("The page preview document could not load."))
|
|
86
85
|
}
|
|
87
86
|
};
|
|
88
87
|
}
|